REST · v1
orgstack API
A Bearer-authed REST API for tenant provisioning, employees, analytics, and feedback. Designed to be consumable by AI agents via /.well-known/agent.json discovery.
Base URL
https://reviews.orgstack.ai/api/v1Authentication
Every request needs a Bearer token. There are two scopes:
- Tenant keys (
orgstack_sk_tnt_*) — scoped to a single tenant. Read/write under your own tenant. Get one at /dashboard/api-keys. - Platform keys (
orgstack_sk_plat_*) — superadmin only. Can list and provision tenants. Get one at /super/api-keys.
Pass the key on every request:
Authorization: Bearer orgstack_sk_tnt_abc123...Keys are shown once at creation and stored as a SHA-256 hash. If you lose a key, revoke it and create a new one — we cannot recover the original value.
Quick start
Read your own tenant:
curl https://reviews.orgstack.ai/api/v1/tenants \
-H "Authorization: Bearer $ORGSTACK_API_KEY"JavaScript:
const res = await fetch(
"https://reviews.orgstack.ai/api/v1/tenants",
{ headers: { authorization: `Bearer ${process.env.ORGSTACK_API_KEY}` } },
);
const { tenants } = await res.json();Python:
import os, requests
r = requests.get(
"https://reviews.orgstack.ai/api/v1/tenants",
headers={"Authorization": f"Bearer {os.environ['ORGSTACK_API_KEY']}"},
timeout=10,
)
r.raise_for_status()
tenants = r.json()["tenants"]Endpoints
/tenantstenants:readList tenants
Tenant-scoped keys see only their own tenant; platform-scoped keys see all.
/tenantstenants:write (platform only)Provision a new tenant
Atomically creates the tenant, default shop, login user, vertical templates, and Trial billing.
curl -X POST .../api/v1/tenants \
-H "Authorization: Bearer orgstack_sk_plat_..." \
-H "content-type: application/json" \
-d '{
"name": "Sin Ming Auto",
"vertical": "auto",
"mapsUrl": "https://maps.app.goo.gl/abc123",
"websiteUrl": "https://sinmingauto.com"
}'/tenants/{tenantId}tenants:readGet one tenant
Returns full tenant detail incl. brand fields, Maps CID, XHS handle, logo URL.
/tenants/{tenantId}/employeesemployees:readList employees
All employees across all shops for this tenant.
/tenants/{tenantId}/employeesemployees:writeCreate an employee
Body: { shopId, name }. Shop must belong to this tenant.
curl -X POST .../tenants/$TID/employees \
-H "Authorization: Bearer $KEY" \
-H "content-type: application/json" \
-d '{ "shopId": "uuid", "name": "Alice" }'/tenants/{tenantId}/analytics?days=7|30|90analytics:readFunnel analytics
Returns { days, summary, employees[], shops[] } over the requested window. Invalid days clamp to 30.
/tenants/{tenantId}/feedbackfeedback:readList private feedback
Newest first. Each row has shop + employee labels joined in.
/tenants/{tenantId}/feedbackfeedback:writeMark feedback resolved
Body: { sessionId, resolved }. Cross-tenant sessions return 404 (same shape as not-found, no probing).
curl -X PATCH .../tenants/$TID/feedback \
-H "Authorization: Bearer $KEY" \
-H "content-type: application/json" \
-d '{ "sessionId": "uuid", "resolved": true }'Permissions
Each key carries an array of permission strings. The full set:
- tenants:read
- tenants:write
- shops:read
- shops:write
- employees:read
- employees:write
- templates:read
- templates:write
- analytics:read
- feedback:read
- feedback:write
Default tenant keys carry all 10 tenant-scope permissions (no tenants:write). Default platform keys carry all 11.
Status codes
| Code | Meaning |
|---|---|
| 200 | OK |
| 201 | Created (POST /tenants, POST /employees) |
| 400 | Validation failed — see `fieldErrors` on the body |
| 401 | Missing or invalid Bearer token |
| 403 | Key lacks the required permission, or tenant scope mismatch |
| 404 | Resource not found in this tenant |
| 429 | Rate limit exceeded (per-key hourly bucket) |
| 500 | Server error — please retry with backoff |
Rate limits
Each key has an hourly bucket configured at create time (default: 1000/hr tenant, 5000/hr platform). When you exceed it you get a 429 until the next top-of-hour. Audit log records every request, so we can review actual usage if you need a higher cap — open an issue.
For AI agents
We expose two discovery surfaces so a foreign agent (Claude CLI, OpenAI CLI, custom GPT, ChatGPT app) can wire itself up without human glue:
- /.well-known/agent.json — short manifest with endpoint URLs, auth format, and capability list.
- /api/v1/openapi — full OpenAPI 3.1 spec with examples. Drop it into Stainless, Swagger UI, openapi-generator, or your agent's planner.
MCP server is on the roadmap (Phase B). Held until the Anthropic SDK and broader MCP ecosystem have a clean security record after the April 2026 SDK CVE.