Skip to content
Docs / Platform / Text generation

Text generation

POST /api/ai/generate sends a prompt through the engine chain in job mode; you poll for the answer and learn which engine served it.

When to use this endpoint

Use /api/ai/generate for anything that is not real-time: reports, grading, drafts, classification, document reading, batches. It supports engine preference order, exact models per engine, JSON mode, attachments and a strict subscription_only switch.

Use Chat completions instead when a person is typing in a chat client or an OpenAI-compatible tool (editor plugins, aichat, Open WebUI), or when you want streaming keepalives on one connection.

Both surfaces share one admission controller (24 running requests globally with a free-memory floor, 12 per API-key owner) and the same account rotation and deny rules.

Submit a job

POST /api/ai/generate

curl -s https://maximind.dev/api/ai/generate \
  -H "x-api-key: $MAXIMIND_API_KEY" -H "content-type: application/json" \
  -d '{"prompt":"…","system":"…","json":false,
       "engines":["agy","codex","claude"],
       "models":{"agy":"gemini-4-argon-high","codex":"gpt-5.6-sol","claude":"opus"},
       "subscription_only":true,"async":true,"attachments":[]}'
{"ok": true, "job_id": "…"}
Name Type Required Description
prompt string Yes The user request.
system string No System prompt.
json boolean No JSON mode: ask the model for a JSON answer. Strip code fences before parsing.
engines string[] No Preference order among agy, codex, claude. Omitted: the key's own default chain (see below).
models object No Exact model per engine, any id from the catalogue, e.g. {"agy":"gemini-4-argon-high","codex":"gpt-5.6-sol","claude":"opus"}. Since 13/10/2026 the old ids gemini-3.1-pro-high and gemini-3.1-pro-low are still accepted and are answered by Gemini 4 Argon (gemini-4-argon-high / -low); the result's model names the model that ran.
subscription_only boolean No true: never touch a pay-per-use API; if no engine can answer the job fails and your app decides. Always send true.
async boolean No true: return {job_id} now and poll. Always send true; the public edge cuts single requests at about 100 s.
attachments array No Images, PDFs and text files by URL. See Vision.

The raw JSON body is bounded to 512 KiB before it is parsed, including chunked bodies. A denied model (Codex Astra, Claude Fable) is silently replaced by that engine's default.

Poll the job

GET /api/ai/generate/jobs/{job_id}

curl -s https://maximind.dev/api/ai/generate/jobs/<job_id> -H "x-api-key: $MAXIMIND_API_KEY"
{"status": "queued|running|done|failed", "text": "…", "engine": "agy", "account": "agy-primary", "model": "gemini-4-argon-high", "error": null}
Field Meaning
status queued (not yet at the front of the single queue), running, done, failed.
text The answer when done.
engine, account, model What actually answered. The model may differ from what you asked for when the request was denied or an account rotated.
error Failure message when failed.
attachments Per-input read receipts when attachments were sent. See Vision.

Poll every 1 to 3 seconds. A queued status is normal: the machine runs one heavy task at a time. Job IDs are visible only to the API-key owner that created them; another key gets 404. Responses are Cache-Control: private, no-store, and finished in-memory records expire after one hour.

Which engine answered

Read engine, account and model from the job result and log them. With subscription_only: true the possible outcomes are:

  • done: an engine answered; the receipt says which.
  • failed: no engine could answer (quota, signed-out accounts, all engines in the chain unavailable). MaxiMind did not spend paid API money. Your app's original paid path, if any, stays in your own ledger.

Default engine chain per key

GET /api/ai/site-chain and POST /api/ai/site-chain

The key's own default engine order, used when a request sends no engines.

curl -s https://maximind.dev/api/ai/site-chain -H "x-api-key: $MAXIMIND_API_KEY"

JSON mode

Send "json": true and instruct the model in system or prompt what shape to return. Models sometimes wrap JSON in code fences; strip fences before json.loads. The OpenAI-compatible endpoint offers the same through response_format: {"type":"json_object"}. JSON schemas are not supported on either surface.

Reference recipe (from the owner's PHP sites)

The owner's sites wrap every non-real-time paid call like this: try MaxiMind first with a tier (pro or fast), an optional prefer engine order and optional exact models; when the result is null (no engine could answer) run the original paid-API code unchanged. A MaxiMind outage then degrades to cost, never to a broken feature. Queue jobs marked subscription_only are skipped rather than sent to a paid key.

Legacy task endpoint

POST /api/ai/agent runs fixed task shapes (translate, write, summarize, proofread, explain, answer; custom is admin-only) with input up to 100k characters, optional options, engine and model, and returns {ok, job_id} to poll at GET /api/ai/agent/status/{job_id} ({status, text, engine, elapsed, isolation_receipt?}). Body limit 256 KiB; 2 credits. GET /api/ai/agent/tasks lists the tasks and engines available to your key. Prefer /api/ai/generate for new work.

curl -s -X POST https://maximind.dev/api/ai/agent \
  -H "x-api-key: $MAXIMIND_API_KEY" -H "Content-Type: application/json" \
  -d '{"task":"translate","input":"Xin chào các bạn","options":{"to":"English"}}'

Errors

Status Meaning
401 Missing or invalid key.
403 Pending account; key lacks generate or a permitted engine.
404 Job id unknown, expired (1 h) or owned by another key.
413 Body over 512 KiB.
429 Admission saturated (24 global / 12 per owner, or the server is short of memory). Retry-After: 5. Sent before the prompt is retained or quota spent.

Limits

  • 512 KiB raw body; 100,000-character attachment prompt bound; attachment file limits in Vision.
  • 12 active requests per API-key owner, 24 globally, shared with chat completions and agent tasks.
  • Job records expire one hour after completion.