API Updates - April 2026
Authentication
API Key Auth on Lists and Campaigns
The lists and campaigns endpoints now accept API-key authentication. Previous scope gates have been removed: API-key callers reach the same surface as session callers.
GET /v1/lists
GET /v1/lists/{list_id}
POST /v1/lists
GET /v1/campaigns
GET /v1/campaigns/{campaign_id}
Authentication:
Authorization: Bearer <api_key>- Standard API-key header. No additional scope is required.
Example:
curl https://api.delivr.ai/api/v1/lists \
-H "Authorization: Bearer $API_KEY"Events
Query DSP Events by Campaign ID
Developer tokens can query DSP events filtered by campaign_id against the v2 events API. The proxy translates the v2 source parameter to the upstream contract.
GET /v2/events
Parameters:
source(string) -delivrdspcampaign_id(string) - Campaign to filter events by.start_time(string, ISO 8601) - Inclusive lower bound.end_time(string, ISO 8601) - Inclusive upper bound.
Example:
curl "https://apiv3.delivr.ai/api/v2/events?source=delivrdsp&campaign_id=cmp_abc123&start_time=2026-04-01T00:00:00Z&end_time=2026-04-30T23:59:59Z" \
-H "Authorization: Bearer $API_KEY"Project-Scoped DSP Queries
The events API supports project-scoped DSP queries, returning events for all DSP campaigns under a given project.
Parameters:
project_id(string) - Restrict results to events belonging to this project.
Audiences
Configurable Intent Lookback
Audiences accept an intent_window_days value on create and edit. Bucket counts scale to match the selected window.
POST /v1/audiences
PATCH /v1/audiences/{audience_id}
Parameters:
intent_window_days(integer) - Number of days of intent history to consider when building the audience.
Response:
audience.intent_window_days(integer) - The configured window.audience.bucket_counts(object) - Counts scaled to the configured window.
Rate Limiting
Rate limits on the data API are now applied per organization rather than globally. Each organization receives 25 requests per second with a burst capacity of 50. Integrators making concurrent requests across many organizations are no longer constrained by a shared global limit.
Response headers:
X-RateLimit-Limit(integer) - 25X-RateLimit-Remaining(integer) - Tokens remaining in the current second.X-RateLimit-Burst(integer) - 50Retry-After(integer, on 429) - Seconds to wait before retrying.
Migration note: Clients previously throttled by the global limit will see additional headroom. Clients running heavy traffic against a single organization should still implement exponential backoff on 429 responses.
Bug Fixes
- DSP exports no longer fail with
pixel not foundwhen source and campaign ID are not threaded into the event query. - Empty audience exports complete with zero records instead of failing the run.
- Fixed an
end_dateboundary mismatch between SQL and application code in export queries; the boundary is now consistent across the stack. - Fixed a race where an export run could continue executing after the export was disabled.
- Audience filters with very large inline value lists now spill values to S3 instead of failing the count worker with
E2BIG. - The
containsfilter no longer splits multi-word values on commas. - Audience download presigned URLs are re-signed on every download call, eliminating expired-URL errors on retry.
- Email subject templates are interpolated on every export send path, including batched, streamed, and multi-file exports.
- The email export windowed path now defaults the S3 bucket instead of erroring with
s3_bucket is required. - S3 exports fail fast with a clear error when integration credentials are empty or partially populated, instead of erroring deep in the run.
For full endpoint details, parameters, and examples, see our developer documentation.