- WooCommerce
- Magento
- Shopify Soon
Calling API endpoints
Understand the request and response structure that all of our API endpoints follow.
Overview
Our API design follows a few simple rules that provide a consistent interface across the entire API surface:
- POST only: Every endpoint is accessed via a
POSTrequest. - JSON input: All request bodies must be a JSON object.
- JSON output: All responses are returned as JSON values.
- Predictable status codes: We use a minimal set of HTTP status codes to indicate the outcome of your request.
To learn more, read the WebFunction specification.
Request structure
To call a Reservepay endpoint, send a POST request with the Accept: application/json, Content-Type: application/json, and Api-Version: 2025-04-01 headers. The request body should be a JSON object containing the arguments for that endpoint.
Example
curl -X POST https://api.reservepay.com/merchants/get-balance \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Api-Version: 2025-04-01" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{}'
Response structure
Responses are always JSON values. Depending on the endpoint, this could be an object, an array, a string, a number, or a boolean.
Pagination
Some endpoints return a paginated response. These endpoints follow a standardized structure to make it easy to navigate through large sets of results.
When an endpoint is paginated, the response is a JSON object with three keys:
page: A JSON array containing the items for the current page.next: A JSON object representing the request for the next page, ornullif there are no more results.previous: A JSON object representing the request for the previous page, ornullif you are on the first page.
Navigating pages
To navigate, you should not attempt to construct or modify the next and previous objects. Instead, treat them as opaque tokens. To get the next or previous page, simply send a POST request to the same endpoint using the exact JSON object provided in the next or previous field as the request body.
For more details, see the WebFunction Pagination specification.
Idempotency and timeouts
Reservepay uses external_id instead of an idempotency header. Pass your own reference, such as an order or invoice number, when you create a payment or payout:
- Payments:
initiate-payment-flow. Must be unique across your payments. - Payouts:
send-payoutorsend-payout-to-contact. Must be unique across your payouts.
Payments and payouts are checked separately, so a payment and a payout can share the same reference. find-payment and find-payout also accept your external_id, so you can look records up without storing the Reservepay ID.
If a request times out, you can't tell whether Reservepay received it. Resolve it this way:
| Operation | After a timeout |
|---|---|
| Create a payment or payout | Send the same request again with the same external_id. If the first request went through, you get the original record back instead of a duplicate. |
| Capture or reverse | Call find-payment and read the status. Don't rely on a second attempt: NOT_CAPTURABLE or NOT_REVERSIBLE only means the action isn't available now, which is also true when the authorization has expired. |
| Refund | Read every page of list-refunds-by-payment and compare it with the refunds you meant to create. Refunds take no client reference, so a retry can create a second refund. |
A NOT_FOUND right after a timeout doesn't prove the request failed, because it may still be processing. Keep the same external_id until you know the outcome. Use a new external_id for every new attempt, including when a customer retries after a FAILED or EXPIRED payment, for example order_12345_2.
Status codes
Almost all business errors return HTTP 400 with an error triple. HTTP 500 is UNHANDLED_ERROR. Branch on the triple code, not the HTTP status.
| Status Code | Meaning |
|---|---|
200 OK |
The request was successful. |
400 Bad Request |
A handled API error. The body is an error triple; read the code. |
500 Internal Server Error |
Unexpected server error. Check the operation's outcome before retrying a write. |
For the triple format, retry rules, and support channels, see Error handling.
Namespaces
The API is split into three public namespaces:
merchants/: For server-side operations using your secret API key. See Merchant API reference.sdk/: For client-side operations (web or mobile apps) using public identifiers. See SDK API reference.terminals/: For managing payment terminals. See Terminal API reference.
Packages and client generation
At the root of each namespace, we provide a WebFunction Package definitions that include all the endpoints available in that namespace. You can use them to:
- Create type-safe API clients for your language.
- Set up a client dynamically based on your environment.
This makes integration faster and keeps your code in sync with our API.
Learn the fundamental concepts of the Reservepay API to build a robust and secure integration.
Understand the request and response structure that all of our API endpoints follows.
Read the guideLearn how to authenticate your requests using API keys for backend and Installation IDs for frontend.
Read the guideHow to interpret API responses and handle common error scenarios gracefully.
Read the guideNo account yet?
Start integrating all these amazing features into your app or website by creating your own merchant account today. It's free to sign up and only takes a few minutes to get started.
