Issue a card
Creates a virtual card and loads it in one call. The load is debited from your wallet at this store, and the card is only created after the issuer accepts — a refusal refunds automatically.
cards.writeRate limit: 10 rpsIdempotent by design: send the same Idempotency-Key and you get the original result back with 200 and no second charge. Changing the body while reusing a key is refused outright rather than silently issuing a second card.
Parameters
tierstringrequired"basic" or "plus". The tier decides the programme and the fees, not the design.
countrystringrequiredTwo-letter ISO country code of the card programme, e.g. "US". Must be exactly 2 characters.
load_usdstringrequiredAmount to load, as a STRING in US dollars (e.g. "50.00"), up to 4 decimals, greater than 0 and at most 100000. A number instead of a string is a validation_failed, on purpose: JSON floats are not how money travels here.
cardholder_namestringoptionalOptional name printed on the card, 2–60 characters.
Idempotency-KeystringrequiredRequired, at least 8 characters. Reuse it to retry safely; never reuse it for a different request.
Code samples
curl -X POST "https://samaprime.com/api/v1/cards/issue" \ -H "Authorization: Bearer sk_test_..." \ -H "Content-Type: application/json" \ -H "Idempotency-Key: 0e7f5c1e-2b3a-4f6d-9c8b-1a2b3c4d5e6f" \ -d '{"tier":"example","country":"example","load_usd":"example","cardholder_name":"example"}'Response
→ 201{ "data": { "id": "cm_card_01J8Z1A2BBCCDD", "last4": "1234", "status": "active" }, "meta": { "request_id": "req_abc123", "timestamp": "2026-08-06T12:00:00Z" }}Errors
| Status | Code |
|---|---|
| 400 | validation_failedThe body is malformed, or carries a field this endpoint does not accept — the schema is strict, so provider or BIN choices cannot be sent from here. |
| 400 | invalid_amountload_usd is not a plain amount. It must be a string like "20.00" with at most 2 decimal places of value ("20.0000" is fine, "20.005" is not) — a JSON number, or anything finer than a cent, is refused before any money is quoted. Nothing is rounded. |
| 400 | idempotency_key_requiredThere is no Idempotency-Key header, or it is shorter than 8 characters. Nothing was charged: issuance debits money, so this endpoint will not run at all without a key to replay against. |
| 403 | test_key_not_allowedA test key (sk_test_) cannot move money: card writes need a live key. Nothing was reserved and the wallet was not touched. |
| 403 | cards_not_enabled_for_storeCard issuing through the API is not enabled for this store. A platform administrator must enable it. Nothing was charged, and this Idempotency-Key was not used up: the same key may be sent again once issuing is enabled. |
| 409 | cards_unavailableCard issuing is temporarily unavailable: the card provider cannot serve right now (issuing paused, provider under maintenance, or its balance known to be exhausted). Refused before anything was claimed or charged — the wallet was not touched and no order is waiting. This Idempotency-Key was not used up: retry later with the same key. |
| 400 | country_unavailableNo selectable card programme exists for that country and tier. This is how the platform is configured, not something a rewritten body can fix. |
| 400 | no_providerNo issuer is configured for that tier at all, so no card of it can be bought. Retrying cannot change the answer. |
| 400 | below_minimumThe load is below the minimum this card type accepts. Raise load_usd. |
| 400 | invalid_inputThe request passed the body schema and was then refused by the issuance engine's own validation — the tier, the resolved BIN or the amount is not usable as sent. |
| 400 | tier_unavailableThat card tier is not offered right now. |
| 400 | bin_not_selectableThe BIN the platform resolved for that country and tier is disabled, unknown, or belongs to a different issuer. Do not replay the same pair; the platform-side choice is what has to change. |
| 400 | provider_bin_unavailableThe chosen BIN is temporarily unavailable at the issuer. A different tier or country can succeed where this pair cannot — and you have not been charged. |
| 422 | insufficient_customer_balanceYour wallet at this store cannot cover the load plus its fees. Fund the wallet; replaying the same request cannot succeed, and this is not a platform outage. |
| 422 | provider_insufficient_fundsThe platform's own float at the issuer is exhausted. Nothing was charged to you — raising it is ours to do, not something you can retry past. |
| 500 | recording_failedDO NOT RETRY THIS ONE. The issuer created the card and our write of it failed, so the money is already spent and the card is held for reconciliation. A second attempt is a second card. |