API Reference
Base URL: https://latexlite.com
All requests require Authorization: Bearer <API_KEY>. Get a key at latexlite.com/get-demo-key.
/v1/renders-sync
Render a LaTeX template to PDF. Returns application/pdf by default. Set Accept: application/json to receive a base64-encoded PDF instead.
Request (JSON)
{
"template": "\\documentclass{article}\n\\begin{document}\nHello [[.Name]]!\n\\end{document}",
"data": {
"Name": "World"
}
}
Response (application/pdf)
PDF binary bytes. Use -o output.pdf with curl.
Response (application/json)
Full-quality PDF (HTTP 200):
{
"success": true,
"render_status": "OK",
"data": {
"content_type": "application/pdf",
"pdf_base64": "JVBERi0xLjQKJeLjz9MK..."
}
}
Watermarked PDF (HTTP 201):
{
"success": true,
"render_status": "WATERMARKED",
"data": {
"content_type": "application/pdf",
"pdf_base64": "JVBERi0xLjQKJeLjz9MK...",
"watermark": {
"reason": "demo_quota_exceeded",
"message": "You have reached your demo usage limit. Open your account page to upgrade to pro tier for a higher allowance.",
"account_url": "https://latexlite.com/account"
}
}
}
/v1/math-sync
Render a LaTeX math expression to PNG. The math string must start and end with $ or $$. Returns image/png by default. Math PNG output is not watermarked.
Request (JSON)
{
"math": "$\\int_0^1 x^2 \\, dx = \\frac{1}{3}$"
}
Response (image/png)
PNG binary bytes. Use -o equation.png with curl.
Response (application/json)
{
"success": true,
"data": {
"content_type": "image/png",
"png_base64": "iVBORw0KGgoAAAANSUhEUgAA..."
}
}
Supported Content Types
For /v1/renders-sync:
| Content-Type | Use case | Data injection |
|---|---|---|
| application/json | Inline template string | Via data field |
| text/plain text/x-tex application/x-tex |
Raw .tex file upload | None (self-contained) |
| multipart/form-data | .tex file with placeholders | Via data form field (JSON string) |
Template Syntax
Templates use Go's text/template syntax with [[ ]] delimiters.
Simple field
[[.FieldName]]
Loop over a list
[[range .Items]][[.Description]] & [[.Qty]] & [[.Total]] \\
[[end]]
Corresponding data
{
"Items": [
{ "Description": "Web Design", "Qty": "1", "Total": "£2,500" }
]
}
\int becomes \\int. However \n and \t are JSON escape sequences and remain single backslash.
HTTP Status Codes
| Status | Meaning |
|---|---|
| 200 | OK — request successful (full-quality PDF on /v1/renders-sync) |
| 201 | Created — /v1/renders-sync only: PDF returned with an evaluation watermark (still success; check render_status or headers) |
| 400 | Bad Request — invalid template or data |
| 401 | Unauthorized — missing or invalid API key |
| 408 | Request Timeout — render timed out |
| 422 | Unprocessable Entity — LaTeX compilation failed |
| 429 | Too Many Requests — per-minute rate limit exceeded (monthly PDF cap returns 201 + watermark instead) |
| 502 | Bad Gateway — renderer service error |
| 503 | Service Unavailable — renderer not configured |
Request Limits
/v1/renders-sync
- Max body size: 1 MiB
- Max template size: 200 KB
- Timeout: 30 seconds
- Max PDF size: 20 MB
/v1/math-sync
- Max body size: 64 KiB
- Max math input: 32 KB
- Timeout: 30 seconds
Error Handling
All error responses follow this structure:
{
"success": false,
"error": {
"message": "LaTeX compilation failed: ! Undefined control sequence.",
"line": 0
}
}
Common Error Messages
Missing or invalid Authorization header— 401Invalid API key— 401API key rate limit exceeded. Try again in 1 minute.— 429IP rate limit exceeded. Maximum 50 requests per minute per IP.— 429missing required field: template— 400template too large (max 200KB)— 400LaTeX compilation failed: ...— 422render timed out. Try optimizing your template.— 408math must start and end with $ (or $$)— 400
Usage tiers
Per-account limits depend on subscription state. Defaults (overridable per user in the database):
- Demo / inactive: 10 requests/minute, 50 requests/month.
- Pro: 60 requests/minute, 10000 requests/month.
- Monthly cap on PDF renders: further
POST /v1/renders-synccalls return HTTP 201 with a watermarked PDF (not 429). Demo keys getdemo_quota_exceededin API metadata; other tiers getmonthly_quota_exceeded. Wait for reset or upgrade tier via your account.
Rate Limits
Rate limit state is communicated via response headers:
| Header | Description |
|---|---|
| X-RateLimit-Limit | Maximum requests allowed per minute |
| X-RateLimit-Remaining | Requests remaining in current window |
| X-RateLimit-Reset | Unix timestamp when the limit resets |