Audio metadata
A library of audio files with missing artist names, blank album art or inconsistent track numbers is a music player's worst nightmare and a listener's daily annoyance. This audio metadata API reads the ID3 tags already embedded in a file and writes new ones you specify, so a whole catalog can be corrected or enriched without opening a single file by hand.
Run it online
Run this on our servers with your account. Free tools run in your browser; this one bills your KIT balance per the price above.
The quiet problem behind every messy library
Metadata is the part of an audio file nobody notices until it's wrong: the podcast app that shows 'Track 1' instead of an episode title, the audiobook that sorts out of order because chapter numbers were never set, the streaming library with a placeholder icon where the cover art should be. Anyone managing more than a handful of files, labels, podcast networks, audiobook publishers, ends up needing to inspect and correct tags at scale rather than one file at a time in a desktop tag editor.
Reading and writing in the same request
You send a file to POST /audio/metadata along with either nothing, to read what is already embedded, or a set of tag values to write, such as title, artist, album, track number or cover artwork. The task queues asynchronously and returns a task_id immediately; once processing finishes, the read tags or the confirmed updated file are delivered via signed webhook or a signed link valid for 24 hours.
A format with three decades of history
ID3 has been the standard way to embed title, artist and album information directly inside an MP3 or similar file since the mid-1990s, and it is the reason a music player can show a song's name without you typing it in yourself. Successive versions of the format expanded what could be stored, adding embedded artwork and more structured fields, which is exactly why reading and writing it correctly still matters: player behavior, sorting and search all depend on those tags being present and accurate.
Fitting metadata work into automation
Because this is one endpoint for both reading and writing, a pipeline can inspect a batch of incoming files for missing tags, then immediately write the corrected values back in a second call, all without a human opening a tag editor. Pricing is $0.077 per request plus $0.0045 per file, which keeps cost predictable whether you're tagging a single track or running a batch through the same specification.
Access and current status
Calling the endpoint requires prepaid balance, same as the rest of the API; without one, requests return HTTP 402 rather than a partial write. This endpoint is currently in deployment and will begin accepting jobs soon. Uploaded files and their metadata are retained only for the delivery window and never used to train models.
What you can do with it
Podcast catalog cleanup
Read the existing tags across a back catalog of episodes to find which files are missing a title or episode number.
Audiobook chapter tagging
Write correct track numbers and chapter titles onto a set of narration files so they play back in the right order.
Cover art batch update
Embed new album artwork into a set of tracks after a rebrand, without editing each file individually.
Music library normalization
Standardize artist and album fields across files that arrived from different sources with inconsistent tagging.
FAQ
How do I read ID3 tags with this API?
Send the file to POST /audio/metadata without new values and the task returns the existing tags, such as title, artist and album, via webhook or a signed link.
Can this API write new ID3 tags too?
Yes, sending the same endpoint a set of tag values, including cover artwork, writes them into the file and returns the updated version.
Is there a free tier for reading ID3 tags?
There's no free tier — free tiers get abused and slow everyone down. Access runs on a prepaid ForHosting KIT balance: top up from $10.00 (it never expires) and each request is charged at its published price, so a call with no balance returns HTTP 402. No subscription, no tokens, no invented credits, and a failed task is never charged.
How much does the audio metadata API cost?
It costs $0.077 per request plus $0.0045 per file, so batch tagging scales predictably with the number of files.
Is the ID3 tag API available now?
It is currently in deployment and will start accepting jobs soon; the read and write behavior described here is what will ship.
What tag fields can be read or written?
Standard ID3 fields such as title, artist, album, track number and embedded cover artwork are supported.
Can I update metadata for a batch of audio files?
Yes, submit one request per file; each is queued and priced independently, so a whole catalog can be processed through the same call pattern.
Does writing new tags affect the audio itself?
No, only the embedded metadata is changed; the audio content of the file is not re-encoded or altered.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, and soon from our app, email and Telegram.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/audio/metadata \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"input":"…"}'const res = await fetch("https://api.kit.forhosting.com/audio/metadata", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"input": "…"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/audio/metadata",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"input": "…"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/audio/metadata", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"input":"…"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"input":"…"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/audio/metadata", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"input": "…"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "audio.metadata",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Limits
max_mb | 200 |
max_minutes | 180 |
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |