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

# Update Webhook

> Change the webhook URL, custom headers, and event subscriptions of an application.

## What it does

Sets the webhook configuration for an application: the HTTPS URL the Gateway posts events to, the custom headers it attaches to each delivery, and which event types you are subscribed to.

The same path also serves a read: send it without a body to get the active configuration back instead — see [Get Webhook](/public-api-reference/developers/get-webhook).

<Tip>
  Point the URL at a request-inspection service (for example `webhook.site`) while you are wiring things up, then switch it to your own endpoint. The change takes effect on the next event, with no redeploy on your side.
</Tip>

<Warning>
  Your endpoint must be reachable over **HTTPS with a valid certificate** and must answer **HTTP 200 within 5 seconds**. Do the real work asynchronously — see [Webhooks](/api-reference/webhooks).
</Warning>

***

## Endpoint

```text theme={null}
POST /api/v1/apps/{app_id}/webhook
```

### Headers

<ParamField header="Authorization" type="string" required>
  Secret key in `Bearer sk_...` format. See [Secret Key authentication](/essentials/authentication#secret-key).
</ParamField>

<ParamField header="Content-Type" type="string" required>
  Always `application/json`.
</ParamField>

### Path parameters

<ParamField path="app_id" type="string" required>
  Application ID. Must belong to the organization (otherwise `404`).
</ParamField>

***

## Request Body

<ParamField body="url" type="string" required>
  The HTTPS endpoint that will receive events. Must be publicly reachable and serve a valid TLS certificate.
</ParamField>

<ParamField body="headers" type="object">
  Custom headers the Gateway attaches to every delivery, as a key → value map. Use it to carry your own shared secret or routing token. Send `{}` to clear the existing headers.

  <Note>
    This is a free-form map, so it is the place to put anything your infrastructure needs (an auth token, a tenant ID, a WAF bypass header). Do not put credentials that you would not want to see stored on the configuration.
  </Note>
</ParamField>

<ParamField body="subscribedEvents" type="object">
  Event name → boolean map controlling which events are delivered. Events set to `false`, and events you leave out, are not delivered.
</ParamField>

### Event types

The five event names accepted inside `subscribedEvents`:

| Event                     | Delivered when                                             |
| ------------------------- | ---------------------------------------------------------- |
| `messages`                | A user sent a message to your WhatsApp number.             |
| `message_status`          | Outbound message status changed (sent, delivered, failed). |
| `read`                    | A user read your outbound message.                         |
| `message_template_status` | A template was approved, rejected, or paused.              |
| `account`                 | Account or phone number update.                            |

The same list, with the endpoints that use it, is on the [Webhook Event](/public-api-reference/developers/reference/enums#webhook-event) reference page. Payload shapes for each event are documented on the [Webhooks](/api-reference/webhooks) page.

***

## Response

<ResponseField name="isSuccess" type="boolean">
  `true` when the configuration was saved.
</ResponseField>

<ResponseField name="data" type="object">
  The stored configuration, read back after the write.

  <Expandable title="data">
    <ResponseField name="id" type="string">
      UUID of the webhook configuration.
    </ResponseField>

    <ResponseField name="url" type="string">
      The URL now in effect.
    </ResponseField>

    <ResponseField name="headers" type="object">
      The custom headers now in effect.
    </ResponseField>

    <ResponseField name="subscribedEvents" type="object">
      The event subscriptions now in effect.
    </ResponseField>

    <ResponseField name="isActive" type="boolean">
      Whether deliveries are enabled for this configuration.
    </ResponseField>

    <ResponseField name="createdAt" type="string">
      ISO-8601 timestamp of creation.
    </ResponseField>

    <ResponseField name="updatedAt" type="string">
      ISO-8601 timestamp of this change.
    </ResponseField>
  </Expandable>
</ResponseField>

***

## Examples

<AccordionGroup>
  <Accordion title="Demo 1 — set the URL and subscribe to events">
    ```text theme={null}
    POST /api/v1/apps/app_7poyXj8GXuv76e/webhook
    Authorization: Bearer sk_...
    Content-Type: application/json
    ```

    ```json theme={null}
    {
      "url": "https://webhook.site/89ac1ca8-22cc-42c3-9f07-49a47f8f6a13",
      "headers": {
        "X-Signature-Token": "s3cr3t"
      },
      "subscribedEvents": {
        "messages": true,
        "message_status": true,
        "message_template_status": false,
        "read": true,
        "account": false
      }
    }
    ```

    ```json theme={null}
    {
      "data": {
        "id": "bb17a17e-9ce1-4c78-88ac-b48f53d322bc",
        "url": "https://webhook.site/89ac1ca8-22cc-42c3-9f07-49a47f8f6a13",
        "headers": {
          "X-Signature-Token": "s3cr3t"
        },
        "subscribedEvents": {
          "messages": true,
          "message_status": true,
          "message_template_status": false,
          "read": true,
          "account": false
        },
        "isActive": true,
        "createdAt": "2026-08-10T22:45:42.314912Z",
        "updatedAt": "2026-08-20T13:36:56.564277Z"
      },
      "isSuccess": true
    }
    ```
  </Accordion>

  <Accordion title="Demo 2 — move to a production URL">
    ```text theme={null}
    POST /api/v1/apps/app_7poyXj8GXuv76e/webhook
    Authorization: Bearer sk_...
    Content-Type: application/json
    ```

    ```json theme={null}
    {
      "url": "https://api.acme.com/connexease/webhook",
      "headers": {},
      "subscribedEvents": {
        "messages": true,
        "message_status": true,
        "message_template_status": true,
        "read": true,
        "account": true
      }
    }
    ```

    Sending `headers: {}` clears the previously stored headers.
  </Accordion>

  <Accordion title="Demo 3 — inbound messages only">
    ```text theme={null}
    POST /api/v1/apps/app_7poyXj8GXuv76e/webhook
    Authorization: Bearer sk_...
    Content-Type: application/json
    ```

    ```json theme={null}
    {
      "url": "https://api.acme.com/connexease/webhook",
      "subscribedEvents": {
        "messages": true,
        "message_status": false,
        "message_template_status": false,
        "read": false,
        "account": false
      }
    }
    ```

    Status, read, template, and account events stop being delivered — the Gateway simply drops them for this app.
  </Accordion>

  <Accordion title="Demo 4 — verify the change">
    ```text theme={null}
    GET /api/v1/apps/app_7poyXj8GXuv76e/webhook
    Authorization: Bearer sk_...
    ```

    Returns the configuration you just saved. See [Get Webhook](/public-api-reference/developers/get-webhook).
  </Accordion>

  <Accordion title="Demo 5 — error: missing url → 400">
    ```text theme={null}
    POST /api/v1/apps/app_7poyXj8GXuv76e/webhook
    Authorization: Bearer sk_...
    Content-Type: application/json
    ```

    ```json theme={null}
    { "subscribedEvents": { "messages": true } }
    ```

    A missing required field is a malformed request, not a field validation error:

    ```json theme={null}
    { "errors": { "code": "REQ_001", "group": "VALIDATION", "description": "Missing required field: url" }, "isSuccess": false }
    ```
  </Accordion>

  <Accordion title="Demo 6 — error: non-HTTPS url → 422">
    ```text theme={null}
    POST /api/v1/apps/app_7poyXj8GXuv76e/webhook
    Authorization: Bearer sk_...
    Content-Type: application/json
    ```

    ```json theme={null}
    { "url": "http://api.acme.com/webhook" }
    ```

    ```json theme={null}
    {
      "errors": {
        "code": "VAL_000",
        "group": "VALIDATION",
        "description": "Validation failed.",
        "fields": {
          "url": { "code": "VAL_002", "description": "Invalid value." }
        }
      },
      "isSuccess": false
    }
    ```
  </Accordion>
</AccordionGroup>

***

## Errors

<ResponseField name="errors" type="object">
  Error details with `code`, `group`, and `description`; `isSuccess` is `false`.
</ResponseField>

| HTTP | Code                      | Group        | When                                                                                                                        |
| ---- | ------------------------- | ------------ | --------------------------------------------------------------------------------------------------------------------------- |
| 400  | `REQ_001`                 | `VALIDATION` | Missing required field or invalid JSON.                                                                                     |
| 401  | `ORGANIZATION_SECRET_010` | `NOT_FOUND`  | Authorization / secret key is missing.                                                                                      |
| 401  | `ORGANIZATION_SECRET_011` | `NOT_FOUND`  | Secret key is invalid.                                                                                                      |
| 404  | `APPLICATION_004`         | `NOT_FOUND`  | `app_id` does not belong to the organization.                                                                               |
| 422  | `VAL_000`                 | `VALIDATION` | Field validation — invalid URL, unknown event name, wrong value type. Each offending field is listed under `errors.fields`. |

***

## Next steps

<CardGroup cols={2}>
  <Card title="Get Webhook" icon="magnifying-glass" href="/public-api-reference/developers/get-webhook">
    Read the configuration currently in effect.
  </Card>

  <Card title="Webhook payloads" icon="bell" href="/api-reference/webhooks">
    Event bodies, retries, and endpoint requirements.
  </Card>

  <Card title="Create API Key" icon="key" href="/public-api-reference/developers/create-api-key">
    Issue a key for an application.
  </Card>

  <Card title="Authentication" icon="lock" href="/essentials/authentication#secret-key">
    How secret keys work.
  </Card>
</CardGroup>
