General
Introduction
This section introduces the concepts used within the Pushpay API. For further assistance, please contact us and we'll be glad to help.
Overview
The Pushpay API is a Representational State Transfer (REST) API, designed with resource-oriented URLs organized around concepts familiar to those using the Pushpay platform. Pushpay uses standard HTTP methods (verbs) to indicate the kind of request being made:
| Method | Purpose |
|---|---|
GET | Reading |
POST | Creating |
PUT / PATCH | Updating |
DELETE | Removing / dismissing |
The API is designed to be easy to use for client implementers:
- Responses are always returned in JSON
- HTTP status codes indicate the outcome of requests
- Error messages are returned in a consistent format
- Links are returned as part of entities to identify related resources
Where possible, Pushpay provides client libraries for common languages/platforms (currently the .NET framework, with plans to support other languages shortly). Pushpay also provides rich metadata about all supported API operations via the OpenAPI Specification 3.1.0 (OAS) — a machine-readable format you can use to generate your own clients or explore the API's surface area programmatically.
The Pushpay API is secured via OAuth2, an industry-standard mechanism for securing APIs that allows fine-grained permissions to be granted to an API consumer — either for itself or on behalf of a Pushpay user.
API Metadata
The Pushpay platform has rich support for exposing metadata about its own API for consumption via the API. This includes available operations, models, documentation, and examples.
This information is exposed as JSON using the OpenAPI Specification 3.1.0 (OAS).
You can download the OAS files for endpoints at:
https://docs.pushpay.io/giving-v1/openapi
Error Responses
When something goes wrong with an API request — for example, a validation failure or a server error — the response will be an error response with a specific format. This, combined with the status code, tells you how to handle the problem.
API documentation and metadata cover requests and expected responses when requests succeed. When requests fail, things look a bit different.
An error response returns a 40X or 50X status code, with a JSON body in the following format:
{
"message": "error description",
"id": "GUID",
"resultCode": {
"code": 1234,
"key": "Declined",
"description": "Declined due to expired card"
},
"validationFailures": {
"name": ["Name must be between 10 and 20 characters in length"],
"password": ["Password must contain upper case letters", "Password must be more than 10 characters"]
}
}Note: All parts of the error response are optional.
Links
Resources in the API don't live in isolation — data is related to other data accessible in other parts of the API. By providing links in the representations returned from the API, Pushpay makes it easy to discover related data and access it without hard-coding the URL structure of each related resource.
Most Pushpay API responses use the content type application/hal+json. This content type represents JSON that includes a standardized representation of links between content, and also provides a mechanism for embedding one resource's representation within another.
For specific details on HAL+JSON, refer to the IETF draft specification. In summary: all representations returned from the API include a _links property — an object where each key represents a link to another resource related to this entity.
_links takes the form of:
{
"_links": {
"self": {
"href": "https://api.pushpay.com/merchant/widgetsinc"
},
"anticipatedPayments": {
"href": "https://api.pushpay.com/merchant/widgetsinc/anticipatedpayments"
}
}
}In this example there are two links:
- A
selflink, which always points to the entity's own location - An
anticipatedPaymentslink, which points to the list of anticipated payments associated with this merchant
A link can also contain additional information:
{
"_links": {
"a_link": {
"href": "....",
"templated": true,
"title": "...."
}
}
}| Property | Description |
|---|---|
href | The absolute URI |
templated | If true, the URI is a template |
title | An optional title for this URL |
HAL+JSON also supports returning an array of links for a relationship, for example:
{
"_links": {
"a_link": [
{ "name": "link #1", "href": "..." },
{ "name": "link #2", "href": "..." }
]
}
}This array format is not currently used by the Pushpay platform, so you do not need to support it when developing clients for the API.
Paging Results
For performance reasons, Pushpay does not return all data matching a query in a single response. Instead, you access the data a page at a time, and the Pushpay API aims to make paging as easy as possible.
API operations that return a collection of items do so in the following form:
{
"items": [
{ "name": "item 1" },
{ "name": "item 2" }
],
"page": 0,
"pageSize": 25,
"total": 2,
"totalPages": 1,
"_links": {
...
}
}- Page size defaults to 25 items per page.
- Paging is controlled via the
pagequery string parameter and is 0-relative (page=0is the first page,page=1is the second, and so on). - The response includes both the total number of items (
total) and the total number of pages (totalPages).
Page Links
The _links property is an object containing a set of links, keyed by the "rel" (relation) of the link.
For collection responses, this link set is populated so you can navigate the result set without building URIs by hand. Pushpay recommends favoring this approach, as it results in more robust clients.
The available link relations are:
firstprefnextlast
Here's an example of viewing a page in the middle of a result set, with links to other pages:
{
"items": [
....
],
"page": 2,
"pageSize": 25,
"total": 120,
"totalPages": 5,
"_links": {
"self": {
"href": "https://api.pushpay.com/v1/merchants?country=US&page=2"
},
"next": {
"href": "https://api.pushpay.com/v1/merchants?country=US&page=3"
},
"pref": {
"href": "https://api.pushpay.com/v1/merchants?country=US&page=1"
},
"first": {
"href": "https://api.pushpay.com/v1/merchants?country=US&page=0"
},
"last": {
"href": "https://api.pushpay.com/v1/merchants?country=US&page=4"
}
}
}Rate Limiting
The Pushpay platform is shared by a large number of merchants and users. To ensure no single user can affect the performance of others, the platform uses rate limiting — preventing any single API integration from sending too many requests within a given timeframe.
When building integrations, be aware of the rate limits in place, and write your code to gracefully handle a rate-limit-exceeded response.
See our Rate Limiting Guidance for details.
Representing Money
As a platform that predominantly manages payments, money is a first-class concept in the Pushpay API — so it's important to know how to represent it.
Money values (such as the amount for an anticipated payment) are represented in JSON as a string, e.g. the dollar amount:
{
"key": "amount",
"value": "10.25"
}Note that the value is a string. Using a JSON float will result in an API error — for example, the following is not acceptable:
{
"key": "amount",
"value": 10.25
}This is because floating-point values in JSON can cause rounding errors when representing amounts in some currencies, and shouldn't be used to represent exact amounts.
The API also does not support JSON numbers encoded as the smallest subdivision of a currency (as seen on some other payment platforms) — this is intentional, so Pushpay can represent values in a human-readable way.
The only allowable characters in the string amount are 0-9 and a decimal point separating the dollar and cent amounts (no culture-specific formatting). The decimal point and cent values are optional:
{
"key": "amount",
"value": "10.277"
}When representing an amount this way, its currency will be either Unspecified (which may cause a validation error, depending on context) or will default to the currency of the merchant the operation is performed for (e.g., creating an anticipated payment on behalf of a merchant uses that merchant's currency).
If you want to specify the currency explicitly, use the alternative object format with amount and currency properties:
{
"key": "amount",
"value": {
"amount": "10.50",
"currency": "USD"
}
}Supported currency values are currently:
| Code | Currency |
|---|---|
AUD | Australian Dollars |
NZD | New Zealand Dollars |
USD | US Dollars |
CAD | Canadian Dollars |
Test Cards
By far the most popular payment method used with Pushpay is credit cards. The main test card numbers you'll use are:
| Card | Number |
|---|---|
| Visa | 4111-1111-1111-1111 |
| Mastercard | 5555-5555-5555-4444 |
| American Express | 3711-111111-11114 |
| Discover | 6011-1111-1111-1117 |
When testing integrations, it's valuable to be able to:
- Make transactions without using real credit card numbers or spending real money
- See how things behave both when payment succeeds and when it fails for various reasons
In the sandbox environment, you can do exactly that by using a special CVV (Card Verification Value — the three-digit code on the back of your card) to trigger a specific response from the test gateway.
Possible values*:
| CVV | Behavior |
|---|---|
100 | Success |
101 | Decline — Insufficient funds |
102 | Decline — Expired card |
103 | Decline — Communication error with gateway |
107 | Decline — Bank declined transaction |
* For American Express, CVVs need to be padded with an additional digit at the end — e.g., 100 becomes 1001, 101 becomes 1011, and so on.
Test ACH Accounts
The other main payment method Pushpay supports is ACH payments, using bank account information.
All test accounts use the same routing number, and all failures triggered are early failures.
Routing number: 999999992
| Result | Account Number |
|---|---|
| Accepted | 999XXX101 |
| Validation failed | 999XXX100 |
The XXX digits specify the number of seconds to wait before triggering the result — for example, account number 999010101 succeeds after 10 seconds.
In the sandbox environment, you can trigger specific early failure conditions using special account numbers:
| Account Number | Behavior |
|---|---|
999XXX101 | Success |
999XXX100 | Bank routing number validation negative (ABA) |
999XXX200 | Bank routing number must be 9 digits |
999XXX300 | Consumer verification negative |
999XXX400 | Invalid login |
999XXX500 | Access denied |
999XXX900 | Object reference not set to an instance of an object |
999XXX910 | Request timed out |
999XXX990 | Delays for 90 seconds to induce a client-side timeout, then responds normally (e.g. "bank routing number validation negative (ABA)") |
Updated 25 days ago
