Registers a customer into a campaign: opens a wallet card (with barcode) and initializes the campaign’s loyalty balances. customer takes two forms: pass a customer id as a string to register an existing customer, or pass an object to create the customer and register them in one step. The returned cards[].id is used directly as card on POST /v1/transactions/process.
Auth: Authorization: Bearer <accessToken> — an organization-scoped token from Authentication. Missing or invalid token returns 401; an organization without an active subscription returns invalid_subscription (403).
Payload schema — existing-customer mode (customer is the customer’s id):
New-customer mode (customer is a create model):
Body
An id field inside the customer object is NOT accepted — it returns customer_id_must_be_string (400). To register an existing customer, send customer as a string.
Registering the same customer into the same campaign twice is idempotent: no error is returned, the customer’s existing card comes back, and nothing changes. Registration never resets existing loyalty balances — only missing balances are initialized at 0.
Example
Response
Returns 201 with the registered customer. collectables comes initialized with the campaign’s loyalty balances; cards contains only the card of this registration (use GET /v1/customers/find for all of the customer’s cards).
Notes:
- Optional fields that have no value are omitted from the response — you will not receive
null. Exception: opaqueId is null when not assigned.
- In new-customer mode,
data.phone is returned in its normalized (E.164) form.
- Every new card gets its own barcode — a customer’s cards from different campaigns have different barcodes.
cards[].barcode (a string) can be used to look the customer up at checkout via GET /v1/customers/find.
- In new-customer mode, if a validation error occurs before the card is opened, the customer is not created either — no partial records are left behind.
Last modified on October 6, 2026