Event Tracking

Adlocaite uses a VAST 4.0 compliant event tracking system to record ad playout progress. Instead of a single confirmation call, individual events (start, quartiles, complete) are tracked as they occur -- enabling granular reporting and accurate billing.

Overview

When a screen plays an advertisement, your player fires tracking pixels at defined points during playback. These events are ingested by the Adlocaite Tracking Service and stored per offer for reporting and billing.

Integration Flow: Request Offer → Accept Offer → Display Ad → Fire Tracking Events

Two integration paths are available:

  • VAST players -- Request offers with vast=true. The returned VAST XML already contains all tracking pixel URLs. Your player fires them automatically during playback.
  • Custom / SDK integration -- Fire tracking events yourself via HTTP, either as individual GET pixel requests or as a batch POST.

VAST tracking events

The tracking system supports the following standard VAST events. Each event corresponds to a specific moment during ad playback:

  • Name
    impression
    Type
    event
    Description

    The ad was loaded and is about to be displayed. Fired once when the ad unit is first rendered.

  • Name
    start
    Type
    event
    Description

    Video/image playback has started (0% progress).

  • Name
    firstQuartile
    Type
    event
    Description

    Playback reached 25% of total duration.

  • Name
    midpoint
    Type
    event
    Description

    Playback reached 50% of total duration.

  • Name
    thirdQuartile
    Type
    event
    Description

    Playback reached 75% of total duration.

  • Name
    complete
    Type
    event
    Description

    Playback finished (100% of duration). This is the primary billing-relevant event.

The tracking service also accepts an error event with a code parameter for VAST 4.0 error reporting, but this is not relevant for billing.


Required events for billing

For a playout to be counted as billable, a minimum set of events must be received. This follows the VAST 3.0 minimum standard:

EventRequiredDescription
impressionRequiredMust be fired for the playout to be registered at all.
startRequiredConfirms that playback actually began.
firstQuartileRecommendedImproves reporting granularity.
midpointRecommendedImproves reporting granularity.
thirdQuartileRecommendedImproves reporting granularity.
completeRequiredMust be fired for the playout to count as billable.
Minimum for billing

At minimum, impression, start, and complete must be received for a playout to be billed. Missing any of these three events means the playout will not be counted. We strongly recommend sending all six standard events for full reporting coverage.


GET/track

Tracking via VAST pixels

When you request offers with vast=true, the returned VAST XML contains tracking pixel URLs for all standard events. A VAST-compliant player fires these URLs automatically as HTTP GET requests during playback.

URL format

https://tracking.adlocaite.com/track?offer_id={offer_id}&event={event}&ts={timestamp}&pub={publisher_id}&scr={screen_id}

Query parameters

  • Name
    offer_id
    Type
    string
    Description

    The UUID of the ad offer being tracked.

  • Name
    event
    Type
    string
    Description

    Event type: impression, start, firstQuartile, midpoint, thirdQuartile, complete, or error.

  • Name
    ts
    Type
    integer
    Description

    Client timestamp in Unix milliseconds. Automatically included in VAST URLs at generation time.

  • Name
    pub
    Type
    string
    Description

    Publisher ID (UUID). Automatically included if available.

  • Name
    scr
    Type
    string
    Description

    Screen ID (UUID). Automatically included if available.

The endpoint returns a 1x1 transparent GIF with Cache-Control: no-store headers. No authentication is required -- VAST players cannot set custom headers, so these URLs are designed to work as fire-and-forget pixels.

VAST XML tracking section

GET
/track
<TrackingEvents>
  <Tracking event="start">
    <![CDATA[https://tracking.adlocaite.com/track
      ?offer_id=550e8400-e29b-41d4-a716-446655440000
      &event=start
      &ts=1710340000000
      &pub=pub-123-uuid
      &scr=screen-456-uuid]]>
  </Tracking>
  <Tracking event="firstQuartile">
    <![CDATA[https://tracking.adlocaite.com/track
      ?offer_id=550e8400-e29b-41d4-a716-446655440000
      &event=firstQuartile
      &ts=1710340000000
      &pub=pub-123-uuid
      &scr=screen-456-uuid]]>
  </Tracking>
  <Tracking event="midpoint">
    <![CDATA[https://tracking.adlocaite.com/track
      ?offer_id=550e8400-e29b-41d4-a716-446655440000
      &event=midpoint
      &ts=1710340000000
      &pub=pub-123-uuid
      &scr=screen-456-uuid]]>
  </Tracking>
  <Tracking event="thirdQuartile">
    <![CDATA[https://tracking.adlocaite.com/track
      ?offer_id=550e8400-e29b-41d4-a716-446655440000
      &event=thirdQuartile
      &ts=1710340000000
      &pub=pub-123-uuid
      &scr=screen-456-uuid]]>
  </Tracking>
  <Tracking event="complete">
    <![CDATA[https://tracking.adlocaite.com/track
      ?offer_id=550e8400-e29b-41d4-a716-446655440000
      &event=complete
      &ts=1710340000000
      &pub=pub-123-uuid
      &scr=screen-456-uuid]]>
  </Tracking>
</TrackingEvents>

Manual pixel request

curl "https://tracking.adlocaite.com/track?offer_id=550e8400-e29b-41d4-a716-446655440000&event=complete&ts=1710340000000&pub=pub-123-uuid&scr=screen-456-uuid"
# Returns: 1x1 transparent GIF

POST/track

Tracking via SDK batch

For custom player integrations or high-volume setups, you can submit multiple events in a single authenticated POST request.

Authentication

The POST endpoint requires HMAC-SHA256 authentication. Generate a token by signing the current Unix timestamp (milliseconds) with your tracking secret:

Authorization: Bearer {timestamp}::{hmac_sha256_hex}

Tokens are valid for 5 minutes after generation.

Request body

  • Name
    offer_id
    Type
    string
    Description

    The UUID of the ad offer. Must be a valid UUID format.

  • Name
    events
    Type
    array
    Description

    Non-empty array of event objects. Each event requires a type (string) and timestamp (ISO-8601 or Unix milliseconds).

  • Name
    publisher_id
    Type
    string
    Description

    Optional. Publisher UUID.

  • Name
    screen_id
    Type
    string
    Description

    Optional. Screen UUID.

  • Name
    player_version
    Type
    string
    Description

    Optional. Your player software version identifier.

  • Name
    screen_resolution
    Type
    string
    Description

    Optional. Screen resolution during playback (e.g., "1920x1080").

Request

POST
/track
curl -X POST "https://tracking.adlocaite.com/track" \
  -H "Authorization: Bearer 1710340000000::a1b2c3d4e5f6..." \
  -H "Content-Type: application/json" \
  -d '{
    "offer_id": "550e8400-e29b-41d4-a716-446655440000",
    "publisher_id": "pub-123-uuid",
    "screen_id": "screen-456-uuid",
    "events": [
      { "type": "impression", "timestamp": "2026-03-13T10:00:00Z" },
      { "type": "start", "timestamp": "2026-03-13T10:00:01Z" },
      { "type": "firstQuartile", "timestamp": "2026-03-13T10:00:04Z" },
      { "type": "midpoint", "timestamp": "2026-03-13T10:00:06Z" },
      { "type": "thirdQuartile", "timestamp": "2026-03-13T10:00:09Z" },
      { "type": "complete", "timestamp": "2026-03-13T10:00:11Z" }
    ],
    "player_version": "2.1.0",
    "screen_resolution": "1920x1080"
  }'

Success response (200)

{
  "success": true,
  "event_id": "evt-a1b2c3d4-uuid",
  "events_count": 6
}

Error: invalid offer_id (400)

{
  "error": "Invalid offer_id: must be a valid UUID"
}

Error: unauthorized (401)

{
  "error": "Missing or invalid authorization token"
}

Best practices

Event timing

Fire each tracking event as close to the actual playback moment as possible. The tracking service stores both the client-provided timestamp (ts) and the server receive time (received_at), so large discrepancies between these two values may flag the playout for review.

Retry logic

  • GET pixel requests -- Fire-and-forget. If a pixel fails, the VAST standard does not require retries. However, for accurate billing, we recommend retrying failed impression, start, and complete pixels up to 3 times with exponential backoff.
  • POST batch requests -- Implement retry with backoff on 5xx responses. 4xx errors indicate a client-side issue (invalid token, malformed body) and should not be retried without fixing the request.

Offline / buffered playback

For screens with intermittent connectivity, buffer events locally and submit them via the POST batch endpoint when connectivity is restored. Include accurate client timestamps so the events can be attributed to the correct playback session.

Performance

  • Tracking pixel requests are non-blocking -- they return a 1x1 GIF immediately and process asynchronously
  • For high-volume setups with many screens, prefer the POST batch endpoint to reduce HTTP overhead
  • Set reasonable timeouts (3-5 seconds) for pixel requests to avoid blocking your content pipeline

POST/playout/confirm/{dealId}

Deprecated: playout/confirm

Deprecated -- removal after 2026-06-01

The legacy POST /playout/confirm/{dealId} endpoint is deprecated. It still works but only fires a single complete event internally and does not provide the granular tracking data needed for full billing and reporting.

Migrate to VAST tracking events or the POST /track batch endpoint.

Migration guide

The old endpoint accepted a deal_id and optional metadata. The new system tracks by offer_id and uses standard VAST events:

Old (playout/confirm)New (event tracking)
Single POST per dealMultiple events per offer
deal_id basedoffer_id based
completion_rate: 100complete event fired
played_at timestampstart event timestamp
No quartile dataFull quartile tracking
Requires API key authGET pixels: no auth / POST batch: HMAC

How to migrate

  1. VAST players: Request offers with vast=true. The VAST XML includes all tracking pixel URLs. Remove any manual playout/confirm calls.
  2. Custom players: Replace the single playout/confirm POST with individual GET pixel requests (or a POST batch) for impression, start, and complete at minimum.
  3. Verify: Check that your playouts appear in reporting with all expected events.

Old (deprecated)

# Don't use this anymore
curl -X POST "https://api.adlocaite.com/functions/v1/api/playout/confirm/DEAL_ID" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "played_at": "2026-03-13T14:30:00Z",
    "duration_seconds": 15,
    "completion_rate": 100
  }'

New (VAST pixel -- recommended)

# Request offer with VAST
curl "https://api.adlocaite.com/functions/v1/api/offers/request/SCREEN_ID?vast=true" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Player automatically fires pixels from VAST XML:
# impression, start, firstQuartile, midpoint,
# thirdQuartile, complete

New (manual pixels)

# Fire events individually
curl "https://tracking.adlocaite.com/track?offer_id=OFFER_ID&event=impression&ts=$(date +%s000)"
curl "https://tracking.adlocaite.com/track?offer_id=OFFER_ID&event=start&ts=$(date +%s000)"
# ... playback happens ...
curl "https://tracking.adlocaite.com/track?offer_id=OFFER_ID&event=complete&ts=$(date +%s000)"

Deprecation response

{
  "success": true,
  "deprecated": true,
  "message": "This endpoint is deprecated and will be removed after 2026-06-01. Playout tracking now happens automatically via VAST tracking pixels.",
  "deal_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
}

Was this page helpful?