# Audio to MIDI Converter API: MP3, WAV to MIDI, Notes, Key (`magnova/audio-to-midi-converter`) Actor

Convert MP3, WAV, FLAC or MP4 audio URLs to MIDI files with Spotify Basic Pitch: .mid download, note list (pitch, timing, velocity), tempo BPM, key and pitch range. $0.01 per audio minute.

- **URL**: https://apify.com/magnova/audio-to-midi-converter.md
- **Developed by:** [Magnova](https://apify.com/magnova) (community)
- **Categories:** AI, Developer tools, Integrations
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $7.00 / 1,000 audio minute converted to midis

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 Audio to MIDI Converter do?

**Audio to MIDI Converter turns recordings into MIDI.** Give it links to MP3, WAV, FLAC, M4A, OGG or MP4 files and it returns, for every file, a downloadable **.mid file**, the full **note list** (start, end, MIDI pitch, note name, velocity), the **estimated tempo (BPM)**, the **estimated key** and the **pitch range**. It uses Spotify's open-source [Basic Pitch](https://github.com/spotify/basic-pitch) model running on Apify, so there is no API key to get, no subscription and no upload form: you pay **$0.01 per minute of audio** and nothing for files that fail.

It works best on **one instrument or one voice at a time**: piano, guitar, violin, cello, flute, sax, a sung or hummed melody, a bass line, a lead synth. It is a music transcription tool that writes MIDI, not an engraver of printed sheet music, and it is not built to separate a full band mix (see [limits](#limits-and-accuracy)).

### Why use this audio to MIDI converter?

- **Developers and music apps**: add "upload a recording, get MIDI" to your product with one API call instead of running TensorFlow/ONNX yourself.
- **Musicians and producers**: turn a hummed idea, a guitar riff or a piano take into MIDI you can drag into Ableton, Logic, FL Studio, Cubase, Reaper or GarageBand and re-voice with any instrument.
- **Music teachers and edtech**: get the notes of a student's performance as JSON to compare against the score, check intonation range or build practice tools.
- **AI agents and LLM apps**: the note list is plain JSON an LLM can read ("what key is this riff in?", "transpose this melody", "write a bass line for it").
- **Researchers and data teams**: batch-convert a library of solo recordings you own into symbolic music data (MIDI + CSV/JSON) for analysis or model training.

### How to convert MP3 or WAV to MIDI

1. Click **Try for free** and paste one or more direct audio or video file URLs into **Audio or video file URLs** (one per line). The link must point at the file itself, e.g. `https://example.com/my-riff.mp3`.
2. Optional: tune the **note onset threshold**, **frame threshold**, **minimum note length** and the **lowest/highest note frequency** (see [tips](#tips-for-better-midi)).
3. Click **Start**. Each file becomes one row in the dataset with a `midiUrl` you can download straight away and a `notes` array.
4. Download the results as JSON, CSV, Excel or HTML, or call the Actor through the [Apify API](https://docs.apify.com/api/v2) from your own code.

Supported formats: MP3, WAV, AIFF, FLAC, M4A/AAC, OGG/Opus, WMA, and the audio track of MP4, MOV, MKV and WEBM video. Files are decoded with FFmpeg.

### Input example

```json
{
  "sources": [
    "https://upload.wikimedia.org/wikipedia/commons/3/37/00_Jazz_Violin_Solo.ogg"
  ],
  "onsetThreshold": 0.5,
  "frameThreshold": 0.3,
  "minNoteLengthMs": 127.7,
  "minFrequencyHz": 190,
  "includeNotes": true,
  "maxMinutesPerFile": 10
}
```

Only `sources` is required; every other setting has a sensible default.

### Output example

One dataset item per input file (notes shortened here):

```json
{
  "sourceUrl": "https://upload.wikimedia.org/wikipedia/commons/3/37/00_Jazz_Violin_Solo.ogg",
  "status": "ok",
  "error": null,
  "fileName": "00_Jazz_Violin_Solo.ogg",
  "title": "00_Jazz_Violin_Solo.ogg",
  "durationSecs": 30.0,
  "processedSecs": 30.0,
  "billedMinutes": 1,
  "midiUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/001-00_Jazz_Violin_Solo.mid",
  "notesJsonUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/001-00_Jazz_Violin_Solo.notes.json",
  "noteCount": 192,
  "notes": [
    {"start": 0.952, "end": 1.196, "pitch": 70, "noteName": "A#4", "velocity": 71, "amplitude": 0.556},
    {"start": 1.312, "end": 1.613, "pitch": 72, "noteName": "C5", "velocity": 64, "amplitude": 0.502}
  ],
  "notesInRow": 192,
  "tempoBpm": 99.7,
  "key": "Bb major",
  "keyConfidence": 0.637,
  "lowestNote": "E1",
  "highestNote": "A#6",
  "lowestPitch": 28,
  "highestPitch": 94,
  "pitchRange": "E1-A#6 (66 semitones)",
  "truncated": false,
  "processingSecs": 1.5,
  "realtimeFactor": 20.2,
  "convertedAt": "2026-10-25T00:00:00Z"
}
```

| Field | What it is |
|---|---|
| `midiUrl` | Download link of the Standard MIDI File (one track, with pitch bends; tempo set to the estimated BPM so the DAW grid lines up) |
| `notesJsonUrl` | Download link of the complete note list as JSON (always complete, even for very long files) |
| `notes` | Up to 10,000 notes in the row: `start`/`end` in seconds, `pitch` as MIDI number (60 = middle C = C4), `noteName`, `velocity` 1-127, `amplitude` 0-1 |
| `noteCount` | Total notes detected |
| `tempoBpm` | Estimated global tempo in beats per minute |
| `key`, `keyConfidence` | Estimated key (e.g. `G minor`) and how clearly the notes fit it (above ~0.8 = clear) |
| `lowestNote`, `highestNote`, `pitchRange` | Range of the detected notes |
| `status` | `ok`, `no_notes` (silence, noise or unpitched sound, free), `skipped` or `error` |
| `error` | Why a file failed, or a note such as "converted the first 10 min" |

The **MIDI files** and **note JSON files** live in the run's default key-value store (Storage tab, or the "MIDI and note files" output link) and follow your account's data retention.

### Use with AI agents / MCP

The Actor is built to be called zero-shot by AI agents through the [Apify MCP server](https://mcp.apify.com) or the API: one required field, a working example, and flat JSON output. Minimal call:

```json
{ "sources": ["https://example.com/melody.mp3"] }
```

The agent gets back `midiUrl` (to hand to the user or another tool), `key`, `tempoBpm`, `pitchRange` and the `notes` array, which an LLM can reason over directly, e.g. "the melody spans G3-E5, is in E minor at about 92 BPM, and starts E4 G4 B4". Set `"includeNotes": false` when the agent only needs the MIDI link and summary, to keep the response small.

### How much does it cost to convert audio to MIDI?

Pay per event, with no start fee and no monthly subscription:

| | Price |
|---|---|
| Each started minute of audio converted (per file, rounded up) | **$0.01** |
| Silver / Gold and higher Apify plans | $0.0085 / $0.007 per minute |
| Files that are unreachable, undecodable, rejected (YouTube, Spotify...) or contain no notes | **free** |

Examples: a 30-second riff costs $0.01, a 4-minute song $0.04, an hour of practice recordings $0.60. Hosted audio-to-MIDI APIs typically start at about $99 per month for a few hundred requests. You can cap spending with **Max total charge** on the run, and with `maxMinutesPerFile` per file; the Actor converts what fits in your limit and marks the rest instead of failing.

### Tips for better MIDI

- **Solo, clean recordings give the best MIDI.** One instrument or voice, little reverb, no backing track.
- **Too many ghost notes?** Raise `onsetThreshold` (0.6-0.7) and `minNoteLengthMs` (150-250), or set `minFrequencyHz` just under the instrument's lowest note (violin 190 Hz, flute 250 Hz, guitar 80 Hz, cello 63 Hz, bass 40 Hz) to drop octave-below errors.
- **Missing soft or fast notes?** Lower `onsetThreshold` (0.3-0.4) and `minNoteLengthMs` (50-80).
- **Vocals**: set `maxFrequencyHz` around 1100 Hz to stop breath and sibilance from turning into high notes.
- Tempo and key are estimates from the audio and the detected notes; relative keys (C major vs A minor) can swap, and tempo can come out at double or half speed.

### Limits and accuracy

- **Best on solo instruments and vocals; not on full band mixes.** On a dense mix (drums, bass, chords and vocals together) you get many overlapping notes from every part at once. Basic Pitch is polyphonic, so piano chords and guitar strums do work, but it does not separate instruments into tracks and does not transcribe drums.
- **MIDI, not engraved sheet music.** You get a MIDI file and note timings in seconds. Open the MIDI in MuseScore, Sibelius, Dorico or your DAW to quantize and lay it out as notation.
- One MIDI track per file; velocities come from the model's note amplitude.
- Very long files are processed in streaming segments, so length is limited only by the run timeout (default 60 minutes, which covers several hours of audio at the default 2 GB memory).

### Tested inputs

Verified on Apify with public-domain and Creative Commons recordings from Wikimedia Commons: solo jazz violin (OGG), solo guitar (OGG), Bach flute partita (OGG), Bach cello suite (OGG), Satie Gymnopedie No. 1 on piano (MP3), Bach violin sonata (OGG, 4.5 min), an 18-minute Beethoven piano sonata performance video (WEBM), a piano video (WEBM), an MP4 video, a silent file, a 404 link, a PDF, an image, web pages and YouTube, Spotify, SoundCloud and TikTok links. Every input produced a result row; bad inputs got a clear free error row.

### FAQ

#### How do I convert an MP3 to MIDI?

Paste the MP3's direct URL into `sources` and start the run. The result row's `midiUrl` is your .mid file. WAV, FLAC, M4A, OGG and MP4 work the same way.

#### Can I convert a YouTube or Spotify link to MIDI?

No. Downloading audio from YouTube, Spotify, SoundCloud, TikTok and similar platforms breaks their terms of service (and Spotify audio is DRM-protected), so those links are rejected with a free error row. Use a direct link to a file you own, for example from your own website, cloud storage with a public link, or an Apify key-value store.

#### Is it legal?

The Actor only processes files you point it at; it does no scraping and stores nothing beyond your own run. You must own the recording or have the rights to transcribe it. Transcribing copyrighted music for anything beyond personal study may need a licence from the rights holder.

#### How accurate is the audio to MIDI conversion?

For clean solo recordings, note pitches and timings are usually close enough to edit quickly in a DAW; Basic Pitch was evaluated by Spotify on solo instruments, vocals and piano datasets. Expect some extra short notes (often an octave above or below) and occasionally merged repeated notes; the threshold settings above fix most of them. Full mixes are much less accurate.

#### Does it work for piano, guitar and vocals?

Yes. Piano (including chords), acoustic and electric guitar, bowed strings, winds, brass, and sung or hummed melodies all work. Drums and percussion are not transcribed.

#### Can I get sheet music or MusicXML?

The Actor outputs MIDI and JSON. Import the MIDI into MuseScore (free) or another notation program to produce sheet music and MusicXML.

#### How do I download the MIDI file?

Open the `midiUrl` link from the dataset row, or go to the run's Storage tab > Key-value store. Via API, list the store's keys and fetch each `.mid` record.

#### How much does it cost?

$0.01 per started minute of audio per file, less on Silver/Gold plans; failed and silent files are free. See [pricing](#how-much-does-it-cost-to-convert-audio-to-midi).

#### Is there an audio to MIDI API?

Yes, this Actor is one. Call it with `POST https://api.apify.com/v2/acts/Magnova~audio-to-midi-converter/run-sync-get-dataset-items` and a JSON body like the input example, or use the Apify JavaScript/Python clients, Make, Zapier, n8n or the MCP server.

### Audio to MIDI API: alternatives and comparison

Hosted services such as Klangio, Songscription and AnthemScore offer polished web apps and sheet-music layout; their APIs require a monthly plan. Spotify's free Basic Pitch web demo converts one file at a time in the browser. This Actor runs the same open Basic Pitch model as a pay-per-minute API with batch input, JSON note output, tempo and key estimates, and no subscription, which suits developers, automations and AI agents.

### Legal and data

- **Pure computation on files you supply.** No scraping, no login, no cookies, no personal data. Platform page URLs (YouTube, Spotify, SoundCloud, TikTok, Instagram, Facebook, X, Apple Music, Bandcamp and others) are refused so that their terms are respected.
- **Your rights**: only submit audio you own or are licensed to transcribe.
- **Open-source components and licences**: Spotify Basic Pitch model and code (Apache-2.0), ONNX Runtime (MIT), pretty_midi (MIT), mir_eval (MIT), librosa (ISC), resampy (ISC), NumPy and SciPy (BSD-3-Clause), FFmpeg (Debian package, run as a separate unmodified command-line program for decoding, not linked into the Actor's code). Tempo and key estimation are our own NumPy code using published key profiles (Krumhansl-Kessler, Aarden-Essen, Temperley). No GPL/AGPL libraries are imported or linked (essentia, for example, is avoided because it is AGPL).
- Example recordings in this README and in the prefilled input are public domain or Creative Commons files hosted on Wikimedia Commons.

### Support

Found a file that converts badly or a format that fails? Open an issue on the Actor's Issues tab with the URL (if public) and the settings you used. Feature requests (MusicXML export, per-instrument presets, stem separation for full mixes) are welcome there too.

# Actor input Schema

## `sources` (type: `array`):

Direct links to audio or video files you own or have rights to: MP3, WAV, M4A/AAC, FLAC, OGG, OPUS, AIFF, MP4, MOV or WEBM. Each file becomes one .mid file plus a note list. Works best on solo instruments and vocals (piano, guitar, violin, flute, singing, humming). YouTube, Spotify, SoundCloud, TikTok, Instagram and other streaming or social page URLs are rejected for free. Example: https://upload.wikimedia.org/wikipedia/commons/3/37/00_Jazz_Violin_Solo.ogg

## `onsetThreshold` (type: `number`):

How confident the model must be that a new note starts (0.05-0.95). Lower = more notes (catches soft notes, more false positives); higher = fewer, cleaner notes. Basic Pitch default 0.5. Example: 0.6 for a noisy recording.

## `frameThreshold` (type: `number`):

How confident the model must be that a note is still sounding (0.05-0.95). Lower = longer notes, higher = shorter notes. Basic Pitch default 0.3. Example: 0.4.

## `minNoteLengthMs` (type: `number`):

Notes shorter than this are dropped. Raise it to remove flutter and ghost notes, lower it for fast passages. Default 127.7 ms (Basic Pitch default). Example: 60 for fast guitar runs.

## `minFrequencyHz` (type: `number`):

Optional: ignore notes below this frequency. Useful to drop rumble or octave errors, e.g. 190 Hz for violin (lowest string G3 = 196 Hz), 80 Hz for guitar, 27.5 Hz for full piano. Leave empty for no limit. Example: 190.

## `maxFrequencyHz` (type: `number`):

Optional: ignore notes above this frequency, e.g. 1100 Hz for a sung melody. Leave empty for no limit. Example: 1100.

## `includeNotes` (type: `boolean`):

Add the notes array (start, end, MIDI pitch, note name, velocity) to each result row (first 10,000 notes; the full list is always available at notesJsonUrl). Turn off for smaller rows when you only need the MIDI file.

## `maxMinutesPerFile` (type: `number`):

Optional cap: convert only the first N minutes of each file (you pay only for what is converted). Leave empty for full files. Example: 5.

## `maxFileSizeMb` (type: `integer`):

Files larger than this are skipped with an error row (not charged). Example: 500.

## Actor input object example

```json
{
  "sources": [
    "https://upload.wikimedia.org/wikipedia/commons/3/37/00_Jazz_Violin_Solo.ogg"
  ],
  "onsetThreshold": 0.5,
  "frameThreshold": 0.3,
  "minNoteLengthMs": 127.7,
  "includeNotes": true,
  "maxFileSizeMb": 500
}
```

# Actor output Schema

## `results` (type: `string`):

No description

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

No description

## `summary` (type: `string`):

No description

# 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 = {
    "sources": [
        "https://upload.wikimedia.org/wikipedia/commons/3/37/00_Jazz_Violin_Solo.ogg"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("magnova/audio-to-midi-converter").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 = { "sources": ["https://upload.wikimedia.org/wikipedia/commons/3/37/00_Jazz_Violin_Solo.ogg"] }

# Run the Actor and wait for it to finish
run = client.actor("magnova/audio-to-midi-converter").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 '{
  "sources": [
    "https://upload.wikimedia.org/wikipedia/commons/3/37/00_Jazz_Violin_Solo.ogg"
  ]
}' |
apify call magnova/audio-to-midi-converter --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,magnova/audio-to-midi-converter"
        }
    }
}
```

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/z5Fhn3SdiTaU5ljpb/builds/etenHta3M19ezsbL3/openapi.json
