Meet the new Scripe, live on October 7.Register

OpenAPI reference · Webhooks

Create webhook endpoint

POST/webhook-endpoints

Register a new outbound webhook endpoint. The response includes the plaintext signing secret — store it immediately, the API will never return it again. Subsequent reads expose only secretLast4.

URL constraints:

  • Must be HTTPS.
  • Hostname must resolve to a public IP (loopback, link-local, RFC 1918, and CGNAT ranges are rejected as ssrf_blocked).
  • The resolved IP is pinned for ~24h to defeat DNS rebinding; re-resolution happens automatically and may auto-disable the endpoint if the IP starts pointing somewhere private.

Subscribe to one or more event names from the closed list (see WebhookEventName schema). Subscribing to an unknown name returns 400 invalid_request.

Requires the webhooks:manage scope.

Authorization

  • Authorizationstringrequired

    Bearer token in the Authorization header.

    Pass Authorization: Bearer scripe_sk_live_<...> (or scripe_sk_test_<...> for test keys) on every request. Keys are scoped to a single workspace and can be revoked from the Scripe dashboard.

    The same header also accepts an OAuth 2.1 access token (scripe_oat_*); both credentials share one scope vocabulary and every operation below documents the scope it requires. An API key can hold every scope named on this surface except webhooks:manage, which is grantable to OAuth tokens only today — the webhook-endpoint operations answer 403 scope_missing to every API key. Operations that name no scope accept any valid token of the workspace.

Header parameters

  • Scripe-Api-Versionstring

    Pin the API version. Format YYYY-MM-DD. Omit to receive the currently rolling default. Unknown versions return 400 version_unsupported.

  • Idempotency-Keystring

    Opaque string (1–64 chars, [A-Za-z0-9_-]) used to dedup retried writes. Within 24h of the first request, the same key

    • same body returns the original response (Idempotent-Replayed: true). Same key + different body returns 409 idempotency_key_conflict.

    Strongly recommended for every write — see /docs/api/v1/idempotency.

Request bodyapplication/json

  • namestringrequired
  • urlstring <uri>required
  • eventsstring[]required
  • projectIdstring | null

    Optional project scope. When set, the endpoint only receives events for that project. null (default) delivers events for every project in the workspace.

Responses

  • 200

    Endpoint created. Response carries the plaintext secret.

  • 400

    Malformed request (bad cursor, bad limit, etc.).

  • 401

    Missing, malformed, expired, or revoked API key.

  • 403

    Plan not eligible, scope missing, or workspace mismatch.

  • 429

    Sliding-window rate limit exceeded.

Example request

bash
curl --request POST \
  --url 'https://api.scripe.io/v1/webhook-endpoints' \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "Production CRM",
  "url": "https://hooks.example.com/scripe",
  "events": [
    "post.created",
    "job.completed"
  ],
  "projectId": "proj_a1b2c3d4e5f6g7h8"
}'

Example response (200)

json
{
  "data": {
    "id": "whe_a1b2c3d4e5f6g7h8",
    "url": "https://hooks.example.com/scripe",
    "name": "Production CRM",
    "events": [
      "post.created",
      "job.completed"
    ],
    "isActive": true,
    "disabledReason": "string",
    "projectId": "string",
    "secretLast4": "string",
    "createdAt": "2026-08-10T09:00:00Z",
    "updatedAt": "2026-08-10T09:00:00Z",
    "secret": "whsec_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  }
}