Skip to content

API and auth

All dashboard behaviour is available over a plain REST API. Responses are JSON.

https://<your-api-host>

Your administrator provides it; the dashboard shows it in its runtime configuration.

  1. Exchange a registered email for a token:
Terminal window
curl -X POST "$API/api/login" \
-H 'Content-Type: application/json' \
-d '{"email":"[email protected]"}'
{ "token": "eyJhbGciOiJSUzI1NiIsImtpZCI6..." }
  1. Send it on every request:
Terminal window
curl "$API/content?type=eq.posts&limit=3" \
-H "Authorization: Bearer $TOKEN"
Claim Meaning
sub The user’s email
app_role super_admin, staff, partner, or a custom role
site_id The site this token is scoped to (* for super admins)
caps Capability array, e.g. ["content.read","content.write"]
iss / aud Issuer and intended audience — both verified
kid Key id, used to pick the signing key
exp Expiry — one hour

Tokens are signed with RS256; the private key never leaves the server. Public keys are published at /.well-known/jwks.json, so a service can verify a token without calling back home.

Query parameters follow a consistent, composable pattern:

Parameter Example Meaning
select select=id,title,status Columns to return
filter status=eq.publish eq, not.eq, ilike, gt, lt, in
order order=created_at.desc Sort
limit / offset limit=20&offset=40 Paging
Prefer: count=exact header Adds Content-Range: 0-19/383
Terminal window
# Published insights, newest first, page 2
curl "$API/content?type=eq.insights&status=eq.publish&order=created_at.desc&limit=20&offset=20" \
-H "Authorization: Bearer $TOKEN" \
-H "Prefer: count=exact"
Terminal window
# create
curl -X POST "$API/content" \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"site_id":"acme","type":"posts","slug":"hello","title":"Hello","status":"draft","body":"<p>Hi</p>"}'
# update one record
curl -X PATCH "$API/content?id=eq.<uuid>" \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"status":"publish"}'
# soft delete
curl -X PATCH "$API/content?id=eq.<uuid>" \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"status":"trash"}'
Terminal window
curl -X POST "$API/media/upload" \
-H "Authorization: Bearer $TOKEN" \
-F "file=@./hero.webp" \
-F "site_id=acme"
{ "key": "acme/2316-hero.webp", "size": 55904 }

Files are then served at <public-base>/<key>.

Code Meaning
200 / 201 / 204 Success
206 Partial content — returned with pagination
401 Missing, expired or invalid token
403 Valid token, insufficient capability or wrong site
404 No such record (or not visible to you)
  • id is a UUID; the human-facing number is content_id.
  • Trash is status=trash, not deletion. Filter with status=not.eq.trash to hide it.
  • Prefer PATCH for edits — it only touches the fields you send.
  • A 403 is usually a capability problem, a 401 almost always an expired token.