Write headlines
A headline is the only part of an article most people ever read, and writing ten good ones by hand is slow work you repeat every single day. This endpoint takes a topic or draft and returns several distinct headline variants built for skimmability, without resorting to bait that punishes your bounce rate.
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.
Built for the daily grind of publishing
Editors, growth marketers and solo bloggers all hit the same wall: the article is finished but the headline is the last 5% that eats an hour of second-guessing. text.headline exists for that exact moment. Feed it the article body, a summary, or just a working title, and it comes back with a set of alternative framings — direct, curiosity-driven, number-led, question-based — so you pick instead of stare at a blank line.
What actually happens after you call it
The call is asynchronous: you POST to /text/headline, receive a task_id immediately, and the model does its work in the background. When it finishes, you get the full set of variants either pushed to your webhook URL or waiting at a signed link that stays valid for 24 hours. There is no polling loop to babysit and no partial response to parse mid-generation.
A short history of the headline as a craft
Headline writing has been a distinct discipline since the penny press of the 1830s discovered that a strong line sold papers on the street before anyone read a word inside. Digital publishing inherited that pressure and amplified it — the same sentence now competes in a feed against video, ads and a hundred other headlines within a two-second glance. The craft has not changed; the volume required to compete has grown by orders of magnitude, which is exactly the gap automation is meant to close.
Quality without the clickbait trap
The variants are generated to be specific and true to the source content you provide — the model does not invent claims, numbers or urgency that isn't in your input. If your draft says a feature saves ten minutes, the headline will not inflate it to 'save hours'. That discipline matters because a headline is a promise, and broken promises are what tank engagement metrics over time, not underselling.
Where it plugs into a bigger pipeline
Because the endpoint is async and webhook-driven, it drops cleanly into a CMS publish hook, a newsletter build script, or an A/B testing queue that needs five headline candidates before it can even start a test. Pair it with our A/B copy variant endpoint when you want to test the winning headline against alternate subheads or CTAs in the same release.
What you can do with it
Newsroom deadline pressure
An editor pastes the final draft ten minutes before publish and gets five headline options instead of forcing the reporter's working title through unchanged.
Newsletter subject lines
A weekly digest script sends the issue summary to the endpoint and slots the top variant directly into the subject line field before the send.
Blog SEO refresh
A content team regenerates headlines for older posts that are ranking but underperforming on click-through, without rewriting the articles themselves.
Social post batching
A social scheduler requests several short variants per article to rotate across platforms so the same link doesn't look identical everywhere it's shared.
FAQ
How does the headline generator API work?
You send a POST request to /text/headline with your source text or topic, get a task_id back immediately, and receive the finished headline variants by webhook or a signed 24-hour link once processing completes.
Is there a free tier for the headline generator API?
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 many headline variants does one request return?
You set the number of variants you want in the request; the request fee is fixed and each additional variant is billed at $0.0135, so you only pay for what you actually generate.
Will the headlines be clickbait?
No. Variants stay grounded in the content you supply and avoid manufactured urgency or numbers not present in your input, so the headline matches what the reader actually finds.
Can I use this for languages other than English?
Send your source content in the language you want the headline in; the endpoint is not restricted to English and will generate variants matching your input language.
What happens if the task fails?
Failed generations are retried automatically up to three times; if all retries fail you get a clear error and are never charged for that task.
How long is the result available after processing?
If you use the signed link instead of a webhook, it stays valid for 24 hours, after which the result is deleted along with your input data.
Can I generate headlines in bulk for a whole archive?
Yes — queue one async task per article; since each call returns a task_id immediately, you can fan out hundreds of requests and collect results as webhooks arrive.
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/headline \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"input":"…"}'const res = await fetch("https://api.kit.forhosting.com/text/headline", {
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/headline",
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/headline", 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/headline", 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.headline",
"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. |