Hooktheory APIhooktheory.com ↗
Search 65,000+ songs in Hooktheory's TheoryTab database. Retrieve chords, melody notes, keys, tempos, and time signatures by song section.
What is the Hooktheory API?
The Hooktheory TheoryTab API gives programmatic access to music theory data for over 65,000 songs across 3 endpoints. The search_songs endpoint returns chord and key information for matching tracks, while get_song_sections lists every section (verse, chorus, bridge, etc.) and get_section_notes delivers the full breakdown: chords with root, type, and inversion, melody notes with scale degree and octave, time signatures, and BPM data.
curl -X GET 'https://api.parse.bot/scraper/6b249d06-c1b6-4e17-ad83-675d92275ddc/search_songs?limit=5&query=imagine&offset=0' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace hooktheory-com-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
from parse_apis.hooktheory_theorytab_song_notes_api import Hooktheory, Song, SongPage, Section, SectionNotes
hooktheory = Hooktheory()
# Search for songs matching a keyword
for song in hooktheory.songs.search(query="bohemian rhapsody"):
print(song.song, song.artist, song.key, song.section)
# Get sections for a specific song
page = hooktheory.songpages.get(artist="queen", song="bohemian-rhapsody")
print(page.url, page.artist)
for section in page.sections:
print(section.section_id, section.section_name)
# Get detailed music theory data for a section
notes_data = page.sections[0].notes()
print(notes_data.song, notes_data.end_beat)
for chord in notes_data.chords:
print(chord.root, chord.type, chord.beat, chord.duration, chord.is_rest)
for note in notes_data.notes:
print(note.scale_degree, note.octave, note.beat, note.duration)
for tempo in notes_data.tempos:
print(tempo.bpm, tempo.swing_factor)
for key in notes_data.keys:
print(key.tonic, key.scale)
Full-text search over Hooktheory's TheoryTab database of 65,000+ songs. Matches song titles and artist names. Returns chord progressions (absolute and relative notation), key signatures, section types, and YouTube IDs. Paginated via offset/limit.
| Param | Type | Description |
|---|---|---|
| limit | integer | Maximum number of results to return (max 200) |
| queryrequired | string | Search keyword (song name, artist, etc.) |
| offset | integer | Offset for pagination |
{
"type": "object",
"fields": {
"limit": "integer, max results requested",
"query": "string, the search query echoed back",
"offset": "integer, current pagination offset",
"results": "array of song result objects with id, song, artist, section, key, youtube_id, chords_absolute, chords_relative",
"total_hits": "integer, total number of matching results"
},
"sample": {
"data": {
"limit": 5,
"query": "imagine",
"offset": 0,
"results": [
{
"id": 287,
"key": "C major",
"song": "Imagine",
"artist": "John Lennon",
"section": "Verse",
"youtube_id": "YkgkThdzX-8",
"chords_absolute": "qqCqqCqqFqqCqqCqqFqq",
"chords_relative": "qqIqqIqqIVqqIqqIqqIVqq"
}
],
"total_hits": 33
},
"status": "success"
}
}About the Hooktheory API
Search and Navigation
The search_songs endpoint accepts a query string (song name, artist name, or any keyword) and returns an array of matching results. Each result includes the song and artist names, a section label, key, and both absolute and relative chord representations. Pagination is controlled via limit (up to 200) and offset, and the total_hits field tells you the full match count for multi-page traversal.
Retrieving Song Sections
Once you have a target song, get_song_sections maps the artist and song URL slugs (e.g. the-beatles, let-it-be) to a list of sections. Each entry in the sections array carries a section_id and a human-readable section_name. The endpoint also returns the canonical TheoryTab URL for the song. These section IDs are the required input for the next step.
Full Music Theory Detail
Passing a section_id to get_section_notes returns the densest data in the API. The chords array contains objects with root, type, inversion, beat, duration, and harmony annotations including applied, adds, omits, alterations, suspensions, and borrowed. The notes array represents the melody line, with each note carrying scale_degree, octave, beat, duration, and an is_rest flag. Key changes are tracked in the keys array (each entry has beat, tonic, and scale), tempo shifts in tempos (with bpm, swingFactor, and swingBeat), and meter changes in meters (with numBeats and beatUnit). A youtube object links to a synced video clip when available.
Coverage and Structure
Data is organized by section rather than by full song, which reflects how TheoryTab's database is structured — different sections of the same song can have different keys, tempos, and meters. The end_beat field on get_section_notes responses marks the total length of the section in beats, useful for sequencing or rendering.
The Hooktheory API is a managed, monitored endpoint for hooktheory.com — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when hooktheory.com changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official hooktheory.com API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Build a chord progression explorer that searches songs by artist and displays relative chords for music students
- Analyze borrowed chords and modal mixture across a genre by querying
chords.borrowedfields on section data - Generate MIDI or sheet music from melody
notesarrays including scale degree, octave, and duration - Study how key signatures change mid-song using the beat-stamped
keysarray fromget_section_notes - Create a tempo and time signature database by aggregating
tempos.bpmandmeters.numBeatsacross thousands of songs - Map YouTube sync windows to specific song sections using
youtube.sync_startandsync_endfor annotated playback - Compare verse versus chorus harmony for a catalog of songs by fetching all sections and diffing their chord arrays
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 100 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
One credit = one API call regardless of which marketplace API you call. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.
Does Hooktheory have an official developer API?+
What does `get_section_notes` return for chords beyond basic root and type?+
root, type, inversion, beat, and duration, plus harmony extensions: applied (secondary dominant target), adds, omits, alterations, suspensions, and borrowed (modal mixture). The is_rest flag marks beats with no chord. This level of detail is only available through get_section_notes using a section_id obtained from get_song_sections.Can I retrieve audio files or sheet music PDFs for a song?+
Is artist or song metadata like genre, release year, or album available?+
song, artist, section, key, and YouTube ID from search results, but does not expose genre, release year, album, or chart data. You can fork the API on Parse and revise it to add an endpoint pulling from a music metadata source to enrich results.How does section-based pagination work, and are there limits on search results?+
search_songs endpoint supports offset and limit (maximum 200 per request) for paging through results. The total_hits field in the response gives the full match count so you can calculate how many pages to fetch. Section retrieval via get_song_sections returns all sections for a song in one response with no pagination.