Starship Rewards API
Getting Started

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 response

2. 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=1

3. 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_code is your unique identifier for this order in your system.
  • The Idempotency-Key header 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.id

Interpret 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 until status == "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 causeFix
401 E_UNAUTHORIZED_ACCESSKey/secret wrong or not yet provisionedRe-check environment vars; if fresh, wait up to 5 min for cache warmup
401 request timestamp expiredHMAC enabled on your credential, server clock driftUse NTP on your machine; timestamp must be within ±5 min
403 FORBIDDEN_ACTIONYour credentials are prod keys hitting sandbox, or vice versaMatch host to key prefix (sk_test_ → sandbox, sk_live_ → prod)
429 E_REQUEST_THROTTLEDPolling too fast on step 5Back off: 10 s minimum between polls, 60 s preferred for DELAYED
400 E_VALIDATION_FAILURE on step 4denomination outside product range or product_id wrongStep 2 output tells you the valid range

Full error reference: Error Codes.

Next

Environments — sandbox vs. production, per-env credentials, IP whitelisting