Authentication#

The Evolu Integrators API uses bearer token authentication with campaign-scoped API keys. Each key is cryptographically generated and prefixed for easy identification.

API key format#

Keys follow the format evolu_{mode}_{campaign_slug}_{secret}:

Key format

Example: evolu_live_aB3dE6gH_x7K2p... — the prefix encodes the environment, followed by a short campaign slug and a random secret. Only the non-secret prefix is stored by Evolu; the secret is held as a one-way hash.

PrefixEnvironmentBehaviour
evolu_live_ProductionReal entries — livemode: true
evolu_test_SandboxSandboxed entries — livemode: false

The mode of the key that authenticated a request becomes the livemode flag on every record it creates (the entry, its enrollment, evaluations) and on every webhook envelope. Live and test data never mix.

Making authenticated requests#

Send the key in the Authorization header on every request:

curl -X POST https://api.evolu.tec.br/v1/entries \  -H "Authorization: Bearer evolu_live_aB3dE6gH_x7K2p..." \  -H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \  -H "Content-Type: application/json" \  -d '{ "enrollment": { ... }, "consent": { ... }, "evidence": { ... } }'
const response = await fetch('https://api.evolu.tec.br/v1/entries', {  method: 'POST',  headers: {    Authorization: `Bearer ${process.env.EVOLU_API_KEY}`,    'Idempotency-Key': crypto.randomUUID(),    'Content-Type': 'application/json',  },  body: JSON.stringify({ enrollment: {}, consent: {}, evidence: {} }),})
import requests, uuidresponse = requests.post(    "https://api.evolu.tec.br/v1/entries",    headers={        "Authorization": f"Bearer {EVOLU_API_KEY}",        "Idempotency-Key": str(uuid.uuid4()),        "Content-Type": "application/json",    },    json={"enrollment": {}, "consent": {}, "evidence": {}},)

Key scoping#

Each API key is scoped to a single campaign:

  • A key can only submit entries to its bound campaign.
  • Keys cannot access other campaigns or workspace-level resources.
  • Rotating a key does not affect other campaigns.

Never expose API keys in client-side code, public repositories, or browser network requests. A key grants write access to your campaign and must be treated as a secret.

Key rotation#

Keys can be rotated from the Evolu dashboard. A key may also carry an optional expiry — expired or deactivated keys are rejected with 401.

Error responses#

Authentication failures return 401 Unauthorized:

{  "detail": "Invalid or missing API key."}

Common causes:

  • Missing or malformed Authorization header.
  • Unknown, deactivated, or expired key.
  • A key whose secret does not match.

See Error Handling for the full list of status codes.