AudD Streams API
Live audio stream monitoring - add and manage streams, with recognition results delivered by callback URL or longpoll.
Live audio stream monitoring - add and manage streams, with recognition results delivered by callback URL or longpoll.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/audd:audd-streams-api"
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: AudD Music Recognition Streams API
version: 1.4.4
description: 'The AudD music recognition API identifies songs from short audio clips
(`api.audd.io/`), large audio/video files (`enterprise.audd.io/`), and
real-time audio streams (callback or longpoll based on `api.audd.io/`).
This OpenAPI document is the canonical contract for the API. Every
official AudD SDK validates its parser against the fixtures shipped
alongside this spec.
Documentation: https://docs.audd.io
Get an api_token: https://dashboard.audd.io
Support: api@audd.io'
contact:
name: AudD API Support
email: api@audd.io
url: https://audd.io
license:
name: MIT
identifier: MIT
servers:
- url: https://api.audd.io
description: Standard recognition, streams and custom catalog endpoints.
- url: https://enterprise.audd.io
description: Enterprise large-file recognition endpoint.
security:
- api_token_form: []
- api_token_query: []
tags:
- name: Streams
paths:
/setCallbackUrl/:
post:
operationId: setCallbackUrl
summary: Configure where AudD POSTs stream-recognition callbacks
tags:
- Streams
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
additionalProperties: true
required:
- api_token
- url
properties:
api_token:
type: string
url:
type: string
format: uri
description: 'Where AudD POSTs callbacks. Set to `https://audd.tech/empty/`
if you only want longpoll. The URL itself can carry a
`?return=apple_music,deezer` parameter to receive that
metadata in callbacks.
'
responses:
'200':
description: Callback URL set or rejected.
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/StreamMutationSuccessResponse'
- $ref: '#/components/schemas/ErrorResponse'
examples:
success:
summary: Standard mutation-success response
value:
status: success
result: null
/getCallbackUrl/:
post:
operationId: getCallbackUrl
summary: Get the configured callback URL
tags:
- Streams
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
additionalProperties: true
required:
- api_token
properties:
api_token:
type: string
responses:
'200':
description: 'Returns the URL or — when no callback URL has ever been
configured — error code 19 with message "Internal error".
**The SDK uses this signal to short-circuit longpoll setup.**
'
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/GetCallbackUrlSuccessResponse'
- $ref: '#/components/schemas/ErrorResponse'
examples:
no_callback_configured:
externalValue: https://raw.githubusercontent.com/AudDMusic/audd-openapi/63414c0a939be98c9ec6d9c2eb5c4c7b92b60a51/fixtures/error_19_no_callback_url.json
/addStream/:
post:
operationId: addStream
summary: Add a stream for live recognition
tags:
- Streams
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
additionalProperties: true
required:
- api_token
- url
- radio_id
properties:
api_token:
type: string
url:
type: string
description: 'Stream URL — direct (DASH/Icecast/HLS/m3u/m3u8) or shortcut
(`twitch:<channel>`, `youtube:<video_id>`, `youtube-ch:<channel_id>`).
'
radio_id:
type: integer
description: Caller-supplied identifier; must be unique per account.
callbacks:
type: string
enum:
- before
description: 'Set to `before` to receive callbacks at song start.
Default is callbacks at song end (with total play length).
'
responses:
'200':
description: Stream added or rejected (e.g.,
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/StreamMutationSuccessResponse'
- $ref: '#/components/schemas/ErrorResponse'
examples:
error_slots_exhausted:
externalValue: https://raw.githubusercontent.com/AudDMusic/audd-openapi/63414c0a939be98c9ec6d9c2eb5c4c7b92b60a51/fixtures/error_902_stream_limit.json
/getStreams/:
post:
operationId: getStreams
summary: List configured streams
tags:
- Streams
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
additionalProperties: true
required:
- api_token
properties:
api_token:
type: string
responses:
'200':
description: Returns the array of configured streams (may be empty).
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/GetStreamsSuccessResponse'
- $ref: '#/components/schemas/ErrorResponse'
examples:
empty:
externalValue: https://raw.githubusercontent.com/AudDMusic/audd-openapi/63414c0a939be98c9ec6d9c2eb5c4c7b92b60a51/fixtures/getStreams_empty.json
/setStreamUrl/:
post:
operationId: setStreamUrl
summary: Update an existing stream's URL
tags:
- Streams
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
additionalProperties: true
required:
- api_token
- radio_id
- url
properties:
api_token:
type: string
radio_id:
type: integer
url:
type: string
responses:
'200':
description: Stream URL updated or rejected.
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/StreamMutationSuccessResponse'
- $ref: '#/components/schemas/ErrorResponse'
examples:
success:
summary: Standard mutation-success response
value:
status: success
result: null
/deleteStream/:
post:
operationId: deleteStream
summary: Delete a stream
tags:
- Streams
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
additionalProperties: true
required:
- api_token
- radio_id
properties:
api_token:
type: string
radio_id:
type: integer
responses:
'200':
description: Stream deleted or rejected.
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/StreamMutationSuccessResponse'
- $ref: '#/components/schemas/ErrorResponse'
examples:
success:
summary: Standard mutation-success response
value:
status: success
result: null
/longpoll/:
get:
operationId: longpoll
summary: Long-poll for new recognition events on a category
description: 'Long-polls for new recognition events. The category can be derived
locally from the api_token + radio_id, or read from the
`longpoll_category` field of `getStreams`.
**Important DX caveat:** when no callback URL is configured for the
account (which the server signals via error #19 from `getCallbackUrl`),
longpoll silently returns timeout responses forever — events never
fire. Every official SDK preflights `getCallbackUrl` and raises a
descriptive error if no callback URL is set. The check is bypassable
via a `skip_callback_check` flag.'
tags:
- Streams
parameters:
- in: query
name: category
required: true
schema:
type: string
description: 9-char longpoll category — `longpoll_category` from `getStreams` or MD5(MD5(api_token)+str(radio_id))[:9].
- in: query
name: timeout
schema:
type: integer
default: 50
minimum: 1
maximum: 90
description: Seconds to wait for events before returning the timeout response.
- in: query
name: since_time
schema:
type: integer
description: Server timestamp (ms) returned in the previous response — used to deduplicate events.
responses:
'200':
description: 'Either a timeout response (no events) or an event response (one
or more new recognitions/notifications).
'
content:
application/json:
schema:
$ref: '#/components/schemas/LongpollResponse'
examples:
timeout:
externalValue: https://raw.githubusercontent.com/AudDMusic/audd-openapi/63414c0a939be98c9ec6d9c2eb5c4c7b92b60a51/fixtures/longpoll_no_events.json
components:
schemas:
NapsterMetadata:
type: object
additionalProperties: true
description: Mirror of the upstream Napster track payload. May be absent for some tracks.
properties:
type:
type: string
id:
type: string
index:
type: integer
disc:
type: integer
href:
type: string
format: uri
playbackSeconds:
type: integer
isExplicit:
type: boolean
isStreamable:
type: boolean
isAvailableInHiRes:
type: boolean
name:
type: string
isrc:
type: string
shortcut:
type: string
blurbs:
type: array
items:
type: string
artistId:
type: string
artistName:
type: string
albumId:
type: string
albumName:
type: string
formats:
type: array
items:
type: object
additionalProperties: true
previewURL:
type: string
format: uri
contributors:
type: object
additionalProperties: true
links:
type: object
additionalProperties: true
AppleMusicMetadata:
type: object
additionalProperties: true
description: 'Mirror of the upstream Apple Music track payload. AudD passes it
through verbatim, so SDK consumers can rely on additional fields
appearing here as Apple ships them.
'
properties:
previews:
type: array
items:
type: object
additionalProperties: true
properties:
url:
type: string
format: uri
artwork:
type: object
additionalProperties: true
properties:
width:
type: integer
height:
type: integer
url:
type: string
bgColor:
type: string
textColor1:
type: string
textColor2:
type: string
textColor3:
type: string
textColor4:
type: string
artistName:
type: string
url:
type: string
format: uri
discNumber:
type: integer
genreNames:
type: array
items:
type: string
durationInMillis:
type: integer
releaseDate:
type: string
name:
type: string
isrc:
type: string
albumName:
type: string
playParams:
type: object
additionalProperties: true
trackNumber:
type: integer
composerName:
type: string
Stream:
type: object
additionalProperties: true
required:
- radio_id
- url
- stream_running
properties:
radio_id:
type: integer
description: Caller-supplied stream identifier.
url:
type: string
description: Stream URL or shortcut (`twitch:<channel>`, `youtube:<video_id>`, `youtube-ch:<channel_id>`).
stream_running:
type: boolean
longpoll_category:
type: string
description: 'Pre-derived 9-character longpoll category for this stream.
Equivalent to MD5(MD5(api_token) + str(radio_id))[:9].
Safe to share with clients (browser/widget) — no token leakage.
'
SpotifyMetadata:
type: object
additionalProperties: true
description: Mirror of the upstream Spotify track payload.
properties:
album:
type: object
additionalProperties: true
artists:
type: array
items:
type: object
additionalProperties: true
available_markets:
oneOf:
- type: array
items:
type: string
- type: 'null'
disc_number:
type: integer
duration_ms:
type: integer
explicit:
type: boolean
external_ids:
type: object
additionalProperties: true
external_urls:
type: object
additionalProperties: true
href:
type: string
format: uri
id:
type: string
is_local:
type: boolean
is_playable:
type: boolean
linked_from:
oneOf:
- type: object
additionalProperties: true
- type: 'null'
name:
type: string
popularity:
type: integer
track_number:
type: integer
type:
type: string
uri:
type: string
ErrorResponse:
type: object
additionalProperties: true
required:
- status
- error
properties:
status:
type: string
const: error
error:
type: object
required:
- error_code
- error_message
additionalProperties: true
properties:
error_code:
type: integer
description: 'AudD-specific numeric error code. The SDK maps each code to a
typed exception class (see audd-<lang>/docs/errors.md). The
full set: 19, 20, 31337, 40, 50, 51, 100, 300, 400, 500, 600,
601, 602, 610, 611, 700, 701, 702, 900, 901, 902, 903, 904,
905, 906, 907, 1000.
'
enum:
- 19
- 20
- 31337
- 40
- 50
- 51
- 100
- 300
- 400
- 500
- 600
- 601
- 602
- 610
- 611
- 700
- 701
- 702
- 900
- 901
- 902
- 903
- 904
- 905
- 906
- 907
- 1000
error_message:
type: string
description: Human-readable, server-provided. Already includes any subscription-nudge appendix.
request_params:
type: object
additionalProperties: true
description: 'Server''s redacted echo of the request parameters. The api_token
field is masked (e.g., "d***e"). Standard endpoint uses this field
name; the enterprise endpoint uses `requested_params` (see below).
'
requested_params:
type: object
additionalProperties: true
description: 'Same as `request_params` but with this alternate name as returned
by the enterprise endpoint. SDKs should normalize these into one
field on the SDK-side error object.
'
request_api_method:
type: string
description: 'Humanized echo of the API method (e.g., "Recognition", "Adding a
stream stream", "Getting the URL for callbacks"). Informational
only — not a programmatic discriminator.
'
request_http_method:
type: string
enum:
- GET
- POST
execution_time:
type: string
description: Wall-clock execution time on the server (enterprise endpoint only).
result:
type: object
additionalProperties: true
description: 'For most errors, omitted. For codes 19 and 31337, the server may
populate a "branded" result with `artist`/`title` strings — the
SDK surfaces these on the exception''s `branded_message` field
and does NOT expose them as a recognition result.
'
properties:
artist:
type: string
title:
type: string
see api documentation:
type: string
format: uri
contact us:
type: string
format: email
LongpollTimeoutResponse:
type: object
additionalProperties: true
required:
- timeout
- timestamp
description: 'Returned when the longpoll wait elapsed without new events. The
client should issue a new request using `timestamp` as the next
`since_time`.
'
properties:
timeout:
type: string
const: no events before timeout
timestamp:
type: integer
description: Server timestamp (ms) — pass as `since_time` on the next request.
LongpollResponse:
anyOf:
- $ref: '#/components/schemas/LongpollTimeoutResponse'
- $ref: '#/components/schemas/LongpollEventResponse'
description: 'Use `anyOf` rather than `oneOf` because both branches use
`additionalProperties: true` and a timeout response (`timeout` +
`timestamp`) trivially also satisfies the event-response branch
(which only requires `timestamp`). SDKs disambiguate by presence
of the `timeout` field.
'
StreamMutationSuccessResponse:
type: object
additionalProperties: true
required:
- status
description: Common shape returned by setCallbackUrl, addStream, setStreamUrl, deleteStream.
properties:
status:
type: string
const: success
result:
type: 'null'
GetCallbackUrlSuccessResponse:
type: object
additionalProperties: true
required:
- status
- result
properties:
status:
type: string
const: success
result:
type: string
format: uri
description: The configured callback URL.
LongpollEventResponse:
type: object
additionalProperties: true
required:
- timestamp
description: 'Returned when one or more new recognition events fired during the
wait. Carries the same per-event shape as a callback payload (either
a `StreamCallbackResultBody` under `result`, or a notification block
under `notification`) plus a `timestamp` to use as the next
`since_time`. Tightening this oneOf during Phase 1 once a real fixture
is captured.
'
properties:
result:
$ref: '#/components/schemas/StreamCallbackResultBody'
notification:
type: object
additionalProperties: true
status:
type: string
timestamp:
type: integer
MusicBrainzEntry:
type: object
additionalProperties: true
description: 'Single MusicBrainz recording match. AudD returns an array of these
because MusicBrainz''s matching often surfaces multiple candidates.
'
required:
- id
properties:
id:
type: string
format: uuid
score:
oneOf:
- type: integer
- type: string
title:
type: string
length:
type: integer
disambiguation:
type: string
video:
oneOf:
- type: boolean
- type: 'null'
artist-credit:
type: array
items:
type: object
additionalProperties: true
releases:
type: array
items:
type: object
additionalProperties: true
isrcs:
oneOf:
- type: array
items:
type: string
- type: 'null'
tags:
oneOf:
- type: array
items:
type: object
additionalProperties: true
- type: 'null'
DeezerMetadata:
type: object
additionalProperties: true
description: Mirror of the upstream Deezer track payload. May be absent for some tracks.
properties:
id:
type: integer
readable:
type: boolean
title:
type: string
title_short:
type: string
title_version:
type: string
link:
type: string
format: uri
duration:
type: integer
rank:
type: integer
explicit_lyrics:
type: boolean
explicit_content_lyrics:
type: integer
explicit_content_cover:
type: integer
preview:
type: string
format: uri
md5_image:
type: string
artist:
type: object
additionalProperties: true
album:
type: object
additionalProperties: true
type:
type: string
StreamCallbackResultBody:
type: object
additionalProperties: true
required:
- radio_id
- results
description: 'Inner shape of the recognition-result callback variant — the value
of the top-level `result` field. Holds the matched songs, the
stream identifier, and per-event metadata.
'
properties:
radio_id:
type: integer
timestamp:
type: string
description: ISO-ish "YYYY-MM-DD HH:MM:SS" UTC.
play_length:
type: integer
description: Seconds the song was played in the stream. Absent when callbacks=before.
results:
type: array
items:
type: object
additionalProperties: true
required:
- artist
- title
- score
properties:
artist:
type: string
title:
type: string
album:
type: string
release_date:
type: string
label:
type: string
score:
type: integer
song_link:
type: string
format: uri
apple_music:
$ref: '#/components/schemas/AppleMusicMetadata'
spotify:
$ref: '#/components/schemas/SpotifyMetadata'
deezer:
$ref: '#/components/schemas/DeezerMetadata'
napster:
$ref: '#/components/schemas/NapsterMetadata'
musicbrainz:
type: array
items:
$ref: '#/components/schemas/MusicBrainzEntry'
GetStreamsSuccessResponse:
type: object
additionalProperties: true
required:
- status
- result
properties:
status:
type: string
const: success
result:
type: array
items:
$ref: '#/components/schemas/Stream'
securitySchemes:
api_token_form:
type: apiKey
in: header
name: api_token
description: 'AudD authentication uses the `api_token` parameter sent either as a
multipart/form-data field (POST) or as a query parameter (GET/POST).
OpenAPI 3.1 has no first-class scheme for "auth in request body"; this
entry documents the parameter for code generators that recognize it.
'
api_token_query:
type: apiKey
in: query
name: api_token
description: api_token sent as a query parameter (works on every endpoint).