Dyrected
API Reference

SDK Reference

Using the @dyrected/sdk client in any JavaScript or TypeScript project.

@dyrected/sdk is a framework-agnostic TypeScript client for the Dyrected REST API. It works in Next.js, Nuxt, SvelteKit, plain Node.js, and browser environments.


Installation

pnpm add @dyrected/sdk
# or
npm install @dyrected/sdk

Creating a Client

import { createClient } from '@dyrected/sdk'

const client = createClient({
  baseUrl: 'https://your-site.com/api',  // Your Dyrected API base URL
  apiKey: process.env.DYRECTED_API_KEY,  // Site API Key
  siteId: process.env.DYRECTED_SITE_ID,  // Required in Cloud mode
})

Options

OptionTypeRequiredDescription
baseUrlstringBase URL of your Dyrected instance
apiKeystringSite API Key. Sent as x-api-key header.
siteIdstringSite ID. Sent as x-site-id header. Required in Cloud mode.
defaultDepthnumberDefault relationship population depth (default: 1)
fetchtypeof fetchCustom fetch implementation (e.g., for Node 18 polyfills)

Collection Methods

All collection methods are accessed via client.collection(slug).

.find(options?)

Returns a paginated list of documents.

const result = await client.collection('posts').find({
  limit: 10,
  page: 1,
  sort: '-createdAt',
  depth: 1,
  where: {
    status: { equals: 'published' },
  },
})

// result.docs: Post[]
// result.total: number
// result.totalPages: number
// result.hasNextPage: boolean

Where Operators

where: {
  title: { like: 'typescript' },         // case-insensitive contains
  price: { greater_than: 100, less_than: 500 },
  status: { in: ['draft', 'published'] },
  publishedAt: { exists: true },
  or: [
    { status: { equals: 'published' } },
    { featured: { equals: true } },
  ],
}

.findOne(id, options?)

Fetch a single document by ID.

const post = await client.collection('posts').findOne('abc123', { depth: 2 })

.create(data)

Create a new document.

const post = await client.collection('posts').create({
  title: 'My New Post',
  status: 'draft',
})

.update(id, data)

Partially update a document. Only the fields you pass are changed.

const updated = await client.collection('posts').update('abc123', {
  status: 'published',
  publishedAt: new Date().toISOString(),
})

.delete(id)

Delete a document by ID.

await client.collection('posts').delete('abc123')

.upload(file, data?)

Upload a file to an upload collection. Accepts a File or Blob (browser).

// Browser — File from <input type="file">
const mediaDoc = await client.collection('media').upload(file, {
  alt: 'A mountain landscape',
})

// Blob from fetch or canvas
const blob = await fetch('/some-image.jpg').then(r => r.blob())
const mediaDoc = await client.collection('media').upload(blob, {
  alt: 'Fetched image',
})

Global Methods

Access globals via client.global(slug).

.get(options?)

const settings = await client.global('site-settings').get({ depth: 1 })

.update(data)

await client.global('site-settings').update({
  maintenanceMode: true,
})

Authentication

Authentication is performed on auth-enabled collections.

.login(email, password)

const { token, user } = await client.collection('users').login('[email protected]', 'password')

// Attach token to the client for subsequent requests
client.setToken(token)

.logout()

await client.collection('users').logout()
client.clearToken()

.me()

Returns the currently authenticated user document.

const user = await client.collection('users').me()

.refreshToken()

const { token } = await client.collection('users').refreshToken()
client.setToken(token)

.invite(email)

Send an invitation to an email address (requires an authenticated token set via setToken).

await client.collection('users').invite('[email protected]')

.acceptInvite(token, password, extraFields?)

Create an account from an invite token. Returns { token, user } — the user is logged in immediately.

const { token, user } = await client.collection('users').acceptInvite(inviteToken, 'my-password', {
  name: 'Jane Doe',
})
client.setToken(token)

.setToken(token) / .clearToken()

Manually manage the authentication header.

client.setToken(token)
client.clearToken()

Schema Methods

.getSchemas()

Returns the full schema definition for all collections and globals.

const schemas = await client.getSchemas()
// schemas.collections: CollectionSchema[]
// schemas.globals: GlobalSchema[]

TypeScript Generics

The SDK is fully typed. Pass your document type as a generic for type-safe responses:

interface Post {
  id: string
  title: string
  status: 'draft' | 'published'
  author: string | Author  // string at depth=0, Author at depth>=1
  createdAt: string
}

const result = await client.collection<Post>('posts').find({ depth: 1 })
// result.docs is Post[]

Error Handling

The SDK throws a DyrectedError on non-2xx responses.

import { DyrectedError } from '@dyrected/sdk'

try {
  const post = await client.collection('posts').findOne('invalid-id')
} catch (err) {
  if (err instanceof DyrectedError) {
    console.log(err.statusCode) // 404
    console.log(err.message)
    console.log(err.errors)     // validation error array (on 400)
  }
}

Next.js Usage

// app/blog/[slug]/page.tsx
import { createClient } from '@dyrected/sdk'

const client = createClient({
  baseUrl: process.env.DYRECTED_URL!,
  apiKey: process.env.DYRECTED_API_KEY!,
})

export default async function BlogPost({ params }: { params: { slug: string } }) {
  const { docs } = await client.collection('posts').find({
    where: { slug: { equals: params.slug } },
    depth: 1,
  })
  const post = docs[0]
  if (!post) notFound()

  return <article>{post.title}</article>
}

Nuxt Usage

See useDyrected composable — the Nuxt module wraps this SDK with SSR-aware caching via useAsyncData.

On this page