REST API
The surface the dashboard itself runs on. Two credentials, deliberately kept apart: a session cookie says who you are, an org token says which workspace a request may touch.
Authentication
Signing in sets an HttpOnly session cookie. That cookie is not sufficient to read workspace data — you exchange it for a workspace-scoped bearer token, and the exchange is where membership is checked.
# 1. sign in — sets the session cookie
curl -c jar.txt -X POST https://api.zealoop.com/api/auth/login \
-H 'content-type: application/json' \
-d '{"email":"you@company.com","password":"…"}'
# 2. see which workspaces this account can open
curl -b jar.txt https://api.zealoop.com/api/auth/me
# 3. trade the session for a workspace token
curl -b jar.txt -X POST https://api.zealoop.com/api/auth/token \
-H 'content-type: application/json' \
-d '{"orgId":"org_…"}'
# 4. use it
curl -H "Authorization: Bearer <token>" \
https://api.zealoop.com/api/org/org_…/settingsResponses
Every response is JSON with a success boolean. Successful reads carry data, and lists add total. Failures carry error with a message written for a human.
{ "success": true, "data": { … }, "total": 353 }
{ "success": false, "error": "You don't have access to that workspace" }Session
| Method & path | Purpose | Auth |
|---|---|---|
GET /api/auth/config | Which sign-in methods this server offers | none |
POST /api/auth/signup | Create an account, sets the session cookie | none |
POST /api/auth/login | Sign in, sets the session cookie | none |
POST /api/auth/logout | Clear the session cookie | none |
GET /api/auth/me | The signed-in account and its workspaces | cookie |
PATCH /api/auth/me | Update the account display name | cookie |
POST /api/auth/token | Exchange the session for a workspace token | cookie |
GET /api/auth/orgs | Workspaces this account holds a seat in | cookie |
POST /api/auth/orgs | Create a workspace and its owner seat | cookie |
POST /api/auth/forgot-password | Begin a password reset | none |
POST /api/auth/reset-password | Complete a reset and sign in | none |
Google and GitHub sign-in are a browser redirect, not a fetch: send the visitor to /auth/google or /auth/github, and the callback sets the session cookie and returns them to the dashboard.
Workspace
| Method & path | Purpose | Auth |
|---|---|---|
GET /api/org/:orgId/settings | Name, agent config, escalation, widget, plan | bearer |
PATCH /api/org/:orgId/settings | Update any of the above | bearer |
POST /api/org/:orgId/widget-secret/reveal | Show the widget secret once | bearer |
POST /api/org/:orgId/widget-secret/rotate | Issue a new widget secret | bearer |
GET /api/org/:orgId/onboarding | Get Started checklist, derived from real data | bearer |
GET /api/org/:orgId/me | The caller's seat in this workspace | bearer |
GET /api/org/:orgId/members | Seats in this workspace | bearer |
POST /api/org/:orgId/members | Invite a seat | bearer |
DELETE /api/org/:orgId/members/:memberId | Remove a seat | bearer |
Knowledge
| Method & path | Purpose | Auth |
|---|---|---|
GET /api/knowledge/:orgId/sources | List sources with status and chunk counts | bearer |
POST /api/knowledge/:orgId/sources | Add a URL, sitemap, file or snippet | bearer |
POST /api/knowledge/:orgId/sources/:sourceId/resync | Re-crawl and re-embed | bearer |
DELETE /api/knowledge/:orgId/sources/:sourceId | Delete a source and its chunks | bearer |
GET /api/knowledge/:orgId/chunks | Inspect chunks for one source | bearer |
Tables
| Method & path | Purpose | Auth |
|---|---|---|
GET /api/org/:orgId/tables | List tables with row counts | bearer |
POST /api/org/:orgId/tables | Create a table and its columns | bearer |
PATCH /api/org/:orgId/tables/:tableId | Rename or re-describe | bearer |
DELETE /api/org/:orgId/tables/:tableId | Delete a table and its rows | bearer |
GET /api/org/:orgId/tables/:tableId/rows | List or search rows | bearer |
POST /api/org/:orgId/tables/:tableId/rows | Add one row | bearer |
PATCH /api/org/:orgId/tables/:tableId/rows/:rowId | Edit one row | bearer |
DELETE /api/org/:orgId/tables/:tableId/rows/:rowId | Delete one row | bearer |
POST /api/org/:orgId/tables/:tableId/import | CSV upsert on the identity key | bearer |
Row writes return 409 when the identity value already exists — see Tables for why a duplicate is refused rather than resolved.
Actions
| Method & path | Purpose | Auth |
|---|---|---|
GET /api/org/:orgId/actions | List actions with test status | bearer |
POST /api/org/:orgId/actions | Create an action | bearer |
PATCH /api/org/:orgId/actions/:actionId | Update, enable or disable | bearer |
DELETE /api/org/:orgId/actions/:actionId | Delete an action | bearer |
POST /api/org/:orgId/actions/:actionId/test | Run a test call with sample arguments | bearer |
Conversations & customers
| Method & path | Purpose | Auth |
|---|---|---|
GET /api/org/:orgId/conversations | Filter by status, search, paginate | bearer |
GET /api/org/:orgId/conversations/:id | Messages, traces and the customer | bearer |
POST /api/org/:orgId/conversations/:id/reply | Reply as a human | bearer |
PATCH /api/org/:orgId/conversations/:id | Set the conversation status | bearer |
GET /api/org/:orgId/users | End users seen by the widget | bearer |
GET /api/org/:orgId/users/:endUserId | One customer with their history | bearer |
Analytics
| Method & path | Purpose | Auth |
|---|---|---|
GET /api/analytics/:orgId/overview | Resolution rate, cost, tokens, outcomes, daily series | bearer |
GET /api/analytics/:orgId/content-gaps | Clustered low-confidence queries | bearer |
Widget
The public surface the browser widget talks to, under /api/widget. It authenticates with your workspace public key rather than a bearer token, and identity is established with the signed payload described in Identity & signing.
Errors
| Status | When |
|---|---|
400 | The request is missing a field or a value failed validation. |
401 | No session, or no workspace token. Sign in, or mint a token. |
403 | Signed in, but not a member of that workspace — or the token is for a different one. |
404 | The workspace or resource does not exist. |
409 | A uniqueness rule was violated — a duplicate identity value, or an already-invited seat. |
500 | Logged with the failing request; the response never leaks internals. |
Conventions
- Every public id carries a type prefix —
org_,acc_,conv_,tbl_,act_— so an id in a log is self-describing. - Secrets are encrypted at rest and never returned by a read endpoint; reads show a masked value.
- List endpoints accept
pageandlimitand returntotal, so a client can always tell how much it has not fetched.