GenAI API
Full REST reference for the GenAI domain. All routes are under
/api/genai, require a Cognito JWT (Authorization: Bearer <token>), and
are backed by services/backend/lambda/genai_handler.py /
genai_service.py. See specs/api/genai.md in the repo for the underlying
spec this page is based on, and the GenAI feature guide
for the product-level behavior.
None of these endpoints stream. Bedrock and the shared client library
support streaming (common.bedrock.generate_streaming), but it isn't
wired up here — API Gateway's HTTP API can't stream a Lambda response, so
every call blocks until Bedrock returns the complete text, then responds
once with the full JSON body.
Endpoints at a glance
| Method | Path | Description |
|---|---|---|
POST | /api/genai/generate | Generate a post from an idea |
POST | /api/genai/iterate | Rewrite existing content on instruction |
POST | /api/genai/proofread | Get grammar/tone annotations |
Every error response has the same shape:
{ "error": "human-readable message" }An unhandled Bedrock failure (a non-throttling ClientError, or throttling
that exhausts all 3 retries) is not caught by this domain and surfaces as a
generic 500, not a { "error": "..." } body.
Request fields are silently truncated, never rejected for length:
| Field | Max length |
|---|---|
audience | 200 chars |
tone | 100 chars |
language | 50 chars |
instruction | 2000 chars |
current_content | 40000 chars |
content (proofread) | 40000 chars |
Generate
POST /api/genai/generate// Request
{
"workspace_id": "ws_123",
"idea_id": "idea_456",
"prompt_id": "prompt_789",
"overrides": { "system_instruction": "Custom persona for this one call" },
"audience": "Engineering leaders",
"tone": "confident",
"language": "English",
"length": "medium"
}prompt_id, overrides, audience, tone, language, and length are
all optional. length must be one of very_short, short, medium,
long, very_long, extra_long (an unrecognized value is silently
ignored — no word-count instruction is added, but the call still succeeds).
// 200 Response
{
"content": "🚀 Here's what most teams get wrong about observability...\n\n#observability #engineering #ai",
"idea_id": "idea_456"
}Nothing is persisted — save the draft yourself via
POST /api/posts if the user keeps it.
A prompt_id that doesn't resolve to a saved prompt is a hard 404 here.
Compare Iterate, where the same situation is not an error.
| Status | Reason |
|---|---|
| 400 | workspace_id or idea_id missing |
| 403 | Caller is not a member of workspace_id |
| 404 | Idea not found in the workspace |
| 404 | prompt_id supplied but no such prompt exists |
Iterate
POST /api/genai/iterate// Request
{
"workspace_id": "ws_123",
"post_id": "post_abc",
"instruction": "Make the hook stronger and add a call to action",
"current_content": "Original draft text...",
"prompt_id": "prompt_789"
}current_content and prompt_id are optional; current_content defaults
to "" if omitted.
// 200 Response
{ "suggestion": "Rewritten post content here...", "post_id": "post_abc" }This call never modifies the post — it only returns a suggestion for the caller to apply (or not).
Unlike Generate, a prompt_id that doesn't resolve to a
saved prompt does not error — it silently falls back to the default
editor persona ("You are editing a LinkedIn post...").
| Status | Reason |
|---|---|
| 400 | workspace_id, post_id, or instruction missing |
| 403 | Caller is not a member of workspace_id |
Proofread
POST /api/genai/proofread// Request
{ "workspace_id": "ws_123", "post_id": "post_abc", "content": "Text to proofread..." }content is optional (defaults to "") — there's no minimum-length check.
// 200 Response
{
"annotations": [
{
"range": [0, 42],
"type": "grammar",
"message": "Subject-verb disagreement.",
"suggestion": "corrected text"
}
],
"post_id": "post_abc"
}annotations is [] when the model finds no issues, its response fails
JSON parsing, or the parsed value isn't a JSON array — this endpoint always
returns 200, never a parsing-related error.
| Status | Reason |
|---|---|
| 400 | workspace_id or post_id missing |
| 403 | Caller is not a member of workspace_id |
See also
- GenAI feature guide — product behavior, prompt assembly, the streaming caveat.
- GenAI MCP tools —
generate_post/iterate_postfor AI clients (note: these do persist, unlike the endpoints on this page).