cheapkeys

Your first API call in 5 minutes

All you need is a shell with curl. In five minutes you will create a ck_test_ token in the supplier portal and get a real, authenticated response from the sandbox.

1. Create a sandbox token

Open the supplier portal at https://pay.mmokick.com/supplierDevelopers → API tokens, set the Live | Sandbox toggle to Sandbox, and create a ck_test_ token. Sandbox access is instant: submitting your supplier application approves you into the sandbox on the spot, so you can mint a token and make your first call within minutes — production vetting runs in the background. Token creation is protected by 2FA, so enrol an authenticator app once in the portal (register → verify email → set up TOTP); see Authentication for the one-time setup. To skip ahead for read calls, use the published seeded sandbox token ck_test_sandbox000000000000000000000000000000001:

# https://pay.mmokick.com/supplier → Developers → API tokens → env: Sandbox → Create
export CK_TEST_TOKEN="ck_test_..."

The token is shown once. Export it now; every example in these guides reuses $CK_TEST_TOKEN.

2. Confirm the token with /whoami

curl "https://sandbox-pay.mmokick.com/api/v1/whoami" \
  -H "Authorization: Bearer $CK_TEST_TOKEN" \
  -H "Accept: application/json"

Expected 200:

{
  "token": {
    "id": "01JZV9AB2CD4EF6GH8JK0MN2PQ",
    "name": "getting-started",
    "mode": "test",
    "scopes": ["catalog:read", "offers:read", "offers:write", "inventory:write", "webhooks:manage"],
    "created_at": "2026-07-12T09:00:00Z",
    "last_used_at": "2026-07-12T09:00:05Z"
  },
  "supplier": {
    "id": "01JZV8K2E4Q6S8A0C2E4G6J8KM",
    "name": "Your Company",
    "status": "active"
  },
  "environment": "sandbox",
  "rate_limits": { "reads": 600, "writes": 120, "sync": 300, "bulk": 12, "simulate": 120, "test": 6 }
}

If you get 401 / wrong_environment, you are using a ck_live_ token against the sandbox host — create a ck_test_ token instead. See Authentication.

3. List the catalog

Suppliers attach offers to platform-owned canonical products. List the first few:

curl "https://sandbox-pay.mmokick.com/api/v1/products?limit=3" \
  -H "Authorization: Bearer $CK_TEST_TOKEN" \
  -H "Accept: application/json"

Expected 200 — a cursor-paginated list. next_cursor is the opaque cursor for the next page, or null on the last page:

{
  "data": [
    {
      "id": "01SANDBX00000000000000PD01",
      "slug": "cyber-odyssey-pc-steam",
      "name": "Cyber Odyssey — PC (Steam)",
      "type": "game_key",
      "platform": "steam",
      "region": "global",
      "allowed_countries": null,
      "blocked_countries": null,
      "category_id": "01JZT2A1B2C3D4E5F6G7H8J9K0",
      "attributes": { "steam_app_id": "1289310", "edition": "standard" },
      "form_fields": [],
      "status": "sellable",
      "market": {
        "buyer_price": { "amount": 2049, "currency": "EUR" },
        "active_offers": 2,
        "your_offer_selected": false
      },
      "created_at": "2026-03-01T10:00:00Z",
      "updated_at": "2026-07-01T08:30:00Z"
    }
  ],
  "next_cursor": "eyJrIjoiMDFTQU5EQlgiLCJkIjoiZGVzYyJ9"
}

To fetch the next page, pass the cursor back: ?limit=3&cursor=eyJrIjoiMDFTQU5EQlgi....

Money is always an object of integer minor units plus an ISO 4217 code: {"amount": 2049, "currency": "EUR"} means €20.49. The Supplier API is EUR-only in v1.

Response headers to know

Every response — success or error — carries:

X-RateLimit-Limit: 600
X-RateLimit-Remaining: 597
X-RateLimit-Reset: 1783519482        # unix seconds when the window resets
X-Request-Id: req_9f3b2c61a8d44e0f   # quote this in support requests

X-Request-Id is echoed in every error body as trace_id. On a 429 response you also get Retry-After in seconds — honor it. See Rate limits for the numbers.

Next steps