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:
How it works:
- iOS app generates unique device ID (
UIDevice.identifierForVendor) - Device secret = HMAC-SHA256(deviceId + serverSalt)
- Server validates signature using same salt
- 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¶
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:
Caching: 30-day cache (supplement data rarely changes).
POST / - Get Supplement Label¶
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:
| 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 |