Skip to main content
This page goes from a fresh API key to a registered customer, the record that goes on to hold XP and spend it. It runs against the gateway API, the surface your own backend calls. You need an API key id and its signing secret to start. Authentication covers where they come from, what every request carries, and what to check when one is rejected. The steps use curl, openssl for the signature, and jq to lift one field out of a response. Without jq, print the response and copy the field by hand instead.
1

Set up your shell

Export the base URL for this environment:
Then hold your credentials, and split that base URL into the host you send to and the path the signature covers. Every step below reuses these four variables:
2

Check the credential

The cheapest call on the surface, a page of one customer. Run it before anything else, so a credential problem shows up here rather than on the write below:
The last line of that output is the status code. A 200 with an empty items list is the normal answer for a tenant with no customers yet, and it is the answer you want here. A 401 means the key, the secret or the signing string is wrong, and Authentication lists the causes in the order the server checks them.
Note the ?limit=1: it is in PATH_AND_QUERY, so it is signed as well as sent. Query parameters you add and forget to sign are the second most common 401.
3

Register a customer

Your first write, and the last step on this page. Three things change from the call above: the method, a compact JSON body that is signed and sent unchanged, and two more headers.email is the only required body field. This sample also sends the optional first_name, last_name and date_of_birth. A phone is optional too, stored exactly as you send it and never format-checked; the onboarding walkthrough shows it in the full payload. When supplied, date_of_birth is written YYYY-MM-DD; a body missing email, or carrying a date in any other format, is refused 422 with VALIDATION_INVALID_INPUT before anything is created.
X-Idempotency-Key is required on this route, not optional: without it the request returns 400 IDEMPOTENCY_KEY_REQUIRED and no customer is created. A fresh random value per write is the right habit, and it is what makes a retry after a timeout safe: replaying a key returns the stored response rather than creating a second customer.
If CUSTOMER_ID came back as null, print $CREATED to see why. A 409 means that email address is already registered under your tenant, so pick another one.
That is the whole page: your integration can now register users. Keep CUSTOMER_ID. Every other customer route takes it, and both walkthroughs below start from it.

Where to go next

  • Onboard a customer for everything the register call can carry: the same single request with the optional phone, attributes and cohort members filled in, and each refusal it can meet.
  • Award and redeem XP to give this customer XP, watch the ledger settle it into a balance of on-chain XP, then create a reward and spend the balance on a redemption.
  • Request conventions for the error envelope, the codes worth branching on, the full idempotency rules, and what a rate limit looks like.
  • Authentication for key rotation and the signing recipe in full.
  • The API reference for everything the gateway surface carries: tiers, rewards, redemptions, transactions and analytics.