API Reference

The definitive technical reference for the SCHMA Content Delivery REST and GraphQL APIs, edge caching, headers, and webhooks.

Core architecture concepts

Workspace (Tenant)
An isolated project environment connected to your own PostgreSQL database. Identified in API requests with the x-tenant-slug header.
Content Type
The schema definition for a content model (e.g., post, author, product). Its fields dictate the validated data shapes stored in PostgreSQL.
Entry
An individual content item adhering to a content type. Draft, review, and scheduled entries remain strictly inside Studio; published entries are served globally through the Delivery API.
Environment
An isolated PostgreSQL database schema (e.g. production by default, or staging). Selected via the x-environment header.

Authentication & request headers

Authenticate all requests by passing a Delivery API key in the Authorization header, accompanied by your workspace slug in x-tenant-slug.

Required HTTP headers
Authorization: Bearer YOUR_DELIVERY_API_KEY
x-tenant-slug: YOUR_WORKSPACE_SLUG
x-environment: production
Request headers specification
HeaderRequiredDescription
AuthorizationYesBearer token containing an active Delivery API key generated in Studio.
x-tenant-slugYesThe unique slug of your workspace (e.g. acme-corp).
x-environmentOptionalDatabase schema environment (production by default; staging on Pro and Max).

REST delivery endpoints

The REST Delivery API provides fast, read-only access to published content. All endpoints respond with JSON.

SCHMA delivery REST endpoints
EndpointDescription
GET /v1/delivery/entriesList published entries. Query parameters: type, limit, offset, locale, sortBy, order, preview.
GET /v1/delivery/entries/:idRetrieve a single published entry by its UUID or slug. Supports locale and preview.
GET /v1/delivery/entries/similarSemantic vector similarity search across entries using ?text=...&limit=5 (Pro and Max).

Example: List published entries

cURL request
curl "https://api.schma.dev/v1/delivery/entries?type=post&limit=10&offset=0" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "x-tenant-slug: YOUR_WORKSPACE_SLUG"
JSON response
{
  "entries": [
    {
      "id": "e4b27c62-1a3f-4e89-b765-92c10df48e01",
      "slug": "getting-started-with-schma",
      "dataJson": {
        "title": "Getting Started with SCHMA",
        "excerpt": "Learn how to connect your PostgreSQL database and query content.",
        "author": "team"
      },
      "locale": "en-US",
      "status": "published",
      "publishedAt": "2026-10-16T08:00:00.000Z",
      "createdAt": "2026-10-15T12:00:00.000Z",
      "updatedAt": "2026-10-16T08:00:00.000Z"
    }
  ],
  "meta": {
    "limit": 10,
    "offset": 0,
    "count": 1,
    "total": 42
  }
}

Example: Retrieve single entry

cURL request
curl "https://api.schma.dev/v1/delivery/entries/e4b27c62-1a3f-4e89-b765-92c10df48e01" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "x-tenant-slug: YOUR_WORKSPACE_SLUG"
JSON response
{
  "id": "e4b27c62-1a3f-4e89-b765-92c10df48e01",
  "slug": "getting-started-with-schma",
  "dataJson": {
    "title": "Getting Started with SCHMA",
    "content": "Full markdown or rich text body here...",
    "tags": ["cms", "postgres", "nextjs"]
  },
  "locale": "en-US",
  "status": "published",
  "publishedAt": "2026-10-16T08:00:00.000Z"
}

GraphQL delivery API

POST /v1/delivery/graphql

SCHMA automatically synthesizes a GraphQL schema from your workspace content types. Send queries as HTTP POST requests to /v1/delivery/graphql.

cURL request
curl -X POST "https://api.schma.dev/v1/delivery/graphql" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "x-tenant-slug: YOUR_WORKSPACE_SLUG" \
  -H "Content-Type: application/json" \
  -d '{"query": "query { entries(type: \"post\", limit: 5) { id slug data publishedAt } }"}'
GraphQL query
query GetBlogPosts($locale: String, $limit: Int) {
  entries(type: "post", locale: $locale, limit: $limit) {
    id
    slug
    data
    publishedAt
  }
}
JSON response
{
  "data": {
    "entries": [
      {
        "id": "e4b27c62-1a3f-4e89-b765-92c10df48e01",
        "slug": "getting-started-with-schma",
        "data": {
          "title": "Getting Started with SCHMA",
          "excerpt": "Learn how to connect your PostgreSQL database..."
        },
        "publishedAt": "2026-10-16T08:00:00.000Z"
      }
    ]
  }
}

Edge caching, rate limits & quotas

Every published GET response includes production-grade HTTP caching headers:

Response caching headers
Cache-Control: public, max-age=10, s-maxage=60, stale-while-revalidate=300
Vary: Authorization, x-environment, x-tenant-slug
ETag: W/"3a7c-4f81..."

Passing a valid ?preview=TOKEN query parameter bypasses edge caching and sets Cache-Control: private, no-store, no-cache, max-age=0 to ensure real-time preview of draft changes.

Quota and rate-limit headers

Responses include rate-limit headers to help your application stay within thresholds:

Rate limit and quota headers
HeaderDescription
X-RateLimit-LimitMaximum allowed requests per minute (60/min on Free, 300/min on Pro).
X-RateLimit-RemainingNumber of requests remaining in the current one-minute sliding window.
X-Quota-LimitTotal monthly delivery API requests included in your workspace plan.
X-Quota-RemainingRemaining monthly delivery API quota before rate limiting engages.

Outbound webhooks & signature verification

SCHMA can dispatch signed HTTP webhooks to your application whenever content or schema changes occur (supporting up to 2 active endpoints on Free and up to 5 on Pro).

Webhook events
Event NameDescription
entry.publishedTriggered when an entry is published or updated while published.
entry.archivedTriggered when an entry is unpublished or moved to archive.
schema.updatedTriggered when fields or validation rules of a content type change.
Illustrative webhook JSON payload
{
  "event": "entry.published",
  "timestamp": "2026-10-27T08:30:00.000Z",
  "tenantSlug": "acme-corp",
  "environment": "production",
  "data": {
    "id": "e4b27c62-1a3f-4e89-b765-92c10df48e01",
    "type": "post",
    "slug": "getting-started-with-schma"
  }
}

Every webhook request includes an HMAC-SHA256 signature in the x-schma-signature header (t=timestamp,v1=signature). Verify this header using your webhook signing secret before processing payloads.

Read the complete Next.js On-Demand ISR webhook guide →

Error status codes

The Delivery API uses standard HTTP response codes to communicate success and failure:

HTTP status codes
CodeReasonResolution
401 UnauthorizedMissing or malformed Authorization header.Ensure the header contains Bearer <API_KEY>.
403 ForbiddenINSUFFICIENT_API_KEY_SCOPE or revoked token.Verify the key has Delivery permissions in your Studio settings.
404 Not FoundEntry or content type does not exist.Verify the UUID or content type slug matches an active published model.
429 Too Many RequestsRate limit reached or DELIVERY_QUOTA_EXCEEDED.Respect Retry-After or upgrade your workspace quota tier.

Follow the troubleshooting guide for API 401 & 403 errors →