API Overview

A versioned REST API at /api/v1/*. JSON in, JSON out. Most endpoints are gated by an API key; a small set is public.

Base URL

https://<your-host>/api/v1

Response envelope

Every endpoint returns the same shape — either data is populated and error is null, or vice versa.

// Success
{
  "data":  <payload>,
  "meta":  { "page": 1, "per_page": 20, "total": 137 },
  "error": null
}

// Failure
{
  "data":  null,
  "error": {
    "code":    "VALIDATION_FAILED",
    "message": "The given data was invalid.",
    "details": { "title": ["The title field is required."] }
  }
}

Endpoint surface

ResourcePublic?Notes
GET /v1/i18n/localesPublicActive locales for frontend switchers
GET /v1/settingsPublicSafe site config — name, logo, social, SEO defaults
POST /v1/forms/{slug}/submitPublic (throttled)5 req/min/IP
GET /v1/forms/{slug}PublicReturns the form schema
GET /v1/pingAuthHealth + echoes key name + scopes
GET /v1/upload/filesAuthList media
POST /v1/uploadAuth + writeUpload file
DELETE /v1/upload/files/{id}Auth + deleteDelete file
GET /v1/searchAuthCross-model full-text
GET /v1/{model}AuthList entries for a content model
GET /v1/{model}/{idOrSlug}AuthSingle entry by UUID or slug
POST /v1/{model}Auth + writeCreate entry
PUT /v1/{model}/{id}Auth + writeUpdate entry
DELETE /v1/{model}/{id}Auth + deleteSoft-delete entry
Route order mattersThe dynamic content routes are catch-alls and registered last. The specific routes (upload, search, i18n, forms, settings, ping) must be defined before them.

Middleware chain

Authenticated endpoints go through:

  1. api.cors — validates Origin against the key's allowlist; handles preflight.
  2. api.auth — validates the public key + secret pair, attaches request()->apiKey.
  3. api.rate — enforces the per-key requests/min limit.
  4. api.log — writes an api_request_logs row at the end.
  5. api.scope:<scope> — for write/delete-only routes.

HTTP status codes

CodeMeaning
200OK
201Created
204No content (delete)
400Malformed request
401Missing / invalid API key
403Missing required scope
404Resource or model slug not found
410Form deactivated
422Validation failed
429Rate limit exceeded — see Retry-After
500Server error

Pagination, sorting, filtering

List endpoints (entries, media, search) accept these query params:

?page=2
&per_page=20
&sort=-published_at        // dash prefix → descending
&filter[status]=published
&filter[locale]=en
&filter[data.tags]=launch
&include=author,hero_image
&fields=title,slug,excerpt,published_at

Quickstart

curl -s https://your-host/api/v1/ping \
  -H "X-API-Key: pk_live_abc123…" \
  -H "X-API-Secret: sk_live_xyz789…" | jq

# {
#   "data": { "message": "pong", "key_name": "Website Production", "scopes": ["read"] },
#   "error": null
# }