Reference
Errors, limits & idempotency
Authentication
Send your secret key as a bearer token: Authorization: Bearer sk_test_…. Keys are matched by a hash on our side and are only ever shown once, at creation.
Errors
Every failed request returns the same JSON envelope and a matching HTTP status. Log the request_id: it lets us find the exact request.
{
"error": {
"code": "invalid_request",
"message": "Request validation failed",
"request_id": "req_5c9f6ff2-3c98-43ad-a179-7af485f0d1f0",
"details": []
}
}| code | HTTP | meaning |
|---|---|---|
| invalid_request | 400 | The request is malformed or failed validation. See details. |
| unauthorized | 401 | Missing, malformed or revoked API key. |
| forbidden | 403 | The key is valid but not allowed: for example the merchant is suspended, or a read-only role. |
| live_mode_disabled | 403 | A live key was used while the platform is testnet-only. |
| not_found | 404 | The object does not exist, or belongs to another merchant. |
| idempotency_conflict | 409 | The Idempotency-Key was already used with a different request. |
| invalid_state_transition | 409 | The action is not allowed in the object's current state, for example refunding an unpaid payment. |
| conflict | 409 | The request conflicts with current state, for example paying an expired payment. |
| rate_limited | 429 | Too many requests. Wait for the Retry-After header's seconds. |
| not_configured | 503 | A capability is not set up on the platform yet. |
| internal_error | 500 | Our fault. Retry; quote the request_id if it persists. |
Idempotency
Requests that create or change money-related objects (POST /v1/payment_intents, cancel, refunds, webhook endpoints) require an Idempotency-Key header: 1 to 255 printable ASCII characters with no spaces.
- The same key with the same request replays the original response, without doing the work again. Use this to retry safely after a timeout or network error.
- The same key with a different request body is refused with
idempotency_conflict. - If the first attempt failed with an error, nothing was saved and you can retry with the same key.
- Keys are remembered for 24 hours per merchant.
Good keys are derived from your own object, such as order-1042 or refund-1042-1. Random keys defeat the purpose if you generate a new one on each retry.
Rate limits
Requests are limited per API key (600 per minute by default) and per IP address. Over the limit you get 429 rate_limited and a Retry-After header. Back off and retry.
Pagination
List endpoints return data, has_more and next_cursor. Pass limit (1 to 100) and starting_after (the id of the last item you received) to get the next page.
Conventions
- Timestamps are ISO 8601 in UTC.
- Ids are prefixed strings such as
pi_…(payment),re_…(refund),we_…(webhook endpoint). - Unknown fields in a request body are rejected, which catches typos early.
- Every response carries an
x-request-idheader.