API reference

Webhooks API

Reference for creating, listing, retrieving, updating, deleting and rotating the signing secret of webhooks.

The webhooks API manages the webhooks of the project that owns your API key. Every endpoint needs a full_access key. For the concepts, see Webhooks overview, Event types and Verify signatures.

The webhook object

JSON
{
  "object": "webhook",
  "id": "jw6k9d3h2s5f8g1j4l7z0x2c",
  "created_at": "2026-11-14T10:00:00.000Z",
  "status": "enabled",
  "endpoint": "https://yourapp.com/webhooks/sooner",
  "events": ["email.delivered", "email.bounced"],
  "signing_secret": "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw"
}

status is enabled or disabled. signing_secret is included when you retrieve a single webhook, and left out of list items.

Create a webhook

POST/webhooks
FieldTypeRequiredDescription
endpointstringYesA public https URL. Private and local addresses are rejected.
eventsstring[]YesAt least one event type, or "*" for all. Unknown names are ignored.
Shell
curl -X POST https://api.sooner.dev/webhooks \
  -H "Authorization: Bearer $SOONER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "endpoint": "https://yourapp.com/webhooks/sooner",
    "events": ["email.delivered", "email.bounced"]
  }'
JSON
{
  "object": "webhook",
  "id": "jw6k9d3h2s5f8g1j4l7z0x2c",
  "signing_secret": "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw"
}

Notable errors: validation_error for a URL that is not https, a private address, no supported event names, or the plan's webhook limit (5 on Free, 20 on Pro, 50 on Scale).

List webhooks

GET/webhooks

Returns the project's webhooks, newest first, without signing secrets. Accepts limit and after. See Pagination.

Shell
curl https://api.sooner.dev/webhooks \
  -H "Authorization: Bearer $SOONER_API_KEY"
JSON
{
  "object": "list",
  "data": [
    {
      "object": "webhook",
      "id": "jw6k9d3h2s5f8g1j4l7z0x2c",
      "created_at": "2026-11-14T10:00:00.000Z",
      "status": "enabled",
      "endpoint": "https://yourapp.com/webhooks/sooner",
      "events": ["email.delivered", "email.bounced"]
    }
  ],
  "has_more": false
}

Retrieve a webhook

GET/webhooks/{id}

Returns one webhook, including its signing_secret. Notable errors: not_found.

Update a webhook

PATCH/webhooks/{id}

Changes only the fields you send.

FieldTypeRequiredDescription
endpointstringNoA new public https URL.
eventsstring[]NoA new, non-empty list of event types. Unknown names are dropped.
statusstringNoenabled or disabled. A disabled webhook receives nothing.
Shell
curl -X PATCH https://api.sooner.dev/webhooks/jw6k9d3h2s5f8g1j4l7z0x2c \
  -H "Authorization: Bearer $SOONER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "status": "disabled" }'
JSON
{ "object": "webhook", "id": "jw6k9d3h2s5f8g1j4l7z0x2c" }

Notable errors: validation_error for an invalid endpoint, not_found.

Delete a webhook

DELETE/webhooks/{id}
Shell
curl -X DELETE https://api.sooner.dev/webhooks/jw6k9d3h2s5f8g1j4l7z0x2c \
  -H "Authorization: Bearer $SOONER_API_KEY"
JSON
{ "object": "webhook", "id": "jw6k9d3h2s5f8g1j4l7z0x2c", "deleted": true }

Rotate the signing secret

POST/webhooks/{id}/signing-secret/rotate

Generates a new secret and returns it. The old secret stops signing right away. See Verify signatures for how to switch without dropping events.

Shell
curl -X POST https://api.sooner.dev/webhooks/jw6k9d3h2s5f8g1j4l7z0x2c/signing-secret/rotate \
  -H "Authorization: Bearer $SOONER_API_KEY"
JSON
{
  "object": "webhook",
  "id": "jw6k9d3h2s5f8g1j4l7z0x2c",
  "signing_secret": "whsec_t9Qm2Xv7LpRk4NwYb8Hc1ZaE5JdGfU0s"
}