Udio Scraper - Prompts, Lyrics, Tags, Audio avatar

Udio Scraper - Prompts, Lyrics, Tags, Audio

Pricing

from $1.00 / 1,000 track results

Go to Apify Store
Udio Scraper - Prompts, Lyrics, Tags, Audio

Udio Scraper - Prompts, Lyrics, Tags, Audio

Collect public Udio tracks with the complete generation prompt, full lyrics, style tags, like and play counts, duration, artwork and a direct audio link. Search the catalogue by keyword and ordering, read a list of track addresses, or pull a public playlist in its original order.

Pricing

from $1.00 / 1,000 track results

Rating

0.0

(0)

Developer

Abot API

Abot API

Maintained by Community

Actor stats

1

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Categories

Share

Udio Scraper: Prompts, Lyrics, Tags & Audio

Udio Scraper turns Udio into a clean AI music data feed. Collect the exact generation prompt behind each public track, the complete lyrics with section markers intact, and the style tags the creator chose, together with the artwork, a direct audio link, like and play counts, duration, timestamps and the creator handle. Search the public catalogue by keyword and ordering, look up specific tracks by address, or pull every track in one or more public playlists in their own order, then export to JSON, CSV or Excel, or read the results straight through the API.

Why This Scraper?

  • Three ways to find tracks. Search the catalogue by keyword and ordering, paste track addresses you already have, or read every track in one or more public playlists.
  • Creative text kept verbatim. The full prompt, complete lyrics and style tags are carried through exactly as the creator wrote them, never trimmed or summarised.
  • Nothing hand-picked is lost. Every field the platform sends comes through in raw too, so a new upstream field reaches your dataset the day it appears.
  • True playlist order. Playlist mode reads the collection's own member list rather than the shorter preview the catalogue view shows, and restores the playlist's own order on every row.
  • Built for schedules. Incremental mode returns only new, updated, reappeared and gone tracks on recurring runs, and unchanged tracks are not billed.
  • Resume without paying twice. Finish one interrupted run by pointing at its run or dataset ID; tracks it already saved are skipped.
  • A refused run fails loudly. If the site cannot be read, the run stops with a clear message instead of quietly returning an empty dataset.

Use Cases

  • AI music researchers and dataset builders: collect prompt-to-track pairs at scale to study how wording shapes generated music.
  • Playlist curators and fans: track a playlist's full membership, order and engagement over time.
  • Music blogs and content teams: pull lyrics, tags and artwork to write about trending AI-generated tracks.
  • Trend watchers: schedule recurring runs to see which tracks are gaining likes and plays.
  • Archivists: keep a durable copy of a track's prompt and lyrics before it is edited or removed by its creator.

Data You Get

Sample shape: values are illustrative placeholders, not from a live record.

FieldExample
trackId"00000000-0000-4000-8000-000000000000"
url"https://www.udio.com/songs/00000000-0000-4000-8000-000000000000"
title"Midnight Coffee Loop"
artist / creatorId"Jane Doe" / "00000000-0000-4000-8000-000000000001"
artistImageUrlcreator avatar image
prompt"lofi, jazzy chill cafe vibes, warm tape saturation"
lyrics"[Verse 1]\nRain on the window, cups going cold\n\n[Chorus]\nStay for one more song"
tags / userTags["chill", "jazz", "downtempo", "instrumental"] / ["study"]
description / attributionfree text, when the creator wrote one
likeCount / playCount128 / 4210
durationSeconds131.2
createdAt / publishedAtwhen the track was generated / made public
audioUrldirect link to the audio file
videoUrldirect link to the video, when one exists
artworkUrlcover artwork image
styleId / styleSourceType / styleSourceTrackIdwhich style produced the track, when applicable
parentTrackIdthe track this one extends or remixes, when applicable
generationId / generationStatusthe generation batch and its reported status
isFinished / isPublishablewhether generation completed / may be shared
collectionId / collectionName / collectionUrl / positionInCollectionplaylist context; filled only in playlist mode (null in the other modes, where collectionUrl is left out)
sourceModewhich mode produced the row
scrapedAtwhen the row was collected
rawevery field exactly as the platform sent it

How to Use

  1. Pick a mode: Search the catalogue (by keyword and ordering), Specific tracks (paste addresses or bare identifiers) or Playlist (paste playlist addresses or identifiers).
  2. Fill in the fields for that mode.
  3. Set Maximum tracks to control run size and cost, then click Start.
  4. Download the dataset as JSON, CSV or Excel, or read it through the API.

Search a keyword, newest first:

{
"mode": "search",
"searchTerm": "lofi",
"sortBy": "newest",
"maxItems": 20
}

Look up specific tracks:

{
"mode": "songIds",
"trackIds": [
"https://www.udio.com/songs/9765efef-43b4-4c0e-a3a0-ce288c99ccc7",
"baf84bf6-ff44-474b-aa4a-1e779776770d"
]
}

Read a whole public playlist, in its own order:

{
"mode": "playlist",
"playlistIds": ["https://www.udio.com/playlists/6467edd4-f519-4418-b207-bd779b752627"],
"maxItems": 0
}

Browse the whole catalogue, most liked first:

{
"mode": "search",
"sortBy": "mostLiked",
"maxItems": 50
}

Run it from your code

Python:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/udio-com-scraper").call(run_input={"mode": "search", "searchTerm": "lofi", "maxItems": 20})
for track in client.dataset(run["defaultDatasetId"]).iterate_items():
print(track["title"], track["prompt"])

JavaScript:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/udio-com-scraper').call({ mode: 'search', searchTerm: 'lofi', maxItems: 20 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.

The 200-track catalogue ceiling

A single catalogue query (one keyword and ordering, or the whole catalogue with no keyword) can reach at most 200 tracks, because that is as far as the site's own search view goes. Raising Maximum tracks past 200 does not reach more of that same query; run several searches with narrower keywords instead. Specific tracks and Playlist mode are not affected: they read an explicit, bounded set of identifiers rather than walking this ceiling.

Resume and recurring updates

These are two different things.

Resume finishes ONE interrupted run. Paste that run's ID (or its dataset ID) into resumeFromRunId; the tracks it already saved are skipped, so you don't pay twice. The new run still reads from the start of your selection, it simply does not re-publish what it recognises.

Incremental mode is for running the same selection again and again, daily say, to watch a playlist gain and lose tracks or a track's play count move. The actor remembers the previous run of that selection and, from the second run on, returns only what changed. Each row then carries changeType (NEW, UPDATED, UNCHANGED, REAPPEARED or EXPIRED), changedFields, firstSeenAt and lastSeenAt. Memory is kept per selection (mode, keyword, ordering and lookup list); set stateKey to name a campaign or to deliberately share one. Resume and an existing Incremental mode memory cannot be combined in the same run; the run refuses with a clear message and asks you to run them separately.

EXPIRED rows are only produced when a run scanned the whole selection: not when Maximum tracks was reached and stopped it early, not when a catalogue search reached the 200-track ceiling, not when part of the selection (a private track, or a collection that is not public) could not be read, and not on a resumed run. When any of these applies, the run marks nothing as gone at all, and its log says which reason applied. Because of the ceiling, a catalogue search can only mark tracks as gone when it has fewer than 200 matches; to watch a larger set for removals, use Specific tracks or Playlist mode.

If a track appears in two of the playlists you list, it is published once, attributed to (and positioned within) the first playlist in your list that contains it; it is not silently dropped, just not duplicated.

Send results into your apps (MCP connectors)

Optionally pipe the collected tracks into apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the collection: the Apify dataset is never changed.

What gets written to the connector: a condensed, human-readable summary of each track, not the full JSON. Each item becomes one entry with a title and its key fields flattened to plain text; nested objects collapse to their main value and long lists are trimmed, so the prompt and lyrics may be shortened there. The complete record always stays in the Apify dataset.

  1. Authorize a connector once under Apify > Settings > Integrations (Notion, Linear, Airtable, or Apify).
  2. Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
  3. For Notion, also set notionParentPageUrl to the page where track pages should be created.

The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.

Input Parameters

ParameterTypeDefaultDescription
modestringsearchsearch, songIds, or playlist.
searchTermstring(none)Keyword matched against titles, prompts and tags (search mode). Empty browses the whole catalogue.
sortBystringnewestnewest, mostLiked, or mostPlayed (search mode).
trackIdsarraysampleOne track per line: a full track address or a bare identifier (specific tracks mode).
playlistIdsarraysampleOne playlist per line: a full playlist address or a bare identifier (playlist mode).
maxItemsinteger20Stop after this many tracks. 0 collects everything available for the selection.
resumeFromRunIdstring(none)Continue one interrupted run without returning tracks it already saved.
incrementalModebooleanfalseReturn only new, updated, reappeared and gone tracks on recurring runs of the same selection.
emitUnchangedbooleanfalseAlso return (and bill) tracks unchanged since the last run, marked UNCHANGED.
emitExpiredbooleanfalseAlso return (and bill) tracks gone since the last run, marked EXPIRED. Only when the whole selection was scanned.
stateKeystring(none)Name or share an incremental-mode memory across runs.
mcpConnectorsarray(none)Optional: send a summary of each track to apps you authorized under Integrations.
notionParentPageUrlstring(none)Notion connector only: page under which track pages are created.
maxNotifyListingsinteger50Cap on tracks written to each connector per run. Does not affect the dataset.
proxyConfigurationobjectApify ProxyConnection settings for the run.

Output Example

Sample shape: values are illustrative placeholders, not from a live record.

{
"trackId": "00000000-0000-4000-8000-000000000000",
"url": "https://www.udio.com/songs/00000000-0000-4000-8000-000000000000",
"title": "Midnight Coffee Loop",
"artist": "Jane Doe",
"artistImageUrl": "https://example.com/avatar/sample.png",
"creatorId": "00000000-0000-4000-8000-000000000001",
"prompt": "lofi, jazzy chill cafe vibes, warm tape saturation",
"lyrics": "[Verse 1]\nRain on the window, cups going cold\n\n[Chorus]\nStay for one more song",
"tags": ["chill", "jazz", "downtempo", "instrumental"],
"userTags": ["study"],
"description": "",
"attribution": null,
"likeCount": 128,
"playCount": 4210,
"durationSeconds": 131.2,
"createdAt": "2026-01-05T09:12:44+00:00",
"publishedAt": "2026-01-05T09:15:02+00:00",
"audioUrl": "https://example.com/audio/sample.mp3",
"videoUrl": null,
"artworkUrl": "https://example.com/art/sample.png",
"styleId": null,
"styleSourceType": "style",
"styleSourceTrackId": null,
"parentTrackId": null,
"generationId": "00000000-0000-4000-8000-000000000002",
"generationStatus": "succeeded",
"isFinished": true,
"isPublishable": true,
"sourceMode": "search",
"collectionId": null,
"collectionName": null,
"positionInCollection": null,
"scrapedAt": "2026-01-06T11:00:00+00:00",
"raw": {}
}

Plan Requirement

The default connection works out of the box on every plan, and the actor rotates connections automatically when one is refused. Leave it as-is unless you have a reason to change it.

FAQ

How much does it cost?

You pay per track returned; unchanged tracks in Incremental mode are not billed unless you turn that on. The Pricing tab shows the current rates. Use Maximum tracks to cap the cost of any run.

This actor collects only publicly available Udio data. You are responsible for how you use it: follow Udio's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Generated audio, lyrics and artwork may carry rights distinct from the plain metadata, so treat creative fields with the same care you would any third-party creative work.

Can I get only new or changed tracks on a schedule?

Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. From the second run on, each run returns only new, updated, reappeared and gone tracks for that selection, and unchanged ones are not billed unless you turn on Emit unchanged.

What is the difference between Resume and Incremental mode?

Resume finishes ONE interrupted run: paste its run or dataset ID into resumeFromRunId and already-saved tracks are skipped. Incremental mode compares each new run of the same selection against the previous one, on a schedule. They solve different problems and cannot be combined while an Incremental mode memory already exists for that selection; a run that tries fails with a message asking you to run them separately.

Why didn't a capped run mark any tracks as gone?

EXPIRED needs a complete look at the selection. A run stopped by Maximum tracks, a catalogue search that hit the 200-track ceiling, a private track or an unreadable playlist, and a resumed run all leave part of the selection unchecked, so none of them may declare anything gone that run; the log states which of these applied. For example, if 60 tracks in a 120-track playlist changed since the last run and Maximum tracks is 50, the run stops after returning 50 and emits no EXPIRED rows, even with Emit expired on. (In Incremental mode the cap counts only tracks actually returned, so a quiet day with fewer changes than the cap still counts as a full scan.) To get a real expiry sweep, periodically run the same selection with Maximum tracks set to 0 (or above the selection's size), alongside your smaller day-to-day capped runs. This works for Specific tracks, Playlist mode, and catalogue searches with fewer than 200 matches. A catalogue search with 200 or more matches always stops at the ceiling, so no setting of Maximum tracks lets it mark tracks as gone.

Why did my run fail instead of returning an empty dataset?

If the site refuses every request, or returns tracks this build cannot recognise at all, the run stops with a clear message so "nothing matched" is never confused with "nothing could be read". A keyword that genuinely matches nothing, or an incremental run where nothing changed, still succeeds with zero published rows. Before giving up, the actor automatically retries the whole request once more on a premium connection pool whenever the default pool is refused on every attempt, so a temporary refusal wave usually costs a few seconds, not the run. Runs that bring their own proxy connections or turn the proxy off keep exactly the connection they configured.

Can I use it with AI agents or MCP?

Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.

๐Ÿ”— Want more AI data?

Pair this actor with these related scrapers from the same team:

๐Ÿค– Suno Scraper
Collect public Suno music data: songs with lyrics, style tags, model version, play and...
๐Ÿ“ฑ Universal Media Extractor
Extract videos, audio, and metadata from 1000+ websites including YouTube, TikTok...
๐Ÿ“ฑ Truth Social Scraper
Scrape public Truth Social profiles, posts, media, metrics, author data, and complete...
๐Ÿงฉ TIDAL Scraper
Scrape TIDAL tracks, albums, artists, playlists and public mixes by search phrase or URL...
๐Ÿ“ฑ Google Play Reviews
Collect Google Play reviews and ratings for any app across country storefronts. Search by...
๐Ÿงฉ KKday Scraper
Scrape KKday travel activities by keyword, city or URL. Every row carries prices...

๐Ÿ‘‰ Browse all abotapi scrapers

๐Ÿ’ฌ Support & custom scrapers

  • ๐Ÿž Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
  • ๐Ÿ› ๏ธ Need another site, extra fields or a private build? Email contact@abotapi.com or message Telegram @abotapi.
  • โญ Enjoying it? A quick review on the actor page helps other users find it.