The Storefront API exposes every operation your customers need to browse menus, build carts, and pay for orders. All endpoints return JSON over HTTPS and authenticate with a location-scoped API key.
Base URL
https://api.craveup.com/api/v1
There is no sandbox server. Storefront applications connect directly to the production API using your API key.
Authentication
Include your API key in the X-API-Key header on every request:
import { createStorefrontClient } from '@craveup/storefront-sdk';
const storefront = createStorefrontClient({
apiKey: 'sk_live_abc123',
});
Generate an API key from the Crave Dashboard under Settings > API Keys. Each key is scoped to a single location.
Location-scoped endpoints
Every storefront endpoint lives under /locations/{locationId}:
GET /api/v1/locations/{locationId}
GET /api/v1/locations/{locationId}/time-intervals
POST /api/v1/locations/{locationId}/ordering-sessions
POST /api/v1/locations/{locationId}/carts/{cartId}/cart-item
GET /api/v1/locations/{locationId}/carts/{cartId}
PUT /api/v1/locations/{locationId}/carts/{cartId}/set-delivery
GET /api/v1/stripe/payment-intent?locationId=...&cartId=...
You can use either the location’s ObjectId (64a7b8c9d1e2f3a4b5c6d7e8) or its slug (downtown-pizza) as {locationId}. Both formats work interchangeably.
Resource groups
The API is organized into these groups:
| Group | Operations |
|---|
| Merchant | Look up a merchant and its locations by slug |
| Locations | Get location info, order times, gratuity config, distance |
| Ordering Sessions | Create or resume a cart |
| Cart | Get, update, add items, set fulfillment, schedule order, manage gratuity |
| Discounts | Apply or remove promo codes |
| Payments | Create a Stripe PaymentIntent |
| Analytics | Track storefront events (page views, checkout, order placed) |
| Ratings | Submit post-order experience ratings |
Send JSON bodies with Content-Type: application/json:
curl -X POST "https://api.craveup.com/api/v1/locations/loc_123/carts/cart_456/cart-item" \
-H "X-API-Key: sk_live_abc123" \
-H "Content-Type: application/json" \
-d '{
"productId": "prod_margherita",
"quantity": 2,
"selections": [],
"itemUnavailableAction": "remove_item"
}'
Successful responses return the resource directly:
{
"id": "cart_456",
"locationId": "loc_123",
"status": "OPEN",
"items": [],
"totalQuantity": 0,
"subTotal": "0.00",
"orderTotalWithServiceFee": "0.00",
"currency": "usd"
}
Error responses include a machine-readable code, a human-readable message, and the HTTP status:
{
"error": "VALIDATION_ERROR",
"message": "The 'quantity' field must be a positive integer.",
"statusCode": 400
}
For the full list of error codes and handling strategies, see Error Codes.
HTTP status codes
| Code | Meaning |
|---|
200 | Request succeeded |
201 | Resource created |
204 | Success, no content returned |
400 | Invalid request data |
401 | Missing or invalid API key |
403 | Insufficient permissions or inactive subscription |
404 | Resource not found |
409 | Conflict with current state (e.g., discount already applied) |
422 | Valid request, but cannot be processed (e.g., location closed) |
429 | Rate limit exceeded |
500 | Internal server error |
Rate limiting
The API allows 200 requests per 10 minutes per IP address. Rate limit state is returned in response headers:
| Header | Description |
|---|
X-RateLimit-Remaining | Requests remaining in the current window |
X-RateLimit-Reset | Unix timestamp when the window resets |
When you exceed the limit, the API returns 429 with a Retry-After header. Implement exponential backoff for retries.
Data types
| Type | Format | Example |
|---|
| ID | String | "64a7b8c9d1e2f3a4b5c6d7e8" |
| Slug | URL-safe string | "downtown-pizza" |
| Price | Decimal string | "12.99" |
| Currency | ISO 4217 lowercase | "usd", "gbp", "aed" |
| Date | YYYY-MM-DD | "2025-03-15" |
| Time | 24-hour HH:mm | "18:30" |
| Timestamp | ISO 8601 | "2025-03-15T18:30:00Z" |
Typical integration flow
The following example shows the standard ordering flow from session to payment:
import { createStorefrontClient } from '@craveup/storefront-sdk';
const storefront = createStorefrontClient({
apiKey: process.env.NEXT_PUBLIC_CRAVEUP_API_KEY!,
});
const locationId = 'loc_123';
// 1. Start an ordering session
const { cartId } = await storefront.orderingSessions.start(locationId, {
marketplaceId: locationId,
});
// 2. Add items
await storefront.cart.addItem(locationId, cartId!, {
productId: 'prod_margherita',
quantity: 2,
selections: [],
itemUnavailableAction: 'remove_item',
});
// 3. Set customer details
await storefront.cart.validateAndUpdateCustomer(locationId, cartId!, {
customerName: 'Alex Johnson',
emailAddress: 'alex@example.com',
});
// 4. Set order time
await storefront.cart.updateOrderTime(locationId, cartId!, {
pickupType: 'ASAP',
});
// 5. Create payment intent
const { clientSecret } = await storefront.payments.createIntent(locationId, cartId!);
// 6. Confirm payment with Stripe.js on the client
Storefront scope
The Storefront API covers customer-facing operations only. Menu management, order fulfillment, analytics, and merchant settings are handled through the Admin API (coming soon) and the Crave Dashboard.
| Available | Not available |
|---|
| Menu browsing | Menu editing |
| Cart management | Order management |
| Payment processing | Customer accounts |
| Discount application | Real-time order tracking |
| Analytics events | Merchant settings |
Next steps