Dyrected
Deliver ContentContent REST API

Overview

Endpoint behavior, authentication, filtering, errors, OpenAPI access, and client code generation.

Dyrected derives a REST API from the collections and globals in your dyrected.config.ts. Every collection gets list, read, create, update, and delete routes; every global gets read and update routes; and features such as auth, uploads, and workflows add their own routes when enabled.

Most JavaScript and TypeScript apps should use the SDK instead of calling REST directly. Reach for REST when you need a language the SDK does not cover, or when you are integrating from another system.

Base URL

Self-hosted routes live beneath your application origin:

https://example.com/api

The SDK is configured with the origin before /api, because SDK methods add /api themselves.

Authentication

Depending on your access rules, requests carry a site API key, a user JWT, and — in Cloud mode — a site identifier.

CredentialHeaderTypical use
Site API keyx-api-keyTrusted server-to-server access
User JWTAuthorization: Bearer …User-scoped and admin operations
Site IDx-site-idCloud tenant selection

An endpoint is public only when its access rule allows the operation.

Listing and filtering

Collection list routes accept limit (default 10, maximum 100), page, sort, depth, optional free-text search, and a JSON-encoded where object.

const query = new URLSearchParams({
  limit: '10',
  search: 'hello',
  sort: '-createdAt',
  depth: '1',
  where: JSON.stringify({ status: { equals: 'published' } }),
})

const response = await fetch(`/api/collections/posts?${query}`)

search runs on the backend against the collection's configured searchable fields, then combines with where using AND. That keeps free-text search aligned with access control, pagination, and any structured filters you already apply.

Operators include equals, not_equals, contains, starts_with, in, not_in, gt, gte, lt, lte, and exists. List responses use a shared pagination envelope with docs, total, limit, page, totalPages, hasNextPage, and hasPrevPage. Note that the limit parameter is capped at 100 for list operations to ensure performance and reliability.

Collection aggregations

Compute statistical totals, averages, counts, minimums, and maximums across a collection in a single request without loading documents:

POST /api/collections/:slug/aggregate

Send a JSON object where each key maps to an aggregation operation:

curl -X POST https://example.com/api/collections/orders/aggregate \
  -H "Content-Type: application/json" \
  -H "x-api-key: your-api-key" \
  -d '{
    "totalOrders": { "count": "*" },
    "totalRevenue": { "sum": "totalAmount" },
    "avgPaid": { "avg": "totalAmount", "where": { "status": { "equals": "paid" } } }
  }'

Aggregations enforce collection access.read gates and inject any row-level tenant constraints automatically. For detailed syntax and type casting, see Aggregating Statistics.

Error responses

Use HTTP status codes as the primary error category: invalid input (400), missing credentials (401), denied access (403), missing resources (404), conflicts (409), oversized uploads (413), and unexpected failures (500). Do not blindly retry validation or authorization failures.

OpenAPI schema access

Every Dyrected project generates an OpenAPI document from its current content model:

GET /api/openapi.json

Use the runtime document for client generation and validation, because it contains your actual collection slugs, fields, globals, uploads, and workflow routes. An interactive UI is available at GET /api/docs.

The documentation site also publishes a representative OpenAPI document built from a maximal fixture. It is useful for tooling tests and route discovery, but it is not your project's schema.

Generating a client

Point any OpenAPI code generator at your runtime document to produce a typed client in the language of your choice:

npx openapi-typescript https://example.com/api/openapi.json -o ./dyrected-api.d.ts

Regenerate whenever the content contract changes. Do not treat an old downloaded specification as permanently compatible. For JavaScript and TypeScript, the SDK already gives you a typed client with no code generation step.

Generated endpoint inventory

The table below is generated from a representative maximal configuration so it can cover every route family. Your project exposes the subset of these routes that your own collections, globals, and features produce.

MethodPathSummaryAuthentication
GET/api/auditGet audit entries across all readable audited collectionsRequired
GET/api/collections/guest-responsesFind Guest ResponsesRequired
POST/api/collections/guest-responsesCreate Guest responseRequired
DELETE/api/collections/guest-responses/{id}Delete Guest responseRequired
GET/api/collections/guest-responses/{id}Get a single Guest responseRequired
PATCH/api/collections/guest-responses/{id}Update Guest responseRequired
POST/api/collections/guest-responses/aggregateAggregate Guest ResponsesRequired
DELETE/api/collections/guest-responses/delete-manyDelete multiple Guest ResponsesRequired
GET/api/collections/mediaFind MediaRequired
POST/api/collections/mediaCreate Media itemRequired
DELETE/api/collections/media/{id}Delete Media itemRequired
GET/api/collections/media/{id}Get a single Media itemRequired
PATCH/api/collections/media/{id}Update Media itemRequired
POST/api/collections/media/aggregateAggregate MediaRequired
DELETE/api/collections/media/delete-manyDelete multiple MediaRequired
GET/api/collections/media/mediaList MediaRequired
POST/api/collections/media/mediaUpload Media itemRequired
GET/api/collections/media/media/{filename}Serve Media item bytesPublic
GET/api/collections/postsFind PostsRequired
POST/api/collections/postsCreate PostRequired
GET/api/collections/posts/__auditGet Post audit entriesRequired
DELETE/api/collections/posts/{id}Delete PostRequired
GET/api/collections/posts/{id}Get a single PostRequired
PATCH/api/collections/posts/{id}Update PostRequired
POST/api/collections/posts/{id}/transitions/{transition}Transition Post workflowRequired
GET/api/collections/posts/{id}/workflow-historyGet Post workflow historyRequired
POST/api/collections/posts/aggregateAggregate PostsRequired
DELETE/api/collections/posts/delete-manyDelete multiple PostsRequired
GET/api/collections/usersFind UsersRequired
POST/api/collections/usersCreate UserRequired
DELETE/api/collections/users/{id}Delete UserRequired
GET/api/collections/users/{id}Get a single UserRequired
PATCH/api/collections/users/{id}Update UserRequired
POST/api/collections/users/{id}/change-passwordChange a User passwordRequired
POST/api/collections/users/accept-inviteAccept an invitationPublic
POST/api/collections/users/aggregateAggregate UsersRequired
DELETE/api/collections/users/delete-manyDelete multiple UsersRequired
POST/api/collections/users/first-userRegister the first UserPublic
POST/api/collections/users/forgot-passwordRequest a password resetPublic
GET/api/collections/users/initGet Users initialization statePublic
POST/api/collections/users/inviteInvite a UserRequired
POST/api/collections/users/loginLog in to UsersPublic
POST/api/collections/users/logoutLog out of UsersRequired
GET/api/collections/users/meGet the current UserRequired
POST/api/collections/users/refresh-tokenRefresh an authentication tokenRequired
POST/api/collections/users/reset-passwordReset a passwordPublic
GET/api/docsOpen interactive API documentationPublic
GET/api/dyrected/options/{collection}/{field}Resolve dynamic field optionsRequired
GET/api/globals/settingsGet Site settingsRequired
PATCH/api/globals/settingsUpdate Site settingsRequired
GET/api/media/{filename}Serve a stored filePublic
GET/api/openapi.jsonGet the OpenAPI specificationPublic
GET/api/preferences/{key}Get an authenticated user preferenceRequired
PUT/api/preferences/{key}Set an authenticated user preferenceRequired
GET/api/preview-dataResolve preview data from a tokenPublic
POST/api/preview-tokenCreate a preview tokenRequired
GET/api/schemasGet the serialized Dyrected schemaPublic

On this page

Dyrected| Cloud

Get your backend ready in minutes

Use a managed database, storage, APIs, and admin dashboard without setting up the infrastructure yourself.

Set Up My Backend