Subject lines
Open rate is decided in the half second before a click, by six or eight words competing against everything else in the inbox, which makes the subject line the single highest-leverage sentence in an email campaign. This endpoint generates multiple distinct variants from one email brief, built to be tested against each other rather than guessed at.
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.
One good subject line is luck, several is a process
Anyone can write a subject line that sounds fine in isolation; the actual skill is producing several genuinely different angles, curiosity, urgency, directness, a number, so that testing means something instead of comparing near-identical phrasings. This endpoint is built around that variety by design, taking the email's content or intent and returning a set of subject lines that differ in approach, not just word choice, so an A/B or multivariate test has real signal to work with.
How a request works
You send the email's topic or a summary of its content, an audience if relevant, and the number of variants you want. The task runs asynchronously and returns a task_id right away, with the finished subject lines delivered by signed webhook or through a signed link that stays valid for 24 hours, formatted as a simple list ready to load into a campaign tool's test slots.
Why testing subject lines became standard practice
Email marketers began split-testing subject lines as soon as sending platforms made it easy to route a fraction of a list to each variant, because open rate turned out to swing hard on wording alone, far more than most people expect from six to ten words. That history is why a single AI-written subject line is worth less than several: the value isn't in one clever line, it's in having enough real variation to let actual recipient behavior pick the winner instead of a guess in a meeting.
Fitting into a sending workflow
This endpoint typically runs right before a campaign is scheduled, once the email body is finalized, feeding variants straight into the test configuration of whatever platform sends the campaign. Pricing is a small base fee plus a per-variant charge, so requesting three variants for a quick send or eight for a high-stakes campaign scales with what the test actually needs, and a failed generation is never billed, since it retries automatically up to three times before returning a clear error.
What it won't do
It generates lines from the content you give it, not from data about your specific list's past behavior, so it's a starting point for testing, not a prediction of which one will win. Subject line data and email content are deleted after the retention window and never used to train models, which matters for campaigns tied to unannounced launches or pricing changes.
What you can do with it
Weekly newsletter testing
A publisher generates four subject line variants for each weekly issue and runs a small split test before sending to the full list.
Product launch announcement
A marketing team requests urgency-driven and curiosity-driven variants side by side to see which framing gets more opens for a limited-time launch.
Abandoned cart recovery
An e-commerce team generates subject lines for a recovery sequence, testing a direct reminder against a softer, benefit-led angle.
Re-engagement campaign
A lifecycle marketer requests variants aimed specifically at subscribers who haven't opened an email in months, distinct from the tone used for active readers.
FAQ
How many subject line variants can I generate per request?
You specify the number of variants you want in the request, and each one is billed individually, so it scales from a quick two-variant test to a larger multivariate one.
Is the email subject line generator API free to use?
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.
What's the cost per variant?
$0.003 per request plus $0.0135 per variant generated, a small and predictable total for however many lines the test needs.
How do I receive the generated subject lines?
By signed webhook for production use, or from a signed link that stays valid for 24 hours after the task completes.
Are the variants actually different from each other?
Yes, the endpoint is built to vary approach, curiosity, urgency, directness and similar angles, rather than returning near-identical rewordings.
What happens if a generation fails?
It retries automatically up to three times, and if it still can't complete, you get a clear error and are not charged.
Can this predict which subject line will perform best?
No, it generates strong candidates for you to test; actual performance depends on your list and should be confirmed with real send data.
Is my email content stored after generating subject lines?
No, content is deleted after the retention window and never used to train models, which matters for campaigns tied to unannounced launches.
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/email-subject \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"input":"…"}'const res = await fetch("https://api.kit.forhosting.com/text/email-subject", {
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/email-subject",
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/email-subject", 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/email-subject", 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.email_subject",
"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. |