OpenRTB 2.6 Integration

The OpenRTB 2.6 interface provides compatibility with standard programmatic advertising systems and Supply-Side Platforms (SSPs). This interface bridges the gap between traditional RTB workflows and the Adlocaite platform.

Deprecated Interface - Limited Functionality

This interface is maintained for legacy compatibility only. We strongly recommend using the Core API instead, which provides:

  • Real-time offer management with instant acceptance/rejection
  • Precise timing control for optimal DOOH playout
  • Full feature set including dynamic pricing and audience targeting
  • Better performance and lower latency

The OpenRTB interface has significant functional limitations due to protocol constraints. Use it only if your system cannot be integrated via the Core API. See the Migration Guide for step-by-step instructions on switching to the Core API.


Overview

The OpenRTB 2.6 interface was developed for integration with Supply-Side Platforms (SSPs) and other standard RTB systems. It provides a bridge between traditional programmatic advertising workflows and the Adlocaite DOOH platform.

When to use this interface

Use the OpenRTB interface only in these scenarios:

  • Your publisher management system is already integrated with an SSP that uses OpenRTB 2.6
  • Your playout system cannot make direct API calls to the Adlocaite Core API
  • You need compatibility with existing RTB workflows for legacy systems

For all other cases, use the Core API which provides superior functionality and performance.


Developer utilities

The interface publishes an OpenAPI 3.0 specification with every endpoint, schema and example. Use it to generate a client, or import it into a tool such as Postman or Insomnia.

Download the specification

Download the OpenAPI specification

curl -o openrtb-openapi.json \
  https://api.adlocaite.com/functions/v1/openrtb-2-6/openapi.json

Or access directly in your browser:

  • Production: https://api.adlocaite.com/functions/v1/openrtb-2-6/openapi.json
  • Staging: https://staging.api.adlocaite.com/functions/v1/openrtb-2-6/openapi.json

Generate a client

The document is a plain OpenAPI 3.0 file, so any generator accepts it:

openapi-generator-cli generate -i openrtb-openapi.json -g <your-language>

Import into Postman

  1. Open Postman and click Import in the top left
  2. Select the downloaded openrtb-openapi.json file, or paste the URL directly
  3. Postman converts the specification into a collection with every endpoint pre-configured

Configure environment variables

After importing, set up your Postman environment with these variables:

  • Name
    base_url
    Type
    string
    Description

    Base URL for the OpenRTB API

    • Production: https://api.adlocaite.com/functions/v1/openrtb-2-6
    • Staging: https://staging.api.adlocaite.com/functions/v1/openrtb-2-6
  • Name
    api_key
    Type
    string
    Description

    Your Publisher API Key for authentication

The specification includes example BidRequests that you can modify for your specific testing needs.


Implementation constraints

The OpenRTB 2.6 standard was designed for traditional web and mobile advertising. Digital Out-of-Home advertising requires precise timing, screen availability management, and real-time content delivery - capabilities that the OpenRTB protocol does not adequately support.

Why these limitations exist

The Adlocaite platform is optimized for reactive, real-time DOOH advertising where offers must be matched, accepted, and displayed within seconds. This approach maximizes:

  • Revenue for publishers: By ensuring the highest-value advertisements are shown at the right time
  • Campaign performance for advertisers: Through precise audience targeting and optimal timing
  • System efficiency: By avoiding bid conflicts and reducing wasted inventory

The OpenRTB protocol, designed for auction-based environments with longer decision windows, cannot fully support this reactive model. Therefore, this interface operates with significant functional constraints to maintain system integrity.

Supported features

  • Name
    Single impression per request
    Description

    Only one impression can be requested per BidRequest. Multiple impressions are not supported.

  • Name
    Fixed price deals only
    Description

    Auction type must be Fixed Price (at=3). First-price and second-price auctions are not supported.

  • Name
    Video format only
    Description

    Only the Video object format is supported. Banner format is not available.

  • Name
    External Screen ID required
    Description

    Each request must include a valid External Screen ID in the tagid field. Our implementation assumes tagid contains the screen identifier; other SSPs may use different identifier attributes.

  • Name
    Exact resolution matching
    Description

    Screen resolution must exactly match the requested dimensions. No scaling or format adaptation.

  • Name
    Audience quantity required
    Description

    Every request must state how many people one play reaches, either as imp.qty.multiplier (OpenRTB 2.6, preferred) or as the legacy imp.ext.totalaud. If both are present, imp.qty.multiplier is used.

Not supported

  • Multiple impressions per request
  • Open auction formats (First-price, Second-price)
  • Banner object format
  • Dynamic creative optimization
  • Synchronous offer acceptance/rejection (the OpenRTB path learns about lost bids asynchronously via the loss notification URL, see below)
  • Flexible scheduling and timing control

How it works

The OpenRTB integration follows a simplified request-response flow:

Request flow

  1. BidRequest received: SSP sends OpenRTB 2.6 BidRequest with screen details and deal information
  2. Validation: Request is validated against implementation constraints
  3. Screen identification: External Screen ID is extracted from imp.tagid (our implementation assumes tagid contains the screen identifier)
  4. Minimum bid calculation: Floor price is calculated from deal.bidfloor × the audience quantity (imp.qty.multiplier, or imp.ext.totalaud for legacy requests)
  5. Offer matching: Platform finds matching offers for the screen above minimum bid
  6. Resolution check: Asset resolution must exactly match requested dimensions
  7. VAST generation: VAST 4.0 XML is generated with tracking URLs and OpenRTB macros
  8. BidResponse returned: Response includes bid price, VAST XML, and deal information

Response types

  • Name
    HTTP 200 + BidResponse
    Description

    Successful bid with offer details and VAST XML

  • Name
    HTTP 200 + Empty seatbid
    Description

    No bid with reason code (NBR) - technical error or constraint violation

  • Name
    HTTP 204 No Content
    Description

    No bid - no matching offers available

  • Name
    HTTP 400 Bad Request
    Description

    Validation error - request does not meet implementation constraints

  • Name
    HTTP 401 Unauthorized
    Description

    Missing or invalid API key

  • Name
    HTTP 500 Internal Server Error
    Description

    Unexpected server error


Asset matching

The platform matches advertisements to screens based on the screen type configured by the publisher. When registering a screen, publishers specify which type of content their screen can display.

Screen types and asset compatibility

Publishers classify their screens into one of three types when registering them in the platform:

  • Static Screen: Displays only static images (JPEG, PNG)
  • Slow Screen: Displays static images and slow animations (Cinemagraphs)
  • Moving Screen: Displays any asset type - static images, slow animations, or full video

The matching algorithm automatically selects assets that are compatible with the publisher-configured screen type. The following table shows which asset types can be returned for each screen type:

Screen Type

Static Assets

Slow Assets
(Cinemagraph)

Moving Assets
(Video)

Static Screen

Slow Screen

Moving Screen

How the matching works

When a BidRequest arrives, the platform performs the following steps:

  1. Screen identification: The External Screen ID from imp.tagid is used to look up the screen and its type (static/slow/moving)
  2. Asset selection: The matching algorithm finds the best matching advertisement and selects an asset that is compatible with the screen type
  3. MIME type check: The selected asset's MIME type is verified against the SSP's allowed types in video.mimes
  4. Response generation: A VAST 4.0 XML response is generated with the asset URL and correct MIME type

SSP MIME type signaling

SSPs use the video.mimes array in the BidRequest to specify which file formats they accept. For example:

  • Roadside screens (image-only): ["image/jpeg", "image/png"]
  • Indoor video screens: ["video/mp4", "video/webm"]
  • Flexible screens: ["video/mp4", "video/webm", "image/jpeg", "image/png"]

The platform checks that the selected asset's MIME type is included in this list. If not, a no-bid response is returned.

Matching examples

Example 1: Moving Screen with video restriction

  • Screen Type: Moving
  • SSP allows: ["video/mp4"]
  • Available assets: Static image, Video
  • Result: Video asset is selected (compatible with both screen type and SSP requirements)

Example 2: Static Screen with flexible SSP

  • Screen Type: Static
  • SSP allows: ["video/mp4", "image/jpeg"]
  • Available assets: Static image, Video
  • Result: Static image is selected (only compatible asset for static screen)

Example 3: No compatible asset

  • Screen Type: Static
  • SSP allows: ["video/mp4"]
  • Available assets: Static image
  • Result: No-bid (HTTP 204) - static image not allowed by SSP

VAST response format

All responses use VAST 4.0 XML format. The MediaFile tag's MIME type reflects the actual asset format:

For static images:

<MediaFile type="image/jpeg" width="1080" height="1920">
  <![CDATA[https://storage.adlocaite.com/assets/static-ad.jpg]]>
</MediaFile>
<Duration>00:00:10</Duration>

For videos:

<MediaFile type="video/mp4" width="1080" height="1920">
  <![CDATA[https://storage.adlocaite.com/assets/video-ad.mp4]]>
</MediaFile>
<Duration>00:00:15</Duration>

The platform automatically determines the correct MIME type from the asset file extension.


Authentication

Authentication uses Bearer token authentication with your Publisher API Key.

Authentication

curl -X POST https://api.adlocaite.com/functions/v1/openrtb-2-6/bid \
  -H "Authorization: Bearer YOUR_PUBLISHER_API_KEY" \
  -H "Content-Type: application/json" \
  -d @bidrequest.json

See the Authentication guide for details on obtaining your API key.


Endpoints

POST /bid

Submit a BidRequest for a specific screen and receive a BidResponse with pricing and creative details.

This is the main endpoint for OpenRTB bidding. The SSP sends a BidRequest containing screen information, deal details, and audience data. The platform responds with either a bid including VAST XML or a no-bid response.

Required headers

  • Name
    Authorization
    Type
    string
    Description

    Bearer token with your Publisher API Key

  • Name
    Content-Type
    Type
    string
    Description

    Must be application/json

Request

POST
/functions/v1/openrtb-2-6/bid
curl -X POST https://api.adlocaite.com/functions/v1/openrtb-2-6/bid \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "auction-12345",
    "imp": [{
      "id": "1",
      "tagid": "screen-ext-001",
      "video": {
        "mimes": ["video/mp4"],
        "w": 1920,
        "h": 1080
      },
      "pmp": {
        "deals": [{
          "id": "deal-001",
          "bidfloor": 2.50,
          "at": 3
        }]
      },
      "qty": {
        "multiplier": 119.47,
        "sourcetype": 1,
        "vendor": "measurement-vendor.example"
      }
    }],
    "at": 3
  }'

Response (200 - Bid)

{
  "id": "auction-12345",
  "seatbid": [{
    "bid": [{
      "id": "bid-uuid-12345",
      "impid": "1",
      "price": 2.50,
      "adid": "offer-uuid-67890",
      "adm": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><VAST version=\"4.0\">...</VAST>",
      "adomain": ["adlocaite.com"],
      "cid": "offer-uuid-67890",
      "crid": "offer-uuid-67890",
      "dealid": "deal-001",
      "w": 1920,
      "h": 1080
    }]
  }],
  "bidid": "bidid-uuid-99999",
  "cur": "EUR"
}

Response (204 - No Bid)

No Content

Response (400 - Validation Error)

{
  "error": "MULTI_IMP_NOT_SUPPORTED",
  "message": "Multiple impressions per request are currently not supported",
  "details": {
    "imp_count": 3
  }
}

POST /

Alternative endpoint that routes to the same bid handler. Use /bid for clarity.


BidRequest format

The BidRequest must follow OpenRTB 2.6 specification with specific requirements for Adlocaite integration.

Required fields

  • Name
    id
    Type
    string
    Description

    Unique auction identifier

  • Name
    imp
    Type
    array
    Description

    Array with exactly one impression object

  • Name
    imp[0].id
    Type
    string
    Description

    Impression identifier

  • Name
    imp[0].tagid
    Type
    string
    Description

    External Screen ID for screen identification (our implementation assumes tagid contains the screen identifier; other SSPs may use different identifier attributes)

  • Name
    imp[0].video
    Type
    object
    Description

    Video object with width and height

  • Name
    imp[0].video.w
    Type
    integer
    Description

    Screen width in pixels

  • Name
    imp[0].video.h
    Type
    integer
    Description

    Screen height in pixels

  • Name
    imp[0].pmp
    Type
    object
    Description

    Private Marketplace object

  • Name
    imp[0].pmp.deals
    Type
    array
    Description

    Array with at least one deal object

  • Name
    imp[0].pmp.deals[0].id
    Type
    string
    Description

    Deal identifier

  • Name
    imp[0].pmp.deals[0].bidfloor
    Type
    number
    Description

    Minimum CPM in EUR

  • Name
    imp[0].pmp.deals[0].at
    Type
    integer
    Description

    Must be 3 (Fixed Price)

  • Name
    imp[0].qty.multiplier
    Type
    number
    Description

    Audience size for one play, used for the bid floor calculation. This is the OpenRTB 2.6 field for the purpose (section 3.2.31) and the preferred way to send the number. Required unless your request carries the audience size in the legacy imp[0].ext.totalaud instead -- send one of the two, not both.

  • Name
    at
    Type
    integer
    Description

    Auction type, must be 3 (Fixed Price)

Optional and legacy fields

These are not required. imp[0].ext.totalaud is the one exception: it stands in for imp[0].qty.multiplier, so a request that omits both is rejected.

  • Name
    imp[0].qty.sourcetype
    Type
    integer
    Description

    Optional. Who measured the quantity, per the AdCOM list "DOOH Multiplier Measurement Source Types": 0 unknown, 1 measurement vendor, 2 publisher, 3 exchange. Send it if you have it -- it tells us how the number came about.

  • Name
    imp[0].qty.vendor
    Type
    string
    Description

    Domain of the measurement vendor. Optional in general, but the specification requires it when sourcetype is 1.

  • Name
    imp[0].ext.totalaud
    Type
    number
    Description

    Legacy alternative to imp[0].qty.multiplier, carrying the same number. Predates OpenRTB 2.6 and is still accepted for existing integrations. Use imp.qty for new ones -- it is the only one of the two that can express where the number came from. If a request carries both, imp[0].qty.multiplier is used.

Minimum bid calculation

The minimum bid in cents is calculated as:

minBidCents = (bidfloor × audience) / 10

Where audience is imp.qty.multiplier, or imp.ext.totalaud if the request uses the legacy field.

Example:

  • bidfloor = 2.50 EUR CPM
  • audience = 119.47 impressions
  • minBidCents = (2.50 × 119.47) / 10 = 30 cents

BidResponse format

The BidResponse follows OpenRTB 2.6 specification with VAST 4.0 XML for creative delivery.

Successful bid

  • Name
    id
    Type
    string
    Description

    Mirrors BidRequest.id

  • Name
    seatbid
    Type
    array
    Description

    Array containing seat bid objects

  • Name
    seatbid[0].bid
    Type
    array
    Description

    Array containing bid objects

  • Name
    seatbid[0].bid[0].id
    Type
    string
    Description

    Unique bid identifier (UUID)

  • Name
    seatbid[0].bid[0].impid
    Type
    string
    Description

    Mirrors impression ID from BidRequest

  • Name
    seatbid[0].bid[0].price
    Type
    number
    Description

    Bid price in EUR (converted from cents)

  • Name
    seatbid[0].bid[0].adm
    Type
    string
    Description

    VAST 4.0 XML containing creative and tracking information

  • Name
    seatbid[0].bid[0].lurl
    Type
    string
    Description

    Loss notice URL. Call it when the bid loses, with ${AUCTION_LOSS} substituted by the loss reason code. See Loss notifications. No nurl or burl is sent; billing is triggered by the VAST impression callback only.

  • Name
    seatbid[0].bid[0].adomain
    Type
    array
    Description

    Advertiser domains (["adlocaite.com"])

  • Name
    seatbid[0].bid[0].dealid
    Type
    string
    Description

    Deal ID from BidRequest

  • Name
    seatbid[0].bid[0].w
    Type
    integer
    Description

    Creative width

  • Name
    seatbid[0].bid[0].h
    Type
    integer
    Description

    Creative height

  • Name
    bidid
    Type
    string
    Description

    Unique bid transaction identifier (UUID)

  • Name
    cur
    Type
    string
    Description

    Currency code (EUR)

Example Response

{
  "id": "auction-12345",
  "seatbid": [{
    "bid": [{
      "id": "f7b3c9e1-4d2a-4c8b-9a1e-3f5d6c7b8a9d",
      "impid": "1",
      "price": 2.53,
      "adid": "offer-a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "adm": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<VAST version=\"4.0\">...</VAST>",
      "lurl": "https://api.adlocaite.com/functions/v1/openrtb-2-6/loss/a1b2c3d4-e5f6-7890-abcd-ef1234567890?reason=${AUCTION_LOSS}&price=${AUCTION_PRICE}&cur=${AUCTION_CURRENCY}&mtw=${AUCTION_MIN_TO_WIN}&aid=${AUCTION_ID}&pub=...&scr=...&ts=1756900000&token=...",
      "adomain": ["adlocaite.com"],
      "cid": "offer-a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "crid": "offer-a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "dealid": "deal-001",
      "w": 1920,
      "h": 1080
    }]
  }],
  "bidid": "bid-transaction-uuid-99999",
  "cur": "EUR"
}

Note: The adm field contains the complete VAST 4.0 XML (truncated above for readability). See the /bid endpoint response for a full example.

No-bid response

  • Name
    id
    Type
    string
    Description

    Mirrors BidRequest.id

  • Name
    seatbid
    Type
    array
    Description

    Empty array

  • Name
    nbr
    Type
    integer
    Description

    No-bid reason code (0 = Unknown, 1 = Technical Error)

  • Name
    cur
    Type
    string
    Description

    Currency code (EUR)

Example Response

{
  "id": "auction-12345",
  "seatbid": [],
  "nbr": 0,
  "cur": "EUR"
}

OpenRTB macros in tracking URLs

The VAST XML includes tracking URLs with OpenRTB macros that are replaced by the SSP:

  • ${AUCTION_PRICE}: Final auction price
  • ${TOTAL_IMP}: Total audience impressions

Example tracking URL:

https://tracking.adlocaite.io/track?offer_id=abc-123&event=impression&price=${AUCTION_PRICE}&aud=${TOTAL_IMP}

Loss notifications

Every bid carries a loss notice URL as defined by OpenRTB 2.6: lurl. It points at the OpenRTB endpoint itself (next to the impression callback) and is signed; call it exactly as returned, with the macros substituted. No request body is required or read for the outcome itself; the information is in the URL. Win notices (nurl) and billing notices (burl) are not part of the bid response: the VAST impression callback is the only billing event.

Loss notices matter for you as much as for us: a bid that never receives a loss notice keeps its budget reservation until the offer expires, which lowers the advertiser budget available for your screens in the meantime. Sending lurl promptly frees that budget within about a minute.

GET https://api.adlocaite.com/functions/v1/openrtb-2-6/loss/{offer_id}?reason=${AUCTION_LOSS}&price=${AUCTION_PRICE}
    &cur=${AUCTION_CURRENCY}&mtw=${AUCTION_MIN_TO_WIN}&aid=${AUCTION_ID}&pub=...&scr=...&ts=...&token=...

Macros

  • Name
    ${AUCTION_LOSS}
    Type
    integer
    Description

    OpenRTB 2.6 loss reason code. 0 = bid won, 1 to 10 = technical (invalid response, expired impression, missing markup, ...), 100 to 104 = auction (below floor, lost to higher bid, lost to PMP deal, seat blocked), 200 to 213 = creative filtered (201 = pending approval, 202 = disapproved by the exchange), 1000 and above = exchange specific.

  • Name
    ${AUCTION_PRICE}
    Type
    number
    Description

    Clearing price of the winning bid (CPM). On a loss notice this is the winner's price, not ours; it is stored for analysis and never used for billing.

  • Name
    ${AUCTION_MIN_TO_WIN}
    Type
    number
    Description

    Minimum bid that would have won. Optional.

  • Name
    ${AUCTION_ID}
    Type
    string
    Description

    The BidRequest id.

  • Name
    ${AUCTION_CURRENCY}
    Type
    string
    Description

    Currency of the auction price.

${TOTAL_IMP} is not part of the notice URL. It belongs in the VAST impression tracking URL only.

Behaviour

  • Method: GET. POST with a JSON body is accepted as well and the body is stored for diagnostics, but it is not required.
  • Response: 204 No Content when the notice was accepted. There is never a response body.
  • Timing: a notice may arrive late; the URL stays valid for 24 hours after the bid response.
  • Idempotency: retries of the same notice are safe. The first call counts, later calls only increment a counter.
  • Loss notices release the advertiser budget reserved for the bid. A loss notice for a bid that was already billed is recorded and ignored.
  • Unsubstituted macros (the literal ${AUCTION_LOSS}) are tolerated: the notice is stored without the value.

Notice response codes

  • Name
    204
    Description

    Notice accepted.

  • Name
    403
    Description

    Signature invalid or ts outside the 24 hour window. The URL was altered or was not issued by Adlocaite.

  • Name
    413 / 414
    Description

    Request body above 16 KB or query string above 4 KB. Send the URL as returned.

  • Name
    503
    Description

    Temporary ingestion problem. Retry with backoff; the notice remains valid.


Error handling

The OpenRTB interface uses standard HTTP status codes and error response format.

Error response format

{
  "error": "ERROR_CODE",
  "message": "Human-readable error description",
  "details": {
    "additional": "context information"
  },
  "deprecated": true,
  "deprecation_message": "This OpenRTB interface is legacy and will be phased out. Please migrate to the official Adlocaite API.",
  "documentation": "https://docs.adlocaite.com",
  "migration_guide": "https://docs.adlocaite.com/migration/openrtb-to-api"
}

error, message and details describe the failure. The remaining fields are the deprecation notice and are identical on every response, so match on error rather than on the text.

Deprecation signalling

Every response carries the deprecation notice as headers:

Deprecation: true
Link: <https://docs.adlocaite.com/migration/openrtb-to-api>; rel="deprecation"

The header names follow RFC 9745 (Deprecation) and RFC 8288 (Link). Note that RFC 9745 defines the value of Deprecation as a structured field date; this interface sends the boolean true instead. Treat the presence of the header as the signal and do not parse its value as a date.

The headers are on all responses, including the 204 no-bid, which has no body to carry the notice in. A successful 200 BidResponse carries it in ext.adlocaite instead of at the top level, so the OpenRTB 2.6 schema stays intact.

Common error codes

  • Name
    INVALID_API_KEY
    Description

    Missing or invalid API key in Authorization header (HTTP 401)

  • Name
    MULTI_IMP_NOT_SUPPORTED
    Description

    Request contains multiple impressions (HTTP 400)

  • Name
    NO_VIDEO_OBJECT
    Description

    Video object is missing or Banner format was used (HTTP 400)

  • Name
    NO_PMP_DEALS
    Description

    PMP deals array is missing or empty (HTTP 400)

  • Name
    NOT_FIXED_PRICE
    Description

    Auction type is not Fixed Price (at≠3) (HTTP 400)

  • Name
    NO_EXTERNAL_SCREEN_ID
    Description

    tagid field is missing (HTTP 400)

  • Name
    NO_TOTAL_AUDIENCE
    Description

    No usable audience quantity: neither imp.qty.multiplier nor imp.ext.totalaud was present and greater than 0 (HTTP 400). The code keeps its historical name. Note that if you send imp.qty, its multiplier must be valid -- we will not fall back to imp.ext.totalaud in that case.

  • Name
    NO_RESOLUTION
    Description

    Video width or height is missing (HTTP 400)

No-bid reason codes (NBR)

When returning HTTP 200 with empty seatbid, the nbr field indicates the reason:

  • Name
    0
    Description

    Unknown error or resolution mismatch

  • Name
    1
    Description

    Technical error (RPC failure, database error)

For legitimate no-bid scenarios (no matching offers, minimum bid not met), HTTP 204 is returned without a response body.

Was this page helpful?