View as Markdown

Best Practices & Examples

1. Always Handle Errors#

// Example: Fetch with error handling
async function getBrands() {
  try {
    const response = await fetch('https://your-store.omnicart.cc/admin/brands', {
      headers: {
        'Authorization': `Bearer ${token}`,
        'Content-Type': 'application/json'
      }
    })

    if (!response.ok) {
      const error = await response.json()
      throw new Error(error.message || 'Request failed')
    }

    return await response.json()
  } catch (error) {
    console.error('Failed to fetch brands:', error)
    throw error
  }
}

2. Use Pagination for Large Lists#

// Bad: Fetch all at once (may timeout)
const brands = await fetch('/admin/brands?limit=10000')

// Good: Fetch in pages
async function getAllBrands() {
  let allBrands = []
  let offset = 0
  const limit = 100

  while (true) {
    const { brands, count } = await fetch(
      `/admin/brands?offset=${offset}&limit=${limit}`
    )
    allBrands.push(...brands)

    if (offset + limit >= count) break
    offset += limit
  }

  return allBrands
}

3. Cache Tokens Appropriately#

// Store token securely
localStorage.setItem('admin_token', token)

// Reuse token for subsequent requests
const token = localStorage.getItem('admin_token')

// Clear token on logout
localStorage.removeItem('admin_token')

4. Validate Input Before Sending#

// Validate before API call
function createBrand(data) {
  if (!data.name || data.name.length < 2) {
    throw new Error('Brand name must be at least 2 characters')
  }

  if (data.website && !isValidUrl(data.website)) {
    throw new Error('Invalid website URL')
  }

  return fetch('/admin/brands', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(data)
  })
}

5. Use Filtering to Reduce Response Size#

// Bad: Fetch everything
const brands = await fetch('/admin/brands')

// Good: Filter by status
const activeBrands = await fetch('/admin/brands?status=active')

// Better: Filter + select fields
const brandNames = await fetch('/admin/brands?status=active&fields=id,name,slug')

6. Implement Retry Logic for Network Errors#

async function fetchWithRetry(url, options, retries = 3) {
  for (let i = 0; i < retries; i++) {
    try {
      const response = await fetch(url, options)
      return response
    } catch (error) {
      if (i === retries - 1) throw error
      await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)))
    }
  }
}

7. Set Appropriate Timeouts#

// Add timeout to prevent hanging requests
const controller = new AbortController()
const timeoutId = setTimeout(() => controller.abort(), 10000) // 10s timeout

try {
  const response = await fetch('/admin/brands', {
    signal: controller.signal,
    headers: { 'Authorization': `Bearer ${token}` }
  })
  return await response.json()
} finally {
  clearTimeout(timeoutId)
}

Complete Examples#

Example 1: Create and Retrieve a Brand#

# Step 1: Create a brand
curl -X POST 'https://your-store.omnicart.cc/admin/brands' \
  -H 'Authorization: Bearer <admin_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Nike",
    "description": "Just Do It - Athletic apparel and footwear",
    "website": "https://example-brand.com",
    "status": "active",
    "metadata": {
      "founded": 1964,
      "headquarters": "Oregon, USA"
    }
  }'

# Response (201 Created)
{
  "brand": {
    "id": "brand_01HQZX...",
    "name": "Nike",
    "slug": "nike",
    "description": "Just Do It - Athletic apparel and footwear",
    "website": "https://example-brand.com",
    "status": "active",
    "metadata": {
      "founded": 1964,
      "headquarters": "Oregon, USA"
    },
    "created_at": "2026-01-12T10:30:00Z",
    "updated_at": "2026-01-12T10:30:00Z"
  }
}

# Step 2: Retrieve the brand
curl -X GET 'https://your-store.omnicart.cc/admin/brands/brand_01HQZX...' \
  -H 'Authorization: Bearer <admin_token>'

# Response (200 OK)
{
  "brand": {
    "id": "brand_01HQZX...",
    "name": "Nike",
    "slug": "nike",
    "description": "Just Do It - Athletic apparel and footwear",
    "website": "https://example-brand.com",
    "status": "active",
    "created_at": "2026-01-12T10:30:00Z",
    "updated_at": "2026-01-12T10:30:00Z"
  }
}

Example 2: Partner Authentication Flow#

# Step 1: Register partner (create auth identity)
curl -X POST 'https://your-store.omnicart.cc/auth/partner/emailpass/register' \
  -H 'Content-Type: application/json' \
  -d '{
    "email": "partner@example.com",
    "password": "SecurePass123!"
  }'

# Response
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

# Step 2: Complete partner registration
curl -X POST 'https://your-store.omnicart.cc/store/partners/auth/register' \
  -H 'x-publishable-api-key: pk_YOUR_PUBLISHABLE_KEY' \
  -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' \
  -H 'Content-Type: application/json' \
  -d '{
    "company_name": "Example Corp",
    "contact_name": "John Doe",
    "phone": "+1-555-0100",
    "website": "https://example.com"
  }'

# Response (201 Created)
{
  "partner": {
    "id": "partner_01HQZX...",
    "company_name": "Example Corp",
    "contact_name": "John Doe",
    "email": "partner@example.com",
    "status": "pending"
  }
}

# Step 3: Login (subsequent sessions)
curl -X POST 'https://your-store.omnicart.cc/auth/partner/emailpass' \
  -H 'Content-Type: application/json' \
  -d '{
    "email": "partner@example.com",
    "password": "SecurePass123!"
  }'

# Response
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

# Step 4: Get partner profile
curl -X GET 'https://your-store.omnicart.cc/store/partners/me' \
  -H 'x-publishable-api-key: pk_YOUR_PUBLISHABLE_KEY' \
  -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'

# Response (200 OK)
{
  "partner": {
    "id": "partner_01HQZX...",
    "company_name": "Example Corp",
    "contact_name": "John Doe",
    "email": "partner@example.com",
    "phone": "+1-555-0100",
    "website": "https://example.com",
    "status": "active",
    "stats": {
      "total_clicks": 1250,
      "total_conversions": 43,
      "total_revenue": 12750.50,
      "total_commission_earned": 1912.58,
      "pending_commission": 1912.58,
      "conversion_rate": 3.44
    }
  }
}

# Search for "sport" brands, active only, 20 per page
curl -X GET 'https://your-store.omnicart.cc/admin/brands?q=sport&status=active&offset=0&limit=20' \
  -H 'Authorization: Bearer <admin_token>'

# Response (200 OK)
{
  "brands": [
    {
      "id": "brand_01HQZX...",
      "name": "Nike",
      "slug": "nike",
      "status": "active"
    },
    {
      "id": "brand_01HQZY...",
      "name": "Adidas",
      "slug": "adidas",
      "status": "active"
    },
    // ... 18 more brands
  ],
  "count": 87,
  "offset": 0,
  "limit": 20
}

# Next page
curl -X GET 'https://your-store.omnicart.cc/admin/brands?q=sport&status=active&offset=20&limit=20' \
  -H 'Authorization: Bearer <admin_token>'

Example 4: Error Handling#

# Missing authentication
curl -X GET 'https://your-store.omnicart.cc/admin/brands'

# Response (401 Unauthorized)
{
  "message": "Authentication required",
  "type": "unauthorized"
}

# Invalid token
curl -X GET 'https://your-store.omnicart.cc/admin/brands' \
  -H 'Authorization: Bearer invalid_token'

# Response (401 Unauthorized)
{
  "message": "Invalid token",
  "type": "unauthorized"
}

# Resource not found
curl -X GET 'https://your-store.omnicart.cc/admin/brands/brand_invalid' \
  -H 'Authorization: Bearer <admin_token>'

# Response (404 Not Found)
{
  "message": "Brand not found",
  "type": "not_found"
}

# Validation error
curl -X POST 'https://your-store.omnicart.cc/admin/brands' \
  -H 'Authorization: Bearer <admin_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "description": "Missing name field"
  }'

# Response (400 Bad Request)
{
  "message": "Invalid brand data: name is required",
  "type": "invalid_data"
}

Example 5: Update Partner Profile#

# Update contact information
curl -X PATCH 'https://your-store.omnicart.cc/store/partners/me' \
  -H 'x-publishable-api-key: pk_YOUR_PUBLISHABLE_KEY' \
  -H 'Authorization: Bearer <partner_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "contact_name": "Jane Doe",
    "phone": "+1-555-0200",
    "website": "https://example-brand-updated.com",
    "payment_method": "paypal",
    "payment_email": "payments@example.com"
  }'

# Response (200 OK)
{
  "partner": {
    "id": "partner_01HQZX...",
    "company_name": "Example Corp",
    "contact_name": "Jane Doe",
    "email": "partner@example.com",
    "phone": "+1-555-0200",
    "website": "https://example-brand-updated.com",
    "status": "active",
    "payment_method": "paypal",
    "payment_email": "payments@example.com"
  }
}

Example 6: Public Endpoint (No Auth)#

# Flow Builder - Create session (no auth required)
curl -X GET 'https://your-store.omnicart.cc/flow-builder/session/create?cart_id=cart_123&email=customer@example.com'

# Response (200 OK)
{
  "session_id": "fb_session_abc123",
  "cart_id": "cart_123",
  "email": "customer@example.com",
  "created_at": "2026-01-12T10:30:00Z"
}

# Tracking endpoint (no auth required)
curl -X GET 'https://your-store.omnicart.cc/track/click?code=PARTNER123&product_id=prod_456'

# Response (302 Redirect)
# Sets tracking cookies and redirects to product page