Reply to an email
Replying well means reading the whole thread first, not just the last message, and matching a tone that was set two or three emails ago. This endpoint takes the thread and your intended response direction, and drafts a reply that actually reads as part of the same conversation instead of a fresh, disconnected message.
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 problem with replying out of context
A reply written without the full thread in view tends to repeat questions already answered, miss a detail the other person mentioned three messages back, or land in a tone that clashes with how the conversation has been going. Support agents juggling dozens of open tickets and account managers handling multiple accounts run into this constantly, not because they're careless but because rereading every thread in full before every reply doesn't scale. This endpoint is built specifically for that gap: it takes the thread as input, not just the latest message, so the reply it drafts actually accounts for what came before.
What a request looks like
You send the thread, or the relevant portion of it, along with the direction you want the reply to take, confirm, decline, ask a follow-up question, escalate, and an optional tone. The task runs asynchronously, returning a task_id immediately, with the drafted reply delivered by signed webhook or a signed link valid for 24 hours, ready to review and send rather than a note that still needs restructuring.
Why thread continuity is harder than it looks
Email threading itself is a fairly old convention, quoting prior messages below a reply so the full history travels with the conversation, but reading that history and actually responding to it coherently is a separate skill from having access to it. Plenty of tools can summarize a thread; fewer can draft a reply that references the right prior point without restating everything or contradicting an earlier commitment made in the same conversation. That continuity is the specific thing this endpoint is built to preserve.
Where it fits into daily operations
This typically runs inside a support desk or CRM, triggered the moment a new message lands in a thread that needs a response, producing a draft an agent reviews and sends rather than one they write from scratch. Pricing is a small base fee plus a per-email charge, so cost scales directly with reply volume rather than thread length, and a failed generation is never billed, since the task retries automatically up to three times before returning a clear error instead of a charge.
Where a person still needs to step in
A drafted reply reflects the thread and the direction you gave it, not private knowledge about the account or company policy beyond what's in the conversation, so anything involving a commitment, a refund, a deadline, should get a human check before sending. Thread content is deleted after the retention window and never used to train models, which matters given how much sensitive account detail tends to live inside an email thread.
What you can do with it
High-volume support queue
A support agent handling sixty open tickets gets a draft reply for each thread that already reflects the customer's full history in that conversation, then reviews and sends.
Account management follow-through
An account manager returning from time off drafts replies to threads that moved on without them, catching up on context automatically instead of rereading each one line by line.
Consistent tone across a team
A team handling shared inboxes uses the same tone setting across agents so customers get a consistent voice regardless of who actually replies.
Escalation drafting
A support lead requests a reply drafted specifically to escalate a thread internally while still sounding appropriately reassuring to the customer.
FAQ
How does the email reply API understand the thread?
You send the thread or the relevant portion of it as input, and the draft is built to reference and stay consistent with that history rather than treating the message in isolation.
Is the email reply 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.
How much does each reply cost?
$0.003 per request plus $0.0135 per email drafted, a small and predictable cost per reply regardless of how long the thread is.
How do I receive the drafted reply?
By signed webhook for production integrations, or from a signed link that stays valid for 24 hours after the task completes.
Can I control what direction the reply takes?
Yes, you specify the intended direction, confirm, decline, ask a follow-up, escalate, and the draft is built around that instruction.
What happens if a generation fails?
It retries automatically up to three times, and if it still fails you get a clear error and are not charged for the attempt.
Should I send the reply without reviewing it first?
Not for anything involving a commitment, refund or deadline; the draft reflects the thread you provided, so a quick human check is still worthwhile before sending.
Is the thread content stored after the reply is generated?
No, thread content is deleted after the retention window and never used to train models, which matters given how much sensitive detail email threads tend to contain.
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-reply \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"input":"…"}'const res = await fetch("https://api.kit.forhosting.com/text/email-reply", {
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-reply",
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-reply", 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-reply", 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_reply",
"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. |