Skip to content

Nutri-E API Reference

Complete API reference for all Cloudflare Workers powering Nutri-E.

Overview

Nutri-E uses three Cloudflare Workers to power its backend:

Worker Purpose Base URL (Production V3)
OpenAI GPT-4 Vision for food/supplement analysis nutrie-openai-worker-v3.invotekas.workers.dev
DSLD NIH supplement database proxy nutrie-dsld-worker-v3.invotekas.workers.dev
Apple Webhook App Store subscription lifecycle nutrie-apple-webhook-worker-v3.invotekas.workers.dev

All workers support multi-environment deployment (production, sandbox) for safe testing.

Authentication

Device Authentication (OpenAI & DSLD Workers)

All API requests require device authentication headers:

X-Device-ID: <device-uuid>
X-Device-Secret: <hmac-sha256-signature>

How it works:

  1. iOS app generates unique device ID (UIDevice.identifierForVendor)
  2. Device secret = HMAC-SHA256(deviceId + serverSalt)
  3. Server validates signature using same salt
  4. Rate limits are enforced per device ID

See Security Guide for implementation details.

No Authentication (Apple Webhook Worker)

Apple's servers call webhook endpoints directly - no authentication headers supported.

Environments

Production V3 (Current)

Worker URL
OpenAI nutrie-openai-worker-v3.invotekas.workers.dev
DSLD nutrie-dsld-worker-v3.invotekas.workers.dev
Apple Webhook nutrie-apple-webhook-worker-v3.invotekas.workers.dev

Sandbox V3

Worker URL
OpenAI nutrie-openai-worker-sandbox-v3.invotekas.workers.dev
DSLD nutrie-dsld-worker-sandbox-v3.invotekas.workers.dev
Apple Webhook nutrie-apple-webhook-worker-sandbox-v3.invotekas.workers.dev

OpenAI Worker

GET / - Health Check

{
  "status": "ok",
  "worker": "nutrie-openai-worker-v3",
  "environment": "PRODUCTION_V3"
}

GET /api/quota - Check AI Quota

Tracks device activity (last seen timestamp). Does NOT increment usage counter.

Headers: X-Device-ID, X-Device-Secret

Response:

{
  "quota": 50,
  "used": 12,
  "remaining": 38,
  "tier": "pro",
  "resetDate": "2025-10-25T00:00:00.000Z"
}

POST /api/openai - Single Image Vision

Single-image GPT-4 Vision request (food or supplement analysis). Increments usage counter.

Headers: Content-Type: application/json, X-Device-ID, X-Device-Secret

Request Body:

{
  "prompt": "Analyze this food image and provide nutritional information",
  "image": "data:image/jpeg;base64,/9j/4AAQSkZJRg...",
  "model": "gpt-4o",
  "temperature": 0
}
Field Type Required Description
prompt string Yes Instruction for GPT-4 Vision
image string Yes Base64-encoded JPEG image (max 20MB)
model string No OpenAI model (default: gpt-4o)
temperature number No Response randomness 0-1 (default: 0)

Caching: 7-day cache for supplement requests. Food requests (no_cache = true) bypass cache.

POST /vision - Multi-Image Vision

Multi-image GPT-4 Vision request (supplement label with multiple photos). Max 5 images.

Request Body:

{
  "images": [
    "data:image/jpeg;base64,/9j/...",
    "data:image/jpeg;base64,/9j/..."
  ],
  "prompt": "Extract supplement information from these label photos"
}

DSLD Worker

POST / - Search Supplements

Request Body:

{
  "api": "dsld_search",
  "query": "vitamin d",
  "filters": {},
  "size": 20
}

Caching: 30-day cache (supplement data rarely changes).

POST / - Get Supplement Label

{
  "api": "dsld_label",
  "productId": "12345"
}

Barcode Normalization: DSLD search supports barcode lookup with automatic formatting (8-digit, 12-digit UPC-A, 13-digit EAN-13, 14-digit ITF-14).

Apple Webhook Worker

GET /health - Health Check

POST /webhook - Apple Server Notifications

Receives Apple Server Notifications (V2 JWT format + V1 legacy).

Supported Events: SUBSCRIBED, DID_RENEW, DID_CHANGE_RENEWAL_STATUS, EXPIRED, REFUND, REVOKE, and more.

Product ID Mapping:

{
  'no.invotek.nutrie.basic_monthly': 'basic',
  'no.invotek.nutrie.pro_monthly': 'pro',
  'no.invotek.nutrie.premium_monthly': 'premium',
  'no.invotek.nutrie.ultimate_monthly': 'ultimate'
}

See Subscriptions for full lifecycle documentation.

Rate Limits & Quotas

OpenAI Worker (AI Requests)

Tier Daily Limit Price/Month
Free 10 requests Free
Basic 10 requests $4.99
Pro 50 requests $11.99
Premium 160 requests $24.99
Ultimate 500 requests $39.99

DSLD Worker (Supplement Lookups)

Tier Daily Limit Price/Month
Free 100 lookups Free
Basic 100 lookups $4.99
Pro 500 lookups $11.99
Premium 2000 lookups $24.99
Ultimate Unlimited $39.99

Error Responses

All workers return errors in consistent format:

{
  "success": false,
  "error": "Error message description",
  "code": "ERROR_CODE"
}
Code HTTP Status Description
INVALID_DEVICE_AUTH 401 Device authentication failed
QUOTA_EXCEEDED 429 Daily quota limit reached
INVALID_REQUEST 400 Request body validation failed
SERVER_ERROR 500 Internal server error

Testing

# OpenAI health check
curl https://nutrie-openai-worker-sandbox-v3.invotekas.workers.dev/

# DSLD search
curl -X POST https://nutrie-dsld-worker-sandbox-v3.invotekas.workers.dev \
  -H "Content-Type: application/json" \
  -H "X-Device-ID: test-device-id" \
  -H "X-Device-Secret: test-signature" \
  -d '{"api": "dsld_search", "query": "vitamin d", "size": 1}'

# Apple webhook health
curl https://nutrie-apple-webhook-worker-sandbox-v3.invotekas.workers.dev/health

Worker Functions Reference

OpenAI Worker (cloudflare-worker-openai/worker.js)

Function Purpose
handleSingleImageVisionRequest() Single-image food/supplement analysis
handleVisionRequest() Multi-image vision requests
isFoodRequest() Determines if request should be cached
generateCacheKey() Creates SHA-256 cache key from prompt
calculateSimilarity() Levenshtein distance for fuzzy cache matching
authenticateDevice() HMAC-SHA256 device verification
getDailyLimit() Fetches subscription tier and quota
incrementDeviceUsage() Increments daily usage counter

DSLD Worker (cloudflare-worker-dsld/worker.js)

Function Purpose
proxyDSLDRequest() Proxies to NIH DSLD API with 30-day caching
generateCacheKey() Creates cache key from request parameters
authenticateDevice() Device verification (same as OpenAI)

Apple Webhook Worker (cloudflare-worker-apple/worker.js)

Function Purpose
handleAppleWebhook() Main webhook entry point
handleV2Notification() Processes V2 JWT notifications
processNotification() Core business logic for all event types
updateSubscription() Updates subscription tier in KV
removeSubscription() Archives and deletes subscription

Monitoring

# Tail logs in real-time
wrangler tail nutrie-openai-worker-v3 --format pretty
wrangler tail nutrie-dsld-worker-v3 --format pretty
wrangler tail nutrie-apple-webhook-worker-v3 --format pretty