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/v1

Authentication

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

GET/tenantstenants:read

List tenants

Tenant-scoped keys see only their own tenant; platform-scoped keys see all.

POST/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"
  }'
GET/tenants/{tenantId}tenants:read

Get one tenant

Returns full tenant detail incl. brand fields, Maps CID, XHS handle, logo URL.

GET/tenants/{tenantId}/employeesemployees:read

List employees

All employees across all shops for this tenant.

POST/tenants/{tenantId}/employeesemployees:write

Create 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" }'
GET/tenants/{tenantId}/analytics?days=7|30|90analytics:read

Funnel analytics

Returns { days, summary, employees[], shops[] } over the requested window. Invalid days clamp to 30.

GET/tenants/{tenantId}/feedbackfeedback:read

List private feedback

Newest first. Each row has shop + employee labels joined in.

PATCH/tenants/{tenantId}/feedbackfeedback:write

Mark 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

CodeMeaning
200OK
201Created (POST /tenants, POST /employees)
400Validation failed — see `fieldErrors` on the body
401Missing or invalid Bearer token
403Key lacks the required permission, or tenant scope mismatch
404Resource not found in this tenant
429Rate limit exceeded (per-key hourly bucket)
500Server 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.

Need help?

Contact
Email support@orgstack.ai with your key prefix (e.g. orgstack_sk_tnt_xxxxxxxxxxxx) and a description of the request. Never send the full key.
For urgent issues (e.g. suspected key leak), revoke the key immediately at /dashboard/api-keys and create a new one.