Integration guides
Working with the API
Open in Markdown

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 POST request.
  • 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, or null if there are no more results.
  • previous: A JSON object representing the request for the previous page, or null if you are on the first page.

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 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:

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:

  1. Create type-safe API clients for your language.
  2. Set up a client dynamically based on your environment.

This makes integration faster and keeps your code in sync with our API.

Working with the API

Learn the fundamental concepts of the Reservepay API to build a robust and secure integration.

Calling the API

Understand the request and response structure that all of our API endpoints follows.

Read the guide
Authentication

Learn how to authenticate your requests using API keys for backend and Installation IDs for frontend.

Read the guide
Error handling

How to interpret API responses and handle common error scenarios gracefully.

Read the guide

No 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.