API REFERENCE

Base: https://gfs-platform.mikelevine.workers.dev · 20 endpoints
LIVE

Authentication

All endpoints except / and /api/health require a Bearer token.
Authorization: Bearer <API_KEY>
Set via: wrangler secret put API_KEY · Returns 401 with hint if missing/invalid

Common Response Headers

HeaderValue
Content-Typeapplication/json
X-Content-Type-Optionsnosniff
X-Frame-OptionsDENY
X-XSS-Protection1; mode=block
Referrer-Policystrict-origin-when-cross-origin
Content-Security-Policydefault-src 'none'; frame-ancestors 'none'
Access-Control-Allow-Origin(matched origin or primary)

Quick Start

Example Requests

# Health check (no auth)
curl -s https://gfs-platform.mikelevine.workers.dev/api/health | python3 -m json.tool

# KPIs (auth required)
curl -s -H "Authorization: Bearer YOUR_API_KEY" \
  https://gfs-platform.mikelevine.workers.dev/api/kpis

# Search customers
curl -s -H "Authorization: Bearer YOUR_API_KEY" \
  "https://gfs-platform.mikelevine.workers.dev/api/customers?q=driscoll&limit=5"

# AR aging
curl -s -H "Authorization: Bearer YOUR_API_KEY" \
  https://gfs-platform.mikelevine.workers.dev/api/ar/aging

# Items with milk allergen
curl -s -H "Authorization: Bearer YOUR_API_KEY" \
  "https://gfs-platform.mikelevine.workers.dev/api/items?allergen=milk&limit=10"
Pagination: Most list endpoints accept limit (1-200, default 50) and offset (0-100000, default 0). Total count returned where available.
Types: All amounts are number (REAL). All dates are string in M/D/YYYY format. All IDs are integer. Null fields are omitted or null.

Public Endpoints

PUBLIC GET /

Root status page
{
  "name": "GFS Platform API",
  "domain": "ai-globalfoodsolutions.co",
  "version": "1.0.0",
  "status": "operational",
  "auth": "Bearer token required for all endpoints except /api/health",
  "endpoints": "/api/health"
}

PUBLIC GET /api/health

Database health check with row counts for 8 main tables
{
  "status": "ok",
  "database": "gfs-netsuite",
  "counts": {
    "customers": 283, "vendors": 484, "items": 1265,
    "transactions": 102367, "invoice_lines": 28528,
    "so_lines": 29098, "vb_lines": 21315, "pricing": 1264
  },
  "timestamp": "2026-05-19T13:33:03.674Z"
}

KPI & Briefing Endpoints

AUTH GET /api/kpis

Core KPIs — revenue, AR, AP, open SOs
{
  "revenue_2026_ytd": 11272175.89,
  "revenue_2025_total": 28435586.26,
  "open_ar": { "amount": 2299955.6, "count": 216 },
  "open_ap": { "amount": ..., "count": ... },
  "open_so": { "amount": ..., "count": 90 },
  "timestamp": "..."
}

AUTH GET /api/briefing

Combined morning briefing data — KPIs + top customers + this month's invoices
{
  "revenue_2026_ytd": ...,
  "open_ar": { "amount": ..., "count": ... },
  "open_so": { "amount": ..., "count": ... },
  "invoices_this_month": { "amount": ..., "count": ... },
  "top_customers_2026": [ { "entity_name": "Driscoll Foods", "revenue": 4107918.47 }, ... ],
  "timestamp": "..."
}

Entity Endpoints

AUTH GET /api/customers

Customer list with terms and categories. Supports search and pagination. → DB: customers table
ParamTypeDefaultDescription
qstringSearch by company name (LIKE %q%)
limitint501-200
offsetint00-100000
{ "items": [...], "total": 283, "limit": 50, "offset": 0 }

AUTH GET /api/customers/:id

Full customer record + contacts + pricing + recent sales orders (20)
{ "id": 475, "companyname": "Jkings", ..., "contacts": [...], "pricing": [...], "recent_orders": [...] }

AUTH GET /api/customers/:id/history

Customer transaction history by year + top items purchased
{ "customer_id": "475", "yearly": [{ "year": 2026, "type": "CustInvc", "txn_count": 47, "total": ... }], "top_items": [...] }

AUTH GET /api/customers/ranking

Top 50 customers by invoice revenue for a given year
ParamTypeDefault
yearint2026
{ "year": 2026, "items": [{ "customer": "Driscoll Foods", "customer_id": 539, "inv_count": ..., "revenue": 4107918.47 }, ...] }

AUTH GET /api/vendors

Active vendor list with terms (limit param, default 50)

AUTH GET /api/vendors/spend

Top 50 vendors by bill spend with min/max/avg
ParamTypeDefault
yearint2026

Item Endpoints

AUTH GET /api/items

Item list with brand/class. Filter by type and allergen.
ParamTypeDefaultAllowed Values
typestringInvtPart, Assembly, Kit, NonInvtPart
allergenstringmilk, eggs, peanuts, soybeans, wheat, fish, tree_nuts, crustacean, celery, lupin, molluscs, mustard, sesame, sulphur_dioxide
limitint501-200
offsetint00-100000

AUTH GET /api/items/:id

Item detail + revenue by year + cost by year + top 10 customers

AUTH GET /api/items/performance

Top 50 items by invoice revenue with qty sold, avg price, customer count
ParamTypeDefault
yearint2026

AUTH GET /api/items/:id/customers

Which customers buy this item — revenue and qty by year (2024+)

Transaction & Financial Endpoints

AUTH GET /api/transactions

Transaction list by type with optional year filter
ParamTypeDefaultAllowed
typestringCustInvc16 validated types
yearint2018-2027
limitint501-200
offsetint00-100000

AUTH GET /api/ar/aging

AR aging by customer — current, 1-30, 31-60, 61-90, 90+ day buckets. → DB: transactions (CustInvc, status=A) · → O2C workflow
{ "items": [{ "customer": "...", "customer_id": ..., "inv_count": ..., "total_ar": ..., "current_bal": ..., "days_1_30": ..., "days_31_60": ..., "days_61_90": ..., "days_90_plus": ... }] }

AUTH GET /api/financials/summary

Revenue vs COGS vs collections by year (all years)
{ "revenue": [{ "year": 2026, "invoices": 712, "total": 11272175.89 }, ...], "cogs": [...], "collections": [...] }

AUTH GET /api/financials/monthly

Monthly breakdown by transaction type
ParamTypeDefault
yearint2026

AUTH GET /api/revenue/trend

Monthly invoice revenue from 2024 onward — for trend charts

AUTH GET /api/gl/accounts

Chart of accounts, optionally filtered by type
ParamTypeDefaultValues
typestringBank, AcctRec, AcctPay, Income, COGS, Expense, Equity, OthCurrAsset, OthCurrLiab, FixedAsset, OthIncome, OthExpense, NonPosting

Search

AUTH GET /api/search

Cross-entity search — searches customers, vendors, and items simultaneously
ParamTypeRequired
qstringYes (max 100 chars)
{ "results": [{ "id": 475, "name": "Jkings", "type": "customer" }, { "id": 539, "name": "Driscoll Foods", "type": "customer" }, ...] }

Error Responses

StatusBodyCause
401{"error":"Unauthorized","hint":"Provide Authorization: Bearer <API_KEY> header"}Missing or invalid Bearer token
400{"error":"Invalid item type"}Type/allergen not in allowlist
400{"error":"Missing q parameter"}Search endpoint without query
404{"error":"Not found"}Record ID doesn't exist
404{"error":"Not found","endpoints":[...]}Unknown path — returns endpoint list
405{"error":"Method not allowed"}Non-GET request (except OPTIONS for CORS)
500{"error":"Internal server error"}Unhandled exception (logged server-side)