Skip to content
MatrixRewards
API docs menu

Authentication

A key is how a script or an assistant gets into your programme. You make it in the app, choose what it may do, and send it with every call.

Making a key

Keys are made on the API keys screen of the app: in Shopify admin, open Apps, then Matrix Rewards, then API keys. Only your store's staff can open it. The API itself cannot make a key: no permission lets one key make another, because a key that could make keys could widen its own reach.

Any store with the app installed can make keys. When you make one, you choose:

  • a name, for your own list and your activity log, of up to 60 characters;
  • what it may do, from the permissions below;
  • whether it is for an AI assistant;
  • whether it is a test key.

An account can hold at most 20 keys at once, test keys included. Revoked keys do not count.

What a key looks like

A live key starts mrk_live_ and a test key starts mrk_test_. The whole key has this shape: mrk_live_<key id>.<secret><checksum>.

The key is shown once, when it is made. Only a keyed hash of its secret is kept, so a lost key cannot be shown again: rotate it to get a new secret.

Sending it

Send the key in the Authorization header of every call, after the word Bearer. The word can be written in any case.

export MATRIX_API_KEY='mrk_live_...'
curl "https://app.matrixrewards.co.uk/api/2026-10/me" -H "Authorization: Bearer $MATRIX_API_KEY"

Never paste a key into a chat or a file you share. One key reaches every store on your account, not only the store you made it in.

GET /me is the call to make first. It says which account the key belongs to, its stores, what the key may do, and whether it is a test key or one for an assistant. It needs no permission beyond a valid key.

What a key may do

Each permission is a box you tick when you make the key. The table gives each one, the words on its box, and the calls it opens.

PermissionWhat the box in the app saysWhat it lets a key call
read_programmeYour programme settings — rates, rewards, rulesGET /stores, GET /stores/{store_key}, GET /stores/{store_key}/programme, GET /stores/{store_key}/programme/rewards, GET /stores/{store_key}/programme/offers, GET /stores/{store_key}/programme/rules, GET /stores/{store_key}/design, GET /stores/{store_key}/brand, GET /stores/{store_key}/images
read_membersMembers, their points, their email addresses and the last four characters of their reward codesGET /members, GET /members/{member_key}, GET /members/{member_key}/codes
read_reportsThe ledger, what you owe, and settlement between storesGET /ledger, GET /reports/liability, GET /reports/settlement
read_usageOrders used this month and which plan you are onGET /usage, GET /plan
read_auditThe activity log — what each key did and sawGET /audit-log
manage_keysThe list of your keys (not their secrets)GET /keys
write_membersChange members’ points and cancel reward codes. This also reads members, their email addresses and the last four characters of their reward codes. Every change is loggedPOST /members/{member_key}/adjustments, POST /members/{member_key}/codes/void, GET /members, GET /members/{member_key}, GET /members/{member_key}/codes
write_webhooksSend every change to members’ points, by member key, to a web address the key chooses (webhooks). Not for an assistant keyGET /webhooks, POST /webhooks, DELETE /webhooks/{endpoint_id}, POST /webhooks/{endpoint_id}/test
write_programmeChange your programme: the earn rate, the joining and birthday bonuses, what a point is worth, when points expire, the rewards and the offers. Every change is previewable and loggedPOST /stores/{store_key}/programme, POST /stores/{store_key}/programme/rewards, POST /stores/{store_key}/programme/rewards/{reward_id}, POST /stores/{store_key}/programme/rewards/{reward_id}/remove, POST /stores/{store_key}/programme/offers, POST /stores/{store_key}/programme/offers/{offer_id}, POST /stores/{store_key}/programme/offers/{offer_id}/remove, POST /stores/{store_key}/design, POST /stores/{store_key}/images, GET /stores, GET /stores/{store_key}, GET /stores/{store_key}/programme, GET /stores/{store_key}/programme/rewards, GET /stores/{store_key}/programme/offers, GET /stores/{store_key}/programme/rules, GET /stores/{store_key}/design, GET /stores/{store_key}/brand, GET /stores/{store_key}/images

What the reference says of the list:

Test keys

A test key reads your real data: there is no separate test copy. It can preview a change, and even send back a preview's confirmation, but the change itself is always refused with test_mode_key. A test key cannot manage webhooks either.

Keys for AI assistants

When you make a key you can mark it as being for an AI assistant. Such a key must preview a points change or a cancelled code, then send back that preview's confirmation, before anything changes. Without it the change is refused with confirmation_required. The one exception is a request that repeats a change already made, which changes nothing. A key for an assistant can never manage webhooks. How the two steps work.

A key for an assistant also moves the programme's money one step at a time (assistant_limit), unless the merchant has lifted its limits on the API keys screen in the app. Only a person can lift or put back those limits, there; no API call can. GET /me says which: key.limits_lifted. Lifted, the key still needs the preview's confirmation for every change (which it sends itself: the API cannot see whether a person agreed), and still cannot manage webhooks.

Rotating a key

Rotating gives a key a new secret and keeps what it may do. When you rotate from the app, the old secret keeps working for 1 day, so you can move whatever uses it; after that it gets unauthenticated. A call made with the old secret while it still works shows key.used_previous_secret as true in GET /me.

Revoking a key

Revoke a key on the API keys screen, or with the key itself: POST /keys/self/revoke needs no permission and never counts against the key's allowance.

If a key leaks, revoke it with itself first, then make a new one.

A key that does not work

A missing, mistyped, unknown or revoked key, and an old secret whose rotation window has closed, all get the same answer: status 401, with the code unauthenticated. That is on purpose: telling them apart would tell someone guessing keys how close they came.

What a key never returns

No call returns a shopper's name, phone number or address, because the platform holds none of them, and no call returns a birthday. The only contact detail is email.

No answer carries a whole reward code either. A code is named by its last four characters, code_ending, and by its ref, which is what a cancel takes. The shopper holds the code itself.

Everything is logged

Every read of a shopper's details is written to your account's activity log before it is returned. If that cannot be written, the call answers with status 503 and the code access_not_recorded, and returns nothing. Every change made with a key is written to the log the same way, with the key's name. Entries are kept for 365 days.

You read the log with GET /audit-log, which needs read_audit. There is no screen for it in the app yet.

Last updated: 3 October 2026