Changelog
Feed the endpoint a batch of commit messages or a diff summary since the last release, and it returns release notes written for the people who'll actually read them — grouped into features, fixes and breaking changes, not a raw commit log. It's built for the release step that engineering teams always mean to do properly and rarely have time for.
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 gap between commits and release notes
A commit log is written for the person who wrote the commit, in the moment they wrote it — 'fix null check,' 'wip,' 'address review comments' — which is exactly the wrong register for someone deciding whether to upgrade. Release notes need to say what changed for the user, not what changed in the code, and that translation step is where changelog quality usually falls apart under deadline pressure. This endpoint does that translation: it takes the raw commit messages and groups them into the categories a reader actually scans for, with each entry rewritten in plain terms.
How the request is structured
POST /text/changelog with the commit messages or diff summary for the release. The task runs asynchronously — a task_id comes back right away, and the finished changelog is delivered by signed webhook or a signed link valid for 24 hours, which fits naturally into a CI/CD pipeline that triggers it automatically at tag time rather than waiting on a person to write notes manually before every release.
Why grouping is the whole job
The 'Keep a Changelog' convention that much of the industry has converged on exists because flat, chronological commit lists don't communicate risk — a reader needs to see breaking changes separated from routine fixes before anything else, since that's the one category that decides whether an upgrade needs planning. This endpoint follows that same instinct: breaking changes, features and fixes are grouped as distinct sections rather than interleaved in commit order, so the one line that matters most to a careful reader isn't buried on line forty of a scroll.
Where it sits in a release pipeline
This is built for teams shipping frequent releases who don't want a person manually curating notes each time, open-source maintainers who owe their users clear upgrade guidance, and platforms that generate release notes on behalf of many projects at once. Because it's async with webhook delivery, a CI job can call it the moment a release branch is tagged and have notes ready before the release is even published. Pricing is $0.003 per request plus $0.0135 per release, charged only when the changelog completes — failed generations retry automatically up to three times at no cost.
What you can do with it
Automated release pipeline
A CI/CD workflow calls the endpoint the moment a version tag is pushed, attaching generated release notes to the release before it goes out.
Open-source maintainer
A maintainer with limited time for documentation feeds in the commits since the last tag and gets grouped, readable notes instead of skipping the changelog that release.
Platform generating notes for many repos
A developer-tools platform offering hosted changelogs generates them on behalf of each connected project without a human touching any of them.
Highlighting breaking changes clearly
A library with a strict semver policy uses the grouped output to make sure breaking changes are never buried among routine bug fixes.
FAQ
Is the changelog generator API free?
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.
Does it just reformat my commit messages?
No, it rewrites them into plain, user-facing language and groups them by category rather than simply reformatting the raw commit text.
Does it separate breaking changes from regular fixes?
Yes, breaking changes, features and fixes are grouped into distinct sections so the entries that matter most for an upgrade decision aren't mixed in with routine commits.
Can I trigger it automatically from CI/CD?
Yes — send the commit messages or diff summary at tag time via POST to /text/changelog and handle the result by webhook, no manual step required.
How do I receive the finished changelog?
By signed webhook, recommended for automated pipelines, or a signed link valid for 24 hours if you'd rather fetch it on demand.
Can I generate changelogs for multiple projects at once?
Yes — each call to /text/changelog is an independent async task, so a platform can process many projects' releases in parallel.
What input format does it expect?
Raw commit messages or a diff summary for the release; there's no required special syntax like conventional commits, though following one can improve grouping.
Is my commit data retained afterward?
No — it's deleted after the retention window and never used for training; the endpoint's only role is producing the changelog.
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/text/changelog \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"input":"…"}'const res = await fetch("https://api.kit.forhosting.com/text/changelog", {
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/text/changelog",
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/text/changelog", 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/text/changelog", 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": "text.changelog",
"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_tokens | 20000 |
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. |
422 | task_failed | The task failed after 3 retries. You are never charged for it. |