Skip to main content
POST
Create a new webhook
Creates a webhook endpoint for receiving events. Only OWNERS and ADMINS can create webhooks.

Authentication

This endpoint requires authentication via Bearer token:
  • Authorization: Bearer <token>

Path Parameters

Request Body

Available Events

Subscribe to any of these events:
  • Organization: organization.updated
  • Members: member.added, member.removed, member.role_updated
  • Invites: invite.created, invite.accepted, invite.cancelled
  • Webhooks: webhook.created
  • Invoices (CFDI): invoice.stamped, invoice.cancelled, invoice.cancellation_pending, invoice.cancellation_rejected, invoice.stamping_failed
  • Certificates (CSD): certificate.uploaded, certificate.expiring, certificate.expired, certificate.deleted
  • Trial: trial.ending_soon, trial.expired, trial.converted

Permissions

Only OWNERS and ADMINS can create webhooks.

Example Request

Example Response

⚠️ Important: Save the secret value - it’s only returned once and used for signature verification.

Webhook Payload

Your endpoint will receive POST requests with this format:

Signature Verification

All webhook requests include an HMAC SHA-256 signature in the X-Webhook-Signature header for verification.

Webhook Event Payloads

invoice.stamped

Sent when a CFDI has been successfully stamped by the PAC.
relatedCfdis is empty for a regular invoice. A substitute CFDI carries [{ "type": "04", "uuids": ["<UUID original>"] }].

invoice.cancelled

Sent when a CFDI has been cancelled (directly or after receiver acceptance).

invoice.cancellation_pending

Sent when a CFDI cancellation request requires receiver approval (per SAT eligibility rules) instead of resolving directly. The receiver has until respondBy to accept or reject it through the SAT portal — the CFDI remains vigente until then.

invoice.cancellation_rejected

Sent when a receiver rejects a pending CFDI cancellation request. The CFDI remains vigente.

invoice.stamping_failed

Sent when CFDI stamping failed at the PAC.

certificate.uploaded

Sent when a CSD is uploaded. replaced is true when it replaced an existing CSD (rotation), and previousSerialNumber holds the old serial. Re-uploading the same CSD also reports replaced: true, with previousSerialNumber equal to serialNumber. rfc may be null if the organization has no legal data on file.

certificate.expiring

Sent once per threshold, 30, 7 and 1 days before the CSD expires (checked daily at 9:00 Mexico City time). daysUntilExpiration counts full days remaining. If several thresholds were crossed since the last check, only the closest one is sent. Uploading a new CSD resets the alerts. daysUntilExpiration can be lower than threshold (for example threshold: 1 with daysUntilExpiration: 0 when it expires later the same day, or when a CSD is uploaded that is already within 30 days of expiring). rfc may be null if the organization has no legal data on file.

certificate.expired

Sent once when the CSD has expired. From this point stamping fails until a new CSD is uploaded. rfc may be null if the organization has no legal data on file.

certificate.deleted

Sent when the organization’s CSD is deleted. Stamping fails until a new one is uploaded. rfc may be null if the organization has no legal data on file.

trial.ending_soon

Sent once when 3 days or less remain in the organization’s free trial. daysRemaining is rounded up (1–3).

trial.expired

Sent once when the trial ended without a paid plan and access was locked. expiredAt is when the lock was applied.

trial.converted

Sent once when a trial organization subscribes to a paid plan. afterExpiration is true when the payment happened after the trial had already ended.
There is no trial.started event: the trial begins the moment the organization is created, before any webhook can be registered. Read the trial dates from GET /organizations/{id} instead.

Retry Logic

Failed webhook deliveries are retried up to 3 times with exponential backoff (1s, 5s, 30s).

Common Errors

400 Bad Request

Invalid input data.

401 Unauthorized

Authentication required.

403 Forbidden

Only owners and admins can create webhooks.

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Path Parameters

organizationId
string
required

Body

application/json
url
string
required

Webhook endpoint URL

Example:

"https://example.com/webhooks"

events
enum<string>[]
required

Events to subscribe to

Available options:
organization.updated,
member.added,
member.removed,
member.role_updated,
invite.created,
invite.accepted,
invite.cancelled,
webhook.created,
invoice.stamped,
invoice.cancelled,
invoice.cancellation_pending,
invoice.cancellation_rejected,
invoice.stamping_failed,
certificate.uploaded,
certificate.expiring,
certificate.expired,
certificate.deleted,
trial.ending_soon,
trial.expired,
trial.converted
Example:

Response

Webhook created successfully. Returns webhook configuration with signing secret.