Ingestions

Create an ingestion, track delivery status, and inspect delivered entities.

Use the ingestions endpoints to submit catalogue or audio content, track how each submission progresses, and inspect which entities were accepted during delivery. Ingestion is usually the first step in a MusiMap workflow: you send content, MusiMap processes it asynchronously, and accepted rows become visible in your catalogue inventory.

Not MusiTag or advanced music search

These endpoints track ingestion and delivery status. They do not run MusiSearch or MusiProfile. Use catalogue search for discovery and tracks for technical inventory after ingestion completes.

When to use ingestions

Ingestion endpoints answer operational questions: what did we submit, what stage is it in, and which entities were delivered? Catalogue inventory endpoints answer a different question: what is currently visible in the catalogue?

  • Ingestion status — submission lifecycle, entity counts, delivery outcomes.
  • Catalogue inventory — current tracks, artists, releases, and works in your accessible catalogue.

After a successful ingestion, entities should appear through /v1/tracks, /v1/artists, /v1/releases, and /v1/works when catalogue membership exists.

Supported modes

Public create requests use the JSON field mode. The internal name source_type is not part of the public contract.

Mode What it is When to use it Source expectation
api_json Structured metadata sent inline in the request body. Direct API integrations, small batches, or tightly controlled pipelines. payload object with artists, albums, tracks, and compositions.
s3_csv Tabular catalogue import from a CSV file already in storage. Bulk catalogue updates from spreadsheets or exports. source.type = s3_object pointing to one existing CSV object.
s3_ddex DDEX delivery imported from a prefix of files already in storage. Labels and distributors shipping ERN-based deliveries. source.type = s3_prefix pointing to an existing prefix.
s3_scan Audio files discovered under a prefix using filename and extension rules. Audio-only drops, filename conventions, or prefix-based audio libraries. source.type = s3_prefix pointing to an existing prefix.

Processing is asynchronous. After you create an ingestion, poll the read endpoints below until the public status reaches a terminal value such as completed or failed.

Create an ingestion

POST /v1/ingestions creates an ingestion and queues expansion automatically on the server. You do not send auto_expand, processing, trigger_analysis, or similar knobs. Eligible audio analysis runs automatically when included in your plan.

Every create request requires:

  • mode — one of the four public modes above.
  • idempotency_key — your stable key for safe retries (max 255 characters).
  • catalog_id — optional when your token already carries a default catalogue context. Must refer to an organisation-owned customer catalogue.

Ingestion always targets customer catalogues only. MusiMap Atlas is read-only and cannot be selected as an ingestion destination. See MusiMap Atlas.

OAuth scope: ingestion.write. Request this scope when exchanging client credentials.

Idempotency

  • New key, accepted create — 202 Accepted.
  • Same key and equivalent body — 200 OK with the existing ingestion.
  • Same key but a different body — 409 Conflict.
No file upload on this endpoint

S3 modes reference objects or prefixes that already exist in your authorised storage. Do not send multipart files to POST /v1/ingestions. Upload files first using storage presigned uploads.

Example: api_json

curl -X POST "https://api.musimap.com/v1/ingestions" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "api_json",
    "idempotency_key": "customer-json-batch-001",
    "payload": {
      "tracks": [],
      "artists": [{"key": "A1", "outer_id": "artist-1", "name": "Artist One"}],
      "albums": [],
      "compositions": []
    }
  }'

Example: s3_csv

curl -X POST "https://api.musimap.com/v1/ingestions" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "s3_csv",
    "idempotency_key": "catalog-2026-06-20",
    "source": {
      "type": "s3_object",
      "uri": ""
    },
    "csv": { "auto_mapping": true }
  }'

Example: s3_ddex

curl -X POST "https://api.musimap.com/v1/ingestions" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "s3_ddex",
    "idempotency_key": "ddex-batch-001",
    "source": {
      "type": "s3_prefix",
      "uri": "/"
    }
  }'

Example: s3_scan

curl -X POST "https://api.musimap.com/v1/ingestions" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "s3_scan",
    "idempotency_key": "audio-scan-2026-06",
    "source": {
      "type": "s3_prefix",
      "uri": "/"
    },
    "scan": { "extensions": [".wav", ".flac", ".mp3"] }
  }'

Track progress

OAuth scope for reads: catalog.read. Request this scope when exchanging client credentials. Tenant and catalogue access is enforced on every call.

List ingestions

curl "https://api.musimap.com/v1/ingestions?mode=api_json&status=completed" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Supported filters include:

  • mode, status, delivery_id, source_ingestion_batch_id.
  • submitted_after, submitted_before, created_after, created_before, updated_after, updated_before.
  • page, page_size for pagination.

Get one ingestion

curl "https://api.musimap.com/v1/ingestions/$MUSIMAP_INGESTION_UUID" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Detail responses include entity counts and links to related sub-resources (entities, items, stats). Poll this endpoint after create until the public status stabilises.

Items, entities, and stats

Ingestion observability uses three complementary read endpoints. They answer different questions and must not be confused:

  • /items — input processing records: what was submitted, expanded, or processed as ingestion items, including failures and skips.
  • /entities — delivered catalogue entities: what was published and is visible through inventory endpoints after successful delivery.
  • /stats — safe aggregate counts and lifecycle summary for the whole ingestion.

V1 does not expose cancel, retry, reprocess, or delete operations on ingestions. Use /items to diagnose failed rows and /stats for a high-level progress summary.

Inspect item-level results

curl "https://api.musimap.com/v1/ingestions/$MUSIMAP_INGESTION_UUID/items?status=failed" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Each item row may include:

  • id — MusiMap ingestion item UUID.
  • source_record_key — safe customer record key when available (never storage paths).
  • outer_id — client identifier when provided.
  • statuspending, processing, completed, failed, or skipped.
  • entity_typetrack, artist, release, or work.
  • mode — public ingestion mode for the parent batch.
  • error_code and message — sanitised, customer-actionable error details when processing failed or was skipped.

Supported filters: status, entity_type, outer_id, source_record_key, error_code, plus pagination.

Read ingestion stats

curl "https://api.musimap.com/v1/ingestions/$MUSIMAP_INGESTION_UUID/stats" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Stats responses summarise item status counts (total, pending, processing, completed, failed, skipped), delivered entity counts, has_errors, and links to self, items, and entities. Error messages on items are sanitised; raw stack traces and storage paths are never returned.

Inspect delivered entities

curl "https://api.musimap.com/v1/ingestions/$MUSIMAP_INGESTION_UUID/entities?entity_type=track" \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Each row describes one delivered entity with:

  • entity_typetrack, artist, release, or work.
  • entity_id — MusiMap canonical UUID.
  • outer_id — client identifier when provided.
  • source_record_key — safe customer record key when available (never storage paths).
  • action — such as created, matched, updated, linked, or skipped.

Storage model

For s3_csv, s3_ddex, and s3_scan, the create request references resources that already exist in storage authorised for your organisation. MusiMap validates the location against your configured inbound area. Arbitrary storage locations are not accepted.

Place files in your authorised inbound area using storage presigned uploads or your agreed onboarding process. Manage long-lived storage credentials through the developer dashboard when your integration requires them.

Responses do not return bucket names, object keys, queue names, or other internal operational details.

Errors

  • 401 — missing or invalid bearer token (invalid_token).
  • 400 — validation error, unsupported mode, or forbidden public field (validation_error).
  • 404 — inaccessible ingestion or missing catalogue or storage context (not_found).
  • 409 — idempotency key reused with a different request body (conflict).
  • 422 — S3 source not authorised for your organisation (validation_error).
  • 503 — upstream dependency unavailable (upstream_unavailable).

See References → Errors for the MusiMap error envelope and public error_code values.