Optical Music Recognition (OMR)
Flat's Optical Music Recognition turns a PDF or photo of sheet music into music you can use: a fully editable score in the Flat Library, or a MusicXML or MIDI file for your own tools. You send the file, Flat recognizes the staves, notes, and symbols, and you get back the result to play, edit, and export.
Beta API
The OMR API is in Beta. Endpoints, fields, and behavior can still change before the stable release. Keep a generic fallback for open-ended values (statuses, step and error codes) and expect breaking changes to be announced.
Looking for the end-user OMR feature instead? See the OMR help center article and its changelog. If you or your users just want to turn files into scores without writing code, and without a Flat account, try Opuscan, our dedicated scan-to-score product.

Powered by Tutteo's own AI model
Every PDF and photo is processed by Tutteo's own in-house deep-learning model, the Optical Music Recognition engine built by our company, Tutteo, behind Flat and Opuscan, not a third-party engine. It does not just spot symbols, it reads them in musical context, the way a trained musician would, so the score it rebuilds actually makes sense.
- Reads in context. Rhythm, pitch, and layout are read together, not symbol by symbol.
- Understands structure. Separates instruments and voices, and attaches lyrics, chords, and text to the right notes.
- Improves with every release. Built end to end in-house, so recognition gets measurably better over time.
Two ways to import
There are two ways to run OMR through the API:
- The Interactive Jobs API gives the best results. You can set the locales, review and correct the detected instruments and title, follow live progress, and export MusicXML without adding it to your Flat Library. It also supports adding pages one by one (ideal for mobile capture). This is the recommended path for a polished integration.
- The Auto simple import is the fewest calls and shares one code path with your MusicXML and MIDI imports: send a file to
POST /scores, poll the task, get a score. Reach for it when you just want a Library score and do not need the review step or progress.
Interactive Jobs API
Recommended. The resumable /omr pipeline: set locales, review and correct detected instruments, follow live progress, export MusicXML, and capture pages incrementally.
Auto simple import
Imports into the Flat Library through the same POST /scores endpoint you use for MusicXML, MIDI, and other formats. Send a file, poll the task, get a score. Fewest calls, no review step.
| Interactive Jobs API | Auto simple import | |
|---|---|---|
| Endpoint | /omr/jobs/* | POST /scores (+ tasks) |
| Best for | Controlling instruments and locales, a progress UI, multi-image or mobile capture | A single PDF, or unifying MusicXML / MIDI / PDF import behind one call |
| Result | A Library score, or a MusicXML file you download directly (without importing it into the Library) | A score in the Flat Library |
| Review step | Optional details step (correct title, language, instruments) | No |
| Live progress | Long-polling with a localized progress key | Task percent |
| Calls to ship | 3 or more | 2 |
Authentication and scopes
Every OMR request is authenticated like the rest of the API (see Authentication). A Personal Access Token is the quickest way to start.
For OAuth2 apps, request these scopes:
| Scope | When you need it |
|---|---|
omr | Every OMR request (both flows). |
scores | Additionally, whenever OMR creates a score in the Library: the Auto simple import, and the Interactive Jobs API with output: library (the default). Not needed for output: musicxml. |
In the Interactive Jobs API, a request that creates a Library score without the scores scope is rejected with 403 (OMR_SCORES_SCOPE_REQUIRED). The Auto simple import enforces the scores scope through the standard endpoint scope check, and separately returns 403 (OMR_SCOPE_REQUIRED) when the omr scope is missing. Personal access tokens and web sessions carry the account's own permissions and are not subject to these OAuth scope checks.
Capabilities and credits
OMR runs on credits tied to the user's Flat account, charged per page at job start. Call GET /omr/capabilities to feature-detect at runtime instead of hardcoding limits: it returns the supported steps, export formats and outputs, the file, page, and parallel-job limits, costPerPage, and the account's remainingCredits. See the getOmrCapabilities reference for the full response.
When the account is out of credits, over quota, or the plan does not include OMR, requests that consume credits return 402. Show remainingCredits and costPerPage to warn users before you start a job.
Need more than our prepaid credit plans? Contact us to discuss custom pricing and a contract for larger volumes.
What OMR can read
OMR works best on clean, printed sheet music: engraved scores, good scans, and sharp photos, in standard notation (single instruments, grand-staff, and multi-instrument scores). Handwritten music and tablature are not supported. As a rule of thumb, if a page is hard for a person to read, it is hard for Flat to read.
For the full, up-to-date details, see the help center:
- Which notations are supported (the complete recognition matrix).
- Getting the best results (capture and file-preparation tips).
- OMR changelog (recognition improvements over time).
Errors
A failed job reports a stable errorCode plus a localized errorMessage. The Auto simple import surfaces the same failures through the task's error message. errorCode is an open string: new codes may be added, so branch on the ones you handle and keep a generic fallback.
errorCode | Meaning |
|---|---|
NO_MUSIC_DETECTED | No musical content found (poor scan, rotated page, or tablature). |
CORRUPTED_FILE | The input file is corrupted and could not be read. |
UNSUPPORTED_FORMAT | The file format or notation is not supported yet. |
UNSUPPORTED_TABLATURE | The file is guitar tablature, not supported yet. |
ENCRYPTED_PDF | The PDF is password-protected. |
TOO_LARGE | The document is too large or has an unusual shape to process. |
ENGINE_TIMEOUT | Recognition took longer than expected and was stopped. |
GENERIC | Unspecified failure. |
HTTP statuses you should handle:
| Status | When it happens |
|---|---|
400 | Invalid request, for example adding a file to a job that is no longer a draft (OMR_JOB_NOT_DRAFT), or a file whose type cannot be determined (OMR_MIME_REQUIRED). |
402 | Out of credits, over quota, or OMR not included in the plan. |
403 | Missing a required scope: OMR_SCOPE_REQUIRED (the omr scope), or OMR_SCORES_SCOPE_REQUIRED (the scores scope for Library output in the Jobs API). |
404 | Job, task, or export not found (or the requested export format is not available). |
409 | State conflict, for example submitting a step the job is not awaiting, or canceling a job the worker is actively processing. |
See the Errors page for the general error response format.
Next steps
- Auto simple import - the quickest path to a score.
- Interactive Jobs API - full control, progress, and the review step.
- Instrument IDs - the catalog used to correct detected parts.
- API Reference: OMR.