Connect a Strapi app
Add the @apitraffic/strapi plugin to a Strapi 5 app: install, register the middleware, configure credentials, verify and troubleshoot.
The ApiTraffic plugin for Strapi captures every request your Strapi app serves and the calls Strapi makes to other APIs. It is built on the Koa adapter, since Strapi runs on Koa, and is configured through environment variables.
Before you begin
- Strapi 5, on Node.js 20 or later.
- An ingest token and a bucket ID. The setup page in ApiTraffic creates the token for you if you are an owner or admin; see API tokens.
- Outbound HTTPS from your servers to
ingest.apitraffic.ioandapi.apitraffic.io.
Set up the plugin
Install the plugin
npm install @apitraffic/strapi
pnpm add @apitraffic/strapi
yarn add @apitraffic/strapi
bun add @apitraffic/strapi
Add the middleware
Add plugin::apitraffic.apitraffic to the array in config/middlewares.js. Leave the middlewares Strapi ships with in place and add it after them:
module.exports = [
'strapi::logger',
'strapi::errors',
'strapi::security',
'strapi::cors',
'strapi::poweredBy',
'strapi::query',
'strapi::body',
'strapi::session',
'strapi::favicon',
'strapi::public',
'plugin::apitraffic.apitraffic'
];
Installing the plugin is not enough on its own: without this entry, nothing is captured.
Set your credentials
Add your token and bucket ID to Strapi’s .env file, or set them wherever you set your other environment variables. Strapi loads .env itself.
API_TRAFFIC_TOKEN=your-ingest-token
API_TRAFFIC_BUCKET=your-bucket-id
Restart Strapi and make a request
Restart Strapi so it reads the variables, then call any endpoint, for example GET /api/articles. The setup page in ApiTraffic shows SDK connected - waiting for a request once the plugin connects and Traffic is flowing when the request arrives.
Configure the plugin
The plugin reads API_TRAFFIC_TOKEN and API_TRAFFIC_BUCKET by default. Every other API_TRAFFIC_* variable from SDK configuration applies as well, for example API_TRAFFIC_DEBUG=true or API_TRAFFIC_INTERCEPT_OUTBOUND=false.
To set options in code instead, add them to the plugin’s configuration in config/plugins.js. Any option from the SDK configuration reference can go here:
module.exports = ({ env }) => ({
apitraffic: {
config: {
token: env('API_TRAFFIC_TOKEN'),
bucket: env('API_TRAFFIC_BUCKET'),
debug: env.bool('API_TRAFFIC_DEBUG', false)
}
}
});
If the token or bucket is missing, Strapi logs [apitraffic] token (API_TRAFFIC_TOKEN) … not set; request capture is disabled. at startup and the middleware passes requests through untouched. It never stops Strapi from starting or serving.
What is captured
- Every request that reaches the middleware, including ones whose controller throws (reported with the status Strapi’s error handling sends) and ones the client abandons (reported as
499). - The request body as Strapi parsed it, and the response body as your controller set it - not a compressed form of it. Streamed responses such as file downloads are recorded as a placeholder.
- The route Strapi matched, with its
/apiprefix, soGET /api/articles/42is grouped as/api/articles/{id}. - Outbound calls your Strapi code makes with
http,httpsorfetch. See Outbound requests. - Each request once, even if the middleware is listed twice.
Tags, traces and spans
The plugin exposes the Koa adapter’s request helpers through its sdk service. Use them in controllers, services and policies:
const { factories } = require('@strapi/strapi');
module.exports = factories.createCoreController('api::article.article', ({ strapi }) => ({
async find(ctx) {
const apitraffic = strapi.plugin('apitraffic').service('sdk');
apitraffic.tag('tenant', String(ctx.state.user?.tenantId ?? 'public'));
return apitraffic.span('db.query', 'load articles', () => super.find(ctx));
}
}));
The service also offers trace, startSpan, embedToken, flush and shutdown. embedToken() mints with an Administrator API token set as API_TRAFFIC_EMBED_TOKEN, not the ingest token; see Embed tokens. Tags follow the tag rules; see Per-request APIs.
Firewall and APM
The Strapi plugin provides request and outbound capture only. The web application firewall and APM spans, which @apitraffic/node adds for Express, Fastify, Koa and hapi, are not part of it.
Shut down
The plugin stops the SDK in Strapi’s destroy phase: it delivers what was captured, waiting up to 2 seconds, then releases the realtime connection and hooks, so Strapi’s shutdown and strapi develop restarts are not held up. You do not need to call shutdown() yourself. Use strapi.plugin('apitraffic').service('sdk').flush() to deliver captured requests before a process is frozen or recycled.
Troubleshooting
Nothing is captured after installing the plugin
- Check that
plugin::apitraffic.apitrafficis inconfig/middlewares.js. - Look for
[apitraffic] … not set; request capture is disabled.in the Strapi log: the token or bucket did not reach the process. - Restart Strapi after changing
.envor the configuration files.
The log says the token was rejected
ApiTraffic: token rejected (HTTP 401) or (HTTP 403) means the token is invalid or cannot access the bucket in API_TRAFFIC_BUCKET. Check both values; a token belongs to one environment. See API tokens.
Routes are grouped by raw path
The route is sent by plugin builds that use @apitraffic/koa 2.0 or later. Update the plugin, and its @apitraffic/koa dependency, to the latest version.
Related
-
SDK configuration: Every option and environment variable the plugin accepts.
-
Koa: The adapter the plugin is built on.
-
Redactions: Mask sensitive fields before they leave your server.
-
Request log: See and search the requests Strapi served.