Authentication

How to authenticate SDK and server requests, which scopes each endpoint needs, and what happens when a key is refused.

Updated 1 Nov 2026 3 min read

The environment (Test or Live) is decided by the key you present. You never send a workspace or environment header to the public API.

Key kinds

Kind Credential Where it is used
SDK app key test_… or live_…, no secret Inside apps and websites. Safe to ship.
Server key App key and secret Your backend only
Data API key App key and secret Your backend, or browsers from allowed origins

Create server and Data API keys under Developers, API Keys. See API keys.

SDK app key

Send the key in a header:

curl https://api.true-engage.com/v1/sdk/config \
  -H "X-TE-App-Key: test_xxxxxxxx"

A browser sendBeacon call cannot set headers. POST /sdk/batch therefore also accepts the key as an appKey query parameter.

Server key, Basic auth

The app key is the username and the secret is the password.

curl -X POST https://api.true-engage.com/v1/events \
  -u "test_xxxxxxxx:YOUR_SECRET" \
  -H "Content-Type: application/json" \
  -d '{"events":[{"externalId":"C10093","name":"Order Placed"}]}'

In Node:

const auth = Buffer.from(`${process.env.TE_APP_KEY}:${process.env.TE_SECRET}`).toString('base64');

const res = await fetch('https://api.true-engage.com/v1/events', {
  method: 'POST',
  headers: { Authorization: `Basic ${auth}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({ events: [{ externalId: 'C10093', name: 'Order Placed' }] }),
});

Server key, Bearer

Join the app key and the secret with a dot.

curl -X POST https://api.true-engage.com/v1/events \
  -H "Authorization: Bearer test_xxxxxxxx.YOUR_SECRET" \
  -H "Content-Type: application/json" \
  -d '{"events":[{"externalId":"C10093","name":"Order Placed"}]}'

Use the auth style you chose when you created the key. Both styles work with every server endpoint.

Scopes

A key can only call endpoints its scopes allow.

Scope Allows
sdk.track POST /sdk/batch, /sdk/track
sdk.identify POST /sdk/identify
sdk.device POST /sdk/devices
sdk.inbound In-app, on-site and card fetch and impression reports
data.create_events POST /events
data.merge_user POST /users/identity/promote
campaigns.create_manage POST /transactional/:slug/send
flows.create_manage POST /business-events/:name/activate, POST /flows/:id/enter

Optional restrictions

When you create a key you can limit it to certain IP addresses (CIDR ranges are accepted), limit a Data API key to certain origins, set an expiry date and set a lower rate limit.

Authentication errors

Code Meaning What to do
API_KEY_REQUIRED No key was sent. Add the header.
INVALID_API_KEY The key or secret is wrong. Check both halves and the auth style.
API_KEY_SECRET_REQUIRED The key needs a secret. Use Basic or Bearer, not the bare app key.
API_KEY_REVOKED The key was revoked. Create or regenerate a key.
API_KEY_EXPIRED The key passed its expiry date. Create a new key.
KEY_KIND_NOT_ALLOWED This kind of key cannot call this endpoint, for example an SDK key on /events. Use a server key.
INSUFFICIENT_SCOPE The key lacks the scope. Edit the key or create one with the scope.
IP_NOT_ALLOWED, ORIGIN_NOT_ALLOWED The request came from outside the key's allowlist. Call from an allowed address or origin.

See Errors for the full list.

Keep secrets safe

  • Never put a server key in a mobile app, a web page or source control.
  • Use test_ keys while building. Use live_ keys only in production. See Test and Live.
  • After a leak, revoke the key. After a planned rotation, regenerate it; the old secret works for 24 hours.