Skip to content

Cards API Reference

Base URLs: https://processing.mainnet.rubin.trade (mainnet), https://processing.testnet.rubin.trade (testnet). {provider} is the id from GET /v4/providers.

Auth column: public — no signature; signed — signed request for the customer address.

MethodPathAuthPurpose
GET/v4/providerspublicProviders, tariffs, limits
GET/v4/{provider}/quotesignedPrice of an operation
POST/v4/{provider}/orders/paidsignedReport a payment, create the order
POST/v4/{provider}/orderssignedWithdraw; order-first issue or top-up
GET/v4/{provider}/orderssignedList orders
GET/v4/{provider}/orders/{orderId}signedOne order
GET/v4/{provider}/accountsignedMoney in progress at the provider
GET/v4/{provider}/cardssignedList cards
GET/v4/{provider}/cards/{cardId}signedOne card
POST/v4/{provider}/cards/{cardId}/revealsignedCard number, CVC, PIN
POST/v4/{provider}/cards/{cardId}/passwordsignedSet or change the PIN
POST/v4/{provider}/cards/{cardId}/renamesignedRename a card
POST/v4/{provider}/cards/{cardId}/deactivatesignedClose a card permanently
GET/v4/{provider}/operationssignedPayment history
GET/v4/{provider}/cards/{cardId}/operationssignedPayment history of one card
GET/v4/{provider}/operations/recentsignedLatest operations
GET/v4/{provider}/operations/summarysignedMonthly totals
GET/v4/{provider}/operations/exportsignedHistory as CSV
GET/v4/{provider}/verification-codessigned3-D Secure and wallet codes
GET/v4/{provider}/events/channelsignedKey of the change-signal channel

Testnet also has simulation endpoints.

An unknown {provider} answers 404. Identifiers are UUIDs (400 otherwise). Amounts are decimal strings. Computed amounts have a fixed scale: USDC 6 decimals, USD 2; tariffs and limits can be shorter, e.g. "10". Timestamps are ISO 8601. Only GET and POST are used. Responses may contain fields not listed here; do not rely on them.

Errors

Every error has the same shape:

{ "errors": [{ "code": "AMOUNT_BELOW_MIN", "msg": "Amount is below minimum of 10 USD", "min": "10" }] }

code, min, max and retryAfterSeconds are present only where they apply. Request validation errors (400) are a list of { "value", "msg", "param", "location" } without code. A card or order that does not exist or belongs to another address answers 404 with msg only; a card missing at the card provider answers 404 CARD_NOT_FOUND.

CodeHTTPMeaning
FEE_NOT_FOUND422No such tariff, or it is not on sale
ISSUE_DISABLED422The provider does not issue cards now
TOO_MANY_CARDS422The address reached limits.maxCards (max), counting cards being issued
TOO_MANY_OPEN_ORDERS422The address reached limits.maxOpenOrders (max)
ORDER_IN_PROGRESS422The card already has an order running
CARD_INACTIVE422The card is not active
AMOUNT_BELOW_MIN422Below the minimum (min)
AMOUNT_ABOVE_MAX422Above the maximum (max)
INSUFFICIENT_CARD_BALANCE422The withdrawal exceeds the card balance (max), or the balance is unknown
WITHDRAW_NOT_SUPPORTED422The card does not allow withdrawals
PASSWORD_NOT_SUPPORTED422The card does not support a PIN of your choice
CARD_BALANCE_NOT_ZERO422Closing a card needs a balance below 1 USD
QUOTE_EXPIRED409expectedTotalUsdc differs from the current price; get a new quote
PAYMENT_NOT_FOUND404The payment is not on chain yet, or another address made it; retry
REVEAL_RATE_LIMITED429Too many card detail requests; wait retryAfterSeconds
WALLET_SIGNATURE_REQUIRED403This action does not accept a session signature
CHAIN_UNAVAILABLE503The chain cannot be read right now; retry
PROVIDER_UNAVAILABLE503 / 502The card provider is down or this operation is closed for now; retry later
PROVIDER_RATE_LIMITED503The card provider is throttling; wait retryAfterSeconds
PROVIDER_ERROR422 / 502The card provider rejected the request (msg has its text) or answered with something unreadable
CARD_NOT_FOUND404The card is missing at the card provider

Authentication errors are listed on the Keys & Authentication page.


Providers

GET /v4/providers

Public. Cards providers with their tariffs and limits; cached for 30 seconds.

{
  "providers": [
    {
      "id": "mock",
      "displayName": "Mock Card (testnet)",
      "flow": {
        "issue": true,
        "topup": true,
        "withdraw": "per_card",
        "password": "per_tariff",
        "verificationCodes": true,
        "rename": true,
        "freeze": false,
        "reveal": "live"
      },
      "fees": [
        {
          "feeId": 905,
          "active": true,
          "name": "Premium",
          "userPriceUsdc": "39.000000",
          "startBalanceUsd": "0",
          "lifespanDays": 1095,
          "depositFeePercent": 1.9,
          "withdrawalFeePercent": 0,
          "txFeeUsd": "0",
          "txFeeRate": 0,
          "txInUsaFeeUsd": "0",
          "minDepositUsd": "10",
          "canWithdraw": false,
          "canSetPassword": true,
          "options": ["E_PAYMENTS_ENABLED", "APPLE_PAY_ENABLED"],
          "brand": "visa"
        }
      ],
      "limits": {
        "maxCards": 3,
        "maxOpenOrders": 3,
        "topupMinUsd": "10",
        "topupMaxUsd": "5000",
        "withdrawMinUsd": "0",
        "withdrawMaxUsd": "5000"
      },
      "payment": { "quoteTtlSeconds": 120, "driftTolerancePercent": "1", "paymentTtlSeconds": 600 },
      "chain": { "providerId": "mock", "assetId": 0, "denom": "uusdc", "decimals": 6, "enabled": true, "maxOrderUsdc": "15500.000000" },
      "providerAvailable": true,
      "simulateOperations": true,
      "feesFetchedAt": "2026-11-06T12:00:00.000Z"
    }
  ]
}
Provider
FieldTypeDescription
idstringThe {provider} path segment
displayNamestringProvider name
flowobjectWhat the provider supports, see below
feesarrayTariffs, see below. May be empty if the tariffs cannot be read now
limitsobjectPer-address limits and USD bounds for top-ups and withdrawals
paymentobjectQuote lifetime, price tolerance and order-first payment window
chainobject | nullOn-chain settings; null while they cannot be read
providerAvailablebooleanThe card provider responds. If false, POST /orders answers 503, and an on-chain payment waits in paid until the provider returns
simulateOperationsbooleanSimulation endpoints are available
feesFetchedAtstring | nullWhen the tariffs were read
flow
FieldValuesMeaning
issue, topupbooleanNew cards and top-ups are available
withdrawper_card, noneDepends on the card's canWithdraw, or not available
passwordper_tariff, noneDepends on the tariff's canSetPassword, or not available
verificationCodesbooleanOne-time codes are delivered through the API
renamebooleanCards can be renamed
freezebooleanTemporary freeze; currently always false
reveallive, noneCard details are read live from the provider, or not available
Tariff (fees[])
FieldTypeDescription
feeIdnumberTariff id
activebooleanOn sale. false — only for showing the terms of cards issued earlier
namestring?Tariff name
userPriceUsdcstringPrice of issuing a card, USDC, all fees included
startBalanceUsdstringBalance on the card right after issue, included in the price
lifespanDaysnumberHow long the card lives
depositFeePercentnumberTop-up fee, percent (1.9 = 1.9 %)
withdrawalFeePercentnumberWithdrawal fee, percent
txFeeUsdstringFixed fee per purchase, USD
txFeeRatenumberFee per purchase as a fraction (0.004 = 0.4 %)
txInUsaFeeUsdstringFixed fee per purchase in the USA, USD
minDepositUsdstringMinimum top-up, USD
canWithdrawbooleanCards of this tariff allow withdrawals
canSetPasswordbooleanCards of this tariff support a PIN of your choice
optionsstring[]E_PAYMENTS_ENABLED, APPLE_PAY_ENABLED
brandstringvisa, mastercard or unknown
limits
FieldDescription
maxCardsActive cards per address, counting cards being issued
maxOpenOrdersOpen orders per address
topupMinUsd, topupMaxUsdBounds of one top-up, USD on the card
withdrawMinUsd, withdrawMaxUsdBounds of one withdrawal, USD off the card
payment
FieldDescription
quoteTtlSecondsHow long to treat a quote as fresh
driftTolerancePercentHow far the card provider's price may move from the order. Beyond it an issue or top-up is refunded and a withdrawal fails; within it the order completes, so the card or the credit can come in slightly below the quote
paymentTtlSecondsOrder-first variant: how long an order waits for its payment
chain
FieldDescription
providerIdprovider_id for MsgOrder
assetId, denom, decimalsThe payment asset: USDC, uusdc, 6 decimals
enabledThe provider accepts payments on chain
maxOrderUsdcThe largest single payment, null — no cap

Quote and orders

GET /v4/{provider}/quote

The price of an operation, after checking the tariff, the card, the amount bounds and running orders on the card. It does not check everything a payment needs.

ParameterRequiredDescription
typealwaysissue, topup or withdraw
feeIdissueTariff
cardIdtopup, withdrawCard
amountUsdtopup, withdrawUSD to put on or take off the card, up to 2 decimals
{
  "type": "issue",
  "amountUserUsdc": "39.000000",
  "amountCardUsd": "0.00",
  "providerFeeUsdt": "39.000000",
  "markupUsdc": "0.000000",
  "feePercent": "0",
  "feeId": 905,
  "cardId": null,
  "driftTolerancePercent": "1",
  "quoteTtlSeconds": 120
}
FieldTypeDescription
amountUserUsdcstringUSDC the customer pays (issue, topup) or should receive (withdraw)
amountCardUsdstringUSD that should land on the card (issue, topup) or leaves it (withdraw)
providerFeeUsdtstringTariff fee inside this amount
markupUsdcstringService fee inside this amount
feePercentstringTariff fee in percent; 0 for issue
feeId, cardIdnumber, string | nullTariff and card of the operation

The price is checked again when the payment arrives: a payment that differs from the current price returns in full.

Errors: FEE_NOT_FOUND, CARD_INACTIVE, AMOUNT_BELOW_MIN, AMOUNT_ABOVE_MAX, WITHDRAW_NOT_SUPPORTED, INSUFFICIENT_CARD_BALANCE, ORDER_IN_PROGRESS. A withdrawal quote can read the balance from the card provider, so it can also answer PROVIDER_UNAVAILABLE, PROVIDER_RATE_LIMITED and PROVIDER_ERROR.

POST /v4/{provider}/orders/paid

Reports an on-chain MsgOrder and creates the order from it. See Integration flow.

{ "ref": "o1:i:905:0123456789abcdef" }

Answers 201 with { "order": … } if the order was created, 200 if it already existed. The order is created from what is on chain: the payer is whoever signed MsgOrder, the amount is what arrived. If the rules no longer allow the operation or the amount differs from the price, the order is created in refund_submitted, and the payment returns.

Errors: 400 — ref is not in the o1:… format, PAYMENT_NOT_FOUND, CHAIN_UNAVAILABLE.

POST /v4/{provider}/orders

Creates a withdrawal, or an issue or top-up order in the order-first variant.

FieldRequiredDescription
typealwayswithdraw, issue or topup
feeIdissueTariff
cardIdtopup, withdrawCard
amountUsdtopup, withdrawUSD, up to 2 decimals
clientIdnoYour unique id, up to 64 characters. A repeat returns the same order before any other check, even with other parameters
expectedTotalUsdcnoThe price you showed; if it differs, answers 409 QUOTE_EXPIRED

Answers 201 with { "order": … }, or 200 if clientId matched an existing order. A withdrawal is checked against the card's live balance.

Errors: everything from the quote, ISSUE_DISABLED, TOO_MANY_CARDS, TOO_MANY_OPEN_ORDERS, QUOTE_EXPIRED, PROVIDER_UNAVAILABLE.

GET /v4/{provider}/orders/{orderId}

{
  "order": {
    "orderId": "2f6c1d7e-8a3b-4c55-9f10-6d2e7a1b3c44",
    "provider": "mock",
    "type": "issue",
    "status": "completed",
    "cardId": "7b1e4f60-2d9a-4e11-8c3f-1a2b3c4d5e6f",
    "feeId": 905,
    "amountUserUsdc": "39.000000",
    "amountCardUsd": "0.00",
    "providerFeeUsdt": "39.000000",
    "markupUsdc": "0.000000",
    "chain": {
      "paymentTxHash": "8F3A…",
      "paymentAmountUsdc": "39.000000",
      "paidAt": "2026-11-06T12:00:04.000Z",
      "refundTxHash": null,
      "refundAmountUsdc": null,
      "refundedAt": null,
      "creditTxHash": null,
      "creditAmountUsdc": null,
      "creditedAt": null
    },
    "payment": null,
    "failReason": null,
    "createdAt": "2026-11-06T12:00:05.000Z",
    "updatedAt": "2026-11-06T12:00:09.000Z",
    "completedAt": "2026-11-06T12:00:09.000Z"
  }
}
FieldTypeDescription
orderIdstring (UUID)Order id
typestringissue, topup, withdraw
statusstringSee statuses
cardIdstring | nullThe card of the order. On issue, set when the card is issued
feeIdnumber | nullThe tariff of an issue order
amountUserUsdcstringUSDC the customer pays or receives
amountCardUsdstring | nullUSD on the card
providerFeeUsdtstringTariff fee inside the amount
markupUsdcstringService fee inside the amount
chainobjectOn-chain transactions: payment, refund, credit. *AmountUsdc appears when the transaction is sent, *TxHash and *At when it passes. paymentTxHash can stay null: keep the hash of your own transaction
paymentobject | nullWhat to sign, only in awaiting_payment: providerId, ref, amountUsdc, amountQuantums, expiresAt
failReasonstring | nullSee reasons. Always null in manual_review
createdAt, updatedAt, completedAtstring | nullTimestamps

GET /v4/{provider}/orders

ParameterDescription
statusopen — not finished; all (default)
typeissue, topup, withdraw
cardIdOrders of one card
pageFrom 1
limit1–100, default 20

{ "orders": [ … ], "total": 3, "page": 1, "limit": 20 }

GET /v4/{provider}/account

The money the address has in progress with the provider. USDC stays in the wallet until an order is paid, so this is for reconciliation, not a balance.

{
  "address": "rit1…",
  "assetId": 0,
  "denom": "uusdc",
  "positions": [{ "provider": "mock", "amount": "139.000000" }],
  "inFlight": [{ "orderId": "2f6c…", "type": "topup", "status": "paid", "amountUsdc": "100.000000" }],
  "source": "chain",
  "updatedAtHeight": null
}
FieldDescription
positionsPaid to the provider and not returned: payments minus refunds minus credits. Caps how much a withdrawal can credit
inFlightOrders whose payment has left the wallet and which are not closed yet
source, updatedAtHeightchain — read live; indexer — from a snapshot at that height

Errors: CHAIN_UNAVAILABLE.


Cards

GET /v4/{provider}/cards

ParameterDescription
includeInactive1 — include closed and expired cards. Default: active only
{
  "cards": [
    {
      "cardId": "7b1e4f60-2d9a-4e11-8c3f-1a2b3c4d5e6f",
      "provider": "mock",
      "status": "active",
      "name": "Travel",
      "cardholderName": "RUBIN CARD",
      "brand": "visa",
      "last4": "4821",
      "expirationMonth": 11,
      "expirationYear": 2029,
      "billingAddress": "…",
      "balanceUsd": "125.40",
      "balanceSyncedAt": "2026-11-06T12:00:00.000Z",
      "canWithdraw": false,
      "canSetPassword": true,
      "activeUntil": "2029-11-06T00:00:00.000Z",
      "feeId": 905,
      "hasOpenOrder": false,
      "createdAt": "2026-11-06T11:00:00.000Z",
      "deactivatedAt": null
    }
  ]
}
FieldTypeDescription
cardIdstring (UUID)Card id
statusstringactive, deactivated, expired, unknown
namestring | nullName given to the card
cardholderName, billingAddressstring | nullAs for an online payment form
brandstring | nullvisa, mastercard, unknown
last4, expirationMonth, expirationYearstring, numberSafe to show without reveal
balanceUsdstring | nullSnapshot of the balance; null — not known
balanceSyncedAtstring | nullWhen the snapshot was taken; null — a refresh is due
canWithdraw, canSetPasswordbooleanWhat this card allows
activeUntilstring | nullEnd of the card's life. After it the card is expired, and the balance cannot be withdrawn through the API
feeIdnumberTariff; GET /v4/providers has its terms even when it is off sale
hasOpenOrderbooleanAn order on this card is not finished. Blocks closing
createdAt, deactivatedAtstring | nullTimestamps

GET /v4/{provider}/cards/{cardId}

{ "card": { … } }. With ?refresh=1, the balance and flags are read from the card provider first, so it can also answer PROVIDER_UNAVAILABLE, PROVIDER_RATE_LIMITED and PROVIDER_ERROR.

POST /v4/{provider}/cards/{cardId}/reveal

No body. Card details, read live from the card provider and not cached (Cache-Control: no-store). See the warning on card data.

{
  "number": "4000123412341234",
  "cvc": "123",
  "pin": "123456",
  "expirationMonth": 11,
  "expirationYear": 2029,
  "cardholderName": "RUBIN CARD",
  "billingAddress": "…",
  "ttlSeconds": 60
}

pin can be null; on the testnet simulator it has 4 digits. ttlSeconds is how long to keep the details on screen.

Errors: CARD_INACTIVE, CARD_NOT_FOUND, REVEAL_RATE_LIMITED, PROVIDER_ERROR, PROVIDER_UNAVAILABLE, PROVIDER_RATE_LIMITED.

POST /v4/{provider}/cards/{cardId}/password

Sets or changes the PIN.

{ "password": "123456" }
FieldDescription
passwordExactly 6 digits

{ "ok": true }. Answers 404 if the provider has flow.password: "none".

Errors: CARD_INACTIVE, PASSWORD_NOT_SUPPORTED, PROVIDER_ERROR, PROVIDER_UNAVAILABLE, PROVIDER_RATE_LIMITED.

POST /v4/{provider}/cards/{cardId}/rename

{ "name": "Travel" }

1–32 characters: letters, digits, space, ., ', -. { "card": { … } }.

Errors: PROVIDER_ERROR, PROVIDER_UNAVAILABLE, PROVIDER_RATE_LIMITED.

POST /v4/{provider}/cards/{cardId}/deactivate

Closes the card permanently. Not available with a session signature.

{ "confirm": true }

{ "card": { … } } with status: "deactivated".

A remainder below 1 USD is not returned. The balance check uses the stored snapshot; read ?refresh=1 first.

Errors: CARD_INACTIVE, ORDER_IN_PROGRESS, CARD_BALANCE_NOT_ZERO, WALLET_SIGNATURE_REQUIRED, PROVIDER_ERROR, PROVIDER_UNAVAILABLE, PROVIDER_RATE_LIMITED.


Payment history

GET /v4/{provider}/operations

GET /v4/{provider}/cards/{cardId}/operations is the same for one card.

ParameterDescription
cardIdOne card
typesComma-separated: purchase, refund, deposit, withdrawal
monthYYYY-MM, UTC. Cannot be combined with from and to
from, toISO 8601 range
merchantMerchant name filter, up to 64 characters
pageFrom 1
limit1–100, default 20
{
  "operations": [
    {
      "operationId": "c41d7a90-5b2e-4f3a-9e81-7d6c5b4a3f21",
      "cardId": "7b1e4f60-2d9a-4e11-8c3f-1a2b3c4d5e6f",
      "type": "purchase",
      "status": "approved",
      "amountUsd": "12.99",
      "currency": "USD",
      "localAmount": "11.99",
      "localCurrency": "EUR",
      "feeUsd": "0",
      "merchant": "NETFLIX.COM",
      "country": "NL",
      "declineReason": null,
      "orderId": null,
      "occurredAt": "2026-11-05T18:21:00.000Z",
      "updatedAt": "2026-11-05T18:21:30.000Z"
    }
  ],
  "total": 1,
  "page": 1,
  "limit": 20
}
FieldTypeDescription
operationId, cardIdstring (UUID)Operation and card
typestringpurchase, refund (by a merchant), deposit (top-up), withdrawal
statusstringpurchase: on_hold, approved, declined. refund: approved. deposit, withdrawal: inited, confirmed, rollbacked
amountUsd, currencystringAmount and card currency
localAmount, localCurrencystring | nullAmount in the merchant's currency
feeUsdstring | nullFee of this operation
merchant, countrystring | nullMerchant name and country
declineReasonstring | nullWhy the purchase was declined
orderIdstring | nullThe order behind a top-up or withdrawal
occurredAt, updatedAtstring | nullTimestamps

GET /v4/{provider}/operations/recent

ParameterDescription
cardIdOne card
limit1–20, default 10

{ "operations": [ … ] }

GET /v4/{provider}/operations/summary

ParameterDescription
monthYYYY-MM, UTC. Default: the current month
cardIdOne card
{
  "month": "2026-11",
  "spentUsd": "412.50",
  "topupUsd": "500.00",
  "withdrawUsd": "0.00",
  "refundUsd": "12.99",
  "declinedCount": 1,
  "byMerchant": [{ "merchant": "NETFLIX.COM", "amountUsd": "12.99", "count": 1 }]
}

byMerchant holds the top 5 merchants, then __other for the rest.

GET /v4/{provider}/operations/export

The filters of GET /operations without page and limit. Answers a UTF-8 CSV file of up to 5,000 rows with the columns date, card_last4, type, status, merchant, country, amount_usd, local_amount, local_currency, fee_usd, decline_reason, operation_id.


One-time codes

GET /v4/{provider}/verification-codes

Codes for 3-D Secure and for adding the card to a wallet that have not expired yet (Cache-Control: no-store). See One-time codes.

ParameterDescription
cardIdOne card
limit1–50, default 20
{
  "codes": [
    {
      "codeId": "a90b1c2d-3e4f-4a5b-8c6d-7e8f9a0b1c2d",
      "cardId": "7b1e4f60-2d9a-4e11-8c3f-1a2b3c4d5e6f",
      "kind": "three_ds",
      "paymentServiceName": null,
      "otp": "482915",
      "amount": "12.99",
      "currency": "USD",
      "merchant": "NETFLIX.COM",
      "createdAt": "2026-11-06T12:00:00.000Z",
      "expiresAt": "2026-11-06T12:03:00.000Z"
    }
  ]
}
FieldDescription
kindthree_ds — a purchase; payment_service — adding the card to a wallet
paymentServiceNameThe wallet for payment_service, e.g. Apple Pay
otpThe code to show
amount, currency, merchantWhat the code confirms; can be null
expiresAtWhen the code stops being valid

Change signals

GET /v4/{provider}/events/channel

{ "channel": "v4_card", "channelId": "6604983f…222f" }

channelId is the id to subscribe with on the indexer WebSocket; null — signals are off.


Service

GET /health

{ "ok": true, "service": "processing" }. Public.