Partner integrations
For hosting and ad-tech partners: discover and connect a show's accounts, set its podcast identity, look up episodes by your own ids, control auto-build, and record ad-server delivery on campaigns.
- GETRetrieve a show's account discovery
- POSTRun account discovery for a show
- PUTConnect a platform to a show
- DELETEDisconnect a platform from a show
- PUTSet a show's podcast identity
- GETLook up an episode by a partner's identifiers
- GETRetrieve a show's auto-build setting and statuses
- PUTSet a show's auto-build mode
- GETList a campaign's external ad-server delivery
- POSTRecord external ad-server delivery on a campaign
- DELETEDelete an external delivery row
Retrieve a show's account discovery
/v1/shows/{show_id}/account-discoveryThe social accounts Listener's discovery found for a show (YouTube, Instagram, TikTok, X, Facebook, Threads, LinkedIn): handle, profile URL, followers, confidence (high, medium, low) and why it was picked. Each candidate carries its connection state against the show's current integrations (connected, connected_account, matches_candidate) and connect_via: api (connect it with PUT /v1/shows/{show_id}/integrations/{platform}) or app_sign_in (a person signs in from verify_url).
verify_url is the show's integrations page in the right Listener app (Listener Networks for network workspaces, Listener for creators); send people there to review and confirm. status is none until a run starts, then running or done.
Path parameters
- A show id in this workspace (see GET /v1/shows).
show_idstringrequired
Returns
200OK
show_idstringrequiredshow_namestringrequired- 'none' (never run), 'running', 'done' or 'failed'.
statusstringrequired - Deep link to the show's integrations page in the right Listener app, for a person to review and connect accounts.
verify_urlstringrequired computed_atstringrequiredobjectstringrequiredwebsitestringran_atstringrunsintegerDefault
0- When someone confirmed the accounts in onboarding, if they did.
committed_atstring candidatesarray of objectsShow child attributesHide child attributes
summaryobjectShow child attributesHide child attributes
notestring
Errors
400parameter_invalid401credential_invalid403scope_missing404resource_not_found429rate_limited500internal_error
Run account discovery for a show
/v1/shows/{show_id}/account-discoveryRun account discovery for a show, the same search Listener's onboarding uses: it finds the show's public accounts, checks each profile, stores the result on the show and returns the candidates with their connection state. Nothing is connected.
Needs "confirm": true: every run is metered (web search, model and scraper credits) and capped per show, and a show that already has a result may get it back without a new search. A running status means the search is still going: read GET /v1/shows/{show_id}/account-discovery a minute later. A dry run returns the request without starting anything.
- Send
"dry_run": trueto get{"object": "dry_run", "would_write": …}without writing anything. - Requires
"confirm": true; without it the API answers 409confirmation_requiredwith the exactpreview.
Path parameters
- A show id in this workspace (see GET /v1/shows).
show_idstringrequired
Headers
- Any unique string (≤ 255 chars). Replays within 24 h return the stored response with Idempotent-Replayed: true.
Idempotency-Keystring
Request body
application/json- true returns exactly what would be written without writing anything (the API's test mode).
dry_runbooleanDefault
false - Must be true to apply destructive or metered changes; without it the API answers 409 with a preview.
confirmbooleanDefault
false
Returns
200OK
One of:
WriteResult
DryRun
Errors
400parameter_invalid401credential_invalid403scope_missing404resource_not_found409confirmation_required413body_too_large429rate_limited500internal_error
Connect a platform to a show
/v1/shows/{show_id}/integrations/{platform}Connect a platform to a show the same way the Listener apps' Integrations page does: the account is seeded, its first data refresh runs and it is listed on the show's public page. The response says whether it connected, which account, and whether the first refresh finished (refreshed).
Public-profile platforms (instagram, tiktok, twitter, facebook, threads, linkedin) take handle (e.g. dugoutdaily) or the profile url; LinkedIn needs the URL. simplecast takes api_key and optionally podcast_id; the key is never returned. youtube, instagramBusiness, spotify and applePodcasts need a person to sign in (Google or Meta sign-in, or the Listener browser extension) and answer 400 oauth_required with connect_url, the page to send them to. Connecting a platform that is connected to another account replaces it (a warning says so). Emits integration.connected.
- Send
"dry_run": trueto get{"object": "dry_run", "would_write": …}without writing anything.
Path parameters
- A show id in this workspace (see GET /v1/shows).
show_idstringrequired - A platform name (e.g. youtube, spotify, applePodcasts, instagram).
platformstringrequiredOne ofinstagramtiktoktwitterfacebookthreadslinkedinsimplecastyoutubeinstagramBusinessspotifyapplePodcasts
Headers
- Any unique string (≤ 255 chars). Replays within 24 h return the stored response with Idempotent-Replayed: true.
Idempotency-Keystring
Request body
application/json- Public URL handle (lowercase, hyphens).
handlestring urlstringapi_keystringpodcast_idstring- true returns exactly what would be written without writing anything (the API's test mode).
dry_runbooleanDefault
false
Returns
200OK
One of:
WriteResult
DryRun
Errors
400parameter_invalid401credential_invalid403scope_missing404resource_not_found409confirmation_required413body_too_large429rate_limited500internal_error
Disconnect a platform from a show
/v1/shows/{show_id}/integrations/{platform}Disconnect a platform from a show the same way the Integrations page does; the response includes the state and account it had. Needs "confirm": true (send ?confirm=true): the show stops refreshing that platform until someone connects it again. Emits integration.disconnected.
- Send
?dry_run=trueto get{"object": "dry_run", "would_write": …}without writing anything. - Requires
?confirm=true; without it the API answers 409confirmation_requiredwith the exactpreview.
Path parameters
- A show id in this workspace (see GET /v1/shows).
show_idstringrequired - A platform name (e.g. youtube, spotify, applePodcasts, instagram).
platformstringrequiredOne ofinstagramtiktoktwitterfacebookthreadslinkedinsimplecastyoutubeinstagramBusinessspotifyapplePodcasts
Query parameters
- true returns exactly what would be written without writing anything (the API's test mode).
dry_runbooleanDefault
false - Must be true to apply destructive or metered changes; without it the API answers 409 with a preview.
confirmbooleanDefault
false
Headers
- Any unique string (≤ 255 chars). Replays within 24 h return the stored response with Idempotent-Replayed: true.
Idempotency-Keystring
Returns
200OK
One of:
WriteResult
DryRun
Errors
400parameter_invalid401credential_invalid403scope_missing404resource_not_found409confirmation_required413body_too_large429rate_limited500internal_error
Set a show's podcast identity
/v1/shows/{show_id}/podcastSet the listing ids that identify the show: rss_url, apple_podcasts_id, spotify_id, podchaser_id and simplecast_podcast_id, the same fields Listener stores when a show is picked during onboarding. Only the fields you send change; an empty string clears one. Ids are validated and may be sent as the platform's own URLs (podcasts.apple.com/…/id123…, open.spotify.com/show/…, podchaser.com/podcasts/…-123).
These are references used to match the show and its episodes. They do not connect Spotify, Apple Podcasts or Simplecast; connect Simplecast with PUT /v1/shows/{show_id}/integrations/simplecast.
- Send
"dry_run": trueto get{"object": "dry_run", "would_write": …}without writing anything.
Path parameters
- A show id in this workspace (see GET /v1/shows).
show_idstringrequired
Headers
- Any unique string (≤ 255 chars). Replays within 24 h return the stored response with Idempotent-Replayed: true.
Idempotency-Keystring
Request body
application/jsonrss_urlstringapple_podcasts_idstringspotify_idstringpodchaser_idstringsimplecast_podcast_idstring- true returns exactly what would be written without writing anything (the API's test mode).
dry_runbooleanDefault
false
Returns
200OK
One of:
WriteResult
DryRun
Errors
400parameter_invalid401credential_invalid403scope_missing404resource_not_found409confirmation_required413body_too_large429rate_limited500internal_error
Look up an episode by a partner's identifiers
/v1/shows/{show_id}/episodes/lookupFind the Listener episode behind your own identifiers. Send any of simplecast_episode_id, guid (the RSS item guid), apple_episode_id, spotify_episode_id, title and published_on (YYYY-MM-DD). Each match returns the Listener episode_id (use it with every episode endpoint), its cluster id and public cluster URL, and match with by (what matched) and confidence:
exact: an id or guid stored on the episode;high: the same title within a day of the date (or a title unique in the show when no date is sent);medium: the same title on another day, or a near-identical title within a day;low: a similar title within a day.
A Simplecast episode id is resolved through the show's Simplecast analytics to its title and publish date, then matched, so it is never better than high. best is set only for an exact or high match that no other episode ties; otherwise review matches. Nothing is guessed silently: note explains misses.
Path parameters
- A show id in this workspace (see GET /v1/shows).
show_idstringrequired
Query parameters
simplecast_episode_idstringguidstringapple_episode_idstringspotify_episode_idstring- Title.
titlestring published_onstring- Maximum number of items to return.
limitintegerDefault
5
Returns
200OK
show_idstringrequiredcomputed_atstringrequiredobjectstringrequiredquerymap of string- Set only when the top match is exact or high confidence and unambiguous; otherwise null.
bestobjectShow child attributesHide child attributes
matchesarray of objectsShow child attributesHide child attributes
ambiguousbooleanDefault
false- The Simplecast episode the id resolved to (title and date come from the show's Simplecast analytics).
simplecast_episodeobjectShow child attributesHide child attributes
notestring
Errors
400parameter_invalid401credential_invalid403scope_missing404resource_not_found429rate_limited500internal_error
Retrieve a show's auto-build setting and statuses
/v1/shows/{show_id}/auto-buildThe show's auto-build setting and recent per-episode build statuses. mode is off, suggest (posts are recorded for review) or auto (the sure ones are added to the episode's cluster); legacy marks a mode read from the older on/off switch. statuses lists the latest episodes first (building, ready, built, nothing, failed, accepted, dismissed) with cluster ids and reasons; counts covers every stored status.
New episodes are picked up by Listener's hourly auto-build run (episodes from the last 14 days without a cluster). To build an episode the moment you publish it, call POST /v1/cluster-builds with scope: "episodes" and its episode id.
Path parameters
- A show id in this workspace (see GET /v1/shows).
show_idstringrequired
Query parameters
- Maximum number of items to return.
limitintegerDefault
20
Returns
200OK
show_idstringrequiredmodestringrequiredOne ofoffsuggestautodraft- How new episodes are picked up.
schedulestringrequired computed_atstringrequiredobjectstringrequired- True when the mode comes from the older on/off automation switch (reads as 'auto').
legacybooleanDefault
false enabled_atstringupdated_atstringlast_runobject- Status → number of episodes, across every stored status.
countsmap of integer - Most recent per-episode statuses first.
statusesarray of objectsShow child attributesHide child attributes
Errors
400parameter_invalid401credential_invalid403scope_missing404resource_not_found429rate_limited500internal_error
Set a show's auto-build mode
/v1/shows/{show_id}/auto-buildTurn auto-build on (suggest or auto) or off for a show, as the Episodes page does, and return the previous and new mode. The hourly auto-build run then picks up new episodes; for an immediate build after publishing call POST /v1/cluster-builds. draft is refused: it is a per-build policy the hourly run never uses.
- Send
"dry_run": trueto get{"object": "dry_run", "would_write": …}without writing anything.
Path parameters
- A show id in this workspace (see GET /v1/shows).
show_idstringrequired
Headers
- Any unique string (≤ 255 chars). Replays within 24 h return the stored response with Idempotent-Replayed: true.
Idempotency-Keystring
Request body
application/json- How the change applies (see the operation description).
modestringrequiredOne ofoffsuggestautodraft - true returns exactly what would be written without writing anything (the API's test mode).
dry_runbooleanDefault
false
Returns
200OK
One of:
WriteResult
DryRun
Errors
400parameter_invalid401credential_invalid403scope_missing404resource_not_found409confirmation_required413body_too_large429rate_limited500internal_error
List a campaign's external ad-server delivery
/v1/campaigns/{campaign_id}/external-deliveryDelivery reported by external ad servers (AdsWizz, AudioServe or other) on a campaign: impressions and optional listeners per day or period, per slot and show, newest first, with meta.totals_by_source. These are true counts from the ad server, kept apart: they are never added to Listener reach, impressions or EMV.
Path parameters
- Campaign id (see GET /v1/campaigns).
campaign_idstringrequired
Query parameters
sourcestringOne ofadswizzaudioserveother- Page size, 1–100 (default 25).
limitintegerDefault
25 - Opaque cursor from the previous page's next_cursor.
cursorstring
Returns
200OK
objectstringrequiredurlstringrequireddataarray of objectsrequiredShow child attributesHide child attributes
has_morebooleanrequired- Pass as
next_cursorstringrequiredcursorto get the next page; null on the last page. - The result's non-list fields (window, coverage, freshness, totals, note …).
metaobjectrequiredShow child attributesHide child attributes
Errors
400parameter_invalid401credential_invalid403scope_missing404resource_not_found429rate_limited500internal_error
Record external ad-server delivery on a campaign
/v1/campaigns/{campaign_id}/external-deliveryRecord ad-server delivery on a campaign. Each row has source (adswizz, audioserve, other), either date or start_date + end_date, impressions, and optionally listeners, slot_id, show_id, label and note. A row with the same source, slot, show and day (or period) as a stored row updates it instead of adding a duplicate, so re-sending a day is safe. Up to 500 rows per request and 2,000 per campaign. The response lists the row ids added and updated and the totals per source. Emits campaign.updated. These counts are never added to Listener reach totals.
- Send
"dry_run": trueto get{"object": "dry_run", "would_write": …}without writing anything.
Path parameters
- Campaign id (see GET /v1/campaigns).
campaign_idstringrequired
Headers
- Any unique string (≤ 255 chars). Replays within 24 h return the stored response with Idempotent-Replayed: true.
Idempotency-Keystring
Request body
application/jsonrowsarray of objectsrequiredShow child attributesHide child attributes
- true returns exactly what would be written without writing anything (the API's test mode).
dry_runbooleanDefault
false
Returns
200OK
One of:
WriteResult
DryRun
Errors
400parameter_invalid401credential_invalid403scope_missing404resource_not_found409confirmation_required413body_too_large429rate_limited500internal_error
Delete an external delivery row
/v1/campaigns/{campaign_id}/external-delivery/{row_id}Delete one external delivery row (xd_…) from a campaign. Needs "confirm": true (send ?confirm=true); there is no undo. Emits campaign.updated.
- Send
?dry_run=trueto get{"object": "dry_run", "would_write": …}without writing anything. - Requires
?confirm=true; without it the API answers 409confirmation_requiredwith the exactpreview.
Path parameters
- Campaign id (see GET /v1/campaigns).
campaign_idstringrequired row_idstringrequired
Query parameters
- true returns exactly what would be written without writing anything (the API's test mode).
dry_runbooleanDefault
false - Must be true to apply destructive or metered changes; without it the API answers 409 with a preview.
confirmbooleanDefault
false
Headers
- Any unique string (≤ 255 chars). Replays within 24 h return the stored response with Idempotent-Replayed: true.
Idempotency-Keystring
Returns
200OK
One of:
WriteResult
DryRun
Errors
400parameter_invalid401credential_invalid403scope_missing404resource_not_found409confirmation_required413body_too_large429rate_limited500internal_error