> ## Documentation Index
> Fetch the complete documentation index at: https://docs.apollodeploy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create webhook

> Registers a new webhook endpoint for the project. Signal will POST a signed JSON payload to the given URL whenever any of the subscribed event types occurs. Each delivery is signed with HMAC-SHA256 using the endpoint's secret, which is returned once at creation time and never shown again.

### Requirements

- **Permission:** `webhooks:write`.
- **Project access:** the path project must match the API key's project.
- **HTTP rate limit:** 60 requests per 60 seconds per API key.



## OpenAPI

````yaml /signal/api-reference/openapi.json post /v1/projects/{projectId}/webhooks
openapi: 3.1.0
info:
  title: Apollo Signal API
  version: 1.0.0
  description: >-
    Public REST API for transactional email, contacts, audiences, webhooks,
    metrics, projects, and sending domains.
servers:
  - url: https://api.signal.apollodeploy.com
    description: Production
security: []
tags:
  - name: Emails
    description: Send, inspect, cancel, validate, and stream transactional email activity.
  - name: Metrics
    description: Read project, topic, message, and deliverability analytics.
  - name: Suppressions
    description: Manage addresses that Apollo Signal must not send to.
  - name: Segments
    description: Create dynamic contact groups and inspect their membership.
  - name: Topics
    description: Manage subscription topics and topic membership.
  - name: Contact properties
    description: Define the custom fields available on project contacts.
  - name: Contacts
    description: >-
      Manage contacts, audience membership, images, activity, and engagement
      data.
  - name: Webhooks
    description: Manage webhook endpoints, deliveries, tests, and replays.
  - name: API key usage
    description: Inspect API key metadata and request usage without exposing raw keys.
  - name: Projects
    description: Inspect projects and project-scoped email logs.
  - name: Sending domains
    description: >-
      Register, verify, inspect, and remove sending domains and BIMI
      configuration.
paths:
  /v1/projects/{projectId}/webhooks:
    post:
      tags:
        - Webhooks
      summary: Create webhook
      description: >-
        Registers a new webhook endpoint for the project. Signal will POST a
        signed JSON payload to the given URL whenever any of the subscribed
        event types occurs. Each delivery is signed with HMAC-SHA256 using the
        endpoint's secret, which is returned once at creation time and never
        shown again.


        ### Requirements


        - **Permission:** `webhooks:write`.

        - **Project access:** the path project must match the API key's project.

        - **HTTP rate limit:** 60 requests per 60 seconds per API key.
      operationId: createWebhook
      parameters:
        - name: projectId
          in: path
          description: The project to register the webhook in.
          required: true
          deprecated: false
          explode: false
          schema:
            type: string
            title: String
      requestBody:
        description: Target URL, event types to subscribe to, and optional description.
        content:
          application/json:
            schema:
              $ref: >-
                #/components/schemas/com.apollodeploy.signal.feature.webhook.api.model.CreateWebhookBody
        required: true
      responses:
        '201':
          description: >-
            Webhook created. The `secret` field is only present in this
            response.
          headers: {}
          content:
            application/json:
              schema:
                $ref: >-
                  #/components/schemas/com.apollodeploy.signal.feature.webhook.api.model.WebhookCreateResponse
        '400':
          description: Invalid URL format or unrecognised event types.
          headers: {}
          content:
            application/problem+json:
              schema:
                $ref: >-
                  #/components/schemas/com.apollodeploy.commons.core.error.ApiProblem
        '401':
          description: Missing or invalid credentials.
          headers: {}
          content:
            application/problem+json:
              schema:
                $ref: >-
                  #/components/schemas/com.apollodeploy.commons.core.error.ApiProblem
        '403':
          description: >-
            The credential lacks the required permission or cannot access this
            project.
          headers: {}
          content:
            application/problem+json:
              schema:
                $ref: >-
                  #/components/schemas/com.apollodeploy.commons.core.error.ApiProblem
        '404':
          description: Project not found.
          headers: {}
          content:
            application/problem+json:
              schema:
                $ref: >-
                  #/components/schemas/com.apollodeploy.commons.core.error.ApiProblem
        '429':
          description: >-
            The endpoint rate limit was exceeded. Wait for the `Retry-After`
            interval before retrying.
          headers:
            Retry-After:
              description: Whole seconds to wait before retrying.
              schema:
                type: integer
                minimum: 1
          content:
            application/problem+json:
              schema:
                $ref: >-
                  #/components/schemas/com.apollodeploy.commons.core.error.ApiProblem
      deprecated: false
      security:
        - bearerAuth: []
      x-codeSamples:
        - lang: TypeScript
          label: TypeScript
          source: >-
            import { createApolloSignalApiClient } from
            "@apollo-deploy/signal-sdk";


            const signal = createApolloSignalApiClient({ apiKey: "ap_signal_..."
            });


            const result = await signal.webhooks.createWebhook(/* params */);


            console.log(result);
        - lang: Python
          label: Python
          source: |-
            from apollo_signal import SignalClient

            signal = SignalClient(api_key="ap_signal_...")

            result = signal.webhooks.createWebhook(# params)

            print(result)
        - lang: Go
          label: Go
          source: >-
            import signal "github.com/apollo-deploy/signal-sdk-go"


            client := signal.NewClient("ap_signal_...")


            result, err := client.Webhooks.CreateWebhook(context.Background() /*
            params */)

            if err != nil {
                log.Fatal(err)
            }

            fmt.Println(result)
        - lang: Java
          label: Java
          source: |-
            import com.apollodeploy.signal.SignalClient;

            SignalClient signal = new SignalClient("ap_signal_...");

            var result = signal.webhooks().createWebhook(/* params */);
            System.out.println(result);
        - lang: Kotlin
          label: Kotlin
          source: |-
            import com.apollodeploy.signal.SignalClient

            val signal = SignalClient("ap_signal_...")

            val result = signal.webhooks.createWebhook(/* params */)
            println(result)
        - lang: Ruby
          label: Ruby
          source: |-
            require "apollo_signal"

            signal = ApolloSignal::Client.new(api_key: "ap_signal_...")

            result = signal.webhooks.createWebhook(# params)
            puts result
        - lang: PHP
          label: PHP
          source: |-
            use ApolloSignal\SignalClient;

            $signal = new SignalClient("ap_signal_...");

            $result = $signal->webhooks->createWebhook(/* params */);
            var_dump($result);
        - lang: Rust
          label: Rust
          source: |-
            use apollo_signal::SignalClient;

            let signal = SignalClient::new("ap_signal_...");

            let result = signal.webhooks.createWebhook(/* params */).await?;
            println!("{:?}", result);
        - lang: C#
          label: .NET
          source: |-
            using ApolloSignal;

            var signal = new SignalClient("ap_signal_...");

            var result = await signal.Webhooks.CreateWebhookAsync(/* params */);
            Console.WriteLine(result);
components:
  schemas:
    com.apollodeploy.signal.feature.webhook.api.model.CreateWebhookBody:
      type: object
      properties:
        events:
          type: array
          items:
            type: string
            enum:
              - email.sent
              - email.delivered
              - email.bounced
              - email.complained
              - email.opened
              - email.clicked
              - email.failed
              - email.rejected
              - email.delivery_delayed
              - email.suppressed
              - email.unsubscribed
              - email.read_engaged
              - webhook.test
          title: List<String>
          description: Event types delivered to this endpoint.
        filters:
          type: array
          items:
            $ref: >-
              #/components/schemas/com.apollodeploy.signal.feature.webhook.api.model.WebhookFilterSerializable
          title: List<WebhookFilterSerializable>
          description: All filters must match for an event to be delivered.
        name:
          type: string
          title: String
          description: Human-readable endpoint name. Signal generates one when omitted.
        secret:
          type: string
          title: String
          description: >-
            Optional signing secret. Signal generates one when omitted and
            returns it in the create response.
        transformations:
          type: array
          items:
            $ref: >-
              #/components/schemas/com.apollodeploy.signal.feature.webhook.api.model.WebhookTransformationSerializable
          title: List<WebhookTransformationSerializable>
          description: Payload transformations applied in list order after filtering.
        url:
          type: string
          title: String
          description: >-
            Public HTTPS delivery URL. Localhost and blocked private-network
            targets are rejected.
          format: uri
      required:
        - events
        - url
      title: CreateWebhookBody
      description: >-
        Webhook destination, subscribed event types, and optional payload
        processing rules.
    com.apollodeploy.signal.feature.webhook.api.model.WebhookCreateResponse:
      type: object
      properties:
        createdAt:
          type: string
          title: String
        enabled:
          type: boolean
          title: Boolean
        events:
          type: array
          items:
            type: string
            title: String
          title: List<String>
        filters:
          type: array
          items:
            $ref: >-
              #/components/schemas/com.apollodeploy.signal.feature.webhook.api.model.WebhookFilterSerializable
          title: List<WebhookFilterSerializable>
        id:
          type: string
          title: String
        name:
          type: string
          title: String
        projectId:
          type: string
          title: String
        secret:
          type: string
          title: String
        transformations:
          type: array
          items:
            $ref: >-
              #/components/schemas/com.apollodeploy.signal.feature.webhook.api.model.WebhookTransformationSerializable
          title: List<WebhookTransformationSerializable>
        updatedAt:
          type: string
          title: String
        url:
          type: string
          title: String
      required:
        - createdAt
        - enabled
        - events
        - id
        - name
        - projectId
        - secret
        - updatedAt
        - url
      title: WebhookCreateResponse
    com.apollodeploy.commons.core.error.ApiProblem:
      type: object
      properties:
        code:
          type: string
          title: ErrorCode
        detail:
          type: string
          title: String
        errors:
          type: array
          items:
            $ref: >-
              #/components/schemas/com.apollodeploy.commons.core.error.FieldProblem
          title: List<FieldProblem>
        instance:
          type: string
          title: ProblemInstance
        requestId:
          type: string
          title: String
        status:
          type: integer
          format: int32
          title: Int
        title:
          type: string
          title: String
        type:
          type: string
          title: ProblemType
      required:
        - code
        - status
        - title
        - type
      title: ApiProblem
    com.apollodeploy.signal.feature.webhook.api.model.WebhookFilterSerializable:
      type: object
      properties:
        field:
          type: string
          title: String
          description: Dot-delimited payload field path.
        operator:
          type: string
          title: String
          description: Comparison to apply.
          enum:
            - eq
            - neq
            - contains
            - exists
        value:
          type: string
          title: String
          description: Comparison value. Omit for the `exists` operator.
      required:
        - field
        - operator
      title: WebhookFilterSerializable
      description: >-
        Predicate evaluated against a dot-delimited field in the canonical event
        payload.
    com.apollodeploy.signal.feature.webhook.api.model.WebhookTransformationSerializable:
      type: object
      properties:
        field:
          type: string
          title: String
          description: Target field path for add, remove, or compute transformations.
        from:
          type: string
          title: String
          description: Source field path for `rename_field`.
        template:
          type: string
          title: String
          description: >-
            Mustache-style template evaluated by `compute_field`, for example
            `{{data.firstName}}`.
        to:
          type: string
          title: String
          description: Destination field path for `rename_field`.
        type:
          type: string
          title: String
          description: Transformation kind.
          enum:
            - rename_field
            - add_field
            - remove_field
            - compute_field
        value:
          type: string
          title: String
          description: Value assigned by `add_field`; `null` is allowed.
      required:
        - type
      title: WebhookTransformationSerializable
      description: >-
        One payload mutation. Required companion fields depend on `type`: `from`
        and `to` for rename; `field` for add/remove; `field` and `template` for
        compute.
    com.apollodeploy.commons.core.error.FieldProblem:
      type: object
      properties:
        detail:
          type: string
          title: String
        pointer:
          type: string
          title: String
      required:
        - detail
        - pointer
      title: FieldProblem
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        Project-bound Apollo Signal API key. Keys begin with `ap_signal_` and
        must carry the permission shown on the operation.

````