Engage Realtime External ID API V2
Overview
This API extends the regular Engage Report externalId API with support for realtime data.
For questions, issues, feature requests, or announcements about new features, join the Engage API Google Group.
API URL
The base URL for all API endpoints is:
https://api.outbrain.com/engage/v2
What's New in V2?
V2 introduces enhanced security by protecting your publisher ID as a hashed string (in both Request and Response). Please contact your Teads account manager to acquire this ID.
Migration from V1 to V2
# V1
GET https://api.outbrain.com/engage/v1/reports/realtime/externalId/publishers/publisherId...
# V2
GET https://api.outbrain.com/engage/v2/reports/realtime/externalId?entityId=extPublisherId...
Authentication
Authentication is the first step toward using the Engage API. Tokens are valid for 30 days and must be included in all further requests using the HTTP header OB-TOKEN-V1.
- Validity: Tokens are valid for 30 days.
- Concurrency: You can generate as many active tokens as you wish; generating a new token does not invalidate existing tokens.
- Revocation: When a user password or email is changed, all previously generated tokens are automatically revoked.
Token Request via Basic Auth
This is the only API transaction that requires supplying credentials via Basic Authentication.
Include an HTTP header:
- Header Name:
Authorization - Value:
BASIC BASE-64-ENC(YOUR_OUTBRAIN_USER_NAME:YOUR_OUTBRAIN_PASSWORD)
All communication with the Engage API uses HTTPS, keeping your credentials secure.
cURL Example
curl -u YOUR_OUTBRAIN_USER_NAME:YOUR_OUTBRAIN_PASSWORD https://api.outbrain.com/engage/v2/login
Add -v to inspect the Authorization HTTP header in the response.
Using Your Token
Include the token in all subsequent API requests:
OB-TOKEN-V1: <your_token>
Rate Limits
| Endpoint / Scope | Limit | Window |
|---|---|---|
Authentication (/login) | 2 requests | Per hour per user |
| Reporting API | 30 requests | Per minute per publisher |
| Unique variants | 100,000 (100K) | Per hour |
When a rate limit is exceeded, the API responds with HTTP status 429 (Too Many Requests).
Recommended Practice: Cache and reuse an active token, refreshing it once every 30 days or less to avoid hitting the login rate limit.
Users
Users represent individual account access to Teads services and the publisher dashboard. Users have permissions to one or more Publisher accounts.
Users cannot be created or managed via this API. Please contact your Teads representative for user account management.
Setup
External ID Injection Methods
Populate your variants/external IDs in the platform using one of the following methods:
1. Global Variables
OB_extId— for externalIdOB_extIdSecondary— for externalSecondaryId
2. Container Attributes
data-external-id— for externalIddata-external-secondary-id— for externalSecondaryId
AMP Example
<amp-embed
width="100"
height="100"
type="outbrain"
data-widgetids="AMP_1"
data-external-id="555"
data-external-secondary-id="444">
</amp-embed>
External ID data is available for querying 48 hours after initial injection.
Reports
Realtime-Specific Notes
| Metric / Setting | Details |
|---|---|
| Data window | Available for the last 48 hours |
| Revenue currency | USD |
| Data freshness cap | Up to 30 minutes |
| Maximum error rate | 5% |
Response Structure
All reporting endpoints share a common response structure:
| Property | Type | Description |
|---|---|---|
items | Array | Metrics of the entities returned (ExternalIdReportItems). |
totalItems | Number | Total count of results after filtering. |
metricsSums | Object | Aggregated metrics for the returned dataset after filtering. |
Filter Parameters
Results can be filtered using the following operators:
Numeric Operators
| Operator | Description | Example |
|---|---|---|
:eq: | Equal | realtime/externalId?filter=revenue:eq:2000 |
:gt: | Greater than | realtime/externalId?filter=organicClicks:gt:300 |
:lt: | Less than | realtime/externalId?filter=paidClicks:lt:890 |
:between: | Between | realtime/externalId?filter=organicListings:between:20,900 |
List Operators
| Operator | Description | Example |
|---|---|---|
:in: | In | realtime/externalId?filter=widget:in:2089,84984,38984 |
:not_in: | Not in | realtime/externalId?filter=widget:not_in:2089,8466 |
String Operators
| Operator | Description | Example |
|---|---|---|
:contains: | Contains | realtime/externalId?filter=externalId:contains:ar |
:not_contains: | Not contains | realtime/externalId?filter=externalId:not_contains:ar |
Combine multiple filters with semicolons (;):
filter=revenue:gt:2000;widget:in:234,657
Note: Nesting of Boolean operators is not currently supported.
ExternalIdReportItems Fields
| Property | Type | Description |
|---|---|---|
externalId | String | Maximum length: 110 characters. |
externalSecondaryId | String | Maximum length: 110 characters. |
widget | Widget | Widget entity (optional breakdown). |
paidReqs | Number | Number of paid requests. |
paidClicks | Number | Total number of paid clicks. |
reqsPaidCtr | Number | Average CTR (Click Through Rate): (Paid clicks / paidReqs) * 100. |
revenue | Number | Revenue in USD. |
reqsRpm | Number | Revenue per 1,000 requests. |
totalPvs | Number | Total pageviews with at least one Teads link (assumes all widgets on the page share the same external ID). |
Request Structure
| Parameter | Type | Required | Details |
|---|---|---|---|
entityId | String | Yes | External ID of the entity (publisher/group). Contact your Teads account manager to obtain this. |
fromDate | String | Yes | Start date-time (yyyyMMddHH or yyyyMMdd, defaults to 00 hour). Max range: 24 hours. |
toDate | String | Yes | End date-time (yyyyMMddHH or yyyyMMdd, defaults to 00 hour of next date). Max range: 24 hours. |
limit | Number | No | Max results to return. Default: 1000, Maximum: 5000. |
offset | Number | No | Ordinal index of first result to retrieve. Default: 0. |
sort | String | No | Sorting field (metric or entity). Default: revenue. |
order | String | No | Sorting order: asc or desc. Default: desc. |
filter | String | No | Filter expression using filter operators. |
breakdowns | Array | No | Aggregation entities. Default: externalId. |
Breakdowns
| Breakdown | Description | Example |
|---|---|---|
externalId | Group by external ID | /v2/reports/realtime/externalId?breakdowns=externalId&entityId={entityId} |
widget | Group by widget entity | /v2/reports/realtime/externalId?breakdowns=widget&entityId={entityId} |
externalSecondaryId | Group by secondary external ID | /v2/reports/realtime/externalId?breakdowns=externalSecondaryId&entityId={entityId} |
Combine multiple breakdowns using commas:
breakdowns=externalId,widget
Note: externalId is included as the primary breakdown by default. To change order, specify explicitly (e.g. breakdowns=widget,externalId).
Error Handling
When the API returns an error status code, the response body includes JSON details describing the error.
HTTP Status Codes
| Code | Meaning | Description |
|---|---|---|
200 | OK | The request was successful. |
400 | Bad Request | The request was malformed or missing required parameters. |
401 | Unauthorized | Authentication failed or insufficient permissions. |
403 | Forbidden | Access denied. |
404 | Not Found | Requested resource was not found. |
429 | Too Many Requests | Rate limit exceeded. |
504 | Gateway Timeout | Request timed out. |
Error Response Format
{
"moreInfo": "getWidgets",
"errorMessage": "access denied"
}
Troubleshooting
If you encounter issues or have questions:
- Community Support: Post in the Engage API Google Group.
- Trace Header: Always include the
x-traceidheader from the response when contacting support to facilitate faster investigation.