Skip to content

Backend service token

Pattern used by password-reset and webhook backends:

  1. The browser logs in with @kataflax/sdk and sends the project JWT to your API (cookie or Authorization).
  2. Your server holds TEFILY_SERVICE_TOKEN (kfxs_…) and never returns it to the client.
  3. The server calls POST /api/p/:projectId/auth/verify to validate the user JWT. A KataflaxClient constructed with serviceToken does that through auth.verify.
  4. The server uses the service token to read and write collections. Rules are bypassed, so only do what the user is allowed to, in your own code.

KataflaxClient constructed with serviceToken sets that token on every call, including auth.verify. The Next.js route that does this is Next.js. The browser never receives kfxs_.

Non-Next servers can copy the request:

POST /api/p/YOUR_PROJECT_ID/auth/verify
Authorization: Bearer kfxs_…
Content-Type: application/json
{ "token": "<project jwt>" }

The response envelope is:

{ "success": true, "data": { "valid": true, "user": { "_id": "…", "email": "…" } } }

auth.verify returns { valid, user? } after unwrapping data. Invalid or non-project tokens come back valid: false.

import { KataflaxClient } from '@kataflax/sdk';
function serverClient() {
return new KataflaxClient({
baseUrl: process.env.TEFILY_API_URL ?? 'https://api.tefily.com',
projectId: process.env.TEFILY_PROJECT_ID!,
serviceToken: process.env.TEFILY_SERVICE_TOKEN!,
});
}
const server = serverClient();
const checked = await server.auth.verify(incomingUserJwt);
// checked.valid, checked.user

Dart (projectId and serviceToken are server env values, incomingUserJwt is the caller’s project JWT):

import 'package:kataflax_client_sdk/kataflax_client_sdk.dart';
final backend = KataflaxClient(
baseUrl: 'https://api.tefily.com',
projectId: projectId,
serviceToken: serviceToken,
);
final checked = await backend.auth.verify(incomingUserJwt);

Create the token in the console (project Developers / service tokens), with the admin SDK, or via MCP (create_service_token). Rotate it if it leaks.

Do not use a PAT (kfx_…) for this. PATs are user-scoped platform credentials and can call console APIs. They are not for auth/verify.