Authentication
Overview
Delivr.ai data APIs (events, audiences, taxonomy, identity lookup) authenticate with an API key + secret pair, created from the dashboard. A key is scoped either to your whole organization or to a single project; see Project-scoped API keys.
X-Api-Key: dlvr_...
X-Api-Secret: ...
There is one supported way to create keys: the dashboard at https://app.delivr.ai/{org_id}/settings/api-keys. The dashboard is the only place that displays the secret half. We do not recommend (and are phasing out) JWT-based programmatic key creation.
First time here? Your Delivr contact (sales or support) creates the organization and invites your first user(s). Once you accept the invite and sign in to app.delivr.ai, everything from API keys to project settings to inviting teammates is self-serve.
Base URL: https://api.delivr.ai
Create your API key in the dashboard
The fastest, safest way to get a working key + secret pair is to create one through the UI.
-
Sign in at app.delivr.ai and switch to the organization you want the key to belong to.
-
Open Settings > API keys. The direct link is
https://app.delivr.ai/{org_id}/settings/api-keys(replace{org_id}with your organization ID). -
Click Create key and give it a descriptive name (for example, "Production export job" or "Hubspot sync"). Under Scope, keep Organization (every project), or choose one project to create a project-scoped key.
-
In the confirmation dialog, copy both values into your secrets manager before closing it:
Value Format Where to use it api_keydlvr_prefixX-Api-Keyheader on every requestapi_secrethex string X-Api-Secretheader on every request
The full
api_secretis shown once, at creation time. If you close the dialog without saving it, you'll need to delete the key from the same page and create a new one. The list view shows only the key prefix; it cannot reveal the secret again.
An organization key reaches every project in the organization that owns it; a project-scoped key reaches one project. Anyone with both halves can call the API with that scope, so treat the pair like a password: rotate on suspected leak, never commit either value to source control. Use the Revoke action in the same dashboard page to retire a key.
Make your first authenticated request
Once you have the pair, every request to api.delivr.ai carries both headers. The two-header pattern works on every data endpoint (events, audiences, taxonomy, identity lookup).
curl "https://api.delivr.ai/api/v3/events_schema?source=pixel" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "X-Api-Secret: YOUR_API_SECRET"Response (200 OK)
{
"fields": [
{ "name": "event_id", "data_type": "Utf8", "nullable": false },
{ "name": "event_type", "data_type": "Utf8", "nullable": false },
{ "name": "ts_millis", "data_type": "Int64", "nullable": false },
{ "name": "resolved", "data_type": "Boolean", "nullable": true }
]
}If you see 401 {"error":"Invalid API key"}, double-check that you copied the full dlvr_-prefixed value. If you see 401 {"error":"Invalid API secret"}, the secret half does not match the key on file. Create a new pair from the dashboard.
Why both halves matter
A leaked api_key on its own is not enough to call the API. The platform compares the supplied api_secret against a stored hash on every request, in constant time, and rejects mismatches with 401. Pair-based auth means:
- You can rotate the secret without re-issuing the key (less downstream config churn).
- Keys can be safely surfaced in logs or dashboards; the secret stays out of those code paths.
- Per-key access logs show exactly which credential made each call.
If your organization has secret_required enabled (default for new keys), a request that omits X-Api-Secret is rejected with 401 {"error":"API secret is required"}. Older keys may still accept secret-less calls during migration, but every new integration should send both headers.
Per-endpoint headers
This table describes an organization key. A project-scoped key reaches fewer of these, and only for its own project; see Project-scoped API keys.
| API | Required headers | Notes |
|---|---|---|
Events (/api/v3/events/{tier}) | X-Api-Key, X-Api-Secret | The tier route fixes both the billing tier and the identity fields returned. Scope with source plus pixel_id, project_id, or campaign_id. See Events API v3. |
Audiences (/api/v1/audiences*) | X-Api-Key, X-Api-Secret | Name the project with the X-Project-Id header or a ?project_id= query param (equivalent); required for create/list/sample. |
Taxonomy (/api/v1/taxonomy/*) | X-Api-Key, X-Api-Secret | Read-only across the org. |
Identity (/api/v1/lookup) | X-Api-Key, X-Api-Secret | HEM/email resolution. |
Organization (/api/v1/organization) | X-Api-Key, X-Api-Secret | GET to read, PUT to update, or DELETE to remove your own organization. |
Organization members (/api/v1/organization/user*) | X-Api-Key, X-Api-Secret | Create/list/retrieve/update/delete members of the key's organization. |
Project management (/api/v1/project*) | X-Api-Key, X-Api-Secret | Create/list/retrieve/update/delete projects in the key's org. Create and list need no project id; retrieve is GET /api/v1/project/retrieve/{project_id}; update and delete take project_id in the body. A project outside the key's org is rejected. |
Project members (/api/v1/project/user*) | X-Api-Key, X-Api-Secret | Manage members of a project. Name the target project with a project_id field (writes) or ?project_id= (reads); the project must belong to the key's org. |
Pixel management (/api/v1/pixel*) | X-Api-Key, X-Api-Secret | Create/list/retrieve/update/delete pixels. Name the target project with a project_id field (writes) or a ?project_id= query parameter (reads). |
Project-scoped API keys
A project-scoped key is bound to one project when you create it. It uses the same X-Api-Key and X-Api-Secret headers as an organization key, but it reads and writes only its own project's data. Use one to give a client, a team, or a single integration access to one project without exposing the rest of your organization. If you run projects for several clients, issue one key per client.
Create one
In Settings > API keys, click Create key and choose a project under Scope. A project admin creating a key from inside their project gets a key bound to that project; the scope selector is not shown.
The scope is fixed at creation. To change it, revoke the key and create another.
What a project key confines
- Naming another project, or a pixel, campaign or record that belongs to another project, is refused. The status code depends on the API; see the table below.
- An endpoint a project key cannot use answers
403, with a message saying the endpoint is not available to a project-scoped API key. - Usage on the events API, identity lookup, the intent API and audience downloads is attributed to the key's project.
- A project key is held to its project's budget as well as your organization's, on every route that bills. When the organization's budget refuses a project key, the
402omits the organization's spend and budget figures. See Project budgets.
Where a project key works
| API | Routes | With a project key |
|---|---|---|
| Events | /api/v3/events/{tier}, /api/v3/events/{tier}/visitors and /api/v3/events/{tier}/schema, /api/v3/events_schema, /api/v1/events, /api/v1/event_counts | A request scoped to the organization reads only the key's project. Another project's project_id returns 404 (project not found), another project's pixel 404 (pixel not found), and another project's DSP campaign 404 (campaign not found). The visitors route needs project_id or pixel_id, which must be the key's own. |
| Identity lookup | /api/v1/lookup, /api/v1/lookup/batch | Same as an organization key: lookup takes no project. |
| Audiences | /api/v1/audiences* | Name the project as usual (X-Project-Id or ?project_id=, required). It must be the key's project; any other returns 403 (access denied). Cloning an audience into another project is refused with 403 too. The audience schema and the audience template catalog work as they do for an organization key. |
| Audience usage | GET /api/v1/audiences/linkage-usage | The key's project only; any other returns 403 (project_id does not match API key scope). |
| Intent | /api/v1/intent/* | Same as an organization key: intent data belongs to no project. An audience_id on /api/v1/intent/people must belong to your organization. |
| Intent topic stats | /api/v1/stats/tables/intent-daily-stats, /api/v1/stats/tables/intent-daily-per-topic-stats | Same as an organization key: topic-level data. |
| Taxonomy | /api/v1/taxonomy/* | Same as an organization key: a shared vocabulary. |
| Field catalog | /api/v1/field-catalog* | Same as an organization key: a shared catalog. |
| Lists, exports, integrations, campaigns | /api/v1/lists*, /api/v1/exports*, /api/v1/integrations*, /api/v1/campaigns* | A request without project_id is answered for the key's project. Another project's project_id returns 403 (project_id does not match API key scope). The campaign_id and audience_id filters return 403. A record in another project, requested by id, returns 404. |
| Resolution statistics | GET /api/v1/resolution/statistics | The key's project only. |
| Billing usage | GET /api/v1/billing/usage, /api/v1/billing/usage/by-meter, /api/v1/billing/usage/daily-by-meter | Usage for the key's project only. |
| Contact query | POST /api/v1/contact/query | Same as an organization key. |
| Who am I | GET /api/v1/whoami | Lists only the key's project. |
| Pixels | /api/v1/pixel* | Pixels in the key's project only. Name the project as usual; another project returns 401. |
| Your project | GET /api/v1/project/retrieve/{project_id}, PUT /api/v1/project/update | The key's own project only; another returns 401. |
Not available to a project key (403): the organization itself (/api/v1/organization), organization members (/api/v1/organization/user*), creating, listing and deleting projects, and project members (/api/v1/project/user*). Use an organization key for these.
A note on legacy auth methods
If you have older integrations that use a JWT (obtained from POST /auth/v1/login with an email and password) or use only the X-Api-Key header without a secret, those continue to work for now. Both patterns are on the deprecation path. Move them to dashboard-created key + secret pairs at your next maintenance window. We will publish a removal timeline before disabling either path.
Next steps
- On-Domain Events API: query pixel events with the v2 endpoint
- Account Setup: create a project and pixel
- Intent Audiences API: build intent-based audiences
Updated 1 day ago
