Stagera API Reference
The Stagera Public API lets you read and write your Stagera account data programmatically. Connect external tools like Truck Packer, build custom integrations, or automate workflows. All endpoints are RESTful, return JSON, and require an API key you generate from your Stagera account.
On this page:
- Quick Start — get your first API call working in 2 minutes
- Authentication — how API keys work, how to generate them
- Rate Limits — 100 requests/minute per key
- Pagination —
page+limiton all list endpoints - Errors — all error codes and what they mean
- Equipment endpoints — list, get, update dimensions/weight
- Jobs endpoints — list, get
- Crew endpoints — list, get
- Truck Packer integration guide
Quick Start
Get your first API call working in under 2 minutes.
- Generate an API key. In Stagera, go to Settings → API Keys. Click New key, give it a name (e.g. "Truck Packer"), select the scopes you need, then click Generate key. Copy the key immediately — it is shown only once.
- Make your first request. Replace
sk_live_...with your actual key:
curl -X GET \ "https://dkgkqkkoqriebjlaufcx.supabase.co/functions/v1/api/v1/equipment?limit=5" \ -H "Authorization: Bearer sk_live_<your_key>" \ -H "Content-Type: application/json"
>{#123;
"data": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Martin MAC 250",
"model": "MAC 250",
"manufacturer": "Martin",
"serial_number": "SN12345",
"category": "Lighting",
"status": "available",
"case_length_in": 48,
"case_width_in": 24,
"case_height_in": 12,
"weight_lbs": 35,
"case_type": "road_case",
"organization_id": "org-uuid",
"created_at": "2026-01-15T10:00:00Z",
"updated_at": "2026-03-20T14:30:00Z"
}
],
"meta": {
"org_id": "your-org-uuid",
"page": 1,
"total": 84
}
} Authentication
All API requests must include a valid API key in the Authorization header as a Bearer token.
Authorization: Bearer sk_live_<your_api_key>
Generating a key
- Go to Settings → API Keys in your Stagera account. Requires org owner or admin role.
- Click New key. Enter a descriptive name (e.g.
Truck Packer Production). - Select the scopes the key needs. Use the minimum scopes required.
- Click Generate key. Copy the key immediately — it is shown only once and cannot be recovered. Store it in a secrets manager or environment variable.
Key format
Keys are prefixed with sk_live_ followed by a 64-character hex string. The prefix is safe to display in logs; never log the full key.
sk_live_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2
└────────────────────────────── 64 hex chars ──────────────────────────────┘ Key security
| What the key list shows | What it means |
|---|---|
| Name | Label you gave the key (e.g. "Truck Packer") |
| Prefix | First 12 characters of the key, for identification. Not enough to authenticate. |
| Scopes | Which endpoints this key can access |
| Last used | Timestamp of the most recent successful request |
Rate Limits
100 requests per 60 seconds per API key. The limit is a rolling window — not a fixed clock-minute reset.
When you exceed the limit, you receive a 429 RATE_LIMITED response. Your request was not processed.
>{#123;
"error": {
"code": "RATE_LIMITED",
"message": "100 requests per minute exceeded"
}
} Best practices for staying within the limit:
- Cache equipment list responses locally — the catalog doesn't change by the second.
- Use
limit=100(max) on list endpoints to reduce total request count for pagination. - For bulk dimension writes (Truck Packer scans), batch PATCH calls and add a small delay between them.
- Create separate API keys per integration if you run multiple tools simultaneously.
Pagination
All list endpoints support cursor-free offset pagination using page and limit query parameters.
| Parameter | Type | Default | Max | Description |
|---|---|---|---|---|
| page | integer | 1 | — | Page number, 1-indexed. |
| limit | integer | 50 | 100 | Records per page. |
>{#123;
"data": [ /* array of records */ ],
"meta": {
"org_id": "your-org-uuid",
"page": 2,
"total": 84 // total records across all pages
}
} To fetch all records, iterate until (page - 1) * limit ≥ total. Example for total=84, limit=50: fetch page 1 (records 1–50), then page 2 (records 51–84). No page 3.
async function fetchAllEquipment(apiKey) { const baseUrl = 'https://dkgkqkkoqriebjlaufcx.supabase.co/functions/v1/api'; const headers = { 'Authorization': `Bearer ${apiKey}` }; const all = []; let page = 1, total = Infinity; while ((page - 1) * 100 < total) { const res = await fetch( `${baseUrl}/v1/equipment?page=${page}&limit=100`, { headers } ); const json = await res.json(); all.push(...json.data); total = json.meta.total; page++; } return all; // complete list }
Errors
All error responses use a consistent envelope:
>{#123;
"error": {
"code": "ERROR_CODE", // machine-readable, use this in your code
"message": "Human description" // for logging/display
}
} | HTTP | Code | Meaning | Fix |
|---|---|---|---|
| 401 | UNAUTHORIZED | Missing, malformed, or revoked API key | Check the Authorization header. Verify the key hasn't been revoked in Settings. |
| 403 | FORBIDDEN | API key lacks the required scope for this endpoint | Regenerate the key with the correct scopes, or create a new key that includes the needed scope. |
| 404 | NOT_FOUND | Resource doesn't exist or belongs to a different org | Confirm the ID is correct and belongs to your organization. The API will not reveal resources from other orgs. |
| 405 | METHOD_NOT_ALLOWED | HTTP method not supported on this path | Check the endpoint table — for example, POST /v1/equipment does not exist; only GET and PATCH are supported. |
| 400 | BAD_REQUEST | Invalid JSON body, or no writable fields provided in a PATCH | Check the request body. For PATCH, ensure at least one writable field is present. |
| 429 | RATE_LIMITED | 100 requests per 60 seconds exceeded | Back off and retry after ~60 seconds. See Rate Limits. |
| 500 | SERVER_ERROR | Unexpected server error | Retry with exponential backoff. If persistent, contact support with the endpoint and timestamp. |
const res = await fetch(`${baseUrl}/v1/equipment/${id}`, { headers }); const json = await res.json(); if (!res.ok) { switch (json.error?.code) { case 'UNAUTHORIZED': // check your API key; break; case 'FORBIDDEN': // missing scope; break; case 'NOT_FOUND': // item doesn't exist; break; case 'RATE_LIMITED': // back off 60s; break; default: // log and retry with backoff; } }
Equipment
Equipment represents the physical gear in your Stagera inventory. The API exposes read access to your full catalog and write access to dimension/weight fields — the fields Truck Packer updates after a LiDAR scan.
List equipment
Returns a paginated list of all equipment records for your organization, ordered alphabetically by name.
Query parameters
| Parameter | Type | Description | |
|---|---|---|---|
| page | integer | optional | Page number. Default: 1. |
| limit | integer | optional | Records per page. Default: 50. Max: 100. |
curl "https://dkgkqkkoqriebjlaufcx.supabase.co/functions/v1/api/v1/equipment?page=1&limit=100" \ -H "Authorization: Bearer sk_live_..."
>{#123;
"data": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Martin MAC 250",
"model": "MAC 250",
"manufacturer": "Martin",
"serial_number": "SN12345",
"category": "Lighting",
"status": "available",
"case_length_in": 48,
"case_width_in": 24,
"case_height_in": 12,
"weight_lbs": 35,
"case_type": "road_case",
"organization_id": "org-uuid",
"created_at": "2026-01-15T10:00:00Z",
"updated_at": "2026-03-20T14:30:00Z"
}
],
"meta": { "org_id": "org-uuid", "page": 1, "total": 84 }
} Equipment object fields
| Field | Type | Description |
|---|---|---|
| id | uuid | Unique identifier. Use this in PATCH requests. |
| name | string | Display name of the equipment item. |
| model | string | null | Model name as entered in Stagera. |
| manufacturer | string | null | Manufacturer / brand name. |
| serial_number | string | null | Serial number. May be null if not entered. |
| category | string | null | Equipment category (e.g. "Lighting", "Audio", "Video"). |
| status | string | "available", "on_job", "maintenance", or "retired". |
| case_length_in | number | null | Case exterior length in inches. Writable via PATCH. |
| case_width_in | number | null | Case exterior width in inches. Writable via PATCH. |
| case_height_in | number | null | Case exterior height in inches. Writable via PATCH. |
| weight_lbs | number | null | Weight in pounds. Writable via PATCH. |
| case_type | string | null | "road_case", "soft_case", "pelican", or null. Writable via PATCH. |
| organization_id | uuid | The org this item belongs to. Always matches the key's org. |
| created_at | ISO 8601 | When the record was created in Stagera. |
| updated_at | ISO 8601 | Last modification timestamp. |
Get equipment
Returns a single equipment record by ID. Returns 404 if the item doesn't exist or belongs to a different organization.
Path parameters
| Parameter | Type | Description | |
|---|---|---|---|
| id | uuid | required | Equipment ID from the list response. |
curl "https://dkgkqkkoqriebjlaufcx.supabase.co/functions/v1/api/v1/equipment/a1b2c3d4-e5f6-7890-abcd-ef1234567890" \ -H "Authorization: Bearer sk_live_..."
>{#123;
"data": { /* single equipment object — same fields as list */ },
"meta": { "org_id": "org-uuid" }
} Update equipment
Updates dimension and weight fields on an equipment record. Only the fields listed below are writable via the API — all other fields (name, serial number, category, status, etc.) are managed inside Stagera and are read-only here. Send only the fields you want to change; omitted fields are not modified.
Path parameters
| Parameter | Type | Description | |
|---|---|---|---|
| id | uuid | required | Equipment ID to update. |
Request body (JSON)
| Field | Type | Description | |
|---|---|---|---|
| case_length_in | number | optional | Case exterior length, inches. Positive number. |
| case_width_in | number | optional | Case exterior width, inches. Positive number. |
| case_height_in | number | optional | Case exterior height, inches. Positive number. |
| weight_lbs | number | optional | Weight in pounds. Positive number. |
| case_type | string | optional | One of: "road_case", "soft_case", "pelican". |
400 BAD_REQUEST.curl -X PATCH \ "https://dkgkqkkoqriebjlaufcx.supabase.co/functions/v1/api/v1/equipment/a1b2c3d4-e5f6-7890-abcd-ef1234567890" \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "case_length_in": 52.5, "case_width_in": 26.0, "case_height_in": 14.0, "weight_lbs": 38.2, "case_type": "road_case" }'
const res = await fetch( `https://dkgkqkkoqriebjlaufcx.supabase.co/functions/v1/api/v1/equipment/${equipmentId}`, { method: 'PATCH', headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ case_length_in: 52.5, case_width_in: 26.0, case_height_in: 14.0, weight_lbs: 38.2, case_type: 'road_case', }), } ); const { data } = await res.json(); console.log('Updated:', data.name, data.case_length_in);
>{#123;
"data": {
"id": "a1b2c3d4-...",
"name": "Martin MAC 250",
"case_length_in": 52.5,
"case_width_in": 26.0,
"case_height_in": 14.0,
"weight_lbs": 38.2,
"case_type": "road_case",
/* ...all other fields unchanged */
"updated_at": "2026-04-08T19:45:00Z"
},
"meta": { "org_id": "org-uuid" }
} Jobs
Jobs represent events or productions in your Stagera account. The API provides read-only access.
List jobs
Returns a paginated list of jobs for your organization, ordered by created_at descending (newest first).
Query parameters
| Parameter | Type | Description | |
|---|---|---|---|
| page | integer | optional | Page number. Default: 1. |
| limit | integer | optional | Records per page. Default: 50. Max: 100. |
| status | string | optional | Filter by job status. One of: "active", "completed", "cancelled", "draft". Omit to return all statuses. |
curl "https://dkgkqkkoqriebjlaufcx.supabase.co/functions/v1/api/v1/jobs?status=active&limit=50" \ -H "Authorization: Bearer sk_live_..."
>{#123;
"data": [
{
"id": "job-uuid",
"name": "Corporate Gala — April 2026",
"status": "active",
"event_date": "2026-04-18",
"event_end_date": "2026-04-20",
"venue": "Grand Hyatt Ballroom",
"client_name": "Acme Corp",
"organization_id": "org-uuid",
"created_at": "2026-03-01T09:00:00Z",
"updated_at": "2026-04-01T12:00:00Z"
}
],
"meta": { "org_id": "org-uuid", "page": 1, "total": 12 }
} Get job
Returns a single job by ID.
curl "https://dkgkqkkoqriebjlaufcx.supabase.co/functions/v1/api/v1/jobs/job-uuid" \ -H "Authorization: Bearer sk_live_..."
Crew
Crew members are the staff in your Stagera account. The API provides read-only access.
List crew
Returns a paginated list of crew members for your organization.
Query parameters
| Parameter | Type | Description | |
|---|---|---|---|
| page | integer | optional | Page number. Default: 1. |
| limit | integer | optional | Records per page. Default: 50. Max: 100. |
curl "https://dkgkqkkoqriebjlaufcx.supabase.co/functions/v1/api/v1/crew?limit=100" \ -H "Authorization: Bearer sk_live_..."
>{#123;
"data": [
{
"id": "crew-uuid",
"name": "Alex Rivera",
"email": "alex@acmeav.com",
"role": "Lighting Director",
"phone": "+15551234567",
"organization_id": "org-uuid",
"created_at": "2025-09-01T00:00:00Z",
"updated_at": "2026-01-10T08:00:00Z"
}
],
"meta": { "org_id": "org-uuid", "page": 1, "total": 8 }
} Get crew member
Returns a single crew member by ID.
curl "https://dkgkqkkoqriebjlaufcx.supabase.co/functions/v1/api/v1/crew/crew-uuid" \ -H "Authorization: Bearer sk_live_..."
Truck Packer Integration Guide
Truck Packer is an iOS app that uses LiDAR to scan equipment cases and produce precise exterior dimensions. With the Stagera API, those measurements push directly into your gear catalog — no CSV export, no manual data entry.
Overview
The integration works in two phases:
- Pull — Truck Packer calls
GET /v1/equipmentto load your full gear list by name. This is the catalog it shows you when matching a LiDAR scan to a gear record. - Push — After a scan, Truck Packer calls
PATCH /v1/equipment/:idwith the measured dimensions. Stagera updates immediately.
Setup (one-time)
- Create an API key. In Stagera, go to Settings → API Keys → New key. Name it
Truck Packer. Select exactly two scopes:equipment:readandequipment:write. Click Generate key and copy the key. - Paste the key into Truck Packer. In the Truck Packer app, go to Settings → Integrations → Stagera. Paste your key and tap Connect. Truck Packer will call
GET /v1/equipmentto verify the connection and load your gear list. - Confirm the connection. You should see your Stagera equipment list appear in Truck Packer. If you see an error, double-check that the key has both
equipment:readandequipment:writescopes.
Scanning workflow
- Open a case in Truck Packer. Point the LiDAR at the case and follow the scan prompts.
- Match to a gear record. Truck Packer searches your Stagera equipment list by name. Tap the correct record to match the scan.
- Review and confirm the measurements. Truck Packer shows the measured dimensions. Confirm to push — this sends a
PATCH /v1/equipment/:idwithcase_length_in,case_width_in,case_height_in, andweight_lbs. - Stagera updates instantly. The equipment record in Stagera now has the measured dimensions, visible to your whole team.
What gets written
Truck Packer writes only the following fields. All other Stagera data is untouched.
| Field written | Source |
|---|---|
| case_length_in | LiDAR measured length |
| case_width_in | LiDAR measured width |
| case_height_in | LiDAR measured height |
| weight_lbs | Scale or estimated weight (if Truck Packer supports it) |
| case_type | Selected in Truck Packer UI (road case / soft case / pelican) |
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Connection fails with 401 | Key is wrong or revoked | Regenerate the key in Stagera Settings and re-paste into Truck Packer |
| Gear list is empty | Key missing equipment:read scope | Create a new key with both equipment:read and equipment:write |
| Scan saves but Stagera doesn't update | Key missing equipment:write scope, or rate limit hit | Check key scopes; if rate-limited, wait 60 seconds and retry |
| Wrong gear matched | Name matching found similar item | Undo the scan in Truck Packer, re-match to the correct record, and re-confirm |
Scopes Reference
Every API key has a set of scopes that control which endpoints it can access. Assign the minimum scopes needed for the integration.
| Scope | Endpoints unlocked | Use when |
|---|---|---|
equipment:read | GET /v1/equipment, GET /v1/equipment/:id | Reading the gear catalog (Truck Packer pull phase, any read-only integration) |
equipment:write | PATCH /v1/equipment/:id | Updating dimensions/weight from a scan (Truck Packer push phase). Requires equipment:read to also be present. |
jobs:read | GET /v1/jobs, GET /v1/jobs/:id | Reading job/event data for external scheduling or reporting tools |
crew:read | GET /v1/crew, GET /v1/crew/:id | Reading crew roster for external scheduling or HR tools |
equipment:read AND equipment:write. equipment:write alone does not grant list access — you need equipment:read to pull the catalog and identify which record to update.
Changelog
Breaking changes will always be announced via email to API key owners before taking effect. Non-breaking additions (new fields, new endpoints) are deployed without notice.