> ## Documentation Index
> Fetch the complete documentation index at: https://docs.craveup.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Customer identity

> Build guest checkout and verified customer accounts without crossing restaurant organizations.

Crave customers belong to one restaurant organization and are shared by that organization's
locations. The same diner ordering from an unrelated organization has a separate customer record.

## Guest checkout

Guest checkout remains available without an identity-provider session. Crave normalizes the supplied
email or phone and creates or reuses only a `guest` customer inside the resolved organization. If the
contact already belongs to a verified customer, Crave creates a separate guest shadow record; it never
returns the verified profile, addresses, saved payment methods, loyalty membership, or order history.

## Sign-in and tenant binding

Crave Customer Identity uses the environment-specific Clerk application. Clerk owns sign-in,
verification, session recovery, logout, and token refresh; Crave exposes no customer login or OTP
endpoint. The storefront requests a short-lived JWT from the active Clerk session with the
`crave-customer` token template and supplies it to the SDK only through `getAuthToken`. Do not copy
the token into `localStorage`, `sessionStorage`, SecureStore, URLs, logs, or analytics.

Every customer-capable SDK client must also provide `getMerchantSlug`. The SDK sends that value as
`X-Crave-Merchant-Slug`, and Crave maps the verified Clerk subject to a customer inside that exact
restaurant organization. One Clerk diner can therefore have separate Crave customer records for
unrelated merchants without exposing data across organizations.

Create customer clients and render customer-only data only after Clerk is loaded and signed in:

```ts theme={null}
const storefront = createStorefrontClient({
  baseUrl,
  sessionStore,
  getAuthToken: () => getToken({ template: "crave-customer" }),
  getMerchantSlug: () => merchantSlug,
});
```

The Customer Clerk application, token template, allowed origins, and sign-in methods must be
activated separately in development/sandbox and production. Use only Crave-provided public Clerk
configuration for the matching environment; never place a Clerk secret key in a storefront.

Verified customer responses expose `identityState` and verified contact channels. They never expose
provider subjects, challenge IDs, Stripe customer IDs, loyalty member IDs, or internal consent evidence.

## Export and deletion

An authenticated customer can download their organization-scoped data from
`GET /customer/data-export`. `DELETE /customer` requires an `Idempotency-Key` and starts a durable
privacy operation. Crave returns `completed` only after local minimization and all provider-owned data
has been erased. Automatic provider work returns `processing`; loyalty/manual obligations or a
provider failure that needs intervention returns `requires_action`. Crave never reports a partial
deletion as complete.

Crave automatically processes Stripe platform customers, account-scoped Square customers, and linked
Clover customers. Each attempt is durable, reads provider truth before a delete, and reads again after
the delete. Network ambiguity remains in `processing`; permission or ownership mismatches require
support.
Poll `GET /customer/privacy-operations/{operationId}` for safe progress. The response contains provider,
state, attempt, retry time, and a safe error code, but never a provider customer or merchant identifier.

Support may retry an action-required provider task only after resolving its cause through the
workforce-only retry endpoint. The action adds a bounded attempt allowance and writes a support audit;
it cannot replay a confirmed or actively processing task. Loyalty membership erasure remains part of
the loyalty integration and keeps the customer active until it is proven.

## Recovering a guest order

After verification, a customer may call `POST /customer/order-claims` with an `Idempotency-Key` and an
order ID. Crave accepts a claim only when:

* the order and customer belong to the same organization;
* the order is no more than 30 days old and is not cancelled or refunded;
* the order still belongs to an active guest customer;
* the claimant proved the exact email or phone stored in the immutable order snapshot; and
* no other customer has claimed the order.

The transfer, cart ownership update, claim audit, and collision resolution are one database transaction.
Loyalty reconciliation happens after ownership succeeds and remains visibly pending if the loyalty
provider cannot complete it.

## Sensitive customer features

Order history, addresses, saved payment methods, gift cards, and loyalty routes require a verified
customer session. Caller ID, a submitted contact, a guest record, and an identity-state label by itself
are never authorization evidence.

Successful first-time Crave linkage of a Clerk-verified customer emits the signed
`customer.verified` webhook. See
[Webhooks](https://docs.craveup.com/guides/webhooks.md) for delivery and retry behavior.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.