Overview
The typed SDK is the fastest way to read and write Dyrected content from JavaScript and TypeScript.
The Dyrected SDK (@dyrected/sdk) is a small typed client for talking to your Dyrected API. It gives you fully typed collection and global access, query building, uploads, and workflow transitions without hand-writing fetch calls.
If you are working in JavaScript or TypeScript, reach for the SDK first. Drop down to the REST API only when you need a language the SDK does not cover.
Creating a client
Create one client and reuse it. Point it at the origin of your Dyrected app — the SDK adds the /api prefix itself.
There are two normal ways to type that client:
- use
InferSchemawhen the app can import exported collection and global constants directly fromdyrected.config.ts - use generated
DyrectedSchemawhen the app should read fromdyrected-types.tsinstead of importing schema code
If you already generated dyrected-types.ts, you do not need to infer the schema again by hand. Use DyrectedSchema directly:
import { createClient } from "@dyrected/sdk";
import type { DyrectedSchema } from "./dyrected-types";
const client = createClient<DyrectedSchema>({
baseUrl: "https://example.com",
apiKey: process.env.DYRECTED_API_KEY,
});
const { docs: posts } = await client.collection("posts").find({
where: { status: { equals: "published" } },
sort: "-createdAt",
depth: 1,
});Because the client is generic over your schema, find, create, and update return typed documents and reject unknown fields at compile time.
If your app and schema live in the same codebase and you prefer not to generate a file, the TypeScript docs show the InferSchema path in TypeScript Overview and InferSchema.
What you can do
- Read and write collections through
client.collection('slug'). - Read and update singletons through
client.global('slug'). - Shape reads with sort, filter, depth, pagination, and free-text
search. - Compute fast statistics and counts with aggregate.
- Upload files and run workflow transitions on documents that support them.
For example, collection search is now first-class in the SDK:
const { docs } = await client.collection("posts").find({
search: "grace hopper",
where: { status: { equals: "published" } },
})Use search when you want the collection's configured backend search behavior. The server merges it with your where clause using AND, so free-text search and structured filters work together.
Handling errors
SDK calls throw a typed DyrectedError when the API returns a non-success status, so you can branch on status codes and surface server validation messages safely.
Generated reference
The contracts below are generated from the public @dyrected/sdk exports by @dyrected/knowledge, so the client, factory, options, and error types stay in sync with the package. Query-shaping details live on the sort, filter, depth, and pagination pages.
AuditEntry
A single audit entry returned by client.audit() or client.collection(slug).audit().
export interface AuditEntry {
id: string;
collection: string;
documentId: string | null;
operation: string;
user: string | null;
timestamp: string;
changes?: string | Record<string, unknown> | null;
}| Option | Description |
|---|---|
id (required) | |
collection (required) | |
documentId (required) | |
operation (required) | |
user (required) | |
timestamp (required) | |
changes (optional) |
BaseSchema
Exported interface from @dyrected/sdk.
export interface BaseSchema {
collections: Record<string, UnknownRecord>;
globals: Record<string, UnknownRecord>;
}| Option | Description |
|---|---|
collections (required) | |
globals (required) |
createClient
Exported function from @dyrected/sdk.
export function createClient<TSchema extends SchemaShape = RegisteredSchema>(
config: DyrectedClientConfig,
): DyrectedClient<TSchema>DyrectedClient
Exported class from @dyrected/sdk.
export class DyrectedClient<TSchema extends SchemaShape = RegisteredSchema> {
}| Option | Description |
|---|---|
setToken (required) | Update the Authorization header with a Bearer token. Call this after a successful login. |
clearToken (required) | Remove the Authorization header. Call this after logout. |
getAuthHeaders (required) | Returns the headers needed to authenticate raw `fetch()` calls made outside the SDK client (e.g. streaming endpoints, dynamic options). Includes the Authorization bearer token (if set), x-api-key, and x-site-id. |
getBaseUrl (required) | |
getSchemas (required) | |
getAdminAuthConfig (required) | |
exchangeAdminAuth (required) | |
getPreference (optional) | |
setPreference (optional) | |
deletePreference (optional) | |
getPreviewData (required) | Fetch draft data for a specific preview token. Used in "token" preview mode. |
createPreviewToken (optional) | Mint a short-lived preview token that carries the current (unsaved) draft data. Used by the Admin in `previewMode: "token"` to hand draft content to a server-rendered frontend that cannot receive it over `postMessage`. Requires an authenticated request (the Admin is logged in). |
find (required) | |
collection (required) | Returns a fluent query builder for a collection. |
global (required) | Access a global by its slug with a fluent builder. |
findOne (optional) | |
create (required) | |
update (required) | |
delete (required) | |
transition (required) | Perform a workflow transition on a document. Sends `POST /api/collections/:collection/:id/transitions/:transition`. Requires the client to have a valid bearer token set via `setToken()`. |
workflowHistory (optional) | Fetch the workflow history for a document. Sends `GET /api/collections/:collection/:id/workflow-history`. |
audit (required) | Fetch audit entries across every audited collection the current caller can read. Sends `GET /api/audit`. |
collectionAudit (required) | Fetch audit entries for a single collection. Sends `GET /api/collections/:collection/__audit`. |
deleteMany (required) | |
getGlobal (optional) | |
updateGlobal (required) | |
listMedia (required) | |
uploadMedia (required) | |
deleteMedia (required) |
DyrectedClientConfig
Exported interface from @dyrected/sdk.
export interface DyrectedClientConfig {
baseUrl: string;
apiKey?: string;
siteId?: string;
headers?: Record<string, string>;
fetch?: typeof fetch;
/**
* Default relationship population depth applied to document reads
* (`find`, `findOne`, `global().get()`, and media listing) when a call
* does not pass its own `depth`. Defaults to `1`.
*/
defaultDepth?: number;
}| Option | Description |
|---|---|
baseUrl (required) | |
apiKey (optional) | |
siteId (optional) | |
headers (optional) | |
fetch (optional) | |
defaultDepth (optional) | Default relationship population depth applied to document reads (`find`, `findOne`, `global().get()`, and media listing) when a call does not pass its own `depth`. Defaults to `1`. |
DyrectedError
Structured error thrown by the SDK when the server returns a non-2xx response.
export class DyrectedError extends Error {
}| Option | Description |
|---|---|
statusCode (required) | |
errors (optional) |
getPreviewToken
Extract the preview token from a request's query string. Accepts a raw query
string, a URLSearchParams, or a plain params object (e.g. Nuxt's
route.query or Next's searchParams). Returns null when absent.
export function getPreviewToken(
search: string | URLSearchParams | Record<string, unknown> | undefined | null,
): string | nullInferSchema
Derives a typed TSchema from your exported collection and global config constants.
Pass it to createClient<Schema>() so every find, findOne, create,
update, global().get() call returns the inferred document shape — no
manual interfaces required.
export type InferSchema<
TCollections extends Record<string, CollectionConfig<UnknownRecord>>,
TGlobals extends Record<string, GlobalConfig<UnknownRecord>> = Record<
never,
never
>,
> = {
collections: { [K in keyof TCollections]: ExtractDoc<TCollections[K]> };
globals: { [K in keyof TGlobals]: ExtractDoc<TGlobals[K]> };
};PREVIEW_TOKEN_PARAM
The query-string parameter the Admin appends to a preview URL in
previewMode: "token". Read it on your frontend to decide whether to fetch
draft data instead of published content.
export const PREVIEW_TOKEN_PARAM = "dyPreview";Register
Exported interface from @dyrected/sdk.
export interface Register {}RegisteredSchema
Exported type from @dyrected/sdk.
export type RegisteredSchema = Register extends { schema: infer S }
? S extends SchemaShape
? S
: BaseSchema
: BaseSchema;RunActionArgs
Arguments accepted by client.collection(slug).runAction().
export interface RunActionArgs {
/** Target a single document (row action). */
id?: string;
/** Target multiple documents (bulk action). */
ids?: string[];
/** Values collected from the action's input form dialog. */
input?: Record<string, unknown>;
}| Option | Description |
|---|---|
id (optional) | Target a single document (row action). |
ids (optional) | Target multiple documents (bulk action). |
input (optional) | Values collected from the action's input form dialog. |
SchemaShape
Exported interface from @dyrected/sdk.
export interface SchemaShape {
collections: Record<string, object>;
globals: Record<string, object>;
}| Option | Description |
|---|---|
collections (required) | |
globals (required) |
TransitionOptions
Options accepted by client.transition().
export interface TransitionOptions {
/**
* The revision number currently shown to the user. When provided, the server
* rejects the transition if the document has changed since it was loaded,
* preventing lost-update races.
*/
expectedRevision?: number;
/** Required for transitions that have `requireComment: true` (e.g. `reject`). */
comment?: string;
}| Option | Description |
|---|---|
expectedRevision (optional) | The revision number currently shown to the user. When provided, the server rejects the transition if the document has changed since it was loaded, preventing lost-update races. |
comment (optional) | Required for transitions that have `requireComment: true` (e.g. `reject`). |
UploadOptions
Options for file uploads.
When onProgress is provided and the runtime supports XMLHttpRequest (browsers),
the upload reports real byte-level progress. In other environments (SSR, custom
fetch) the callback is ignored and the standard fetch path is used.
export interface UploadOptions {
/** Called with an integer 0–100 as the file bytes are sent. */
onProgress?: (percent: number) => void;
/** Abort the in-flight upload. */
signal?: AbortSignal;
}| Option | Description |
|---|---|
onProgress (optional) | Called with an integer 0–100 as the file bytes are sent. |
signal (optional) | Abort the in-flight upload. |
WorkflowDocument
Shape of a document returned from a workflow-enabled collection.
export interface WorkflowDocument {
id: string;
_workflow: WorkflowMetadata;
[key: string]: unknown;
}| Option | Description |
|---|---|
id (required) | |
_workflow (required) |
WorkflowHistoryEntry
A single workflow history entry returned by client.workflowHistory().
export interface WorkflowHistoryEntry {
id: string;
collection: string;
documentId: string;
transition: string;
from: string;
to: string;
revision: number;
comment: string | null;
actorId: string | null;
createdAt: string;
}| Option | Description |
|---|---|
id (required) | |
collection (required) | |
documentId (required) | |
transition (required) | |
from (required) | |
to (required) | |
revision (required) | |
comment (required) | |
actorId (required) | |
createdAt (required) |