Skip to main content
Resolves a customer of your organization using a single search term. Use it to identify the customer who is checking out, and to load their balances, cards, and coupons before running a transaction.
Auth: Authorization: Bearer <accessToken> — an organization-scoped token from Authentication. The search runs within your token’s organization only.

Query parameters

A missing/empty q returns _q_required (400). No match returns customer_not_found (400) — match the exact string. Use URL encoding (e.g. URLSearchParams) so the + in phone numbers is not lost.

Example

Response

Returns 200 with a single customer object (no envelope). The model has two layers: the customer’s state (balances, tier level, counters) lives in the top-level collectables; the rules (earn/spend/tier configuration) live in cards[].campaigns[].actions[].options.
Notes:
  • A barcode search returns only that card; phone/email searches return all of the customer’s cards. collectables and coupons are scoped to the returned card(s).
  • cards[].campaigns[] are the campaigns attached to the card: {id, name?, actions}. actions[].options is the campaign’s configuration and passes through as-is — its content depends on the action type (collect-points, collect-tiered-points, collect-stamps, apply-discount, …). Two exceptions: options.collectable is always the collectable key (matching the keys in the top-level collectables), and reward coupons are reduced to {id, name}. Inactive actions are not listed. On tiered campaigns tiers[] contains ALL of the campaign’s levels.
  • tiers[].name is the tier’s display name, returned as a multi-language object ({ "EN": "Bronze", "TR": "Bronz", ... } — the languages defined by the organization). The field is omitted when the tier has no name defined; single-level campaigns have no tier names, so name is never present there (like the stamp campaign in the example).
  • The customer’s state lives in the top-level collectables: value is the spendable balance, total the lifetime collected amount. On tiered campaigns, tierLevel (the customer’s current level) and tierStartedAt are also present, along with the counters the campaigns track (the key named by options.track — e.g. totalAmount). These fields are omitted when not applicable.
  • Derived values are not returned — compute them from config + state:
    • Active tier config: the tiers[] entry where level === collectables[key].tierLevel; read the display name from that entry’s name.
    • Remaining to next tier: nextTier.threshold - collectables[key][options.track].
    • Money value of one point: active tier’s spend.convertto / spend.pointstoconvert.
    • Stamp target: active tier’s convert.threshold — display progress as value/threshold (e.g. 4/10).
  • collect configurations are estimates: active promotions can change the final earned amount.
  • tags / categories are the labels attached to the customer ({id, name, color?}); color is omitted when not set, and both are empty arrays when the customer has none.
  • coupons are the customer’s redeemable coupons: redeemed coupons are excluded; coupons sent directly to the customer (not tied to a campaign) are always listed. Same item shape as GET /v1/customers/:id/coupons.
  • Optional coupon fields (maxDiscountAmount, includesModifiers, products, issued, issuedAt, expiresAt, redeemed, redeemedAt) are omitted when absent — you will not receive null. type: "product" (free product) coupons come as discountAmount: 100, isPercent: true; the covered products are in products.productIds (your external product codes).
  • cards[].id is the card parameter of the coupon endpoints and of POST /v1/transactions/process; coupons[].id is the :couponId of redeem.
Last modified on September 29, 2026