Partner API
Live · Version 1.0.0
Overview
This API is for partners that buy screen time on the Programmatic Engine network. It covers four jobs:
- find out which screens you can buy (
GET /{partner}/inventory), - upload a creative and check whether it was approved (
POST /{partner}/video,GET /{partner}/moderated), - check your account and the current server time (
GET /{partner}/me), - download the plays you will be billed for (
GET /{partner}/reconciliation/impressions).
The network sells screen time through real-time bidding only. There is no endpoint for booking a campaign, a date range or a fixed number of plays. When a screen is about to play a slot, the network asks every partner assigned to that screen for a bid. The request that carries the slot, and the answer you send back, are described on the Bid protocol page. This API only prepares and settles that exchange.
A typical integration order:
- Call
/meto confirm that your key works. - Call
/inventoryand store the screens you want to bid on. - Upload each creative with
/video. Keep theidand your ownexternal_id. - Poll
/moderateduntil the creative reachesconfirmed. - Answer bid requests (see the Bid protocol page) with the
external_idof a confirmed creative. - Pull
/reconciliation/impressionsevery day and compare it with your own records.
Access
We issue one API key per partner when you are onboarded. We also tell you your partner path, the first segment of every URL. In this document it is written as {partner} and the examples use acme.
Send the key in the Authorization header on every call:
Authorization: Bearer <your key>
Keys are sent over HTTPS only. Anyone who holds your key can read your inventory and upload creatives in your name, so keep it on your servers. If a key leaks, ask us to replace it. A key stays valid until we replace it.
The key and the path belong together. A key does not work under another partner's path. A missing, wrong or empty key returns 401 with the header WWW-Authenticate: Bearer. A partner only ever sees its own screens, creatives and plays.
Call GET /{partner}/me first. It confirms the key, shows how many screens are assigned to you and returns the server clock, which helps when you compare timestamps.
Time and identifiers
Times in query parameters and request bodies are read as UTC unless the value carries an offset such as +04:00. date_start, date_end, date_from and date_to accept 2026-10-08, 2026-10-08 10:00:00 and 2026-10-08T10:00:00Z. A date without a time means the start of that day in date_from and the end of that day in date_to.
Times in responses are Unix seconds (start_time, end_time) or ISO 8601 UTC (server_time). Bid requests use milliseconds, see the Bid protocol page.
Four identifiers are in use. Keep them apart:
| Name | Where it comes from | Where you use it |
|---|---|---|
id |
Assigned by us when you upload a creative. An integer. | ids[] in /moderated; video_id in /reconciliation/impressions. |
external_id |
Chosen by you. Up to 64 characters. | Returned by us in upload and reconciliation. In a bid, you send it back as video_id. |
request_id |
Created per bid request. | In a bid you echo it back. It is the key of a play in reconciliation. |
gid |
The screen. An integer. | In inventory it is gid. In reconciliation it is side_gid. In a bid request it is screen.gid, as a string. |
gid is the same number everywhere. Screen 173 in inventory is side_gid 173 in reconciliation and "173" in the bid request.
Creative lifecycle
Every creative has one status. The status changes as we download, check and moderate the file.
| Status | Meaning | Can win a bid | Billed |
|---|---|---|---|
new |
Accepted. The download from url is queued. |
no | no |
loaded |
File downloaded. | no | no |
checking |
The file is being inspected. | no | no |
checked |
Inspected. A moderator must confirm the target screens. Skipped when you upload with gid or gids. |
no | no |
waiting |
Queued for conversion. | no | no |
decode |
Being converted for the players. | no | no |
accepted |
Converted. Waiting for the technical and legal review by a moderator. | no | no |
confirmed |
Approved. | yes | yes |
rejected |
A moderator refused it. comment holds the reason. |
no | no |
failed |
Download or inspection failed. comment holds the reason, which can be in Russian. |
no | no |
archived |
Removed from circulation. | no | no |
Only confirmed creatives can win a bid, and only a confirmed creative that was played and verified shows up in reconciliation. A creative can leave confirmed, for example when a moderator rejects it later. Poll /moderated and stop bidding with it when it does.
Approval is a manual step by our moderators. There is no fixed time for it. rejected and failed are final. Upload a corrected file as a new creative with a new external_id.
A creative can only win on screens it is assigned to. The assignment is made at upload through gid, gids or operator, and confirmed by a moderator.
Limits
| What | Limit |
|---|---|
| Requests per partner key | 300 per minute. The minute starts with the first request and the counter resets 60 seconds later. Over the limit the API returns 429. A second cap of 600 requests per minute applies to each client IP address, whatever keys it sends. |
| Reconciliation window | 3 days per call. A longer window is cut short and reported in errors. |
ids[] in /moderated |
1024 values. |
gids in /video |
1024 values. |
file_url in /video |
5 URLs, each up to 191 characters. |
shot_second in /video |
16 values, each 0 to 32767. |
url, title, video_md5 |
191 characters. |
external_id, video_id, operator |
64 characters. |
width, height |
0 to 32767. |
/inventory, /moderated and /reconciliation/impressions do not paginate. They return everything that matches in one response.
Errors
Every error has the same body:
{"status": "error", "error_message": "Unauthorized"}
| HTTP status | When |
|---|---|
400 |
A field has the wrong type or value. error_message names the field, for example Value error in gids: One or more values are not available. |
401 |
The key is missing, wrong or empty. The response carries WWW-Authenticate: Bearer. |
429 |
More than 300 requests per key, or 600 per IP address, in a minute. The response carries Retry-After (seconds) and X-RateLimit-Limit. Successful responses carry X-RateLimit-Limit and X-RateLimit-Remaining. |
500 |
Something failed on our side. error_message is always Internal Server Error. Repeat later and write to us if it persists. |
The API never returns 422. Unknown fields in a request body are ignored without a warning, so a misspelled field name does not fail the call. The field is then missing. Empty strings are treated as if the field was not sent.
Two cases return 200 although the call did not do what you meant. Read the response, not only the status code:
/reconciliation/impressionswithoutunique_idor both dates returns an empty list and a message inerrors./reconciliation/impressionswith a window longer than 3 days returns only the first days and a message inerrors.
Versioning
This is version 1.0.0. We make additive changes only: new endpoints, new optional parameters and new fields in responses. We do not rename or remove fields, and we do not change their meaning without a new path.
Read response fields by name, never by position, and ignore fields you do not know. Unknown request fields are ignored by us in the same way. Changes are announced to the technical contact of each partner before they go live.
Account
Check your key and read the server clock.
Check your key and account#
Returns the partner path and name, the number of screens assigned to you, the request limit and the server time. Use it as the first call after you receive a key, and as a health check.
The response never contains keys or other secrets.
Parameters
| Name | In | Type | Required | Description | Example |
|---|---|---|---|---|---|
| partner | path | string | yes | Your partner path, assigned by us at onboarding. |
acme |
Responses
The key is valid.
| Header | Type | Description | Example |
|---|---|---|---|
| X-RateLimit-Limit | integer | Requests allowed per minute for your key. | 300 |
| X-RateLimit-Remaining | integer | Requests left in the current minute. | 299 |
Response fields
| Field | Type | Description | Example |
|---|---|---|---|
| partnerrequired | string | The partner path of this request. |
acme |
| namerequired | string | The internal account name. It can differ from the partner path. |
acme |
| screensrequired | integer | Number of screens assigned to you. It equals the length of the inventory list. |
42 |
| rate_limit_per_minuterequired | integer | Requests per minute allowed for your key. |
300 |
| server_timerequired | string (date-time) | Current server time in UTC, ISO 8601 with a trailing |
2026-10-09T14:03:11Z |
{
"partner": "acme",
"name": "acme",
"screens": 42,
"rate_limit_per_minute": 300,
"server_time": "2026-10-09T14:03:11Z"
} The key is missing, wrong or empty.
| Header | Type | Description | Example |
|---|---|---|---|
| WWW-Authenticate | string | Always | Bearer |
Response fields
| Field | Type | Description | Example |
|---|---|---|---|
| statusrequired | string one of: error | Always |
error |
| error_messagerequired | string | What went wrong. For |
Value error in gids: One or more values are not available. |
{
"status": "error",
"error_message": "Unauthorized"
} More than 300 requests in the last minute for this key. Wait for the number of seconds in Retry-After.
| Header | Type | Description | Example |
|---|---|---|---|
| Retry-After | integer | Seconds to wait before the next call. | 42 |
| X-RateLimit-Limit | integer | Requests allowed per minute for your key. | 300 |
Response fields
| Field | Type | Description | Example |
|---|---|---|---|
| statusrequired | string one of: error | Always |
error |
| error_messagerequired | string | What went wrong. For |
Value error in gids: One or more values are not available. |
{
"status": "error",
"error_message": "Too many requests"
} Example request
curl 'https://accounting.programmatic-engine.com/acme/me' \
-H "Authorization: Bearer $API_KEY"
Inventory
The screens you can bid on.
List your screens#
Returns every screen assigned to you. The call takes no filters and does not paginate.
The list holds screens as they are configured, not as they are online. It does not say whether a screen is playing right now, and it includes screens that we have blocked. No bid requests are sent for a blocked screen. A screen added to your account appears here on the next call, so read the list again from time to time instead of caching it for good.
There is no price information. Floor prices are not published through this API.
Parameters
| Name | In | Type | Required | Description | Example |
|---|---|---|---|---|---|
| partner | path | string | yes | Your partner path, assigned by us at onboarding. |
acme |
Responses
All screens assigned to the partner. The list is empty when none are assigned.
| Header | Type | Description | Example |
|---|---|---|---|
| X-RateLimit-Limit | integer | Requests allowed per minute for your key. | 300 |
| X-RateLimit-Remaining | integer | Requests left in the current minute. | 299 |
Response fields
| Field | Type | Description | Example |
|---|---|---|---|
| itemsrequired | object[] | One entry per screen. |
|
| items[].gidrequired | integer | Screen id. Use it as |
173 |
| items[].faceoptional | string | null | Face or side of the structure, as entered by the screen owner. |
A |
| items[].namerequired | string | Display name of the screen. |
Dubai Marina Walk, west entrance |
| items[].playeridrequired | integer | The same value as |
173 |
| items[].photooptional | string | null (uri) | Address of a photo of the screen, or null. |
https://accounting.programmatic-engine.com/storage/players/173.jpg |
| items[].durationoptional | integer | null | Length of one slot in seconds. Null when the owner has not set it. Then the bid request carries |
10 |
| items[].cityoptional | string | null | City. |
Dubai |
| items[].addressoptional | string | null | Street address. |
Marina Walk 12 |
| items[].typeoptional | string | null | Screen type as entered by the screen owner. It is free text, not a fixed list. |
Citylight |
| items[].formatrequired | string | Resolution as width and height in pixels, written |
1080x1920 |
| items[].dimensionsoptional | string | null | Aspect ratio as entered by the screen owner, written |
9x16 |
| items[].latoptional | number | null | Latitude in degrees. Stored with single precision, so expect about seven significant digits and rounding noise. |
25.0805 |
| items[].lonoptional | number | null | Longitude in degrees. Same precision as |
55.1403 |
| items[].indoorrequired | boolean | True for an indoor screen. False for outdoor and for screens where the owner did not set a placement. |
false |
| items[].creative_formatrequired | string[] | Accepted file formats, each as |
{
"items": [
{
"gid": 173,
"face": "A",
"name": "Dubai Marina Walk, west entrance",
"playerid": 173,
"photo": "https://accounting.programmatic-engine.com/storage/players/173.jpg",
"duration": 10,
"city": "Dubai",
"address": "Marina Walk 12",
"type": "Citylight",
"format": "1080x1920",
"dimensions": "9x16",
"lat": 25.0805,
"lon": 55.1403,
"indoor": false,
"creative_format": ["mp4;h264;1080x1920", "jpeg;1080x1920"]
}
]
} The key is missing, wrong or empty.
| Header | Type | Description | Example |
|---|---|---|---|
| WWW-Authenticate | string | Always | Bearer |
Response fields
| Field | Type | Description | Example |
|---|---|---|---|
| statusrequired | string one of: error | Always |
error |
| error_messagerequired | string | What went wrong. For |
Value error in gids: One or more values are not available. |
{
"status": "error",
"error_message": "Unauthorized"
} More than 300 requests in the last minute for this key. Wait for the number of seconds in Retry-After.
| Header | Type | Description | Example |
|---|---|---|---|
| Retry-After | integer | Seconds to wait before the next call. | 42 |
| X-RateLimit-Limit | integer | Requests allowed per minute for your key. | 300 |
Response fields
| Field | Type | Description | Example |
|---|---|---|---|
| statusrequired | string one of: error | Always |
error |
| error_messagerequired | string | What went wrong. For |
Value error in gids: One or more values are not available. |
{
"status": "error",
"error_message": "Too many requests"
} Example request
curl 'https://accounting.programmatic-engine.com/acme/inventory' \
-H "Authorization: Bearer $API_KEY"
Creatives
Upload creatives and follow their moderation status.
Upload a creative for moderation#
Registers a creative. Send the address of the file in url. The file itself is not part of this request: we download it later, so the address must be reachable from the internet without a login for as long as the creative is in review.
The call returns at once with status new. It does not wait for the download or the moderation. Use GET /{partner}/moderated to follow the status.
Name the screens with gid (one screen) or gids (up to 1024 screens), or name a network with operator, or both. At least one is required. All screens must be assigned to you, and without operator they must belong to one network. With gid or gids the screens are approved at upload and the creative skips the checked step. With operator alone the creative is assigned to all your screens of that network and a moderator confirms the screens. The network name is given to you at onboarding and also appears as operator in reconciliation.
video_id (preferred) or external_id is stored as the creative's external_id. If both are sent, video_id wins. If neither is sent, we use the current Unix time in seconds, which is not unique when you upload several creatives in the same second. The external_id is not checked for duplicates. If you reuse one, both creatives exist, and a bid that names it can resolve to either of them. Use a new external_id for every upload.
Always send url. If the field is missing, the call still succeeds, but the creative ends in failed when the download is attempted. An empty url is rejected with 400.
date_start and date_end are stored with the creative for the moderators. A creative is not stopped at its date_end. To stop a creative, stop bidding with it.
The body must be JSON (Content-Type: application/json). A body that is not valid JSON is read as empty and returns the operator and gids error.
Parameters
| Name | In | Type | Required | Description | Example |
|---|---|---|---|---|---|
| partner | path | string | yes | Your partner path, assigned by us at onboarding. |
acme |
Request body · application/json
| Field | Type | Description | Example |
|---|---|---|---|
| urlrequired | string (uri)maxLength 191 | Public address of the file. We download it after the call returns. |
https://cdn.example.com/acme/spring_2026_001.mp4 |
| video_idoptional | stringmaxLength 64 | Your identifier of the creative. Stored as |
spring_2026_001 |
| external_idoptional | stringmaxLength 64 | Alternative name for |
spring_2026_001 |
| titleoptional | stringmaxLength 191 | A name that moderators see. |
Spring campaign, 10 s |
| video_md5optional | stringmaxLength 191 | MD5 checksum of the file, in hexadecimal. It is stored with the creative. |
5d41402abc4b2a76b9719d911017c592 |
| operatoroptional | stringmaxLength 64 | Network name. Use it to target all your screens in one network. Given to you at onboarding. |
marina-network |
| gidoptional | integer | One screen id. When sent, it is used instead of |
173 |
| gidsoptional | integer[]maxItems 1024 | Screen ids from inventory. All must be assigned to you. |
|
| date_startoptional | string | Start of the campaign, UTC unless an offset is given. Stored for the moderators. The zero date |
2026-10-10 00:00:00 |
| date_endoptional | string | End of the campaign, UTC unless an offset is given. Stored for the moderators. The zero date |
2026-10-31 23:59:59 |
| widthoptional | integermin 0 · max 32767 | Width of the creative in pixels. |
1080 |
| heightoptional | integermin 0 · max 32767 | Height of the creative in pixels. |
1920 |
| durationoptional | number | Length of the creative in seconds, as you declare it. We also inspect the file. |
10 |
| shot_secondoptional | integer[]maxItems 16 | Seconds from the start of the creative at which the camera takes a proof-of-play photo. Up to 16 values. |
|
| file_urloptional | string[]maxItems 5 | Addresses of additional files that belong to the creative. We download and store them. A single string is accepted as a list of one. |
{
"url": "https://cdn.example.com/acme/spring_2026_001.mp4",
"video_id": "spring_2026_001",
"title": "Spring campaign, 10 s",
"video_md5": "5d41402abc4b2a76b9719d911017c592",
"gids": [173, 174],
"date_start": "2026-10-10 00:00:00",
"date_end": "2026-10-31 23:59:59",
"width": 1080,
"height": 1920,
"duration": 10,
"shot_second": [3]
}
Responses
The creative was registered. The status is new. The response code is 200, not 201.
| Header | Type | Description | Example |
|---|---|---|---|
| X-RateLimit-Limit | integer | Requests allowed per minute for your key. | 300 |
| X-RateLimit-Remaining | integer | Requests left in the current minute. | 299 |
Response fields
| Field | Type | Description | Example |
|---|---|---|---|
| idrequired | integer | Our identifier of the creative. Use it in |
1234 |
| external_idrequired | string | Your identifier, as stored. |
spring_2026_001 |
| operator_idrequired | integer | Our numeric id of the network that owns the target screens. |
7 |
| statusrequired | string | The status right after upload. Always |
new |
| commentrequired | string | Empty after upload. |
|
| successrequired | boolean | Always true in a 200 response. |
true |
{
"id": 1234,
"external_id": "spring_2026_001",
"operator_id": 7,
"status": "new",
"comment": "",
"success": true
} A field is invalid, or the screens cannot be used.
Response fields
| Field | Type | Description | Example |
|---|---|---|---|
| statusrequired | string one of: error | Always |
error |
| error_messagerequired | string | What went wrong. For |
Value error in gids: One or more values are not available. |
{
"status": "error",
"error_message": "Value error: Undefined value in \"operator\" and \"gids\"."
} The key is missing, wrong or empty.
| Header | Type | Description | Example |
|---|---|---|---|
| WWW-Authenticate | string | Always | Bearer |
Response fields
| Field | Type | Description | Example |
|---|---|---|---|
| statusrequired | string one of: error | Always |
error |
| error_messagerequired | string | What went wrong. For |
Value error in gids: One or more values are not available. |
{
"status": "error",
"error_message": "Unauthorized"
} More than 300 requests in the last minute for this key. Wait for the number of seconds in Retry-After.
| Header | Type | Description | Example |
|---|---|---|---|
| Retry-After | integer | Seconds to wait before the next call. | 42 |
| X-RateLimit-Limit | integer | Requests allowed per minute for your key. | 300 |
Response fields
| Field | Type | Description | Example |
|---|---|---|---|
| statusrequired | string one of: error | Always |
error |
| error_messagerequired | string | What went wrong. For |
Value error in gids: One or more values are not available. |
{
"status": "error",
"error_message": "Too many requests"
} Example request
curl -X POST 'https://accounting.programmatic-engine.com/acme/video' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"url": "https://cdn.example.com/acme/spring_2026_001.mp4",
"video_id": "spring_2026_001",
"title": "Spring campaign, 10 s",
"video_md5": "5d41402abc4b2a76b9719d911017c592",
"gids": [
173,
174
],
"date_start": "2026-10-10 00:00:00",
"date_end": "2026-10-31 23:59:59",
"width": 1080,
"height": 1920,
"duration": 10,
"shot_second": [
3
]
}'
Check the status of your creatives#
Returns the status of creatives you uploaded. Pass the id values from the upload responses in ids[].
Without ids[] the call returns every creative of yours, including rejected, failed and archived ones, in one unpaginated response. That list grows over time. Ask for the ids you are waiting for.
An id that does not exist, or belongs to another partner, is left out of the answer. The call still returns 200. Compare the ids you sent with the ids you got back.
comment is filled only for rejected and failed. For other statuses it is an empty string. The text is written by a moderator or by our checks and can be in Russian.
The answer holds id and status, not your external_id. Keep the mapping from id to external_id on your side, or read it from the upload response.
Parameters
| Name | In | Type | Required | Description | Example |
|---|---|---|---|---|---|
| partner | path | string | yes | Your partner path, assigned by us at onboarding. |
acme |
| ids[] | query | integermin 1 | no | Creative ids to look up, as returned by the upload call. Repeat the parameter for each id, as in |
[1234,1235] |
Responses
The statuses of the creatives that were found.
| Header | Type | Description | Example |
|---|---|---|---|
| X-RateLimit-Limit | integer | Requests allowed per minute for your key. | 300 |
| X-RateLimit-Remaining | integer | Requests left in the current minute. | 299 |
Response fields
| Field | Type | Description | Example |
|---|---|---|---|
| itemsrequired | object[] | One entry per creative found. |
|
| items[].idrequired | integer | Our identifier of the creative. |
1234 |
| items[].commentrequired | string | Reason text for |
Resolution does not match the screen |
| items[].statusrequired | string one of: new, loaded, checking, checked, waiting, decode, accepted, confirmed, rejected, failed, archived | Current status. See Creative lifecycle for the meaning of each value. |
confirmed |
{
"items": [
{
"id": 1234,
"comment": "",
"status": "confirmed"
},
{
"id": 1235,
"comment": "Resolution does not match the screen",
"status": "rejected"
}
]
} The ids are malformed.
Response fields
| Field | Type | Description | Example |
|---|---|---|---|
| statusrequired | string one of: error | Always |
error |
| error_messagerequired | string | What went wrong. For |
Value error in gids: One or more values are not available. |
{
"status": "error",
"error_message": "Type error in ids.0: Invalid number."
} The key is missing, wrong or empty.
| Header | Type | Description | Example |
|---|---|---|---|
| WWW-Authenticate | string | Always | Bearer |
Response fields
| Field | Type | Description | Example |
|---|---|---|---|
| statusrequired | string one of: error | Always |
error |
| error_messagerequired | string | What went wrong. For |
Value error in gids: One or more values are not available. |
{
"status": "error",
"error_message": "Unauthorized"
} More than 300 requests in the last minute for this key. Wait for the number of seconds in Retry-After.
| Header | Type | Description | Example |
|---|---|---|---|
| Retry-After | integer | Seconds to wait before the next call. | 42 |
| X-RateLimit-Limit | integer | Requests allowed per minute for your key. | 300 |
Response fields
| Field | Type | Description | Example |
|---|---|---|---|
| statusrequired | string one of: error | Always |
error |
| error_messagerequired | string | What went wrong. For |
Value error in gids: One or more values are not available. |
{
"status": "error",
"error_message": "Too many requests"
} Example request
curl 'https://accounting.programmatic-engine.com/acme/moderated' \
-H "Authorization: Bearer $API_KEY"
Reconciliation
The plays you are billed for.
List the plays you are billed for#
Returns the plays that count for billing: bids of yours that won, were played on the screen and were verified. One row is one play.
A play is verified after the player reports the playback and the network has called the nurl that you returned in your bid. If that call to you failed, the play is not in this list and is not billed. The call is made once and is not repeated. See the Bid protocol page.
Send either unique_id (the request_id of the bids you want) or both date_from and date_to. If you send neither, the call returns 200 with no rows and a message in errors. If you send both kinds of filter, both apply.
The window is at most 3 days per call. If date_to is more than 3 days after date_from, the API does not fail. It silently replaces date_to with the day that is 3 days after date_from (date only, so that whole day is included), returns what it finds and adds Максимальный интервал между датами: 3 дней to errors. Always check errors in the response, and request one day or one hour at a time for large networks.
A search by date lists a play only after it has been matched with the playback log of the player, which usually takes a few hours. A search by unique_id does not wait for that match.
operator limits the result to the screens of one network or several networks. side_gid (or player_id, the same value) limits it to screens. Pass arrays as side_gid[]=173&side_gid[]=174. An unknown operator returns an empty list.
start_time and end_time are Unix seconds. They come from the player's playback log. end_time is null when the duration is unknown. When you search by unique_id alone, start_time can also be null if no playback record was matched.
price is the price you bid, unchanged, as a string with two decimals. The currency is the one in your contract, the API has no currency field.
A malformed date_from or date_to currently returns 500, not 400. Send valid dates.
Parameters
| Name | In | Type | Required | Description | Example |
|---|---|---|---|---|---|
| partner | path | string | yes | Your partner path, assigned by us at onboarding. |
acme |
| date_from | query | string | no | Start of the period, UTC. A date without time means the start of that day. Required together with |
2026-10-08 |
| date_to | query | string | no | End of the period, UTC. A date without time means the end of that day. Required together with |
2026-10-08 |
| unique_id[] | query | string | no | One or more |
["req_8f3a1c92e7"] |
| operator | query | string | no | Network name. Only plays on screens of this network are returned. A single value or |
marina-network |
| side_gid[] | query | integer | no | Screen ids ( |
[173] |
Responses
The plays found. Check errors as well, it can be present with a normal status code.
| Header | Type | Description | Example |
|---|---|---|---|
| X-RateLimit-Limit | integer | Requests allowed per minute for your key. | 300 |
| X-RateLimit-Remaining | integer | Requests left in the current minute. | 299 |
Response fields
| Field | Type | Description | Example |
|---|---|---|---|
| itemsrequired | object[] | One entry per verified play. |
|
| items[].request_idrequired | string | The |
req_8f3a1c92e7 |
| items[].video_idoptional | integer | null | Our id of the creative that played. Null if the creative no longer exists. |
1234 |
| items[].external_idoptional | string | null | Your identifier of the creative that played. |
spring_2026_001 |
| items[].side_gidrequired | integer | null | Screen id, the same value as |
173 |
| items[].operatoroptional | string | null | Network name of the screen. |
marina-network |
| items[].pricerequired | string | null | The price in your bid, as a decimal string with two digits. Null if your answer had no price. |
150.00 |
| items[].start_timeoptional | integer | null | Start of the play in Unix seconds, UTC. |
1791454530 |
| items[].end_timeoptional | integer | null | End of the play in Unix seconds, UTC. Null when the duration is unknown. |
1791454540 |
| totalrequired | integer | Number of entries in |
1 |
| errorsoptional | string[] | Present only when the call was adjusted or could not run as asked. Texts are currently in Russian. |
{
"items": [
{
"request_id": "req_8f3a1c92e7",
"video_id": 1234,
"external_id": "spring_2026_001",
"side_gid": 173,
"operator": "marina-network",
"price": "150.00",
"start_time": 1791454530,
"end_time": 1791454540
}
],
"total": 1
} The key is missing, wrong or empty.
| Header | Type | Description | Example |
|---|---|---|---|
| WWW-Authenticate | string | Always | Bearer |
Response fields
| Field | Type | Description | Example |
|---|---|---|---|
| statusrequired | string one of: error | Always |
error |
| error_messagerequired | string | What went wrong. For |
Value error in gids: One or more values are not available. |
{
"status": "error",
"error_message": "Unauthorized"
} More than 300 requests in the last minute for this key. Wait for the number of seconds in Retry-After.
| Header | Type | Description | Example |
|---|---|---|---|
| Retry-After | integer | Seconds to wait before the next call. | 42 |
| X-RateLimit-Limit | integer | Requests allowed per minute for your key. | 300 |
Response fields
| Field | Type | Description | Example |
|---|---|---|---|
| statusrequired | string one of: error | Always |
error |
| error_messagerequired | string | What went wrong. For |
Value error in gids: One or more values are not available. |
{
"status": "error",
"error_message": "Too many requests"
} Something failed on our side, or a date could not be parsed.
Response fields
| Field | Type | Description | Example |
|---|---|---|---|
| statusrequired | string one of: error | Always |
error |
| error_messagerequired | string | What went wrong. For |
Value error in gids: One or more values are not available. |
{
"status": "error",
"error_message": "Internal Server Error"
} Example request
curl 'https://accounting.programmatic-engine.com/acme/reconciliation/impressions' \
-H "Authorization: Bearer $API_KEY"