Try the Sandbox
Experiment with the Firmly API against a sandbox — a test merchant and test cards, no real money. To make live calls you first need a sandbox App ID, which Firmly issues on request: email firmlydocs@firmly.ai and we’ll send you one for evaluating the API. Once you have it, the calls below run end to end.
What you get
| Sandbox App ID | Issued on request — email firmlydocs@firmly.ai |
| Test merchant | staging.luma.gift (sample catalog) |
| Test card | 4111111111111111, exp 12 / 2030, CVV 123 |
| Hosts | https://api.firmly.work (general API), https://cc.firmly.work (payment) |
Run your first calls (curl)
1. Export the sandbox App ID Firmly sent you, then bootstrap a session — it returns an access_token:
export FIRMLY_APP_ID=<the sandbox App ID from firmlydocs@firmly.ai>curl -s -X POST https://api.firmly.work/api/v1/browser-session \-H "x-firmly-app-id: $FIRMLY_APP_ID" \-H "User-Agent: Mozilla/5.0 (compatible)"
Capture that access_token in a shell variable in one line (with
jq):
TOKEN=$(curl -s -X POST https://api.firmly.work/api/v1/browser-session \-H "x-firmly-app-id: $FIRMLY_APP_ID" \-H "User-Agent: Mozilla/5.0 (compatible)" | jq -r '.access_token')
No jq? Copy the access_token value out of the response above by hand, then run export TOKEN=<paste>.
2. Search the test merchant’s catalog:
curl -s -X POST https://api.firmly.work/api/v1/discovery/search \-H "x-firmly-authorization: $TOKEN" -H "Content-Type: application/json" \-H "User-Agent: Mozilla/5.0 (compatible)" \-d '{"query":"bag","filters":{"domains":["staging.luma.gift"]},"page_size":5}'
3. Add an item to the cart — 24-MB05 is a sample variant_id from the step-2 search response; swap in any variant_id from your own results:
curl -s -X POST https://api.firmly.work/api/v1/domains/staging.luma.gift/cart/line-items \-H "x-firmly-authorization: $TOKEN" -H "Content-Type: application/json" \-H "User-Agent: Mozilla/5.0 (compatible)" \-d '{"add_to_cart_ref":{"variant_id":"24-MB05"},"quantity":1}'
From here you set a shipping address and method, encrypt the test card as a JWE (a JSON Web Encryption token — the card is encrypted inside your own process before it is sent), and place the order. That payment + order step needs a little code — the Standard Checkout Guide is a complete, runnable Node script that carries this same flow (session → cart → payment → placed order) end-to-end against this sandbox. Need split shipments, add-ons, or delivery scheduling? The Advanced Checkout Guide does it on the richer /api/v2 cart.
Next
- Standard Checkout Guide — finish this flow end-to-end (session → cart → payment → placed order) in ~90 lines of Node against this sandbox. Right for most integrations.
- Advanced Checkout Guide — the same flow on the richer
/api/v2cart: split shipments, add-ons, delivery scheduling - API Reference — every endpoint, with a live API Explorer
- Onboarding — request your own scoped App ID for a real integration
- Agentic Pay in the sandbox — enroll a card and pay with a network token instead of a JWE card; needs an Agentic Pay API token and network sandbox test cards