Overview

The Crave Storefront API is designed around several core concepts that work together to enable online ordering experiences. Understanding these concepts will help you build effective storefronts.

Core Entities

Locations

Locations represent individual restaurant locations with their own menus, hours, and settings.
  • Location ID: Can be either a MongoDB ObjectId (64a7b8c9d1e2f3a4b5c6d7e8) or a slug (downtown-pizza)
  • Multi-location support: Each location operates independently
  • Geographic data: Includes address, coordinates, and delivery radius
  • Operating hours: Day-specific hours with timezone support
  • Fulfillment methods: Delivery, pickup, dine-in, table service
// Example: Get location information
const location = await fetch(`https://api.cravejs.com/api/v1/locations/downtown-pizza`, {
  headers: { 'X-API-Key': 'your_api_key' }
});

// Location contains:
// - Basic info (name, address, contact)
// - Operating hours and timezone
// - Fulfillment methods available
// - Delivery radius and fees
// - Ordering capabilities

Products & Menus

Products are the items customers can order, organized into categories within menus.
  • Hierarchical structure: Menu → Categories → Products
  • Pricing: Stored in cents (e.g., $12.99 = 1299)
  • Availability: Real-time availability checking
  • Modifiers: Customization options (size, toppings, etc.)
  • Time-based filtering: Products can be available at specific times
// Example: Get menu with products
const menu = await fetch(`https://api.cravejs.com/api/v1/locations/downtown-pizza/menus`, {
  headers: { 'X-API-Key': 'your_api_key' }
});

// Structure:
// menu.categories[] → category.products[] → product.modifiers[]

Carts

Carts hold customer selections before checkout and handle all pricing calculations.
  • Session-based: Each cart has a unique ID
  • Auto-calculation: Subtotal, tax, tips, and delivery fees
  • Validation: Ensures items are still available
  • Configuration: Delivery address, table number, order time
  • Persistence: Carts exist until explicitly deleted
// Example: Cart lifecycle
const cart = await fetch(`https://api.cravejs.com/api/v1/locations/downtown-pizza/carts`, {
  method: 'POST',
  headers: { 'X-API-Key': 'your_api_key' },
  body: JSON.stringify({
    marketplaceId: 'downtown-pizza',
    currentCartId: ''
  })
});

// Cart automatically calculates:
// - Subtotal (sum of all items)
// - Tax (based on location tax rates)
// - Delivery fee (if applicable)
// - Total (subtotal + tax + tip + fees)

Orders

Orders are created automatically when payments succeed (not directly via API).
  • Webhook-based creation: Created by Crave backend after payment
  • Immutable: Cannot be modified once created
  • Merchant-managed: Fulfillment handled by Crave Business Manager
  • Status tracking: Merchant updates status through Crave Business Manager

API Patterns

Authentication

All API requests require authentication via API key:
const headers = {
  'X-API-Key': 'your_api_key_here',
  'Content-Type': 'application/json'
};

Location-Scoped Operations

All operations are scoped to a specific location:
// All endpoints follow this pattern:
// https://api.cravejs.com/api/v1/locations/{locationId}/...

// Examples:
GET https://api.cravejs.com/api/v1/locations/downtown-pizza/menus
POST https://api.cravejs.com/api/v1/locations/downtown-pizza/carts
GET https://api.cravejs.com/api/v1/locations/downtown-pizza/products

Error Handling

The API returns consistent error responses:
// Error response format:
{
  "error": "validation_error",
  "message": "Invalid location ID",
  "details": {
    "field": "locationId",
    "code": "invalid_format"
  }
}

// Common HTTP status codes:
// 200 - Success
// 400 - Bad Request (validation errors)
// 401 - Unauthorized (invalid API key)
// 403 - Forbidden (merchant subscription required)
// 404 - Not Found
// 429 - Rate limited
// 500 - Internal server error

Rate Limiting

  • Limit: 200 requests per 10 minutes per IP address
  • Headers: X-RateLimit-Remaining, X-RateLimit-Reset
  • Exceeded: Returns 429 with retry information

Data Types

Common Fields

Most entities include these common fields:
  • id: Unique identifier (MongoDB ObjectId)
  • createdAt: ISO timestamp when created
  • updatedAt: ISO timestamp when last modified
  • isActive: Boolean indicating if entity is active

Price Format

All prices are stored as integers in cents:
// $12.99 is stored as 1299
const price = 1299;
const displayPrice = (price / 100).toFixed(2); // "12.99"

Time Format

  • Times: 24-hour format strings (“14:30”)
  • Dates: ISO 8601 timestamps (“2024-01-15T14:30:00Z”)
  • Timezones: Location-specific timezone handling

Typical Integration Flow

Here’s how a typical storefront integration works:
// 1. Load location information
const location = await fetchLocation(locationId);

// 2. Load menu and products
const menu = await fetchMenu(locationId);

// 3. Create cart when customer starts ordering
const cart = await createCart(locationId);

// 4. Add items to cart
await addItemToCart(locationId, cartId, {
  productId: 'prod_123',
  quantity: 2,
  modifiers: [...]
});

// 5. Configure cart (delivery, tip, etc.)
await setCartDelivery(locationId, cartId, deliveryAddress);
await setCartTip(locationId, cartId, tipAmount);

// 6. Validate cart before checkout
await validateCart(locationId, cartId);

// 7. Create payment intent
const paymentIntent = await createPaymentIntent(locationId, cartId);

// 8. Process payment with Stripe
// 9. Order is created automatically via webhook

Best Practices

Performance

  • Cache location data: Changes infrequently
  • Cache menu data: Update every 5-10 minutes
  • Don’t cache carts: Always fetch fresh cart data
  • Batch API calls: Use Promise.all for parallel requests

Error Handling

  • Implement retry logic: For temporary failures
  • Validate inputs: Before making API calls
  • Handle rate limits: Implement exponential backoff
  • Monitor errors: Track and log API errors

Security

  • Server-side API keys: Never expose in client code
  • Environment variables: Store keys securely
  • HTTPS only: Always use secure connections
  • Input validation: Sanitize all user inputs

User Experience

  • Loading states: Show loading during API calls
  • Error messages: Provide clear, actionable error messages
  • Optimistic updates: Update UI immediately when possible
  • Offline handling: Handle network connectivity issues

Limitations

Storefront Scope

The Storefront API is designed for customer-facing operations only:
  • Available: Menu browsing, cart management, payment processing
  • Not Available: Order management, menu editing, analytics
  • Not Available: Real-time order tracking, customer accounts

Merchant Requirements

  • Active subscription: Merchant must have active or trial subscription
  • Onboarding complete: Merchant must complete setup process
  • Payment configured: Stripe integration must be set up

Technical Constraints

  • Location-scoped: Cannot perform cross-location operations
  • No real-time updates: Polling required for data changes
  • Webhook-based orders: Cannot create orders directly via API
  • Rate limited: 200 requests per 10 minutes per IP

Next Steps

Now that you understand the core concepts, explore the specific API endpoints: