Connecting to the REST API, step by step

4 min read

From issuing a key to your first delivered order: reading the catalogue at your price, placing an order with an Idempotency-Key, following it, and subscribing to webhooks.

Everything you do in the dashboard, your own store can do too: read the catalogue at your price, read your balance, place orders and follow them. The interface is REST, the responses are JSON, and authentication is a key you issue yourself.

The base address is printed on the API reference page under /docs/api; it is written $BASE below.

The steps

  1. Issue a key from the API page in your dashboard, and give it the narrowest abilities that do your job: catalog.read, balance.read, orders.read, orders.write.
  2. Read the catalogue from GET /v1/catalog. The prices that come back are yours, worked out on our server from your account.
  3. Check your balance from GET /v1/balance before a run of purchases, if you want to.
  4. Place the order with POST /v1/orders, carrying an Idempotency-Key header with a value of your own — your invoice number, for instance.
  5. Follow the order by its number at GET /v1/orders/{number} until it is delivered and carries the code.
  6. Subscribe to webhooks instead of polling: order.delivered, order.refunded and wallet.credited.

The key

A key begins with mp_live_ and is shown once, when it is created — we keep only its fingerprint, so we cannot show it to you again. It is sent in the Authorization header:

curl "$BASE/catalog?per_page=25" \
  -H "Authorization: Bearer mp_live_..."

Placing an order

curl -X POST $BASE/orders \
  -H "Authorization: Bearer mp_live_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-invoice-84213" \
  -d '{"sku":"PUBG_MOBILE_60_UC","quantity":1,"player_id":null}'

player_id is required for packages topped up directly against a player id, and means nothing for code packages. Reading the order back afterwards, by its number:

curl $BASE/orders/01kzhxexgmfqka0q1zmtr0f292 \
  -H "Authorization: Bearer mp_live_..."

Every webhook message is signed with a signature header, which you should verify before believing the message.

The Idempotency-Key is the most important line here

A network fails after your request reaches us, not before. Retry without a key and you have created a second order, bought the code twice and paid twice.

With the same key, the second send creates nothing: it returns the first order as it stands, with its state, its number and its code if one was issued. Make the key something of your own that identifies the sale — an invoice number, a basket id — rather than a fresh random value on each attempt, which throws away the whole point of it.

Limits and errors

  • The default ceiling is 60 requests per minute for the account unless we have agreed otherwise, and every response carries X-RateLimit-Limit and X-RateLimit-Remaining. Above it you get 429 with the code rate_limited.
  • A quantity outside a package's bounds returns 422 with invalid_quantity and no order is created.
  • Errors come back in one shape, with a code to read programmatically rather than a sentence to parse.

An order that is taking a while

An order that stays pending for longer than usual is under review here. Do not resend it to hurry it along: resending with the same key returns the first order and moves nothing, and resending with a new key buys a second time. You will not be charged twice for one order, however long it takes.

Questions

Is there an endpoint to request a refund?

No, and there will not be. A refund happens on its own when an order cannot be fulfilled: the order reads refunded, the money is back in your wallet, and order.refunded is sent to you. A code that has been issued is final.

Do API prices differ from the dashboard's?

No. Both ask the same question of the same server, so what the API reads is what the dashboard shows and what your wallet is charged.

I have lost my key — what now?

Revoke it in your dashboard and issue another. We cannot show you an old key because we do not hold one, and revocation takes effect immediately.

Last updated

Want to put this into practice?

Agreed wholesale prices, instant automatic delivery, and an API for shops.

More guides