Skip to content

Webhook endpoints tools

MCP tools for Webhook endpoints: webhook_endpoints_create, webhook_endpoints_delete, webhook_endpoints_get, webhook_endpoints_list, webhook_endpoints_rotate_secret, webhook_endpoints_test, webhook_endpoints_update.

  • webhook_endpoints_create: Create a webhook endpoint
  • webhook_endpoints_delete: Delete a webhook endpoint
  • webhook_endpoints_get: Get a webhook endpoint
  • webhook_endpoints_list: List webhook endpoints
  • webhook_endpoints_rotate_secret: Rotate a webhook endpoint's signing secret
  • webhook_endpoints_test: Send a test event to a webhook endpoint
  • webhook_endpoints_update: Update a webhook endpoint

webhook_endpoints_create

Create a webhook endpoint. Operation webhook_endpoints.create · Brand level · permission webhooks:admin · risk tier security · since M4

Creates an endpoint that receives the brand's events in the request's mode: Ownrecord POSTs each event it subscribes to as JSON, signed with the Ownrecord-Signature header (see the webhooks concept page).

  • events lists event types from the catalogue that are delivered to webhooks, or ["*"] for all of them, including types added later.
  • url must be a public https URL. In development and test (dev gate open), http://localhost works too.
  • The response contains the signing secret in secret. It is shown only once: it is stored encrypted and can't be read again. Rotate it with webhook_endpoints.rotate_secret if you lose it.

A brand can have at most 16 endpoints per mode. Send a test event with webhook_endpoints.test.

Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: false · openWorldHint: false

Arguments

ArgumentTypeRequiredDescription
urlstringyesThe https URL Ownrecord POSTs events to, e.g. https://example.com/webhooks/ownrecord. (1–2048 characters)
eventsarray of stringyesEvent types to receive (from the event catalogue), or ["*"] for every event of the brand. (1–100 items)
descriptionstringno(at most 500 characters)
enabledbooleannoStart receiving events at once (default) or create it disabled. (default true)
metadataobjectnoYour own key-value pairs (at most 50 keys). On updates the whole set is replaced.
entity_idID (ent_…)noOptional: the brand's legal entity (ent_…); brand_id alone is enough.
brand_idID (brd_…)noThe brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand.
idempotency_keystringnoA unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters)
dry_runbooleannotrue: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false)
  • Brand: pass brand_id with an organization or entity key; a brand key acts on its own brand.
  • Idempotency: the result returns the idempotency_key used, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours).
  • Dry run: supported. dry_run: true checks permissions and rules and computes the result, then rolls everything back.

Errors

Examples

An endpoint for order fulfilment

Arguments:

JSON
{
  "url": "https://example.com/webhooks/ownrecord",
  "events": ["customer.created", "checkout.session.completed"],
  "description": "Order fulfilment",
  "brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}

Result output:

JSON
{
  "id": "we_01m4tx5nj8emwbyf7y9vcf47z0",
  "object": "webhook_endpoint",
  "brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
  "livemode": false,
  "url": "https://example.com/webhooks/ownrecord",
  "description": "Order fulfilment",
  "events": ["customer.created", "checkout.session.completed"],
  "enabled": true,
  "disabledReason": null,
  "disabledAt": null,
  "failingSince": null,
  "secretRotatedAt": null,
  "previousSecretExpiresAt": null,
  "metadata": {},
  "createdAt": "2026-10-13T12:00:00.000Z",
  "updatedAt": "2026-10-13T12:00:00.000Z",
  "secret": "whsec_ExampleOnlyNotARealSigningSecret0000000"
}

Every event of the brand

Arguments:

JSON
{
  "url": "https://example.com/webhooks/all",
  "events": ["*"],
  "brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}

Result output:

JSON
{
  "id": "we_01m4tx5nj8emwbyf7y9vcf47z0",
  "object": "webhook_endpoint",
  "brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
  "livemode": false,
  "url": "https://example.com/webhooks/all",
  "description": null,
  "events": ["*"],
  "enabled": true,
  "disabledReason": null,
  "disabledAt": null,
  "failingSince": null,
  "secretRotatedAt": null,
  "previousSecretExpiresAt": null,
  "metadata": {},
  "createdAt": "2026-10-13T12:00:00.000Z",
  "updatedAt": "2026-10-13T12:00:00.000Z",
  "secret": "whsec_ExampleOnlyNotARealSigningSecret0000000"
}

webhook_endpoints_delete

Delete a webhook endpoint. Operation webhook_endpoints.delete · Brand level · permission webhooks:admin · risk tier security · since M4

Deletes an endpoint and its signing secret for good. Nothing more is sent to it: deliveries waiting for a retry are canceled instead of sent. Its delivery log stays readable with webhook_deliveries.list. To pause an endpoint instead, set enabled: false with webhook_endpoints.update.

Annotations: readOnlyHint: false · destructiveHint: true · idempotentHint: true · openWorldHint: false

Arguments

ArgumentTypeRequiredDescription
idID (we_…)yes–
entity_idID (ent_…)noOptional: the brand's legal entity (ent_…); brand_id alone is enough.
brand_idID (brd_…)noThe brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand.
idempotency_keystringnoA unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters)
dry_runbooleannotrue: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false)
  • Brand: pass brand_id with an organization or entity key; a brand key acts on its own brand.
  • Idempotency: the result returns the idempotency_key used, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours).
  • Dry run: supported. dry_run: true checks permissions and rules and computes the result, then rolls everything back.

Errors

Example

Delete an endpoint

Arguments:

JSON
{
  "id": "we_01m4tx5nj8emwbyf7y9vcf47z0",
  "brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}

Result output:

JSON
{
  "id": "we_01m4tx5nj8emwbyf7y9vcf47z0",
  "object": "webhook_endpoint",
  "deleted": true
}

webhook_endpoints_get

Get a webhook endpoint. Operation webhook_endpoints.get · Brand level · permission webhooks:read · risk tier read · since M4

Returns one webhook endpoint of the brand in the request's mode: its URL, event types, whether it is enabled (and why not), and since when its deliveries have been failing. Never its signing secret.

Annotations: readOnlyHint: true · destructiveHint: false · idempotentHint: true · openWorldHint: false

Arguments

ArgumentTypeRequiredDescription
idID (we_…)yes–
entity_idID (ent_…)noOptional: the brand's legal entity (ent_…); brand_id alone is enough.
brand_idID (brd_…)noThe brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand.
  • Brand: pass brand_id with an organization or entity key; a brand key acts on its own brand.
  • Read-only: changes nothing; idempotency_key is ignored.

Errors

Example

An endpoint

Arguments:

JSON
{
  "id": "we_01m4tx5nj8emwbyf7y9vcf47z0",
  "brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz"
}

Result output:

JSON
{
  "id": "we_01m4tx5nj8emwbyf7y9vcf47z0",
  "object": "webhook_endpoint",
  "brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
  "livemode": false,
  "url": "https://example.com/webhooks/ownrecord",
  "description": "Order fulfilment",
  "events": ["customer.created", "checkout.session.completed"],
  "enabled": true,
  "disabledReason": null,
  "disabledAt": null,
  "failingSince": null,
  "secretRotatedAt": null,
  "previousSecretExpiresAt": null,
  "metadata": {},
  "createdAt": "2026-10-13T12:00:00.000Z",
  "updatedAt": "2026-10-13T12:00:00.000Z"
}

webhook_endpoints_list

List webhook endpoints. Operation webhook_endpoints.list · Brand level · permission webhooks:read · risk tier read · since M4

Lists the brand's webhook endpoints in the request's mode, newest first. Filter with enabled (true or false) to find endpoints that were disabled, by you or after failing for 3 days.

Paginate with limit (1–100, default 10) and starting_after (the next_cursor of the previous page).

Annotations: readOnlyHint: true · destructiveHint: false · idempotentHint: true · openWorldHint: false

Arguments

ArgumentTypeRequiredDescription
enabledstringnoOnly enabled (true) or disabled (false) endpoints.
limitintegerno(1–100)
starting_afterID (we_…)no–
entity_idID (ent_…)noOptional: the brand's legal entity (ent_…); brand_id alone is enough.
brand_idID (brd_…)noThe brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand.
  • Brand: pass brand_id with an organization or entity key; a brand key acts on its own brand.
  • Read-only: changes nothing; idempotency_key is ignored.

Errors

Examples

The brand's endpoints

Arguments:

JSON
{
  "brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz"
}

Result output:

JSON
{
  "object": "list",
  "data": [
    {
      "id": "we_01m4tx5nj8emwbyf7y9vcf47z0",
      "object": "webhook_endpoint",
      "brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
      "livemode": false,
      "url": "https://example.com/webhooks/ownrecord",
      "description": "Order fulfilment",
      "events": ["customer.created", "checkout.session.completed"],
      "enabled": true,
      "disabledReason": null,
      "disabledAt": null,
      "failingSince": null,
      "secretRotatedAt": null,
      "previousSecretExpiresAt": null,
      "metadata": {},
      "createdAt": "2026-10-13T12:00:00.000Z",
      "updatedAt": "2026-10-13T12:00:00.000Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

Endpoints that were disabled

Arguments:

JSON
{
  "enabled": "false",
  "brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz"
}

Result output:

JSON
{
  "object": "list",
  "data": [
    {
      "id": "we_01m4tx5nj8emwbyf7y9vcf47z1",
      "object": "webhook_endpoint",
      "brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
      "livemode": false,
      "url": "https://example.com/webhooks/ownrecord",
      "description": "Order fulfilment",
      "events": ["customer.created", "checkout.session.completed"],
      "enabled": false,
      "disabledReason": "failing",
      "disabledAt": "2026-10-14T09:30:00.000Z",
      "failingSince": "2026-10-11T09:30:00.000Z",
      "secretRotatedAt": null,
      "previousSecretExpiresAt": null,
      "metadata": {},
      "createdAt": "2026-10-13T12:00:00.000Z",
      "updatedAt": "2026-10-14T09:30:00.000Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

webhook_endpoints_rotate_secret

Rotate a webhook signing secret. Operation webhook_endpoints.rotate_secret · Brand level · permission webhooks:admin · risk tier security · since M4

Replaces the endpoint's signing secret and returns the new one in secret. It is shown only once.

  • Without overlapSeconds (or with 0) the old secret stops at once: deliveries are signed with the new one only, and receivers still checking the old one fail until they switch (failed deliveries are retried).
  • With overlapSeconds (up to 86400) the old secret keeps signing next to the new one until previousSecretExpiresAt: each delivery carries two v1= signatures, and a receiver accepts it when either matches. Deploy the new secret, then let the overlap run out.

Rotating again ends an earlier overlap at once.

Annotations: readOnlyHint: false · destructiveHint: true · idempotentHint: false · openWorldHint: false

Arguments

ArgumentTypeRequiredDescription
idID (we_…)yes–
overlapSecondsintegernoSeconds the old secret keeps signing next to the new one (0–86400, default 0: it stops at once). During the overlap each delivery carries two v1 signatures. (0–86400) (default 0)
entity_idID (ent_…)noOptional: the brand's legal entity (ent_…); brand_id alone is enough.
brand_idID (brd_…)noThe brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand.
idempotency_keystringnoA unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters)
dry_runbooleannotrue: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false)
  • Brand: pass brand_id with an organization or entity key; a brand key acts on its own brand.
  • Idempotency: the result returns the idempotency_key used, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours).
  • Dry run: supported. dry_run: true checks permissions and rules and computes the result, then rolls everything back.

Errors

Example

Rotate with a one-hour overlap

Arguments:

JSON
{
  "id": "we_01m4tx5nj8emwbyf7y9vcf47z0",
  "overlapSeconds": 3600,
  "brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}

Result output:

JSON
{
  "id": "we_01m4tx5nj8emwbyf7y9vcf47z0",
  "object": "webhook_endpoint",
  "brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
  "livemode": false,
  "url": "https://example.com/webhooks/ownrecord",
  "description": "Order fulfilment",
  "events": ["customer.created", "checkout.session.completed"],
  "enabled": true,
  "disabledReason": null,
  "disabledAt": null,
  "failingSince": null,
  "secretRotatedAt": "2026-10-14T09:30:00.000Z",
  "previousSecretExpiresAt": "2026-10-14T10:30:00.000Z",
  "metadata": {},
  "createdAt": "2026-10-13T12:00:00.000Z",
  "updatedAt": "2026-10-14T09:30:00.000Z",
  "secret": "whsec_ExampleOnlyNotARealSigningSecret0000000"
}

webhook_endpoints_test

Send a test webhook. Operation webhook_endpoints.test · Brand level · permission webhooks:write · risk tier write · since M4

Sends a webhook_endpoint.test event to this endpoint only, signed like every delivery, so you can check that your receiver verifies Ownrecord-Signature and answers 2xx. It works for enabled and disabled endpoints.

The call returns the queued delivery at once; it is attempted right after (one attempt, no retries). Read the outcome with webhook_deliveries.get: status, responseCode and the start of your response body. The test event isn't part of the event feed, and endpoints can't subscribe to it.

Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: false · openWorldHint: true

Arguments

ArgumentTypeRequiredDescription
idID (we_…)yes–
entity_idID (ent_…)noOptional: the brand's legal entity (ent_…); brand_id alone is enough.
brand_idID (brd_…)noThe brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand.
idempotency_keystringnoA unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters)
dry_runbooleannotrue: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false)
  • Brand: pass brand_id with an organization or entity key; a brand key acts on its own brand.
  • Idempotency: the result returns the idempotency_key used, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours).
  • Dry run: supported. dry_run: true checks permissions and rules and computes the result, then rolls everything back.

Errors

Example

Send a test event

Arguments:

JSON
{
  "id": "we_01m4tx5nj8emwbyf7y9vcf47z0",
  "brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}

Result output:

JSON
{
  "id": "whd_01m4tx5nj8emwbyf7y9vcf47z3",
  "object": "webhook_delivery",
  "endpointId": "we_01m4tx5nj8emwbyf7y9vcf47z0",
  "brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
  "livemode": false,
  "eventId": "evt_01m4tx5nj8emwbyf7y9vcf47z5",
  "eventType": "webhook_endpoint.test",
  "trigger": "test",
  "redeliveryOf": null,
  "status": "pending",
  "attempt": 0,
  "maxAttempts": 1,
  "nextAttemptAt": "2026-10-14T10:30:00.000Z",
  "responseCode": null,
  "canceledReason": null,
  "attempts": [],
  "createdAt": "2026-10-14T10:30:00.000Z",
  "updatedAt": "2026-10-14T10:30:00.000Z"
}

webhook_endpoints_update

Update a webhook endpoint. Operation webhook_endpoints.update · Brand level · permission webhooks:admin · risk tier security · since M4

Changes an endpoint's URL, event types, description or metadata, or disables or enables it. Send only the fields to change; metadata replaces the whole set.

  • enabled: false stops deliveries: event deliveries waiting for a retry are canceled instead of sent.
  • enabled: true resumes deliveries of new events, also after Ownrecord disabled the endpoint for failing for 3 days. Events that happened while it was disabled aren't sent again on their own: redeliver them with webhook_deliveries.redeliver.

The signing secret doesn't change (use webhook_endpoints.rotate_secret).

Annotations: readOnlyHint: false · destructiveHint: false · idempotentHint: true · openWorldHint: false

Arguments

ArgumentTypeRequiredDescription
idID (we_…)yes–
urlstringnoThe https URL Ownrecord POSTs events to, e.g. https://example.com/webhooks/ownrecord. (1–2048 characters)
eventsarray of stringnoEvent types to receive (from the event catalogue), or ["*"] for every event of the brand. (1–100 items)
descriptionstring or nullnoA new description, or null to remove it.
enabledbooleannofalse stops deliveries (waiting retries are canceled); true resumes them.
metadataobjectnoYour own key-value pairs (at most 50 keys). On updates the whole set is replaced.
entity_idID (ent_…)noOptional: the brand's legal entity (ent_…); brand_id alone is enough.
brand_idID (brd_…)noThe brand to act on (brd_…), inside your API key's reach. Needed with an organization or entity key; a brand key acts on its own brand.
idempotency_keystringnoA unique string for this change. Retrying with the same key and arguments never acts twice. When left out, the server generates one and returns it in the result's idempotency_key. (1–255 characters)
dry_runbooleannotrue: check permissions and rules and compute the result, then roll everything back. Nothing is saved. (default false)
  • Brand: pass brand_id with an organization or entity key; a brand key acts on its own brand.
  • Idempotency: the result returns the idempotency_key used, yours or one the server generated. Retry with it: a call with the same key and arguments never acts twice (keys are kept for 24 hours).
  • Dry run: supported. dry_run: true checks permissions and rules and computes the result, then rolls everything back.

Errors

Examples

Subscribe to more event types

Arguments:

JSON
{
  "id": "we_01m4tx5nj8emwbyf7y9vcf47z0",
  "events": ["customer.created", "checkout.session.completed", "invoice.paid"],
  "brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}

Result output:

JSON
{
  "id": "we_01m4tx5nj8emwbyf7y9vcf47z0",
  "object": "webhook_endpoint",
  "brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
  "livemode": false,
  "url": "https://example.com/webhooks/ownrecord",
  "description": "Order fulfilment",
  "events": ["checkout.session.completed", "customer.created", "invoice.paid"],
  "enabled": true,
  "disabledReason": null,
  "disabledAt": null,
  "failingSince": null,
  "secretRotatedAt": null,
  "previousSecretExpiresAt": null,
  "metadata": {},
  "createdAt": "2026-10-13T12:00:00.000Z",
  "updatedAt": "2026-10-14T09:30:00.000Z"
}

Enable an endpoint again after it was disabled for failing

Arguments:

JSON
{
  "id": "we_01m4tx5nj8emwbyf7y9vcf47z0",
  "enabled": true,
  "brand_id": "brd_01jbx4m3v8e9t0s6k2c5n7q1wz",
  "idempotency_key": "8d0c5f8e-4b7a-4e43-9b0f-2f6a0c1d9e21"
}

Result output:

JSON
{
  "id": "we_01m4tx5nj8emwbyf7y9vcf47z0",
  "object": "webhook_endpoint",
  "brandId": "brd_01m4tx5nj8emwbyf7y9vcf47x4",
  "livemode": false,
  "url": "https://example.com/webhooks/ownrecord",
  "description": "Order fulfilment",
  "events": ["customer.created", "checkout.session.completed"],
  "enabled": true,
  "disabledReason": null,
  "disabledAt": null,
  "failingSince": null,
  "secretRotatedAt": null,
  "previousSecretExpiresAt": null,
  "metadata": {},
  "createdAt": "2026-10-13T12:00:00.000Z",
  "updatedAt": "2026-10-14T09:30:00.000Z"
}