← All engineering notes
INTEGRATIONS·7 min read

Provider Adapters: Verifying Outcomes Across TikTok, Instagram, YouTube, and X

Every social platform reports performance data differently — and changes its API without asking. Here's the adapter pattern that keeps Astera's verification engine from breaking every time one of them does.

Astera pays creators based on verified views, clicks, and installs across TikTok, Instagram, YouTube, and X. Each platform exposes different metrics, rate limits, and auth flows, and each has changed its API in ways that broke integrations we didn't control.

Every provider implements the same internal interface — fetch, normalize, verify — regardless of what the underlying API looks like. The rest of the system, including the payout engine, only ever talks to that interface, never to a platform's SDK directly.

providers/SocialProvider.kt
interface SocialProvider {
    suspend fun fetchMetrics(contentId: String): RawMetrics
    fun normalize(raw: RawMetrics): VerifiedOutcome
}

class TikTokProvider(private val client: TikTokApiClient) : SocialProvider {
    override suspend fun fetchMetrics(contentId: String) = client.videoStats(contentId)
    override fun normalize(raw: RawMetrics) = VerifiedOutcome(
        views = raw["play_count"] as Long,
        verifiedAt = Clock.System.now(),
    )
}
// PayoutEngine depends only on SocialProvider — never a concrete provider class

When a provider changes its API or rate limits, the damage stays inside that one adapter. We've replaced a provider's verification logic entirely without touching campaigns, payouts, or any other provider integration.

Define the interface from the payout engine's point of view first — what it actually needs (a verified outcome, a timestamp, a confidence score) — then write each provider adapter to produce exactly that shape, however messy the source API is underneath.

Treat every third-party platform integration as a volatile dependency from day one. An adapter boundary is cheap insurance against the coupling that turns one vendor's API change into your outage.