API Usage Guide

Version: 2.0 Last Updated: 2026-01-12 Audience: Frontend developers, integration partners, API consumers


Table of Contents


Introduction

This guide provides practical examples and patterns for working with the OmniCart API. All examples use curl for demonstration, but the patterns apply to any HTTP client.

Base URL:

All API requests use your assigned OmniCart store domain as the base URL:


Authentication

OmniCart uses four authentication patterns depending on the route category.

Admin Authentication

Admin routes (/admin/*) require a valid admin JWT token obtained through the OmniCart authentication endpoints.

Required Header:

Authorization: Bearer <admin_jwt_token>

Example: Get Admin User

curl -X GET 'https://your-store.omnicart.cc/admin/brands' \
  -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' \
  -H 'Content-Type: application/json'

How to Obtain Admin Token:

# Login as admin user
curl -X POST 'https://your-store.omnicart.cc/auth/user/emailpass' \
  -H 'Content-Type: application/json' \
  -d '{
    "email": "admin@example.com",
    "password": "your_password"
  }'

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

Authentication Enforcement:

Secret API Keys (recommended for server-to-server)

For scheduled jobs, BI pipelines, and backend integrations, prefer a secret API key over email/password JWT logins: keys don't expire on a timer, aren't tied to a person's password, and can be revoked individually. Create one in the admin dashboard under Settings → API Key Management (secret keys start with sk_).

Use it with HTTP Basic auth — the key is the username, the password is empty:

curl -X GET 'https://your-store.omnicart.cc/admin/orders?limit=10' \
  -u "sk_YOUR_SECRET_KEY:"

# equivalent explicit header form
curl -X GET 'https://your-store.omnicart.cc/admin/orders?limit=10' \
  -H 'Authorization: Basic sk_YOUR_SECRET_KEY'

Most admin endpoints accept secret keys; a small number of sensitive operations require an interactive user session or JWT instead — if a key gets a 401 on a specific route, fall back to the JWT flow for that call.


Partner Authentication

Partner routes (/store/partners/*) use bearer token or session-based authentication with varying requirements.

Required Header:

Authorization: Bearer <partner_jwt_token>

Example: 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...' \
  -H 'Content-Type: application/json'

Authentication Patterns:

  1. Required Authentication:

    • Routes: /store/partners/me, /store/partners/me/*
    • Must have valid partner token
    • Returns 401 if not authenticated
  2. Registration (Allow Unregistered):

    • Route: /store/partners/auth/register (POST)
    • Requires auth identity but allows unregistered partners
    • Used for completing registration after email verification
  3. Optional Authentication:

    • Route: /store/partners/offers (GET)
    • Works without authentication (public list)
    • Personalized if authenticated
    • Uses allowUnauthenticated: true

How to Obtain Partner Token:

# Register partner (Step 1: 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": "secure_password"
  }'

# 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 <temp_token_from_step1>' \
  -H 'Content-Type: application/json' \
  -d '{
    "company_name": "Example Corp",
    "contact_name": "John Doe",
    "phone": "+1-555-0100"
  }'

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

Customer Authentication

Store routes (/store/*) support optional customer authentication for personalization.

Required Header — Publishable API Key:

Every /store/* request must include your publishable API key (starts with pk_). It identifies your storefront and scopes results to the correct sales channel. Requests without it are rejected. Get yours from the admin dashboard under Settings → API Key Management (or from your onboarding materials).

x-publishable-api-key: pk_YOUR_PUBLISHABLE_KEY

Optional Header — Customer Token:

Authorization: Bearer <customer_jwt_token>

Example: List Products (Public)

# Without authentication (public catalog)
curl -X GET 'https://your-store.omnicart.cc/store/products' \
  -H 'x-publishable-api-key: pk_YOUR_PUBLISHABLE_KEY'

# With authentication (personalized pricing, recommendations)
curl -X GET 'https://your-store.omnicart.cc/store/products' \
  -H 'x-publishable-api-key: pk_YOUR_PUBLISHABLE_KEY' \
  -H 'Authorization: Bearer <customer_token>'

Example: Get Cart (Requires Auth)

curl -X GET 'https://your-store.omnicart.cc/store/carts/my-cart' \
  -H 'x-publishable-api-key: pk_YOUR_PUBLISHABLE_KEY' \
  -H 'Authorization: Bearer <customer_token>'

How to Obtain Customer Token:

# Register customer
curl -X POST 'https://your-store.omnicart.cc/auth/customer/emailpass/register' \
  -H 'Content-Type: application/json' \
  -d '{
    "email": "customer@example.com",
    "password": "secure_password"
  }'

# Login
curl -X POST 'https://your-store.omnicart.cc/auth/customer/emailpass' \
  -H 'Content-Type: application/json' \
  -d '{
    "email": "customer@example.com",
    "password": "secure_password"
  }'

Public Endpoints

Public routes require no authentication and are typically used for:

Example: Flow Builder Embed

curl -X GET 'https://your-store.omnicart.cc/flow-builder/session/create?cart_id=cart_123'

Example: Webhook Receiver

curl -X POST 'https://your-store.omnicart.cc/webhooks/stripe' \
  -H 'Content-Type: application/json' \
  -H 'Stripe-Signature: t=1234,v1=abc...' \
  -d '{
    "type": "payment_intent.succeeded",
    "data": {...}
  }'

Note: Public endpoints may have other security measures:


Core Commerce Endpoints

Beyond the routes catalogued in this reference, every OmniCart store serves a standard commerce API. These endpoints follow the same conventions documented in this guide (authentication, pagination via limit/offset/count, fields selection, operator-map date filters). All /store/* calls require the x-publishable-api-key header.

Catalog & regions:

Method Path Description
GET /store/products List products (supports q, limit, offset, fields, category/collection filters)
GET /store/products/:id Product detail with variants and prices
GET /store/product-categories List categories
GET /store/collections List collections
GET /store/regions List regions (currencies, countries)

Cart & checkout flow:

Method Path Description
POST /store/carts Create a cart (pass region_id and sales_channel_id — required when your publishable key is linked to multiple sales channels, so always provide it; optional email)
GET /store/carts/:id Retrieve cart
POST /store/carts/:id Update cart (email, addresses)
POST /store/carts/:id/line-items Add item (variant_id, quantity)
POST /store/carts/:id/line-items/:line_id Update item quantity
DELETE /store/carts/:id/line-items/:line_id Remove item
GET /store/shipping-options?cart_id=:id List shipping options for a cart
POST /store/carts/:id/shipping-methods Select a shipping option
POST /store/payment-collections Create payment collection for the cart
POST /store/payment-collections/:id/payment-sessions Initialize a payment session
POST /store/carts/:id/complete Complete the cart → creates the order

Customers & orders:

Method Path Description
POST /store/customers Register a customer (after auth registration — see Customer Authentication)
GET /store/customers/me Current customer profile (requires customer token)
GET /store/orders Current customer's orders (requires customer token)

On the admin side, the same conventions apply to the standard management surface — GET /admin/products, GET /admin/orders, GET /admin/customers, and their CRUD counterparts — usable with a secret API key or admin JWT. The Data & Reporting tutorials cover the admin endpoints most relevant to data pulls.


Common Patterns

Pagination

Most list endpoints support offset-based pagination with offset and limit query parameters.

Query Parameters:

Example: Get Brands with Pagination

# First page (items 0-49)
curl -X GET 'https://your-store.omnicart.cc/admin/brands?offset=0&limit=50' \
  -H 'Authorization: Bearer <admin_token>'

# Second page (items 50-99)
curl -X GET 'https://your-store.omnicart.cc/admin/brands?offset=50&limit=50' \
  -H 'Authorization: Bearer <admin_token>'

Response Format:

{
  "brands": [...],
  "count": 237,
  "offset": 0,
  "limit": 50
}

Pagination Calculation:

// Calculate pagination
const totalPages = Math.ceil(count / limit)
const currentPage = Math.floor(offset / limit) + 1
const hasNextPage = offset + limit < count
const hasPrevPage = offset > 0

// Next page
const nextOffset = offset + limit

// Previous page
const prevOffset = Math.max(0, offset - limit)

Filtering

Many list endpoints support filtering by status, dates, or other entity properties.

Example: Filter Brands by Status

curl -X GET 'https://your-store.omnicart.cc/admin/brands?status=active' \
  -H 'Authorization: Bearer <admin_token>'

Example: Filter Orders by Date Range

curl -X GET 'https://your-store.omnicart.cc/admin/orders?created_at_gte=2026-01-01&created_at_lte=2026-01-31' \
  -H 'Authorization: Bearer <admin_token>'

Common Filter Parameters:

Multiple Filters:

# Active brands updated in January 2026
curl -X GET 'https://your-store.omnicart.cc/admin/brands?status=active&updated_at_gte=2026-01-01&updated_at_lte=2026-01-31' \
  -H 'Authorization: Bearer <admin_token>'

Searching

List endpoints often support full-text search via the q query parameter.

Example: Search Brands by Name or Slug

curl -X GET 'https://your-store.omnicart.cc/admin/brands?q=nike' \
  -H 'Authorization: Bearer <admin_token>'

Search Behavior:

Example: Search + Filter + Pagination

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

Sorting

Some endpoints support sorting via order or sort parameters.

Example: Sort by Creation Date

# Newest first (descending)
curl -X GET 'https://your-store.omnicart.cc/admin/orders?order=created_at:desc' \
  -H 'Authorization: Bearer <admin_token>'

# Oldest first (ascending)
curl -X GET 'https://your-store.omnicart.cc/admin/orders?order=created_at:asc' \
  -H 'Authorization: Bearer <admin_token>'

Common Sort Fields:


Relations & Field Selection

The API supports loading related entities via the fields query parameter.

Example: Load Brands with Customer Avatars

curl -X GET 'https://your-store.omnicart.cc/admin/brands?fields=+customer_avatars' \
  -H 'Authorization: Bearer <admin_token>'

Example: Select Specific Fields Only

curl -X GET 'https://your-store.omnicart.cc/admin/brands?fields=id,name,slug,status' \
  -H 'Authorization: Bearer <admin_token>'

Note: Relation loading behavior varies by endpoint. Check specific endpoint documentation for supported relations.


Request Formats

Headers

Required Headers:

Content-Type: application/json

Authentication Headers:

Authorization: Bearer <token>

Optional Headers:

Accept: application/json
X-Request-ID: <unique_request_id>

Request Body

POST, PATCH, and PUT requests typically accept JSON bodies.

Example: Create 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",
    "website": "https://example-brand.com",
    "status": "active",
    "metadata": {
      "founded": 1964,
      "headquarters": "Oregon, USA"
    }
  }'

Example: Update Partner Profile

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.com"
  }'

Body Format:


Query Parameters

GET and DELETE requests use query parameters for filtering, pagination, and configuration.

Example with Multiple Query Params:

curl -X GET 'https://your-store.omnicart.cc/admin/brands?status=active&q=sport&offset=0&limit=20&fields=id,name,slug' \
  -H 'Authorization: Bearer <admin_token>'

URL Encoding: Query parameters must be URL-encoded:

# Space → %20 or +
curl -X GET 'https://your-store.omnicart.cc/admin/brands?q=nike%20air'

# Special characters
curl -X GET 'https://your-store.omnicart.cc/admin/brands?q=50%25%20off'

Path Parameters

Dynamic route segments use :parameter notation.

Example: Get Brand by ID

curl -X GET 'https://your-store.omnicart.cc/admin/brands/brand_01HQZX...' \
  -H 'Authorization: Bearer <admin_token>'

Example: Delete Partner Offer

curl -X DELETE 'https://your-store.omnicart.cc/admin/partners/offers/offer_123' \
  -H 'Authorization: Bearer <admin_token>'

Common Path Parameters:


Response Formats

Success Responses

Status Code: 200 OK

Single Resource:

{
  "brand": {
    "id": "brand_01HQZX...",
    "name": "Nike",
    "slug": "nike",
    "status": "active",
    "created_at": "2026-01-10T12:00:00Z",
    "updated_at": "2026-01-10T12:00:00Z"
  }
}

Example Request:

curl -X GET 'https://your-store.omnicart.cc/admin/brands/brand_01HQZX...' \
  -H 'Authorization: Bearer <admin_token>'

Paginated Responses

Status Code: 200 OK

List with Pagination:

{
  "brands": [
    {
      "id": "brand_01HQZX...",
      "name": "Nike",
      "slug": "nike"
    },
    {
      "id": "brand_01HQZY...",
      "name": "Adidas",
      "slug": "adidas"
    }
  ],
  "count": 237,
  "offset": 0,
  "limit": 50
}

Response Fields:


Created Resources

Status Code: 201 Created

Response:

{
  "brand": {
    "id": "brand_01HQZX...",
    "name": "Nike",
    "slug": "nike",
    "status": "active",
    "created_at": "2026-01-12T10:30:00Z"
  }
}

Example Request:

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"
  }'

Deleted Resources

Status Code: 200 OK

Response:

{
  "id": "brand_01HQZX...",
  "deleted": true
}

Example Request:

curl -X DELETE 'https://your-store.omnicart.cc/admin/brands/brand_01HQZX...' \
  -H 'Authorization: Bearer <admin_token>'

Error Handling

Error Response Format

All errors follow a consistent format:

Status Code: 4xx or 5xx

Response Body:

{
  "message": "Human-readable error message",
  "type": "error_type",
  "code": "ERROR_CODE"
}

Example: Authentication Error

{
  "message": "Partner authentication required",
  "type": "unauthorized",
  "code": "UNAUTHORIZED"
}

Example: Validation Error

{
  "message": "Invalid brand data: name is required",
  "type": "invalid_data",
  "code": "INVALID_DATA"
}

Example: Not Found Error

{
  "message": "Partner not found",
  "type": "not_found",
  "code": "NOT_FOUND"
}

Common HTTP Status Codes

Code Name Description Example
200 OK Request succeeded GET resource
201 Created Resource created successfully POST brand
400 Bad Request Invalid request data Missing required field
401 Unauthorized Authentication required or failed Missing or invalid token
403 Forbidden Authenticated but not authorized Admin-only endpoint with partner token
404 Not Found Resource doesn't exist GET /brands/invalid_id
422 Unprocessable Entity Validation error Invalid email format
500 Internal Server Error Server error Database connection failed
503 Service Unavailable Service temporarily down External API timeout

Error Types

Error responses follow a consistent JSON shape: a human-readable message, and where applicable a type code you can branch on programmatically.

1. Unauthorized (401)

Returned when authentication is missing or invalid.

{
  "message": "Partner authentication required",
  "type": "unauthorized"
}

2. Not Found (404)

Returned when the requested resource does not exist.

{
  "message": "Partner not found",
  "type": "not_found"
}

3. Invalid Data (400)

Returned when the request body or parameters fail validation.

{
  "message": "CustomerLabs not configured properly",
  "type": "invalid_data"
}

4. Generic Error (400)

Some endpoints return an error field with additional detail instead of a type code.

{
  "message": "Failed to create brand",
  "error": "Slug already exists"
}

Best Practices

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
    }
  }
}

Example 3: Paginated Brand Listing with Search

# 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

Additional Resources


Questions or Issues?