import {
createUpstreamHttpClient,
createOAuthPassthroughResolver,
defineSalesPlatform,
} from '@adcp/sdk/server';
const snap = createUpstreamHttpClient({
baseUrl: 'https://adsapi.snapchat.com',
auth: {
kind: 'dynamic_bearer',
getToken: async (ctx) => (ctx as any)?.authInfo?.credential?.token,
},
});
const resolve = createOAuthPassthroughResolver({
httpClient: snap,
listEndpoint: '/v1/me/adaccounts',
idField: 'id',
rowsPath: 'adaccounts',
toAccount: (row, ctx) => ({
id: row.id,
name: row.name,
status: 'active',
advertiser: row.advertiser_url,
ctx_metadata: {
upstreamId: row.id,
// Treat as secret — see `toAccount` JSDoc above.
accessToken: (ctx as any)?.authInfo?.credential?.token,
},
}),
cache: { ttlMs: 60_000 },
});
defineSalesPlatform({
accounts: { resolve },
...
});
Behavior:
{ account_id } discriminated-union arm.
Other arms ({ brand, operator }) and undefined ref return null
without calling upstream.composeMethod over the result if they want to catch and map
to a typed envelope (e.g. throw AdcpError('AUTH_REQUIRED') on 401).account_ids that buyer queries.
Create an
accounts.resolveimplementation that resolves buyer-suppliedAccountReferenceagainst an upstream OAuth-protected listing endpoint. Returns just the resolve function — adapters compose it into their ownAccountStore(typically alongside a no-opupsertsince Shape B adapters don't manage account lifecycle).