API Extensions

API Endpoints

Endpoints allow you to register new API routes in your Directus project.

Endpoints allow you to register new API routes in your Directus project.

This extension type is loaded into the Directus process. They can use the provided services exported by the @directus/extensions-sdk package and can be written in JavaScript or TypeScript.

Endpoint Entrypoint

The index.js or index.ts file exports a register function that is read by Directus. It contains one or more route handlers, each being a sub-route of /<extension-name>.

Entrypoint Example

export default (router, context) => {
    router.get('/', (req, res) => res.send('Hello, World!'));
};

Alternatively, you can export a configuration object to be able to customize the root route:

export default {
    id: 'greet',
    handler: (router, countext) => {
        router.get('/', (req, res) => res.send('Hello, World!'));
        router.get('/intro', (req, res) => res.send('Nice to meet you.'));
        router.get('/goodbye', (req, res) => res.send('Goodbye!'));
    },
};

The routes of this endpoint are accessible at /greet, /greet/intro and /greet/goodbye.

Register Function

The register function receives the two parameters router and context. router is an Express router instance. context is an object with the following properties:

PropertyDescription
servicesAll API internal services.
databaseKnex instance that is connected to the current database.
getSchemaAsync function that reads the full available schema for use in services.
envParsed environment variables.
loggerPino instance.
emitterEvent emitter instance that can be used to emit custom events for other extensions.

Sandboxed Endpoints

When using the sandbox, the register function receives the router object only. Each handler function receives only a request object and must return a response object.

interface SandboxEndpointRequest {
    url: string;
    headers: Record<string, string>;
    body: any;
}

interface SandboxEndpointResponse {
    status: number;
    body: string | Record<string, unknown>;
}

TypeScript

You can import the SandboxEndpointRouter type from directus:api to type the router object:

/// <reference types="@directus/extensions/api.d.ts" />
import type { SandboxEndpointRouter } from 'directus:api';

export default (router: SandboxEndpointRouter) => {
    router.get('/', () => {
        return {
      status: 200,
      body: 'Hello World'
    }
    });
};
Learn more about the Directus sandbox for API extensions.

Using Directus Internals

To access systems like permission checks and your collections, you can use internal Directus services, available through an API extension's context parameter.

Learn more about using internal Directus services.

Error Handling

To create errors in API extensions, you can utilize the @directus/errors package which is available to all extensions without installation.

import { createError } from '@directus/errors';

const ForbiddenError = createError('FORBIDDEN', "You don't have permissions to see this.", 403);

throw new ForbiddenError();