API Reference
REST API Documentation
Integrate TraceLayer into your own systems. All API endpoints are JSON-based and authenticated via session cookie or API key.
Authentication
All authenticated endpoints require a valid session. Authentication is handled by your configured auth provider (Logto, Supabase, Auth0, etc.).
Sign-in flow:
GET /api/auth/sign-in— redirects to your auth providerGET /api/auth/callback— handles the OAuth callback, sets a session cookieGET /api/auth/sign-out— clears the session
The session cookie tl_session is a signed JWT valid for 7 days. All subsequent API calls use this cookie automatically.
Access levels:
- public — no auth required (QR resolve endpoint)
- staff+ — staff or admin role required
- admin — admin role required
Base URL
https://qr.yourdomain.comTraceLayer is deployed on your own infrastructure with your own domain. The API base URL is the same as your QR domain — no separate API subdomain needed.
QR Codes
/api/qrstaff+Bulk generate QR code tokens
{ "count": 50, "entityType": "ingredient_lot" }{ "tokens": ["DCC5UQ5H", "K9N3RT7W", ...] }/api/qrstaff+List QR codes with optional filters
?status=unused&limit=100&offset=0{ "items": [{ "token": "DCC5UQ5H", "status": "unused", "entityType": null, "createdAt": "..." }] }/api/qr/:tokenpublicResolve a QR token — logs a scan event. Returns entity data based on caller role.
{ "token": "DCC5UQ5H", "entity": { "id": "...", "name": "...", "metadata": {...} } }/api/qr/:token?format=pngstaff+Download QR code image. Use format=svg for SVG output.
Binary PNG or SVG imageEntities
/api/entitiesstaff+Create a new tracked entity (ingredient lot, product, batch, etc.)
{
"name": "Dark Chocolate Couverture 70%",
"type": "ingredient_lot",
"state": "registered",
"visibility": "internal",
"metadata": {
"lotNumber": "L2026-0421",
"supplier": "Valrhona",
"photoUrls": ["/api/uploads/tenant/uuid.jpg"]
}
}{ "id": "ent_abc123", "name": "...", "type": "ingredient_lot", ... }/api/entities/:idstaff+Get a single entity by ID.
{ "id": "...", "name": "...", "state": "in_use", "metadata": {...} }/api/entities/:idstaff+Update entity name, type, state, visibility, or metadata. Logs a state_changed event if state changes.
{ "state": "completed", "metadata": { "notes": "batch finished" } }Batches
/api/batchesstaff+Create a production batch.
{
"batchCode": "B-2026-047",
"entityId": "ent_abc123",
"recipeVersion": "v2.1",
"notes": "Summer blend"
}/api/batchesstaff+List batches. Filter by state or entity ID.
?state=in_progress&entityId=ent_abc123/api/batches/:idstaff+Update batch — mark complete, add notes, set expiry.
{ "state": "completed", "expiresAt": "2026-09-01T00:00:00Z" }/api/batches/:id/ingredientsstaff+Add an ingredient lot to an existing batch. Logs added_to_batch event.
{ "entityId": "ent_xyz789", "quantity": "2.4", "unit": "kg" }Events
/api/eventsstaff+List events. Filter by QR token, entity ID, event type, or date range.
?token=DCC5UQ5H&type=registered&limit=200{
"events": [{
"id": "evt_123",
"eventType": "registered",
"userId": "user_abc",
"userRole": "staff",
"createdAt": "2026-06-14T09:15:00Z",
"metadata": { "lotNumber": "L2026-0421" }
}]
}Uploads
/api/uploadstaff+Upload a photo. Send as multipart/form-data with a "file" field.
multipart/form-data: file=<image>{ "url": "/api/uploads/tenant-id/uuid.jpg" }Event Types
All event types that can appear in the event log. The log is append-only — events cannot be deleted.
qr_scannedregisteredlinked_to_entitystate_changedadded_to_batchremoved_from_batchorder_createdorder_fulfilledmarked_voidviewed_public_pageintake_completedshippedreturnedError Responses
All error responses use standard HTTP status codes and return JSON:
// 4xx / 5xx response body
{
"error": "Human-readable error message",
"code": "machine_readable_code" // optional
}Ready to integrate?
Start a trial and get API access on the Growth plan or higher.