Quickstart
Five curl commands — from credentials to a delivered sandbox voucher in under five minutes
Quickstart
Five commands against the sandbox. You'll list products, fetch one, get a quote, place an order, and retrieve the delivered voucher. Paste them into a terminal with your sandbox API key + secret exported and work through them top to bottom.
Prerequisites
export HOST="https://api-playground.starshiprewards.com"
export API_KEY="sk_test_your_sandbox_key"
export API_SECRET="your_sandbox_secret"All examples below use $HOST, $API_KEY, $API_SECRET — set them once and the snippets work as-is.
Sandbox only. The production host is https://api.starshiprewards.com. Do not run this quickstart against production — your sandbox wallet is separate from prod and only sandbox orders are refundable on demand.
1. List products
Fetch the first page of the catalog, filtered to a currency you care about.
curl -sS "$HOST/api/v1/products?currency_id=1&limit=5" \
-H "X-API-Key: $API_KEY" \
-H "X-API-Secret: $API_SECRET" | jq .You'll get a JSON array of products. Note the id, name, and delivery_time (INSTANT or DELAYED) on one you recognize. Save its id:
export PRODUCT_ID=1001 # substitute a real id from the response2. Fetch a single product
Get the full detail including denomination ranges and available vendors.
curl -sS "$HOST/api/v1/products/$PRODUCT_ID" \
-H "X-API-Key: $API_KEY" \
-H "X-API-Secret: $API_SECRET" | jq .Note delivery_time, delivery_type, and the available_denominations array. Pick a denomination within the allowed range:
export DENOM="10.00" # must be within min/max for the product
export QTY=13. Quote the charges
Get the exact amount that will be debited from your wallet. This includes FX conversion, your client discount, and any fees.
curl -sS -X POST "$HOST/api/v1/products/$PRODUCT_ID/charges" \
-H "X-API-Key: $API_KEY" \
-H "X-API-Secret: $API_SECRET" \
-H "Content-Type: application/json" \
-d "{
\"denomination\": \"$DENOM\",
\"quantity\": $QTY
}" | jq .The response includes total — that is the debit amount in your wallet currency. Display that number to your end-user as the "Pay now" amount; do not recompute it yourself.
4. Place the order
Now place the real (sandbox) order. Critical details:
- The
reference_codeis your unique identifier for this order in your system. - The
Idempotency-Keyheader protects you from double-charges on retries.
export REF="qs-$(date +%s)-$$"
export IDEMP_KEY="qs-$REF"
curl -sS -X POST "$HOST/api/v1/orders" \
-H "X-API-Key: $API_KEY" \
-H "X-API-Secret: $API_SECRET" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $IDEMP_KEY" \
-d "{
\"reference_code\": \"$REF\",
\"product_id\": $PRODUCT_ID,
\"denomination\": \"$DENOM\",
\"quantity\": $QTY,
\"customer_info\": {
\"name\": \"Jane Doe\",
\"email\": \"jane@example.com\"
}
}" | jq .Save the order ID:
export ORDER_ID=456789 # from response.idInterpret the response status:
DELIVERED— vouchers were allocated synchronously. Jump to step 5.PENDING— inventory wasn't cached; order is parked. In sandbox, this usually resolves within a minute via the pump. Wait, then re-poll step 5 untilstatus == "DELIVERED".
5. Retrieve the vouchers
Fetch the full order, which includes decrypted voucher codes once status is DELIVERED:
curl -sS "$HOST/api/v1/orders/$ORDER_ID" \
-H "X-API-Key: $API_KEY" \
-H "X-API-Secret: $API_SECRET" | jq '.items[] | {code, pin, redemption_url}'You now have voucher credentials suitable for delivery to your end-user. Never log these values in plaintext — treat them like credit-card numbers.
You're done
In five commands you've exercised the happy path. What to build next, in priority order:
Set up a webhook
Rather than polling step 5 for every order, subscribe to order.delivered and get notified when vouchers are ready.
Add idempotency to every write
You already used Idempotency-Key once. Make it systematic for POST /orders, POST /payouts, and POST /cart/checkout. See the Idempotency guide.
Build the DELAYED path
Try the same quickstart with a product whose delivery_time is DELAYED. You'll see the PENDING → DELIVERED sequence play out via webhook.
Read the Core Concepts
Fulfillment Model and Order Lifecycle explain why the API behaves as it does. Reading them now will save you debugging time later.
Something went wrong?
| You saw... | Likely cause | Fix |
|---|---|---|
401 E_UNAUTHORIZED_ACCESS | Key/secret wrong or not yet provisioned | Re-check environment vars; if fresh, wait up to 5 min for cache warmup |
401 request timestamp expired | HMAC enabled on your credential, server clock drift | Use NTP on your machine; timestamp must be within ±5 min |
403 FORBIDDEN_ACTION | Your credentials are prod keys hitting sandbox, or vice versa | Match host to key prefix (sk_test_ → sandbox, sk_live_ → prod) |
429 E_REQUEST_THROTTLED | Polling too fast on step 5 | Back off: 10 s minimum between polls, 60 s preferred for DELAYED |
400 E_VALIDATION_FAILURE on step 4 | denomination outside product range or product_id wrong | Step 2 output tells you the valid range |
Full error reference: Error Codes.
Next
→ Environments — sandbox vs. production, per-env credentials, IP whitelisting