Sandbox API Reference

Introduction

The sandbox environment includes simulation endpoints for generating test activity: transaction scenarios against enrolled cards, and synthetic network file ingestion to drive the bulk-enrollment pipeline. No real network is ever called.

This page is the endpoint reference for those simulation endpoints. For what the environment is, how to get a token, and what is included, start at Sandbox Testing. For guided end-to-end walkthroughs, see Testing Single Card Enrollment, Testing Bank Linking and Testing Bulk Enrollment.

All endpoints below are sandbox-only, served from https://api.sandbox.astrada.co, and require an OAuth2 access token with the simulation:write scope. They all return 202 Accepted and process asynchronously: results are observed through the existing read APIs (transactions, card subscriptions) and webhooks.

Requests use the standard headers only: Authorization: Bearer <access-token> and Content-Type: application/json. Account context is derived from your access token (no Account header is needed), matching the rest of the public API.

Simulate a transaction scenario

POST /simulate/transaction/scenario

Runs a predefined transaction scenario against an enrolled card in the sandbox, publishing the resulting transaction messages to the ingestion pipeline.

Body params

ParamTypeRequiredDescription
scenariostring (enum)RequiredThe predefined scenario to simulate. One of: simple_purchase, split_shipment, tip_adjustment, expired_auth, refund, hotel_preauth, car_rental, gas_pump, partial_clearing, recurring_subscription, fx_conversion, amex_auth_baseline, amex_auth_adjustment, amex_auth_reversal, uber_canada_reversal, uber_netherlands_positive_advice, uber_turkey_dual_auth, uber_brazil_cancelled, uber_korea_settle_at_auth, uber_turkey_fx_reversal, uber_india_fx_clearing.
cardIdstring (uuid)RequiredThe identifier of the enrolled card to transact against.
subaccountIdstring (uuid)RequiredThe subaccount identifier the card belongs to.
amountinteger (≥1)OptionalTransaction amount in minor units (cents). When omitted, the scenario's default amount is used.
currencystring (3 chars)OptionalISO 4217 three-letter currency code. When omitted, the scenario's default currency is used.
networkstring (enum)OptionalCard network override (VISA, MASTERCARD, AMEX), so one scenario can run against any network. When omitted, the scenario's own default network is used.
sourcestring (enum)OptionalIngestion-source tag applied to every emitted message (amexgl, amexrta, smartdata, tns, vbds). When omitted, the scenario's own source if it sets one (the amex_auth_* scenarios default to amexrta), else tns, or amexgl when the resolved network is AMEX.

The three amex_auth_* scenarios mirror Amex's sandbox RTA mock authorizations: amex_auth_baseline (a single approved auth), amex_auth_adjustment (initial auth → adjusted auth → clearing at the adjusted amount), and amex_auth_reversal (initial auth → follow-up hold → reversal → clearing of the initial). They default to the AMEX network, so you can trigger the same Amex auth lifecycles Amex publishes as mock auth IDs, on any enrolled card. Full step shapes are in sandbox-simulation docs/SYNTHETIC_TRANSACTIONS.md.

The seven uber_* scenarios are multi-country Uber ride-share authorization flows (Canada, Netherlands, Turkey, Brazil, Korea and India), covering reversals, positive advice, dual authorizations, cancellations, settle-at-auth and FX clearing. Full step shapes are in sandbox-simulation docs/SYNTHETIC_TRANSACTIONS.md.

Example request

{
  "scenario": "simple_purchase",
  "cardId": "24c4f90d-ab3b-4f6e-8a1d-d251a4fcf34c",
  "subaccountId": "f297d659-c13d-4219-aeaa-e10a845140a5",
  "amount": 1500,
  "currency": "USD"
}

Responses

StatusDescription
202Accepted: the transaction messages were published to the ingestion pipeline and will be processed asynchronously. Body contains transactions[], each with the messageIds (uuids) published for that transaction; use GET /transaction-messages/{transactionMessageId} to retrieve each message once processed.
400Bad request: validation error on the request body.
401Unauthorized: missing or invalid access token.
403Forbidden: token does not have the simulation:write scope.
500Server error.

Example 202 response

{
  "transactions": [
    {
      "messageIds": [
        "9b2e6c4a-1f3d-4e8b-9a7c-2d5f8e1b4c6a",
        "1a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
      ]
    }
  ]
}

Simulate Visa VCF ingestion

POST /simulate/ingestion/vcf

Writes a synthetic Visa bulk-enrollment file to the ingestion bucket to drive the bulk-enrollment pipeline without a real network file delivery. The pipeline then runs asynchronously: enrolled cards appear as card subscriptions once processing completes.

Prerequisite: a bulk feed must already exist for this account, created via POST /network-bulk-feeds. The networkReference below must match that feed.

Repeat calls, new cards, and transactions

The simulated cards come from a fixed, reserved test-card pool (BIN 404507; the full list is published in Test Card Pools below), mirroring how production files carry a stable card population:

  • cardCount includes the head of the pool, the same cards every call. Once they are
    enrolled in the subaccount, re-ingesting them deduplicates (no new cardsubscription.created),
    exactly like a re-delivered production file.
  • newCardCount draws cards this subaccount has never seen. Every call enrolls that many new
    cards and emits their cardsubscription.created webhooks. Use this to re-test the full
    feed → cards → transactions flow without creating a new subaccount.
  • Feed activation: a feed only moves from submitted to active once an ingestion creates at
    least one new card data link. On a feed that has never completed an ingestion, a head-only replay
    would deduplicate and leave the feed stuck, so newCardCount: 0 still draws one never-seen
    card. This happens at most once per feed; once the feed is active, replays stay pure.
  • Every included card (head or new) gets transactionsPerCard transactions with fresh
    transaction references and recent dates
    , so repeat calls always emit transaction.created /
    transaction.updated webhooks, including for already-enrolled cards.

Enrolled sandbox cards carry cardholder data: GET /cards/{cardId}/cardholder returns firstName, lastName, postalCode, email, and corporate.employeeId for cards enrolled through this endpoint. The exact field set varies by network. See the SmartData and Amex GL sections below for their differences (notably, email).

Body params

ParamTypeRequiredDescription
networkReferencestringRequiredThe Visa VCF PIC for the bulk feed, in the format 'ProcessorId_IssuerId_CompanyId', such as 123_45_6789. The full RPIC used at feed creation ('RegionId_ProcessorId_IssuerId_CompanyId', such as 1_123_45_6789) is also accepted; the region segment is stripped before use. Must match the feed created via POST /network-bulk-feeds. Pattern: ^\d+(_\d+){2,3}$
cardCountinteger (0–100)Optional (default 5)Cards from the head of the test-card pool, the same cards every call; deduplicated once enrolled. cardCount + newCardCount must be at least 1.
newCardCountinteger (0–20)Optional (default 0)Not-yet-enrolled cards drawn from the pool for this feed's subaccount. Each call enrolls this many new cards. On a feed that has never completed an ingestion, leaving this at 0 still draws one new card so the feed can activate (see above).
transactionsPerCardinteger (0–10)Optional (default 3)Transactions generated per included card, with fresh references and recent dates each call. Use 0 for a cards-only starter file.

Example request

{
  "networkReference": "123_45_6789",
  "cardCount": 0,
  "newCardCount": 5,
  "transactionsPerCard": 3
}

Responses

StatusDescription
202Accepted: the synthetic file was written to the ingestion bucket and the pipeline will process it asynchronously. Empty response body.
400Bad request: validation error on the request body; no active feed for the networkReference; or the subaccount has exhausted the new-card pool.
401Unauthorized: missing or invalid access token.
403Forbidden: token does not have the simulation:write scope.
413Content too large: a numeric field exceeded its maximum (cardCount above 100, newCardCount above 20, or transactionsPerCard above 10).
500Server error.

Simulate Mastercard SmartData ingestion

POST /simulate/ingestion/smartdata

Writes a synthetic Mastercard bulk-enrollment file to the ingestion bucket to drive the bulk-enrollment pipeline without a real network file delivery. The pipeline then runs asynchronously: enrolled cards appear as card subscriptions once processing completes.

Prerequisite: a bulk feed must already exist for this account, created via POST /network-bulk-feeds. The networkReference below must match that feed.

Repeat-call semantics match the VCF endpoint above: cardCount replays the head of a reserved Mastercard test-card pool (BIN 510755, listed in Test Card Pools below; deduplicated once enrolled), newCardCount enrolls cards the subaccount has never seen, and every included card gets transactionsPerCard transactions with fresh references and recent dates on each call. Enrolled cards carry cardholder firstName, lastName, postalCode, and corporate.employeeId / corporate.alternativeEmployeeId; Mastercard feeds do not expose a cardholder email, so email stays null (as in production).

Body params

ParamTypeRequiredDescription
networkReferencestringRequiredThe Mastercard Delivery ID for the bulk feed, such as G1234567. Must match the feed created via POST /network-bulk-feeds. Pattern: ^[a-zA-Z0-9-]+$
cardCountinteger (0–100)Optional (default 5)Cards from the head of the test-card pool, the same cards every call; deduplicated once enrolled. cardCount + newCardCount must be at least 1.
newCardCountinteger (0–20)Optional (default 0)Not-yet-enrolled cards drawn from the pool for this feed's subaccount. Each call enrolls this many new cards.
transactionsPerCardinteger (0–10)Optional (default 3)Transactions generated per included card, with fresh references and recent dates each call. Use 0 for a cards-only starter file.

Example request

{
  "networkReference": "G1234567",
  "cardCount": 0,
  "newCardCount": 5,
  "transactionsPerCard": 3
}

Responses

StatusDescription
202Accepted: the synthetic file was written to the ingestion bucket and the pipeline will process it asynchronously. Empty response body.
400Bad request: validation error on the request body; newCardCount > 0 with no active feed for the networkReference; or the subaccount has exhausted the new-card pool.
401Unauthorized: missing or invalid access token.
403Forbidden: token does not have the simulation:write scope.
500Server error.

Simulate Amex GL ingestion

POST /simulate/ingestion/amex-gl

Writes a synthetic Amex bulk-enrollment file (plus a companion clearing file when transactionsPerCard > 0) to the ingestion bucket without an Amex file drop. Processing runs asynchronously: enrolled cards appear as card subscriptions once processing completes, and clearings follow shortly after enrollment.

Prerequisite: a bulk feed must already exist for this account, created via POST /network-bulk-feeds. The networkReference below must match that feed.

The repeat-call mechanics match the VCF endpoint above, though the cardCount default and the tokenized behavior differ (see the body params and callout below): cardCount replays the head of a reserved account pool (BIN 370000, listed in Test Card Pools below; deduplicated once enrolled), newCardCount enrolls accounts the subaccount has never seen, and every included card gets transactionsPerCard clearings with fresh transaction ids and recent dates on each call. Enrolled cards carry cardholder firstName, lastName, postalCode, and corporate.employeeId; Amex GL feeds do not carry a cardholder email, so email stays null.

Body params

ParamTypeRequiredDescription
networkReferencestringRequiredThe Amex Recipient ID for the bulk feed, in the format R{RecipientId}, such as R12345. Must match the feed created via POST /network-bulk-feeds. Pattern: ^R\d+$
cardCountinteger (0–100)OptionalCards from the head of the account pool, the same accounts every call; deduplicated once enrolled. When omitted, the count resolves off the feed's panFormat: an encrypted feed draws 3, a tokenized feed draws its whole enrollable tokenized pool (see the tokenized note below). The cardCount + newCardCount must be at least 1 rule applies only when cardCount is sent explicitly; omitting it entirely is fine, so a bare { "networkReference": "R12345" } succeeds.
newCardCountinteger (0–20)Optional (default 0)Not-yet-enrolled accounts drawn from the pool for this feed's subaccount. Each call enrolls this many new cards. Not available on a tokenized feed: the tokenized pool has no new-card region, so any newCardCount > 0 on a panFormat: tokenized feed is rejected with 400.
transactionsPerCardinteger (0–10)Optional (default 3)Clearings generated per included card (written as a companion clearing file), with fresh transaction ids and recent dates each call. Use 0 for a cards-only file.
📘

Tokenized Amex feeds

A feed created with panFormat: tokenized (sandbox-only, Amex-only) draws Amex network tokens instead of encrypted PANs, and two knobs behave differently on it. An omitted cardCount draws the feed's whole enrollable tokenized pool rather than the encrypted default, and newCardCount is unsupported: there is no tokenized new-card region, so any newCardCount > 0 returns 400. An explicit cardCount larger than the tokenized pool under-delivers to the pool size rather than erroring.

Example request

{
  "networkReference": "R12345",
  "cardCount": 0,
  "newCardCount": 5,
  "transactionsPerCard": 3
}

Responses

StatusDescription
202Accepted: the synthetic file(s) were written to the ingestion bucket and the pipelines will process them asynchronously. Empty response body.
400Bad request: validation error on the request body; newCardCount > 0 with no active feed for the networkReference; newCardCount > 0 on a tokenized feed (the tokenized pool has no new-card region); or the subaccount has exhausted the new-card pool.
401Unauthorized: missing or invalid access token.
403Forbidden: token does not have the simulation:write scope.
500Server error.

Simulate Visa VBDS ingestion

POST /simulate/ingestion/vbds

Simulates a Visa (VBDS) delivery for an existing bulk feed. VBDS is pull-based rather than file-drop: creating a feed via POST /network-bulk-feeds already triggers an initial synthetic starter-data fetch in sandbox (sized by the creation-time cardCount field, 1–20, default 5), so this endpoint exists to re-drive the pipeline on demand: enroll additional cards and generate clearings without recreating the feed. Processing runs asynchronously: enrolled cards appear as card subscriptions once processing completes, and clearings follow shortly after enrollment.

Prerequisite: a bulk feed must already exist for this account, created via POST /network-bulk-feeds. The networkReference below must match that feed.

Repeat-call semantics match the other networks above: cardCount replays the head of a reserved card pool (deduplicated once enrolled), newCardCount enrolls cards the subaccount has never seen, and every included card gets transactionsPerCard clearings with fresh transaction ids and recent dates on each call.

Body params

ParamTypeRequiredDescription
networkReferencestringRequiredThe Visa RPIC identifier for the bulk feed, in the format {regionId}_{processorId}_{issuerId}_{companyId}, such as 1_12345_67890_54321. Must match the feed created via POST /network-bulk-feeds. Pattern: ^[a-zA-Z0-9]+_[a-zA-Z0-9]+_[a-zA-Z0-9]+_[a-zA-Z0-9]+$
cardCountinteger (0–100)Optional (default 5)Cards from the head of the card pool, the same cards every call; deduplicated once enrolled. cardCount + newCardCount must be at least 1.
newCardCountinteger (0–20)Optional (default 0)Not-yet-enrolled cards drawn from the pool for this feed's subaccount. Each call enrolls this many new cards.
transactionsPerCardinteger (0–10)Optional (default 3)Clearings generated per included card, dispatched through the real VBDS clearing ingestion path with fresh transaction ids and recent dates each call. Use 0 for a cards-only simulation.

Example request

{
  "networkReference": "1_12345_67890_54321",
  "cardCount": 0,
  "newCardCount": 5,
  "transactionsPerCard": 3
}

Responses

StatusDescription
202Accepted: the synthetic delivery was enqueued and the pipeline will process it asynchronously. Empty response body.
400Bad request: validation error on the request body; no active feed for the networkReference; or the subaccount has exhausted the new-card pool.
401Unauthorized: missing or invalid access token.
403Forbidden: token does not have the simulation:write scope.
413Content too large: a numeric field exceeded its maximum (cardCount above 100, newCardCount above 20, or transactionsPerCard above 10).
500Server error.

Starter data at feed creation (cardCount)

Distinct from this endpoint's cardCount body param above, cardCount is also an optional sandbox-only field on POST /network-bulk-feeds (integer, 1–20, default 5, type: VBDS feeds only): the number of synthetic Visa cards to generate in the starter data, drawn deterministically from the head of the Visa test-card pool below, the same PANs every feed, deduplicated once enrolled, and accepted by sandbox enrollment by construction. Requests containing this field outside the sandbox environment, or for any other feed type (including Visa VCF), are rejected with a 400.

newCards is a deprecated alias of cardCount and behaves identically; when both are provided, cardCount wins. Use cardCount in new integrations: it matches the field of the same name and meaning on the simulate-ingestion endpoints.

Test card pools

Every simulated card comes from a fixed, reserved pool per network (Visa BIN 404507, Mastercard 510755, Amex 370000). The full PAN lists, the head/new region semantics, and the per-network Luhn notes live on Test Card Pools.

Next steps


Did this page help you?