SDK Quickstart

The SDK API (/v2/sdk) powers CTV and DOOH measurement: census-based audience enrichment, QR scan attribution, and impression ingestion with GIVT dedup and frequency counting. Use it from a device SDK, a server-side measurement pipeline, or a pixel proxy.

Base URL: https://api.trillboards.com

1. Get an API key

SDK keys have the prefix tb_dat_ (issued via the portal). They must carry SDK scopes such as sdk:enrich, sdk:qr, and sdk:impression. Pass the key in the X-API-Key header on every request.

2. Enrich an impression context

Census enrichment returns a stable household ID, IAB demographic segments, and connection-type hints for the caller's IP.


curl -s -X POST "https://api.trillboards.com/v2/sdk/enrich" \
  -H "X-API-Key: tb_dat_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{}'

Success response:


{
  "geohash6": "dr5ruq",
  "iabIncomeSegmentId": "1003",
  "iabIncomeSegmentName": "$75,000-$99,999",
  "iabAgeSegmentId": "2004",
  "iabAgeSegmentName": "35-44",
  "educationTier": "bachelors_plus",
  "connectionType": "residential",
  "householdId": "a8c3f1d7b2e4...",
  "source": "maxmind"
}

source names the geolocation database behind the record: maxmind (MaxMind GeoLite2), dbip (IP Geolocation by DB-IP, CC BY 4.0), or ipinfo when neither is loaded.

Pass an optional geohash6 (6-character geohash) in the body when the client knows its location more precisely than the caller IP suggests.

3. Handle errors

Authentication, validation, and rate-limit failures all return the canonical envelope:


{
  "error": {
    "type": "rate_limit_error",
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded. Please retry after the specified time.",
    "request_id": "req_a1b2c3d4e5f6789012345678901234ab",
    "doc_url": "https://api.trillboards.com/docs/errors#rate_limit_exceeded"
  }
}

429 responses also include the standard Retry-After header. The enrich endpoint is capped at 300 req/min per key; QR beacon at 200 req/min; impression at 1000 req/min. Back off on the client side — don't stack retries.

4. Ingest impressions

Once enriched, post impressions to /v2/sdk/impression with a client-generated impressionId (UUID) so GIVT dedup can latch across retries. Required fields include adId, placementId, and channel (ctv, dooh, or web). See validation/sdkSchemas.js or the generated OpenAPI for the full body shape.

Next steps