Cards
Tokenise a card once and re-use the token on subsequent transactions. Manage the lifecycle: list, detail, update, delete.
List cards
GET
/v1/cards/{page}/{limit}
List stored cards
Returns a paged list of the cards stored under your credentials, newest first. Deleted cards are not returned. The list is always scoped to the instance your API key belongs to; with merchant-level credentials it is additionally scoped to that merchant and the merchant filter is ignored. Only the user and merchant filters are read — any other query parameter is ignored, and instance cannot be supplied. data is an object: the cards are in data.items and the total count in data.total_items. There is no total_pages counter — derive it from total_items and limit. This is a GET with no request body: the HMAC hash is calculated over ApiKey + Timestamp + Operation, with an empty string in place of the body. Authentication: HMAC (cards_list).
Path parameters
| Name | Example | Description |
|---|---|---|
page
|
1 |
Page number, starting at 1. There is no default — the segment cannot be left out. 0 on page or limit turns paging off and returns every matching card in one response; always send 1 or more. |
limit
|
20 |
Number of cards per page. There is no default; 20 is a sensible starting point. |
Query parameters
| Name | Example | Description |
|---|---|---|
user
|
3f86c24b-dd63-47bc-bc21-1a7deb7ac679 |
Return only the cards stored against this user token. |
merchant
|
df1f946a-8b03-4a21-8eb7-dab86a77a027 |
Return only one merchant's cards. Ignored when your credentials are merchant-level — the merchant behind the API key always wins. |
Response
| Field | Type | Description | |||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
code
|
integer (0,any) | ||||||||||||||||||||||||||||||||||||||||
data
|
object required | ||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||
Example response
- Cards found
- No cards
{
"code": 0,
"data": {
"items": [
{
"token": "89adaf41-95e6-4a42-b4ee-a686caba7139",
"card_number_masked": "411111XXXXXX1111",
"cardholder_name": "John Doe",
"card_expiration_month": "01",
"card_expiration_year": "30",
"card_alias": "my-visa",
"user": "3f86c24b-dd63-47bc-bc21-1a7deb7ac679",
"merchant": "df1f946a-8b03-4a21-8eb7-dab86a77a027"
}
],
"total_items": 1
}
}
{
"code": 0,
"data": {
"items": [],
"total_items": 0
}
}
Card detail
GET
/v1/cards/{token}
Card details
Returns one stored card by its token. The object is the same one the list returns. A token that does not exist, has been deleted, or belongs to someone else all produce the same result: card not found (code 90001, returned with HTTP 200). The endpoint does not distinguish between them. The lookup is scoped to your instance, and to your merchant when your credentials are merchant-level. merchant is accepted in the query string but has no effect here — unlike the list and delete endpoints, this one ignores it. This is a GET with no request body: the HMAC hash is calculated over ApiKey + Timestamp + Operation, with an empty string in place of the body. Authentication: HMAC (card_details).
Path parameters
| Name | Example | Description |
|---|---|---|
token
|
89adaf41-95e6-4a42-b4ee-a686caba7139 |
Card token, as returned by POST /v1/cards. |
Query parameters
| Name | Example | Description |
|---|---|---|
user
|
3f86c24b-dd63-47bc-bc21-1a7deb7ac679 |
Additionally require the card to belong to this user token. |
Response
| Field | Type | Description | |||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
code
|
integer (0,any) | ||||||||||||||||||||||||||||
data
|
object required | ||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||
Example response
- Card found
- Card not found
{
"code": 0,
"data": {
"token": "89adaf41-95e6-4a42-b4ee-a686caba7139",
"card_number_masked": "411111XXXXXX1111",
"cardholder_name": "John Doe",
"card_expiration_month": "01",
"card_expiration_year": "30",
"card_alias": "my-visa",
"user": "3f86c24b-dd63-47bc-bc21-1a7deb7ac679",
"merchant": "df1f946a-8b03-4a21-8eb7-dab86a77a027"
}
}
The token is unknown, deleted, or belongs to someone else.
{
"code": 90001,
"message": "services.card-not-found"
}
Update card
PUT
/v1/cards/{token}
Replace a stored card
Operation
card_updateThis call does not modify the card you name. It stores a new card and returns a new token: the token in the response is different from the token in the URL, and everything you hold that refers to the old token must be repointed at the new one. The card in the path is left as it is — it is not deleted and stays usable — and the new card is linked back to it. Use it when a cardholder's card is reissued — a new expiry date, or a new number after a replacement — and you want the new card recorded as a continuation of the old one rather than as an unrelated card. The replacement must be the same card brand as the original: the check compares the first digit of the two card numbers, so replacing a Visa with a Mastercard is rejected with code 90022. To swap in a card of a different brand, store it as a new card with POST
/v1/cards instead. The new card is stored under the merchant of the card being replaced. If the card in the path is not found under your credentials the call fails with code 90001. Authentication: HMAC (card_update).Path parameters
| Name | Example | Description |
|---|---|---|
token
|
89adaf41-95e6-4a42-b4ee-a686caba7139 |
Token of the card being replaced. This card is not modified; the new card is linked back to it. |
Request body
| Field | Type | Description |
|---|---|---|
card_
|
string (0,any) | Full card number. Required; the only check applied is that it is not blank (whitespace alone is rejected). There is no Luhn, length or expiry check — a card number that cannot be used is accepted here and fails on the first financial operation. |
cardholder_
|
string (0,any) | Name as printed on the card. |
card_
|
string (0,any) | Expiry month, MM. Not validated. |
card_
|
string (0,any) | Expiry year, YY. Not validated. |
card_
|
string (0,any) | Your own label for the card. Returned on the list and details calls, so you can show the cardholder which card they saved without holding any card data yourself. |
user
|
string (0,any) | Your end-user's token. Store it with the card to be able to list one user's cards later. |
Example request
Reissued card with a new expiry date
{
"card_number": "4111111111111111",
"cardholder_name": "John Doe",
"card_expiration_month": "01",
"card_expiration_year": "32",
"card_alias": "my-visa"
}
Response
| Field | Type | Description | ||||||
|---|---|---|---|---|---|---|---|---|
code
|
integer (0,any) | |||||||
data
|
object | |||||||
|
||||||||
Example response
- Card replaced
- Different card brand
- Card in the path not found
- card_number missing or blank
{
"code": 0,
"data": {
"token": "b7d1f0c2-3a44-4f19-9c88-2e5a1d7f0b63"
}
}
The first digit of the new card number differs from the card being replaced.
{
"code": 90022,
"message": "services.cannot_update_card_with_different_brand"
}
{
"code": 90001,
"message": "services.card-not-found"
}
{
"code": 11001,
"message": "services.general.validation_error",
"errors": {
"card_number": "This value should not be blank."
}
}
Delete card
DELETE
/v1/cards/{token}
Delete a stored card
Deletes a stored card. After this the token can no longer be used on an acquiring operation and the card stops appearing in the list and details calls. The delete is scoped to your instance, and to your merchant when your credentials are merchant-level. A token that does not exist, is already deleted, or belongs to someone else fails with code 11002 (services.general.entity_not_found), returned with HTTP 200. There is no request body: the HMAC hash is calculated over ApiKey + Timestamp + Operation, with an empty string in place of the body. Authentication: HMAC (card_delete).
Path parameters
| Name | Example | Description |
|---|---|---|
token
|
89adaf41-95e6-4a42-b4ee-a686caba7139 |
Card token to delete. |
Query parameters
| Name | Example | Description |
|---|---|---|
user
|
3f86c24b-dd63-47bc-bc21-1a7deb7ac679 |
Additionally require the card to belong to this user token. |
merchant
|
df1f946a-8b03-4a21-8eb7-dab86a77a027 |
Restrict the delete to one merchant's cards. Ignored when your credentials are merchant-level — the merchant behind the API key always wins. |
Response
| Field | Type | Description |
|---|---|---|
code
|
integer (0,any) | 0 = the card was deleted. |
Example response
- Card deleted
- Card not found
{
"code": 0
}
The token is unknown, already deleted, or belongs to someone else.
{
"code": 11002,
"message": "services.general.entity_not_found"
}
Tokenize card
POST
/v1/cards
Store a card and get a token
Operation
card_newStores a card and returns the token that represents it. Send the token as card on pre-authorization, purchase, credit and oct instead of card_number, so the card number never has to touch your system again. This call does not contact the card scheme and does not verify that the card exists or is active — it is storage, not validation; the first time you learn whether the card works is on the first financial operation you run with it. card_number is the only field the API enforces, and it only checks that it is not blank. merchant and instance are taken from your credentials and cannot be set from the body; with instance-level credentials the card is stored without a merchant. Authentication: HMAC (card_new).
Request body
| Field | Type | Description |
|---|---|---|
card_
|
string (0,any) | Full card number. Required; the only check applied is that it is not blank (whitespace alone is rejected). There is no Luhn, length or expiry check — a card number that cannot be used is accepted here and fails on the first financial operation. |
cardholder_
|
string (0,any) | Name as printed on the card. |
card_
|
string (0,any) | Expiry month, MM. Not validated. |
card_
|
string (0,any) | Expiry year, YY. Not validated. |
card_
|
string (0,any) | Your own label for the card. Returned on the list and details calls, so you can show the cardholder which card they saved without holding any card data yourself. |
user
|
string (0,any) | Your end-user's token. Store it with the card to be able to list one user's cards later. |
Example request
- Card with expiry and alias
- Card stored against an end-user
- Card number only
A card stored with its expiry date and your own label.
{
"card_number": "4111111111111111",
"cardholder_name": "John Doe",
"card_expiration_month": "01",
"card_expiration_year": "30",
"card_alias": "my-visa"
}
Store the user token with the card to list that user's cards later with GET /v1/cards/{page}/{limit}?user=...
{
"card_number": "4111111111111111",
"cardholder_name": "John Doe",
"card_expiration_month": "01",
"card_expiration_year": "30",
"user": "3f86c24b-dd63-47bc-bc21-1a7deb7ac679"
}
card_number is the only required field.
{
"card_number": "4111111111111111"
}
Response
| Field | Type | Description | ||||||
|---|---|---|---|---|---|---|---|---|
code
|
integer (0,any) | |||||||
data
|
object | |||||||
|
||||||||
Example response
- Card stored
- card_number missing or blank
{
"code": 0,
"data": {
"token": "89adaf41-95e6-4a42-b4ee-a686caba7139"
}
}
The errors object names the field.
{
"code": 11001,
"message": "services.general.validation_error",
"errors": {
"card_number": "This value should not be blank."
}
}