Build a lightweight ordering page using the Crave REST API directly. This quickstart uses plain JavaScript with fetch — no build tools, no framework, no SDK dependency.
Prerequisites
- A Crave API key from the Dashboard
- At least one live location in your merchant account
- A browser or any environment with
fetch (Node.js 18+, Deno, Bun)
1. API basics
Every request to the Storefront API requires a location-scoped API key passed in the X-API-Key header.
curl -H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
https://api.craveup.com/api/v1/locations/{locationId}/...
Generate an API key from the Crave Dashboard under Settings → API Keys. Each key is scoped to a single location.
Keep API keys secret. Never commit them to source control or expose them in client-side code that cannot be trusted. For browser apps, use a server-side proxy or restrict the key to read-only storefront operations.
Base URL: https://api.craveup.com/api/v1
All storefront endpoints are scoped under /locations/{locationId}.
2. Create an API helper
const API_BASE = 'https://api.craveup.com/api/v1';
const API_KEY = 'sk_live_your_api_key'; // replace with your key
const LOCATION_ID = 'loc_your_location_id';
async function api(method, path, body) {
const res = await fetch(`${API_BASE}${path}`, {
method,
headers: {
'Content-Type': 'application/json',
'X-API-Key': API_KEY,
},
body: body ? JSON.stringify(body) : undefined,
});
if (!res.ok) {
const text = await res.text();
throw new Error(`API ${res.status}: ${text}`);
}
if (res.status === 204) return null;
return res.json();
}
3. Fetch the merchant
async function getMerchant(slug) {
return api('GET', `/merchant/${slug}`);
}
// Usage
const merchant = await getMerchant('downtown-pizza');
console.log(merchant.name, merchant.locations.length, 'locations');
4. Start an ordering session
async function startSession() {
return api('POST', `/locations/${LOCATION_ID}/ordering-sessions`, {
marketplaceId: LOCATION_ID,
});
}
const session = await startSession();
const cartId = session.cartId;
console.log('Cart created:', cartId);
5. Add items to the cart
async function addItem(cartId, productId, quantity = 1) {
return api('POST', `/locations/${LOCATION_ID}/carts/${cartId}/cart-item`, {
productId,
quantity,
selections: [],
itemUnavailableAction: 'remove_item',
});
}
const result = await addItem(cartId, 'prod_margherita', 2);
console.log('Cart total:', result.cart.orderTotalWithServiceFeeFormatted);
6. Get the cart
async function getCart(cartId) {
return api('GET', `/locations/${LOCATION_ID}/carts/${cartId}`);
}
const cart = await getCart(cartId);
console.log(`${cart.totalQuantity} items — ${cart.orderTotalWithServiceFeeFormatted}`);
7. Update customer details
async function setCustomer(cartId, name, email) {
return api('PUT', `/locations/${LOCATION_ID}/cart/${cartId}/validate-and-update`, {
customerName: name,
emailAddress: email,
});
}
await setCustomer(cartId, 'Alex Johnson', 'alex@example.com');
8. Full HTML example
<!DOCTYPE html>
<html>
<head><title>My Storefront</title></head>
<body>
<h1 id="name">Loading...</h1>
<button id="add-btn">Add Margherita</button>
<p id="cart-info"></p>
<script type="module">
const API_BASE = 'https://api.craveup.com/api/v1';
const API_KEY = 'sk_live_your_api_key';
const LOCATION_ID = 'loc_your_location_id';
const SLUG = 'your-restaurant-slug';
async function api(method, path, body) {
const res = await fetch(`${API_BASE}${path}`, {
method,
headers: { 'Content-Type': 'application/json', 'X-API-Key': API_KEY },
body: body ? JSON.stringify(body) : undefined,
});
if (!res.ok) throw new Error(`API ${res.status}`);
return res.status === 204 ? null : res.json();
}
const merchant = await api('GET', `/merchant/${SLUG}`);
document.getElementById('name').textContent = merchant.name;
const session = await api('POST', `/locations/${LOCATION_ID}/ordering-sessions`, {
marketplaceId: LOCATION_ID,
});
document.getElementById('add-btn').addEventListener('click', async () => {
const result = await api('POST', `/locations/${LOCATION_ID}/carts/${session.cartId}/cart-item`, {
productId: 'prod_margherita',
quantity: 1,
selections: [],
itemUnavailableAction: 'remove_item',
});
document.getElementById('cart-info').textContent =
`${result.cart.totalQuantity} items — ${result.cart.orderTotalWithServiceFeeFormatted}`;
});
</script>
</body>
</html>
Next steps