Public API
The REST API — base URL, Bearer authentication, the two key levels, scopes, and example endpoints.
Sennith has a REST API so you can drive your workspace — projects, updates, customers, webhooks and more — from your own scripts, tools, or AI agents. Everything the API can do is also available as a CLI command, because both are built from the same contract.
The API is a Pro feature. API keys can only be created on a workspace or organization that is on a paid plan. If the plan is later downgraded, existing keys stop working until you upgrade again.
Base URL
All endpoints live under /api/v1 on your Sennith instance:
https://sennith.com/api/v1Authentication
Every request carries an API key as a Bearer token:
Authorization: Bearer sennith_...Keys always start with the sennith_ prefix. You create them in the web app under Settings → API keys (workspace keys) or in your Organization settings (organization keys). The full key is shown once at creation time — copy it then, because Sennith only stores a hashed version and can never show it to you again. If you lose a key, revoke it and create a new one.
Treat keys like passwords. Anyone holding a key can act with exactly the scopes and level it was given. If a key leaks, revoke it immediately in the web app.
The two key levels
Sennith keys come in two levels, and a key only ever works at its own level — there are no all-powerful "god" keys.
| Level | What it's for | Where you create it | Availability |
|---|---|---|---|
| Workspace key | The day-to-day work inside one workspace: projects, updates, customers, triggers, webhooks, templates. | Workspace → Settings → API keys | Any paid plan |
| Organization key | Managing the organization itself: workspaces, members, roles, billing overview. | Organization settings → API keys | Team plan and up |
A workspace key is tied to exactly one workspace and can never reach organization-level endpoints. An organization key manages the org and never touches a single workspace's day-to-day data. If you send a workspace key to an org endpoint (or the reverse), the request is refused with 403 wrong_key_level.
Not sure what a key can do? Run sennith whoami (see the CLI page) or call GET /api/v1/whoami — it reports the key's level, organization, workspace, and scopes without ever revealing the token.
Scopes
Each key carries a list of scopes — fine-grained permissions of the form resource:action (e.g. projects:read, updates:write, customers:delete). A request only succeeds if the key holds the scope the endpoint requires. A key can never be granted more than its creator personally has permission to do.
Workspace-key scopes (chosen when you create a workspace key):
projects,updates,customers,customer_contacts,customer_portal_domains— read / write / deletetriggers— read / write / delete ·outgoing_webhooks— read / write / deleteupdate_templates— read / write / delete ·resource_shares— read / write / deletemembers— read / write / delete ·permissions— read / write ·routing— read / writeworkspace— read / write ·integrations— read ·settings— read / write
Organization-key scopes (Team plan and up):
org— read / write ·workspaces— read / write / deleteorg_members— read / write / delete ·org_roles— read / write / delete ·org_permissions— read / writebilling— read ·settings— read / write
A few actions stay in the web app only, even with the right scope — for example deleting a whole workspace or organization, removing the last owner, and self-service billing changes. These are deliberately kept out of the API because they're irreversible or sensitive.
Requests and responses
Send and receive JSON. Request bodies use camelCase field names.
A single resource comes back wrapped in data:
{ "data": { "id": 42, "name": "Website relaunch", "publicId": "a1b2c3", "createdAt": "2026-07-12T10:00:00Z" } }A list comes back as an array under data, with a next_cursor for pagination — pass it back as ?cursor= to get the next page; null means you've reached the end:
{ "data": [ /* … */ ], "next_cursor": 41 }Lists accept ?limit= (default 25, max 100) and ?cursor=.
Errors always have the same shape — a stable machine-readable error code plus a human message:
{ "error": "forbidden", "message": "Missing required scope" }| Status | error code | Meaning |
|---|---|---|
| 401 | unauthorized | Missing, malformed, or revoked key |
| 402 | plan_required | The plan no longer includes API access |
| 403 | wrong_key_level | Right key, wrong level (workspace vs. org) |
| 403 | forbidden | Key is missing the required scope |
| 404 | not_found | No such resource (or not in your scope) |
| 429 | rate_limited | Too many requests — slow down |
Rate limits
Each key may make up to 120 requests per minute. Beyond that you get 429 rate_limited; wait for the next minute and retry.
Example endpoints
List your projects
curl https://sennith.com/api/v1/projects \
-H "Authorization: Bearer sennith_..."Create a project
curl -X POST https://sennith.com/api/v1/projects \
-H "Authorization: Bearer sennith_..." \
-H "Content-Type: application/json" \
-d '{ "name": "Website relaunch" }'Post an update to a project
Updates are the thing your customers actually receive. Posting one through the API triggers the same email fan-out and outgoing-webhook delivery as posting it in the web app.
curl -X POST https://sennith.com/api/v1/projects/42/updates \
-H "Authorization: Bearer sennith_..." \
-H "Content-Type: application/json" \
-d '{ "title": "Staging is live", "message": "Preview it at the link below.", "isImportant": true }'Check what your key can do
curl https://sennith.com/api/v1/whoami \
-H "Authorization: Bearer sennith_..."{ "data": { "level": "workspace", "orgId": 7, "workspaceId": 12, "scopes": ["projects:read", "projects:write", "updates:write"] } }Other resources follow the same pattern: GET /api/v1/<resource> to list, GET /api/v1/<resource>/<id> to fetch one, POST to create, PATCH to update, DELETE to remove — whenever the key holds the matching scope. Available resources include customers, updates, triggers, outgoing_webhooks, update_templates, members, and (with an organization key) workspaces, org_members, org_roles, and billing.