AI generation API
The /ai/generate, /ai/generate-template and /ai/improve endpoints, the 402 hard block and the 20/min limit.
Reference for the AI assistant endpoints. All of them run under JwtAuthGuard + TenantGuard, and the three generation endpoints are limited to 20 requests/min per user.
Shared context
The three generation endpoints accept these optional context fields, on top of their own:
| Field | Notes |
|---|---|
templateId / versionId | Anchors the result to a template/version |
locale | Target language (up to 10 characters) |
templateDescription | Purpose description (up to 500) |
currentSubject | Current subject as a reference (up to 200) |
variables | List of template variables |
POST /ai/generate
Generates free text. Responds 200.
| Field | Required | Notes |
|---|---|---|
prompt | Yes | Instruction (up to 4000 characters) |
task | No | subjects, plain_text or general |
systemPrompt | No | Overrides the system prompt |
model | No | Forces a specific model |
Response: { content, model, tokens: { prompt, completion } }.
POST /ai/generate-template
Builds a full template. Responds 200.
| Field | Required | Notes |
|---|---|---|
prompt | Yes | The email you want (up to 4000) |
tone | No | Desired tone (up to 120) |
model | No | Forces a specific model |
Response: { subject, preheader, html, model, tokens }.
POST /ai/improve
Rewrites existing HTML. Responds 200.
| Field | Required | Notes |
|---|---|---|
html | Yes | HTML to improve (up to 50000 characters) |
instruction | Yes | What to change (up to 500) |
model | No | Forces a specific model |
Response: { content, model, tokens }.
POST /ai/improve
Authorization: Bearer <accessToken>
X-Tenant-Id: {tenantId}
Content-Type: application/json
{
"html": "<h1>Hi</h1><p>...</p>",
"instruction": "Make it shorter with a clear CTA"
}
Token hard block (402)
Before calling the provider, the API estimates the cost (ceil((prompt length) / 4)) and checks your AI token balance. If the balance does not cover the estimate, it responds 402 AI_TOKEN_QUOTA_EXCEEDED and consumes nothing — there is no grace period, unlike the email quota.
Rate limit
The three generation endpoints are limited to 20 requests per minute per user (counted by user:<id>). Exceeding it returns 429. This limit tightens the global limit to protect an expensive resource.
Balance & history
| Method | Path | Description |
|---|---|---|
GET | /ai/balance | Current token balance ({ balance }) |
GET | /ai/usage | Paginated usage history (?page=&limit=) |
GET /ai/balance and GET /ai/usage are not subject to the 20/min limit (only the global one).