Initiating a test transaction over REST
REST is the simplest way to initiate a test: one HTTPS call, authenticated with
an API key, no mTLS. Complete Before you begin first — you
need an sk_live_… API key and a configured behaviour for the card you plan to
send.
This page is the narrative walkthrough. For the machine-readable contract —
request/response schemas and every error body — see the
API reference, generated from src/openapi/switchbench.yaml. Keep the
two in sync when either changes.
Endpoint
Section titled “Endpoint”POST https://api.switchbench.com/transactionNon-production environments use a single-level environment prefix on the host —
for example https://test-api.switchbench.com/transaction. The endpoint is
fronted by nginx behind a Cloudflare Tunnel; the path and payload are identical
across environments.
Authentication
Section titled “Authentication”Send your API key as a bearer token:
Authorization: Bearer sk_live_...JWT bearer tokens are rejected with 401 on this endpoint. POST /transaction
accepts a CPS-validated API key only. A Logto-issued JWT — even a valid one
carrying an organization_id claim — is refused here, because SMP cannot yet map
a Logto org to the numeric org_id server-side without trusting a caller-supplied
id. Use the API key.
Request body
Section titled “Request body”| Field | Type | Required | Description |
|---|---|---|---|
iso8583 | string | yes | The request message as hex. A 0x prefix is accepted. |
network | string | no | visa (default) or mastercard. Selects the engine. |
merchant_id | string | no | Accepted for forward compatibility but currently ignored — not read, logged, or routed on. |
terminal_id | string | no | Accepted for forward compatibility but currently ignored — not read, logged, or routed on. |
{ "iso8583": "0200...", "network": "visa", "merchant_id": "12345", "terminal_id": "ABC123"}Response body
Section titled “Response body”200 OK with:
| Field | Type | Description |
|---|---|---|
request_id | string | Trace identifier for this request (for example req_abc123). |
iso8583 | string | The finalized ISO 8583 response, uppercase hex. |
status | string | approved when DE 39 = 00, otherwise declined. |
response_code | string | ISO 8583 DE 39 from the finalized response. |
{ "request_id": "req_abc123", "iso8583": "0210...", "status": "approved", "response_code": "00"}Errors
Section titled “Errors”Errors use RFC 7807 application/problem+json.
| Status | Meaning |
|---|---|
400 | Malformed request — the iso8583 field is not valid hex, or network is neither visa nor mastercard. |
401 | Authentication failed — missing, invalid, revoked, or suspended API key, or a JWT was sent. |
429 | Rate limit exceeded — the API key’s requests-per-second limit. A Retry-After header is returned. |
502 | Delivery error — no active mTLS connection for the org, or a write/read failure (a delivery timeout included) on the outbound leg to your fintech backend; also an engine HTTP error or an undecodable engine response. |
503 | API-key validation with CPS is unavailable, so the tenant could not be resolved. |
504 | The Visa/Mastercard engine call itself timed out, hit an open circuit breaker, or failed at the transport level. |
Worked example
Section titled “Worked example”Substitute <hex> with a real authorization frame — the literal below is a
template, not a runnable payload (SMP returns 400 on non-hex iso8583). For
Visa the frame is an MTI 0100/0200 message carrying at least DE 2 (PAN),
DE 3 (processing code), DE 4 (amount), DE 14 (expiry), DE 22 (POS entry mode),
DE 41 (terminal id), DE 42 (merchant id), and DE 49 (currency). The card number
in DE 2 is what your configured behaviour is keyed against.
curl -X POST https://test-api.switchbench.com/transaction \ -H "Authorization: Bearer sk_live_your_key_here" \ -H "Content-Type: application/json" \ -d '{ "iso8583": "<hex>", "network": "visa" }'Response shape on success (200 OK) — the iso8583 and response_code values
reflect the behaviour configured for the card and the response your fintech
backend returned over the mTLS leg:
{ "request_id": "req_abc123", "iso8583": "0210...", "status": "approved", "response_code": "00"}Delivery still needs a live TCP connection
Section titled “Delivery still needs a live TCP connection”POST /transaction originates the authorization, but the outbound leg to your
fintech backend is written over the existing client-established mTLS TCP
connection through the FRP edge. A pure-REST caller with no active connection
for the org gets a 502 delivery error on that leg. To exercise the full round
trip you must also have a live mTLS TCP connection open — see
Visa ISO 8583 over mTLS TCP for the connection and wire
contract.