API reference

Every endpoint, generated from the same source as the OpenAPI spec. Base URL: https://www.primcard.io/api/partner/v1 · auth: Authorization: Bearer sk_… · amounts in cents.

Account

Key check and balance.

get/pingCheck your key

Responses

  • 200 — The key works.
  • 401 — Unknown, revoked, or malformed API key.
get/balanceYour funding balance

Responses

  • 200 — Balance for the key's mode.
  • 401 — Invalid key.

Products

The card BINs you may issue on.

get/productsYour available BINs

The card products (BINs) enabled for your account. Use a product_code from here as the optional `product_code` on POST /cards; omit it to use the one marked is_default.

Responses

  • 200 — Your allowed products.

Cards

Create and manage virtual cards.

get/cardsList cards

Parameters

  • limit (query)
  • starting_after (query) — Card id to paginate after.
  • external_ref (query)
  • status (query)

Responses

  • 200 — Newest first.
post/cardsCreate a card

Creates AND funds a USD virtual card in one call. The card receives `amount`; your balance is debited `amount` + issuance fee + top-up fee (see POST /quotes). 201 = active immediately; 202 = the network accepted it and it activates within minutes — poll GET /cards/{id} or listen for the card.issued webhook.

Parameters

  • Idempotency-Key (header, required) — Required on every money-moving POST. Reuse the SAME key when retrying the same request — the stored response is replayed instead of moving money twice. A new request needs a new key.

Request body

object
  amount*: integer — Cents to land on the card. Example: 10000 = a $100.00 card.
  external_ref*: string — Your id for this card — unique per account, lets you key cards by your own system.
  product_code: string — Optional. The BIN/product to issue on — must be one of your GET /products entries. Omit to use your default.
  card_name: string — Display label.
  cardholder_first_name: string
  cardholder_last_name: string
  email: string

Responses

  • 201 — Card active and funded.
  • 202 — Accepted — card is funding_pending.
  • 400 — Validation problem or missing Idempotency-Key.
  • 402 — insufficient_funds or provider_declined.
  • 409 — external_ref_taken, idempotency_in_flight, or no_product_configured.
  • 422 — limit_exceeded, idempotency_conflict, or product_not_allowed.
get/cards/{cardId}Card details (polling target)

Parameters

  • cardId (path, required)

Responses

  • 200 — The card.
  • 404 — Not on this account (or wrong mode).
post/cards/{cardId}/topupsTop up a card

Adds `amount` to an active card; your balance is debited `amount` + the top-up fee. 202 means the network is completing it asynchronously — the topup.succeeded webhook (or card polling) confirms.

Parameters

  • cardId (path, required)
  • Idempotency-Key (header, required) — Required on every money-moving POST. Reuse the SAME key when retrying the same request — the stored response is replayed instead of moving money twice. A new request needs a new key.

Request body

object
  amount*: integer

Responses

  • 201 — Funded.
  • 202 — Accepted, completing asynchronously.
  • 402 — insufficient_funds or provider_declined.
  • 409 — invalid_state — only active cards top up.
post/cards/{cardId}/freezeFreeze (reversible)

Parameters

  • cardId (path, required)

Responses

  • 200 — Frozen — authorizations decline until unfrozen.
  • 409 — invalid_state.
post/cards/{cardId}/unfreezeUnfreeze

Parameters

  • cardId (path, required)

Responses

  • 200 — Active again.
  • 409 — invalid_state.
post/cards/{cardId}/blockBlock (PERMANENT)

Irreversible. Remaining card balance is released back to your PrimCard balance. Cancel recurring subscriptions first — merchants can keep submitting debits after a block, and those still generate fees.

Parameters

  • cardId (path, required)

Responses

  • 200 — Blocked; balance released.
  • 409 — invalid_state.
get/cards/{cardId}/transactionsSettled transactions

Parameters

  • cardId (path, required)
  • limit (query)

Responses

  • 200 — Newest first.
get/cards/{cardId}/secure-detailsFull card number + CVV (restricted)

Returns PAN, CVV and expiry, fetched live from the card network. DISABLED by default — PrimCard enables it per account after review. Hard limits: 3/minute and 20/day, fail-closed. Never store what this returns; request it again when needed.

Parameters

  • cardId (path, required)

Responses

  • 200 — Sensitive — response is never cached or logged.
  • 403 — secure_details_disabled — not enabled for this account.
  • 429 — Reveal limit reached.

Funding

Move money into your PrimCard balance (live mode).

post/funding/deposit-addressGet a USDT deposit address (live keys)

Fresh USDT (TRC-20) address for the stated amount. Send exactly that amount; your balance credits automatically on confirmation (deposit.confirmed webhook / GET /funding/deposits). Addresses expire in ~8 hours — request a new one per deposit.

Request body

object
  amount*: integer — Intended deposit in cents.

Responses

  • 201 — The deposit instruction.
  • 403 — test_key_not_allowed — use POST /test/credit in sandbox.
get/funding/depositsDeposit history / status

Parameters

  • limit (query)

Responses

  • 200 — Newest first.

Pricing

Preview fees before committing.

post/quotesPreview fees

Exactly what a card creation or top-up would cost right now, including any negotiated rates on your account. Read-only.

Request body

object
  type*: string (card_issue | card_topup)
  amount*: integer — Cents to land on the card.

Responses

  • 200 — The fee breakdown.
  • 400 — Invalid type or amount.

Test mode

sk_test_ only — sandbox helpers.

post/test/creditSandbox faucet

Credits pretend money to your TEST balance (sk_test_ keys only, max $100,000 per call, 60/hour).

Parameters

  • Idempotency-Key (header, required) — Required on every money-moving POST. Reuse the SAME key when retrying the same request — the stored response is replayed instead of moving money twice. A new request needs a new key.

Request body

object
  amount*: integer

Responses

  • 201 — New test balance.
  • 403 — live_key_not_allowed.
post/test/cards/{cardId}/simulate-transactionSimulate card spend

Fakes a purchase or decline on a TEST card and runs the real settlement pipeline — fees post, the transaction appears in GET /cards/{id}/transactions, and the card.transaction.created webhook fires.

Parameters

  • cardId (path, required)

Request body

object
  type*: string (purchase | decline)
  amount*: integer

Responses

  • 201 — Simulated and processed.
  • 403 — live_key_not_allowed.
  • 409 — invalid_state — card must be active.