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

# API Overview

> Use the direct public Storefront API with capabilities, customer JWTs, and optimistic concurrency.

## Base URLs

```text theme={null}
Production: https://api.craveup.com/api/v1/storefront
Sandbox:    https://sandbox-api.craveup.com/api/v1/storefront
```

## Authorization

The public API does not use a browser API key.

| Resource | Authorization |
| - | - |
| Published merchant, location, menu, product, order-time, gratuity | Anonymous |
| Guest cart | Purpose-limited `X-Cart-Token` capability |
| Customer profile, orders, addresses, saved payments, loyalty history | Merchant-bound bearer JWT |
| Receipt | Customer JWT or purpose-limited `X-Receipt-Token` capability |

Private admin and integration credentials belong only in trusted server or CLI environments.

## Start an ordering session

```bash theme={null}
curl -X POST "https://api.craveup.com/api/v1/storefront/locations/LOCATION_ID/ordering-sessions" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: session_01JEXAMPLE" \
  -d '{"fulfillmentMethod":"takeout"}'
```

The response contains `cart` and, for a newly created guest cart, `cartAccessToken`. Save the token in tab-scoped storage. The response `ETag` contains the cart revision.

## Mutate the cart

```bash theme={null}
curl -X POST "https://api.craveup.com/api/v1/storefront/locations/LOCATION_ID/carts/CART_ID/items" \
  -H "Content-Type: application/json" \
  -H "X-Cart-Token: CART_CAPABILITY" \
  -H 'If-Match: "cart-0"' \
  -H "Idempotency-Key: item_01JEXAMPLE" \
  -d '{"productId":"PRODUCT_ID","quantity":1,"selections":[],"itemUnavailableAction":"remove_item"}'
```

Use the returned `ETag` for the next mutation. A stale revision returns `409 CART_CONFLICT`; reload current cart state before offering a retry.

## Checkout

```text theme={null}
POST /locations/{locationId}/carts/{cartId}/orders
GET  /locations/{locationId}/carts/{cartId}/order-submissions/{attemptId}
POST /locations/{locationId}/carts/{cartId}/rating
GET  /receipts/{receiptId}
```

An order-submission outcome is `PROCESSING`, `CUSTOMER_ACTION_REQUIRED`, `PAID`,
`ACCEPTED`, or `ACTION_REQUIRED`. Only `PAID` is online-payment success;
`ACCEPTED` is an audited pay-at-store order.

## Customer authentication

```text theme={null}
GET  /customer
GET  /customer/orders
GET  /customer/addresses
GET  /customer/saved-payments
GET  /customer/locations/{locationId}/loyalty/ledger
```

Clerk owns customer sign-in, verification, recovery, and token refresh. Customer API requests use a
short-lived JWT from the active Clerk session plus `X-Crave-Merchant-Slug`; the SDK supplies these
through `getAuthToken` and `getMerchantSlug`. Crave binds that verified subject to a customer inside
the selected restaurant organization and exposes no customer login or OTP endpoint.

## Error envelope

```json theme={null}
{
  "code": "CART_CONFLICT",
  "message": "The cart changed. Refresh it before retrying.",
  "requestId": "req_123",
  "details": {}
}
```

Common statuses are `400` validation, `401` invalid capability/session, `404` hidden or missing resource, `409` state/revision conflict, `429` rate limit, `503` dependency unavailable, and `500` internal error.

## SDK

```ts theme={null}
const crave = createStorefrontClient({
  baseUrl: process.env.NEXT_PUBLIC_CRAVEUP_API_URL!,
  sessionStore,
  getAuthToken,
  getMerchantSlug: () => merchantSlug,
});
```

Prefer the SDK for TypeScript storefronts because it owns capability headers, revisions, idempotency defaults, timeouts, and typed errors.


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