ai-essay-writer
AI Essay Writer API — generate a complete essay from a topic. Pass a topic plus academic level, essay type, and length; the API returns a structured essay. Async submit + poll, optional humanize pass, per-essay pricing by length.
The AI Essay Writer API generates a complete, structured essay from a
topic plus an academic level, essay type, and length. One
async call returns a task id; poll until the essay is ready. An optional
humanized pass rewrites the result to read more human. Pricing is per
essay, scaled by the length tier — see current rates on the
model page.
Quick example
curl https://reapi.ai/api/v1/essay \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "ai-essay-writer",
"type": "Descriptive",
"academic_level": "HighSchool",
"length": "Short",
"input": "Write an essay about the ketogenic diet"
}'import requests
resp = requests.post(
"https://reapi.ai/api/v1/essay",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
json={
"model": "ai-essay-writer",
"type": "Descriptive",
"academic_level": "HighSchool",
"length": "Short",
"input": "Write an essay about the ketogenic diet",
},
timeout=30,
)
print(resp.json())const r = await fetch("https://reapi.ai/api/v1/essay", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "ai-essay-writer",
type: "Descriptive",
academic_level: "HighSchool",
length: "Short",
input: "Write an essay about the ketogenic diet",
}),
});
console.log(await r.json());package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)
func main() {
body, _ := json.Marshal(map[string]any{
"model": "ai-essay-writer",
"type": "Descriptive",
"academic_level": "HighSchool",
"length": "Short",
"input": "Write an essay about the ketogenic diet",
})
req, _ := http.NewRequest("POST",
"https://reapi.ai/api/v1/essay", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
out, _ := io.ReadAll(resp.Body)
fmt.Println(string(out))
}Submit response
{
"id": "task_018f5a3a1b6e7d9f8c2b4d6e8f0a2c4e",
"model": "ai-essay-writer",
"status": "processing",
"created_at": 1735000000
}Poll GET /api/v1/tasks/{id} (see the Tasks reference) until
status === "completed". The completed payload carries the generated essay text
in the task output.
Authentication
Every call needs a Bearer token. Generate keys at reapi.ai/settings/apikeys.
Authorization: Bearer YOUR_API_KEYEndpoint
POST /api/v1/essay
GET /api/v1/tasks/{id}Submission is async. The POST returns immediately with a task_id; the task
endpoint returns the same envelope until completion. Polling does not consume
credits.
Request body
model — required
string. Must be "ai-essay-writer".
input — required
string. The essay topic or instructions the model builds the essay around.
type — required
string. The rhetorical mode of the essay.
| Value | Notes |
|---|---|
"Descriptive" | Descriptive essay |
"Narrative" | Narrative essay |
"Persuasive" | Persuasive / argumentative |
"Analytical" | Analytical essay |
"CompareAndContrast" | Compare-and-contrast essay |
academic_level — required
string. The writing level the essay targets (vocabulary, structure, depth).
| Value |
|---|
"HighSchool" |
"University" |
"Doctorate" |
length — required
string. Output length tier. Pricing scales with this tier.
| Value |
|---|
"Short" |
"Medium" |
"Long" |
humanized — boolean, default false
Run the finished essay through a de-AI pass so it reads more human.
model_version — string, default "v2"
Generation model version.
Response envelope
Submit and poll share the same shape — only status and output fill in over
time. The completed output carries the generated essay text.
{
"id": "task_018f5a3a1b6e7d9f8c2b4d6e8f0a2c4e",
"model": "ai-essay-writer",
"status": "completed",
"created_at": 1735000000,
"output": {
"text": "The ketogenic diet, commonly referred to as the keto diet, is a high-fat, low-carbohydrate eating plan…"
},
"error": null
}| Field | Type | Notes |
|---|---|---|
id | string | Task identifier — keep it for polling and audit |
model | string | Echo of the submitted model |
status | string | processing / completed / failed |
created_at | integer | Submission unix timestamp |
output | object | null | null until completion. output.text is the essay |
error | object | null | Populated on failed — { code, message } |
Pricing
Per essay, scaled by the length tier. Each tier is priced at a fixed
estimated output-word count × the per-word rate.
Bill formula (1 credit = $0.001):
credits = ceil(per_word_usd × estimated_words(length) × 1000)length (Short / Medium / Long) selects the estimated word count. See the
current per-tier rates in the pricing table on the
model page. Failed jobs refund
automatically.
Validation errors
All cases below return HTTP 400. Pattern-match on code, not message.
| Trigger | Code | Message (illustrative) |
|---|---|---|
input missing | 20002 | input is required |
type missing / invalid | 20003 | invalid type |
academic_level missing / invalid | 20003 | invalid academic_level |
length missing / invalid | 20003 | invalid length |
| Upstream out of credits | 80003 | Upstream provider could not process the request |
The full envelope is { "error": { "code", "message", "request_id" } } — see
Errors catalog.
Tips
- Length drives the bill. A Short essay costs less than a Long one; pick the smallest tier that fits the assignment.
- Set the type and level deliberately.
academic_levelandtypechange the vocabulary, structure, and depth more than the prompt wording does. - Use
humanizedfor a natural read. Turn it on when the essay needs to read less like AI; leave it off for the fastest result. - The topic can be detailed.
inputaccepts full instructions, not just a title — constraints and angles in the topic carry into the essay.