Events
The event log behind webhooks, readable directly.
| Endpoint | What it does |
|---|---|
GET /v1/event-types |
List event types |
GET /v1/events |
List events |
GET /v1/events/{id} |
Retrieve an event |
Try any of them in the API tester.
List event types
Section titled “List event types”GET /v1/event-types
The code values accepted in subscribed_events when you create a webhook endpoint, with a JSON Schema for each payload where one exists.
Cacheable for an hour; this catalogue changes a few times a year.
Behind the secret key rather than the publishable one, even though nothing here is confidential: the audience is a backend integrator, and a publishable key has no reason to be able to read your webhook configuration surface.
Authentication: a secret key (server-side only) with the scope webhook.read.
Response 200
Section titled “Response 200”| Field | Type | What it is |
|---|---|---|
data |
array | |
object |
string |
Errors
Section titled “Errors”401: the key is missing, wrong or revoked403: the key lacks the scope, or your account may not do this429: too many requests; wait forRetry-After500: Internal Server Error503: the payment partner is unreachable; safe to retry
Every error is a JSON problem with a stable code. See Errors.
List events
Section titled “List events”GET /v1/events
Everything we tried to send you, with the payload exactly as it was signed. Reading this sends nothing — it is how you backfill after an outage without your handler being hit by a burst of replays.
TWO ORDERS, AND THEY ANSWER DIFFERENT QUESTIONS. By default the list is newest-first and keyset-paginated with cursor. Pass after_sequence instead and you get OLDEST-FIRST by sequence, which is the only order in which applying missed events is correct. The two cannot be combined.
sequence is monotonic per account across every event type and every endpoint, and is sent on every delivery as X-PaySigna-Sequence. Record the highest you have processed; a gap in it means a lost event, and after_sequence is how you ask for exactly the range you are missing.
A date window is always applied in newest-first order: omitting one defaults to the last 7 days and a window wider than 90 days is refused. The sequence walk is bounded by 90 days of history instead.
data is returned byte-for-byte as we signed it, so a stored X-PaySigna-Signature still verifies against it.
Authentication: a secret key (server-side only) with the scope webhook.read.
Parameters
Section titled “Parameters”| Field | Type | Required | Allowed values and limits | What it is |
|---|---|---|---|---|
limit |
integer | no | min 1; max 100; default 25 |
Rows per page. Clamped to 100. |
cursor |
string | no | The paging.next_cursor from the previous page. Newest-first order only; cannot be combined with after_sequence. | |
after_sequence |
integer | no | min 0 | Return events with a sequence strictly greater than this, OLDEST FIRST. This is the backfill order: use it to replay a gap in the order the events happened. Cannot be combined with cursor. |
created_after |
string | no | RFC 3339, inclusive. Defaults to 7 days ago. The window may not exceed 90 days. | |
created_before |
string | no | RFC 3339, exclusive. Defaults to now. Ignored when after_sequence is used, which is bounded by the sequence instead. | |
type |
string | no | at most 60 characters | Exact event type code. |
resource_id |
string (uuid) | no | Every event about one transaction, customer or dispute. |
Response 200
Section titled “Response 200”| Field | Type | What it is |
|---|---|---|
data |
array | |
highest_sequence |
integer | |
object |
string | |
order |
string | One of: newest_first, sequence_ascending |
paging |
object | |
paging.has_more |
boolean | |
paging.limit |
integer | The page size actually applied, after clamping. |
paging.next_cursor |
string | Pass as ?cursor= to fetch the next page. Absent when has_more is false. |
window |
object | |
window.created_after |
string (date-time) | |
window.created_before |
string (date-time) |
Errors
Section titled “Errors”400: the request is malformed401: the key is missing, wrong or revoked403: the key lacks the scope, or your account may not do this422: a field is invalid;errorsnames it429: too many requests; wait forRetry-After500: Internal Server Error503: the payment partner is unreachable; safe to retry
Every error is a JSON problem with a stable code. See Errors.
Retrieve an event
Section titled “Retrieve an event”GET /v1/events/{id}
The id here is the X-PaySigna-Event-Id header on every delivery of the event, and is what you should deduplicate on — delivery is at-least-once and always will be.
The payload is frozen as it was when the event fired. If the underlying transaction has moved on since, read /v1/transactions for the current state; this is the history.
Authentication: a secret key (server-side only) with the scope webhook.read.
Parameters
Section titled “Parameters”| Field | Type | Required | Allowed values and limits | What it is |
|---|---|---|---|---|
{id} |
string (uuid) | yes | The event’s id. |
Response 200
Section titled “Response 200”| Field | Type | What it is |
|---|---|---|
created_at |
string (date-time) | |
data |
The payload as it was signed and sent. Byte-identical to the body of the webhook, so a stored signature still verifies against it. | |
id |
string | Also the X-PaySigna-Event-Id on every delivery of this event. Deduplicate on it. |
object |
string | |
resource_id |
string | The id of the thing the event is about. |
resource_type |
string | |
sequence |
integer | |
transaction_id |
string | |
type |
string | One of the codes listed at /v1/event-types. |
Errors
Section titled “Errors”401: the key is missing, wrong or revoked403: the key lacks the scope, or your account may not do this404: no such resource on this account422: a field is invalid;errorsnames it429: too many requests; wait forRetry-After500: Internal Server Error503: the payment partner is unreachable; safe to retry
Every error is a JSON problem with a stable code. See Errors.

