Docs
API reference

Create a webhook endpoint

POST
/api/v1/webhook-endpoints

Registers an HTTPS URL to receive signed events. The response is the only place, besides rotating the secret, that shows the signing secret (whsec_…); store it now. An organization can have 5 endpoints. Send Idempotency-Key so a retry returns the same secret instead of creating a second endpoint.

Required scope: webhooks:write.

Errors

  • 400: invalid_content_type, invalid_idempotency_key, invalid_json, invalid_webhook_url, request_body_too_large, unknown_event_type, unknown_field
  • 401: authentication_required, invalid_api_key
  • 403: api_access_disabled, insufficient_scope, webhooks_not_enabled
  • 409: idempotency_key_reused, idempotency_request_in_progress, webhook_endpoint_limit
  • 422: invalid_parameter
  • 429: rate_limit_exceeded
  • 500: api_error
  • 503: maintenance_mode, service_unavailable

Authorization

ApiKey
headerAuthorizationBearer <probb_live_<id>_<secret>>

Header Parameters

Idempotency-Key?string

Makes retries safe. Repeating a request with the same key and body within 24 hours returns the original response with Idempotent-Replayed: true. The same key with a different body, or from a different API key, returns idempotency_key_reused.

Length1 <= length <= 255

Request Body

application/json
  1. body
url*string

Where to send events: an HTTPS URL on port 443 on the public Internet, without credentials or a fragment. Addresses inside private networks are refused.

Length1 <= length <= 2048
description?string

A label for you, shown in the app.

Lengthlength <= 120
events*array<>

The event types to send, for example ["report.completed", "decision.updated"], or ["*"] for every current and future type. ping is not subscribable: it is sent only by the test endpoint.

Items1 <= items <= 100

Response Body

Success.

application/json
  1. response
object*string
id*string

The endpoint's ID.

url*string

The HTTPS URL events are sent to.

description*|

A label for you, shown in the app.

events*array<string>

The event types sent to this endpoint, or ["*"] for every current and future type.

status*string

paused endpoints receive nothing; events that happen meanwhile are not sent later, but stay in GET /v1/events.

Value in"active""paused"
revision*string

Opaque token that changes whenever the endpoint does. Send it as If-Match on PATCH to refuse the change if someone else got there first.

previousSecretExpiresAt*|

While a rotated secret is still accepted, when the old one stops signing. Events are signed with both until then.

secretRotatedAt*|

When the signing secret was last rotated, if ever.

createdAt*string

When the endpoint was created.

Formatdate-time
updatedAt*string

When the endpoint last changed.

Formatdate-time
secret*string

The signing secret (whsec_…). It is shown only in this response; store it now. Use it to verify the webhook-signature header.

Example Request
# Set PROBB_URL and PROBB_API_KEY. Replace any *_VALUE placeholder and any example ID (such as job_example) with a real one.# Idempotency-Key is optional. Reuse the same key and body when retrying one logical write.curl --fail-with-body -X POST "$PROBB_URL/api/v1/webhook-endpoints" \  -H "Authorization: Bearer $PROBB_API_KEY" \  -H "Idempotency-Key: $REQUEST_KEY" \  -H 'Content-Type: application/json' \  --data-binary '{  "url": "https://example.com/webhooks/probb",  "description": "Production receiver",  "events": [    "report.completed",    "interview.completed",    "decision.updated"  ]}'
Example Response
{  "object": "webhook_endpoint",  "id": "string",  "url": "string",  "description": "string",  "events": [    "string"  ],  "status": "active",  "revision": "string",  "previousSecretExpiresAt": "2019-08-24T14:15:22Z",  "secretRotatedAt": "2019-08-24T14:15:22Z",  "createdAt": "2019-08-24T14:15:22Z",  "updatedAt": "2019-08-24T14:15:22Z",  "secret": "string"}