# Songsterr scraper (`scrapescape/songsterr-scraper`) Actor

Download Songsterr tabs as Guitar Pro (GP5) files, track JSON, lyrics and chords. Scrape a single song or a full artist catalog.

- **URL**: https://apify.com/scrapescape/songsterr-scraper.md
- **Developed by:** [Scrape Scape](https://apify.com/scrapescape) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### What does Songsterr Tabs Scraper do?

**Songsterr Tabs Scraper** downloads guitar, bass and drum tabs from [Songsterr](https://www.songsterr.com) for **one song** or an **artist's whole catalog**. Point it at a Songsterr URL, a song ID, a search like "Metallica - One", or an artist name. It saves the full tab data, including **Guitar Pro files**, track JSON, lyrics and chords. Songsterr has no official API, so this Actor works as a **Songsterr API alternative**.

It doesn't log in and doesn't download Songsterr Plus features such as audio.

### Why use Songsterr Tabs Scraper?

- 🎸 **Get Guitar Pro files** for any tab, including tabs that only exist in Songsterr's web editor. A Guitar Pro 5 file is built from the current tab.
- 📚 **Scrape whole catalogs.** Give an artist name and get every song, most popular first.
- 🔎 **Search by name.** "One by Metallica" finds Metallica's own tab, not covers with the same title.
- 🤖 **Build machine-learning datasets.** Optional [DadaGP](https://github.com/dada-bots/dadaGP) token export, plus raw note-level JSON.
- 🧾 **Lyrics and chords** in plain text and ChordPro format.

The Apify platform adds scheduling, API access, integrations (Make, Zapier, Google Drive, webhooks), proxy rotation and run monitoring.

### What data can Songsterr Tabs Scraper extract?

Each song becomes one dataset item. Its files go to the key-value store as `song-<songId>-<file>`.

| Field / file | Type | Description |
|---|---|---|
| `title`, `artist`, `songId`, `url` | text | Song identity and Songsterr link |
| `tracks` | array | Every track: name, instrument, tuning, difficulty, views |
| `tags`, `views`, `favoritesCount` | array / number | Genre tags and popularity |
| `generatedGpUrl` → `generated.gp5` | file | Guitar Pro 5 file built from the current tab |
| `originalGpUrl` → `source.gp` | file | Guitar Pro file originally uploaded to Songsterr |
| `<partId>.json` | file | Raw track data: measures, beats, notes, effects, tempo |
| `meta.json` | file | Full Songsterr metadata for the song |
| `lyricsUrl` → `lyrics.txt` / `lyrics.json` | file | Lyrics |
| `chordsUrl` → `chords.chordpro` | file | Chord sheet |
| `bundleUrl` → `bundle.zip` | file | Everything for the song in one ZIP |
| `dadagp.txt` | file | DadaGP tokens (optional) |
| `revisions.json` | file | Full revision history (optional) |

### How to scrape Songsterr tabs

1. Open the Actor's **Input** tab.
2. Add what you want to scrape: Songsterr URLs, search queries such as `Metallica - One`, artist names, or song IDs. You can mix them.
3. Optionally limit songs per artist, or pick instruments (guitar, bass, drums, vocals).
4. Click **Start**.
5. When the run finishes, open the **Output** tab. Download the dataset, or click the ZIP / Guitar Pro links for each song.

### How much will it cost to scrape Songsterr?

The Actor uses plain HTTP requests (no browser), so it is light on compute units. You pay only Apify platform usage. A typical song with 10 or more tracks takes a few seconds. Large artist catalogs (hundreds or thousands of songs) cost proportionally more. Run a small test with **Max songs in total** first to see the cost for your use case. The Apify free plan covers small runs.

### Input

See the **Input** tab for every option. Examples:

```json
{ "startUrls": [{ "url": "https://www.songsterr.com/a/wsa/led-zeppelin-stairway-to-heaven-tab-s27" }] }
```

```json
{ "searchQueries": ["Metallica - One", "smells like teen spirit"] }
```

```json
{ "artists": ["Led Zeppelin"], "maxSongsPerArtist": 50, "trackInstruments": ["guitar", "bass"] }
```

- **Search mode**: by default only the best match per query is scraped. "All results" scrapes up to *Max results per query*.
- **Artist URLs** (`...-tabs-a20`) in *Songsterr URLs* scrape the whole catalog, like the *Artists* field.
- Songs are scraped once, even when several inputs point to the same song.

### Output

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel. Example item (shortened):

```json
{
  "songId": 27,
  "artist": "Led Zeppelin",
  "title": "Stairway to Heaven",
  "url": "https://www.songsterr.com/a/wsa/led-zeppelin-stairway-to-heaven-tab-s27",
  "revisionId": 9538267,
  "trackCount": 13,
  "tracks": [{ "partId": 1, "name": "Jimmy Page | Harmony Sovereign | Acoustic Guitar", "instrument": "Acoustic Guitar (steel)", "category": "guitar", "tuning": [64, 59, 55, 50, 45, 40], "difficulty": 3 }],
  "lyricsSource": "track newLyrics",
  "originalGp": { "revisionId": 2579237, "isCurrentRevision": false, "format": "Guitar Pro 7+", "file": "source.gp" },
  "generatedGp": { "built": true, "file": "generated.gp5" },
  "bundleUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/song-27-bundle.zip",
  "generatedGpUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/song-27-generated.gp5",
  "errors": []
}
```

A song that can't be scraped (for example, a wrong ID) still gets an item, with an `error` field, so you can see what failed.

### Tips and advanced options

- **Save compute units.** Turn off *Save track JSON files* and *ZIP per song* if you only need Guitar Pro files, or turn off *Build a Guitar Pro 5 file* if you only need the raw data.
- **Original vs. generated Guitar Pro file.** Songsterr keeps an uploaded `.gp` only for revisions imported from Guitar Pro. If the current revision has none, the Actor takes the newest older imported revision. That tab can be outdated: check `originalGp.isCurrentRevision`. `generated.gp5` always reflects the current tab. It matched the originals on 99%+ of measures in our checks; GP5 can't store double-dotted notes, so they become a dotted note plus a tied note.
- **GP7 files.** Most uploads are Guitar Pro 7 (`.gp`). Tools based on PyGuitarPro read only GP3 to GP5, so use `generated.gp5` with them.
- **DadaGP.** DadaGP allows at most 3 distorted guitars, 2 clean guitars, 1 bass and drums. The Actor keeps the most-viewed tracks that fit and lists the rest in `dadagp.skippedTracks`.
- **Blocked requests.** Songsterr normally works without a proxy. If you see repeated errors, enable a proxy under *Advanced*.

### FAQ, disclaimers, and support

#### Is it legal to scrape Songsterr?

Our Actors are ethical and do not extract any private user data, such as email addresses, gender, or location. They only extract what the user has chosen to share publicly. We therefore believe that our Actors, when used for ethical purposes by Apify users, are safe. However, you should be aware that your results could contain personal data. Personal data is protected by the GDPR in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers.

Tabs are transcriptions of copyrighted music. Respect Songsterr's terms of service and the rights holders when you use the data.

#### Why does a song have no original Guitar Pro file?

The song was written in Songsterr's editor and never imported from Guitar Pro. Use `generated.gp5`.

#### Why are there no lyrics?

Many tabs have no vocal track with lyrics. `lyricsSource` is `null` for those songs.

#### Can I use it from code?

Yes. See the **API** tab for HTTP, Python and JavaScript examples.

#### Something is wrong or missing

Please open an issue in the **Issues** tab with the song URL and run ID.

### For developers

How it works: the Actor uses the same public endpoints as songsterr.com's frontend.

- Search: `/api/search?pattern=`
- Artist catalogs: `/api/artist/{id}/search`, paged by 50
- Metadata: `/api/meta/{songId}`, falling back to the song page's `<script id="state">` JSON
- Track JSON: the CloudFront host from the page's `<link rel="dns-prefetch">`, at `/<songId>/<revisionId>/<image>/<partId>.json`
- Lyrics: `.../lyrics.json`, or `newLyrics` in the vocal tracks
- Original Guitar Pro upload: `/api/revision/{id}` → `source`
- Chords: `/api/chords/{songId}` → ChordPro CDN

Run it locally:

```bash
python -m venv .venv && .venv/bin/pip install -r requirements.txt pytest
apify run                       # input: storage/key_value_stores/default/INPUT.json
.venv/bin/python -m src.cli "Metallica - One" --dadagp   # standalone, writes data/raw/<songId>/
.venv/bin/python -m pytest      # offline tests
```

The DadaGP encoder in `src/dadagp/` is adapted from [dada-bots/dadaGP](https://github.com/dada-bots/dadaGP) (MIT, © 2020 Dadabots).

# Actor input Schema

## `startUrls` (type: `array`):

Song URLs (e.g. https://www.songsterr.com/a/wsa/led-zeppelin-stairway-to-heaven-tab-s27) and/or artist URLs (e.g. https://www.songsterr.com/a/wsa/metallica-tabs-a20). Artist URLs scrape the whole catalog.

## `searchQueries` (type: `array`):

Free text such as "Metallica - One", "One by Metallica" or "stairway to heaven". By default only the best match is scraped.

## `searchMode` (type: `string`):

Scrape only the best matching song per query, or every result up to the limit below.

## `maxResultsPerQuery` (type: `integer`):

Used with "All results" search mode.

## `artists` (type: `array`):

Artist names or numeric Songsterr artist IDs. Scrapes every song by the artist.

## `songIds` (type: `array`):

Numeric Songsterr song IDs (the number after "-s" in a song URL).

## `maxSongsPerArtist` (type: `integer`):

Limit for each artist catalog, most popular songs first. 0 means no limit.

## `maxSongs` (type: `integer`):

Overall limit across all inputs. 0 means no limit.

## `revisionId` (type: `integer`):

Scrape this revision instead of the current one. Only used when exactly one song is requested. 0 means the current revision.

## `downloadTracks` (type: `boolean`):

Save each track's raw JSON (notes, measures, effects) as <partId>.json.

## `trackInstruments` (type: `array`):

Only download these kinds of tracks. The filter also applies to the generated Guitar Pro file.

## `downloadLyrics` (type: `boolean`):

Save lyrics.json (from the legacy lyrics file or the vocal tracks) and a plain-text lyrics.txt.

## `downloadOriginalGp` (type: `boolean`):

Download the Guitar Pro file that was uploaded to Songsterr. Revisions edited in Songsterr's editor have none (see the next option).

## `gpFallbackToOlderRevision` (type: `boolean`):

Use the newest earlier revision that was imported from Guitar Pro. That tab may be older than the current one; the output records which revision it came from.

## `buildGpFromJson` (type: `boolean`):

Convert the current revision's track JSONs into generated.gp5 (notes, rhythms, tunings, repeats, markers, tempo changes, common effects and lyrics).

## `downloadChords` (type: `boolean`):

Save the chord sheet as chords.chordpro when the song has one.

## `includeRevisionHistory` (type: `boolean`):

Save the song's full revision list as revisions.json.

## `encodeDadaGP` (type: `boolean`):

Encode the song into DadaGP machine-learning tokens (dadagp.txt). DadaGP supports at most 3 distorted guitars, 2 clean guitars, 1 bass and drums, so the most-viewed compatible tracks are picked.

## `dadaGpSource` (type: `string`):

Which Guitar Pro file DadaGP encodes. "Auto" uses the original upload if it is GP3-GP5 and otherwise the file generated from the current tab. Most Songsterr uploads are GP7, which DadaGP cannot read.

## `bundleZip` (type: `boolean`):

Also save one ZIP per song containing all of the files above.

## `maxConcurrency` (type: `integer`):

How many songs are scraped at the same time.

## `proxyConfiguration` (type: `object`):

Songsterr usually works without a proxy. Turn one on if requests get blocked.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.songsterr.com/a/wsa/led-zeppelin-stairway-to-heaven-tab-s27"
    }
  ],
  "searchQueries": [
    "Metallica - One",
    "Nirvana Smells Like Teen Spirit"
  ],
  "searchMode": "bestMatch",
  "maxResultsPerQuery": 10,
  "artists": [
    "Led Zeppelin"
  ],
  "songIds": [],
  "maxSongsPerArtist": 0,
  "maxSongs": 0,
  "revisionId": 0,
  "downloadTracks": true,
  "trackInstruments": [
    "guitar",
    "bass",
    "drums",
    "vocals",
    "other"
  ],
  "downloadLyrics": true,
  "downloadOriginalGp": true,
  "gpFallbackToOlderRevision": true,
  "buildGpFromJson": true,
  "downloadChords": true,
  "includeRevisionHistory": false,
  "encodeDadaGP": false,
  "dadaGpSource": "auto",
  "bundleZip": true,
  "maxConcurrency": 5,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `songs` (type: `string`):

One item per song with metadata, track summaries and file links

## `files` (type: `string`):

Track JSON, Guitar Pro, lyrics, chords and ZIP files, keyed song-<songId>-<file name>

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrls": [
        {
            "url": "https://www.songsterr.com/a/wsa/led-zeppelin-stairway-to-heaven-tab-s27"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapescape/songsterr-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "startUrls": [{ "url": "https://www.songsterr.com/a/wsa/led-zeppelin-stairway-to-heaven-tab-s27" }] }

# Run the Actor and wait for it to finish
run = client.actor("scrapescape/songsterr-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrls": [
    {
      "url": "https://www.songsterr.com/a/wsa/led-zeppelin-stairway-to-heaven-tab-s27"
    }
  ]
}' |
apify call scrapescape/songsterr-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapescape/songsterr-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/hgfdFKYBNDIWoh5Kb/builds/ge6vKi3TfRtSLfVKT/openapi.json
