POSThttps://api.veriko.mx/v1/webhooks

Create a webhook endpoint

Audience
public
Auth
API key
Permission
webhooks:create
How-to guide →

Registers an HTTPS endpoint that will receive the subscribed events. The URL must resolve to a public address: localhost and private ranges are rejected.

That secret verifies every delivery: the HMAC-SHA256 of the received body must match the X-{Brand}-Signature: sha256=<hex> header. Signing, retries and automatic deactivation are described in the webhooks architecture.

Each endpoint accepts between 1 and 10 events. The validation.* ones produce deliveries from the moment of subscription; billing.* are accepted as a valid subscription but do not produce deliveries yet.

The number of endpoints allowed depends on the account role. Once the cap is reached, creation responds webhook_limit_reached with the applied limit in meta.limit.

POST /v1/webhooks/{id}/test sends a synthetic delivery to the newly created endpoint; confirming that the receiver returns 2xx before directing real traffic to it is recommended.

Parameters
ParameterTypeRequiredDescription
urlstring (uri) (?–2048)required

HTTPS URL that receives the webhook. Must be HTTPS.

e.g. https://example.com/webhooks/entregas
eventsarray<string> (items: 1–10)required

Events the endpoint subscribes to (1–10).

descriptionstring (?–255)optional

Descriptive label for the endpoint.

e.g. Alta de pagos en el ERP
Request
curl -X POST 'https://api.veriko.mx/v1/webhooks' \
  -H 'Authorization: Bearer veriko_••••' \
  -H 'Content-Type: application/json' \
  -d '{
    "url": "https://webhook.example.com/platform",
    "events": [
      "validation.completed",
      "validation.failed",
      "validation.error",
      "billing.payment_succeeded",
      "billing.payment_failed"
    ],
    "description": "Webhook plataforma completo"
  }'

Python example — coming soon.

JavaScript example — coming soon.

PHP example — coming soon.

Response 201WebhookEndpoint — Endpoint created. The `secret` field appears **in this response only** and cannot be read again: it is what verifies the `X-{Brand}-Signature: sha256=<hex>` signature carried by every delivery.
FieldTypeDescription
type*string

Resource type, fixed for this operation. Part of the resource identity in the JSON:API envelope. Always webhook_endpoint.

e.g. webhook_endpoint
id*string (uuid)

Endpoint identifier.

e.g. a1b2c3d4-e5f6-7890-abcd-ef0123456789
attributes*object

Canonical webhook endpoint attributes (receiver URL, subscribed events, status, and secret).

urlstring (uri)

HTTPS receiver URL. Production rejects plain HTTP, URLs resolving to private IPs (SSRF), and URLs >2048 chars.

e.g. https://example.com/webhooks/entregas
eventsarray

List of subscribed events. Maximum 10.

descriptionstring | nullnullable

Free-form endpoint label.

e.g. Alta de pagos en el ERP
statusstring

active receives deliveries. disabled was manually paused. auto_disabled was disabled by the platform after exceeding webhooks.auto_disable_threshold consecutive failures.

e.g. active
consecutive_failuresinteger

Consecutive failures counter. Resets on a success.

e.g. 0
last_delivery_atTimestampUTC | null

UTC timestamp of the last delivery attempt (any status). null when the endpoint hasn't received any delivery yet.

secretstring

Shared secret for signature verification. Only present in the create and rotate-secret responses; omitted from every other response.

e.g. whsec_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6
secret_hintstring

Last 4 chars of the secret prefixed with .... Present on any response where the full secret is hidden.

e.g. ...4f2a
created_atstring (date-time)

ISO 8601 timestamp in UTC with explicit Z suffix. Example: "2026-05-01T05:14:38Z". Every datetime field uses this shape. The descriptor at meta.datetime makes the contract runtime-assertable.

e.g. 2026-05-01T05:14:38Z
updated_atstring (date-time)

ISO 8601 timestamp in UTC with explicit Z suffix. Example: "2026-05-01T05:14:38Z". Every datetime field uses this shape. The descriptor at meta.datetime makes the contract runtime-assertable.

e.g. 2026-05-01T05:14:38Z
Response status codesPOST /v1/webhooks
StatusClassDescriptionBody
2012xxEndpoint created. The secret field appears in this response only and cannot be read again: it is what verifies the X-{Brand}-Signature: sha256=<hex> signature carried by every delivery.No body
4004xxThe request body is empty or is not valid JSON.ErrorResponse
4014xxAuthentication is required or the provided credentials are invalid.ErrorResponse
4034xxInsufficient permissions.ErrorResponse
4134xxThe request body exceeds the maximum accepted size (body_too_large).ErrorResponse
4224xxThe URL or the event list failed validation, or the account has reached its endpoint cap.ErrorResponse
4294xxRate limit exceededErrorResponse
Errors from POST /v1/webhooks
StatusCodeExample
400body_empty

The request body is empty.

Envelope
meta.request_id
e6f7a2b3c4d5
400invalid_json

The body is not valid JSON.

Envelope
meta.request_id
f7a2b3c4d5e6
401unauthorized

Invalid or missing authentication credentials.

Envelope
meta.request_id
c4d5e6f7a8b9
403forbidden

You do not have permission to access this resource.

Envelope
meta.request_id
d5e6f7a8b9c0
413body_too_large

The request body is too large.

Envelope
meta.request_id
1a2b3c4d5e6f
422url_dns_failed

The host name could not be resolved.

Envelope
meta.request_id
d4e5f6a1b2c4
422url_ssrf_blocked

The given URL resolves to a non-public address.

Envelope
meta.request_id
d4e5f6a1b2c5
422validation_error

The url field is required.

Envelope
source.pointer
/data/attributes/url
meta.request_id
b4c5d6e7f8a9
422webhook_event_invalid

The given event does not exist. The rejected event is in meta.event.

Envelope
meta.request_id
c4d5e6f7a2b3
422webhook_events_required

The endpoint must subscribe to at least one event.

Envelope
meta.request_id
a2b3c4d5e6f7
422webhook_events_too_many

An endpoint accepts at most 10 events.

Envelope
meta.request_id
b3c4d5e6f7a2
422webhook_limit_reached

The maximum number of allowed endpoints has been reached. The applied cap is in meta.limit.

Envelope
meta.request_id
d5e6f7a2b3c4
422webhook_url_invalid_format

The URL is not a valid URL.

Envelope
meta.request_id
c3d4e5f6a1b2
422webhook_url_not_https

The URL must use HTTPS.

Envelope
meta.request_id
d4e5f6a1b2c3
422webhook_url_required

The url field is required.

Envelope
meta.request_id
a1b2c3d4e5f6
422webhook_url_too_long

The URL cannot exceed 2,048 characters.

Envelope
meta.request_id
b2c3d4e5f6a1
429rate_limit_exceeded

Rate limit exceeded. Try again in 45 seconds.

Envelope
meta.request_id
f7a8b9c0d1e2
Response headers
  • Retry-After: integer — Seconds to wait before retrying. Matches the endpoint's rate-limit window (typically 60s for list endpoints, 1-5s for in-flight idempotent operations).
  • X-RateLimit-Limit: integer — Configured request cap for this bucket (emitted only on 429).
  • X-RateLimit-Remaining: integer — Requests remaining in the current window — always 0 at the moment of the 429 (emitted only on 429).
  • X-RateLimit-Reset: integer — Absolute Unix epoch (seconds) when the window resets. Emitted only on 429, alongside Retry-After. Per-endpoint overrides exist (e.g. `rate_limited_login`).