Quickstart
From API client to your first simulated transaction.
This walks through the shortest path from a fresh API client to a settled test-mode
transaction: create a client, mint a token, set up a card product and cardholder,
issue a card, and drive a simulated spend against it. Every request below is plain
REST over https://api.rigid.fi — no client library required.
Create an API client
In the console, open API clients and create a new client. The client secret is shown exactly once at creation time — store it before leaving the screen. Create an org-wide client (not one pinned to a single programme): this walkthrough's final transactions-list step requires org-wide access.
Mint a token
Exchange the client ID and secret for a bearer token using the client_credentials
grant:
curl -X POST https://api.rigid.fi/v1/oauth/token \
-u "$CLIENT_ID:$CLIENT_SECRET" \
-d 'grant_type=client_credentials'{
"access_token": "eyJhbGciOiJFUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 1800
}The token is valid for 30 minutes. See the token endpoint reference and the Authentication guide for the full credential and rate-limit rules.
Create a card product
A card product is the template cards get issued from — network, currency and form
factor. iin selects a test-mode issuer identification number:
curl -X POST https://api.rigid.fi/v1/card-products \
-H "Authorization: Bearer $RIGID_API_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"programme_id": "<programme-id>",
"name": "Employee expense card",
"network": "visa",
"currency": "USD",
"form_factor": "virtual",
"iin": "999901"
}'Reference: Create a card product.
Create a cardholder
curl -X POST https://api.rigid.fi/v1/cardholders \
-H "Authorization: Bearer $RIGID_API_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"programme_id": "<programme-id>",
"full_name": "Ada Lovelace",
"email": "[email protected]",
"country": "GB"
}'Creating a cardholder does not itself clear them to hold a card. Under a KYC-enabled
programme, issuance normally waits for a passed verification; where a programme has
verified a cardholder out of band, a console admin can record that as an
attestation (POST /v1/cardholders/{id}/attestation) from the console's cardholder
list. Attestation is an admin-only override — no API client, org-wide or
programme-pinned, may call it. The response's kyc_complete field tells you
whether that requirement is met — it is true once the cardholder has either
passed KYC (kyc_state: "passed") or been attested by a console admin, and
card issuance requires it whenever the programme's kyc module is enabled.
Reference: Create a cardholder.
Issue a card
curl -X POST https://api.rigid.fi/v1/cards \
-H "Authorization: Bearer $RIGID_API_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"card_product_id": "<card-product-id>",
"cardholder_id": "<cardholder-id>"
}'Reference: Issue a card.
Simulate a spend
Test mode drives a simulated authorization over the same wire path a real network
would use. This call is deliberately not idempotency-keyed — each accepted
request is its own distinct transaction, so no Idempotency-Key header is sent:
curl -X POST https://api.rigid.fi/v1/simulated-spends \
-H "Authorization: Bearer $RIGID_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"card_id": "<card-id>",
"amount": { "amount": "42.50", "currency": "USD" },
"mcc": "5411",
"merchant_name": "Corner Grocer",
"channel": "ecommerce"
}'The response is 202 Accepted with a correlation handle and the wire identity —
it is an acknowledgement, not the decision:
{
"simulation_id": "0198e2c1-9f3a-7c42-b8d1-6a2f5c0e77b3",
"accepted_at": "2026-08-07T12:00:00Z",
"stan": "123456",
"rrn": "000000418027"
}stan and rrn are the identifiers the message carried over the wire — useful
for correlating against the transaction later. They are null only when the
simulator leg failed before a message was built.
The decision itself is not here. Read it with
GET /v1/simulated-spends/{id}
using the simulation_id above, or receive it asynchronously as an
authorization.decided webhook
event. Reference: Simulate a spend.
Read the transaction
Once the authorization has decided, list transactions to see the result:
curl "https://api.rigid.fi/v1/transactions?limit=5" \
-H "Authorization: Bearer $RIGID_API_TOKEN"Filter with ?state=approved (or declined, partial, reversed, pending) and
paginate with cursor. Reference: List transactions.