Trillboards CTV Measurement SDK β Quickstart
Use the Android SDK for native Android TV, Fire TV, and tablet players. It is
built from agent-core-lite, the same heartbeat, identity, and proximity code
used by Trillboards-managed players.
The Android heartbeat is deliberately simple:
POST /openrtb/v1/heartbeat
Register the device once, then initialize the SDK with that same stable device identifier. Heartbeat liveness, MAID, HEM, and UID2 ingestion do not require a Partner API key. The registered device/screen binding is the trust boundary.
The separate @trillboards/ctv-measurement web package still accepts a Partner
API key because it also calls authenticated /v2/sdk/* enrichment and
attribution endpoints.
1. Register each device
Registration is an authenticated provisioning action:
curl -X POST https://api.trillboards.com/v1/partner/device \
-H "Authorization: Bearer trb_partner_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"external_id": "store-123-player-1",
"name": "Store 123 front screen"
}'
Keep external_id stable for the physical player. The app bundle and screen
binding belong to that registered device; do not substitute a screen UUID for a
platform advertising identifier.
2. Install the Android SDK
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven { url = uri("https://maven.trillboards.com") }
}
}
dependencies {
implementation("com.trillboards:ctv-measurement:1.3.2")
}
Requires Android API 24+ and JDK 17 for the build.
3. Initialize with the registered device ID
import com.trillboards.measurement.MeasurementConfig
import com.trillboards.measurement.TrillboardsMeasurement
val config = MeasurementConfig.Builder(
deviceId = "store-123-player-1",
)
.scanIntervalMs(30_000)
.build()
TrillboardsMeasurement.initialize(applicationContext, config)
TrillboardsMeasurement.setConsentStatus(true)
TrillboardsMeasurement.startScheduledScans()
No API key is needed for this heartbeat flow. The legacy
MeasurementConfig.Builder(apiKey, deviceId) overload remains available for
apps that also call authenticated Partner API operations.
The AAR declares its own networking, Bluetooth, Wi-Fi, and Android advertising ID permissions. Request the runtime Bluetooth/Wi-Fi permissions appropriate to the device OS.
4. Send targeting identities
The built-in collector sends the actual platform advertising identifier
(GAID/AAID) when the platform exposes one. It never fabricates a screen ID as
device.ifa.
For audience IDs owned by the host, provide typed extended identities:
import com.trillboards.ctv.core.identity.ExtendedIdentity
import com.trillboards.ctv.core.identity.ExtendedIdentityProvider
val identityProvider = ExtendedIdentityProvider {
listOf(
ExtendedIdentity.hemSha256(
digest = existingSha256EmailDigest,
source = "your-identity-domain.example",
observedAt = observedAtIso8601,
),
ExtendedIdentity.uid2Token(
token = currentUid2AdvertisingToken,
source = "uidapi.com",
observedAt = observedAtIso8601,
expiresAt = uid2ExpiryIso8601,
),
)
}
val config = MeasurementConfig.Builder("store-123-player-1")
.extendedIdentityProvider(identityProvider)
.build()
Value semantics are exact:
- MAID/GAID is persisted raw and emitted as OpenRTB
device.ifa. hem_sha256must already be one SHA-256 digest. The server lowercases the hexadecimal representation once and does not hash it again.uid2_tokenis opaque and case-sensitive. Send it exactly as issued, with its expiration time so the host can refresh it.- HEM and UID2 are emitted under OpenRTB 2.6
user.eids.
5. Verify ingress and egress
Heartbeat success proves only that the registered-device contract accepted the request. For revenue readiness, verify the full chain:
- PostgreSQL
earner_screen_deviceshas the raw MAID state. - PostgreSQL
device_extended_identitieshas the exact active HEM/UID2 rows. - Redis
dtwin:{screenId}contains the same active identity projection. - A real outbound OpenRTB request contains
device.ifaand/oruser.eids. - A buyer response produces a VAST render and a canonical
completed_impressionsrow.
Never use request volume or a VAST tracker alone as revenue proof. Canonical revenue is a completed impression tied to the actual demand source and creative.
Endpoint authentication
| Endpoint | Authentication |
|---|---|
POST /v1/partner/device | Partner API key; provisioning |
POST /v1/partner/device/{deviceId}/heartbeat | None after device registration |
POST /openrtb/v1/heartbeat | None after device/screen registration |
GET /v1/partner/device/{deviceId}/heartbeat | Partner API key; readback |
/v2/sdk/* enrichment and attribution | Partner API key |
Full OpenAPI: https://api.trillboards.com/docs/openapi/partner-api.yaml.
Deep integration guide: https://api.trillboards.com/docs/integrations/ctv-measurement-partner-integration.md.