Developer API
Run every GreatAutomate PDF tool from your own code. Upload files, get the processed file back in the same response. No polling and nothing stored on our side.
- Base URL:
https://greatautomate.com/api/v1 - Format: JSON for metadata endpoints;
multipart/form-datain and the binary result out for processing. - Privacy: files are processed in memory and the result is streamed straight back. API results are never stored.
- Billing: only successful calls count against your key's allowance.
Authentication
Every request needs an API key. Keys are issued by an administrator, start with ga_, and are included with Pro plans. Request a key with your username and intended use.
Send the key in either header:
X-API-Key: ga_your_key_here
# or
Authorization: Bearer ga_your_key_here
Quick start
Check that your key works and see your remaining allowance:
export GA_KEY=ga_your_key_here
curl -H "X-API-Key: $GA_KEY" https://greatautomate.com/api/v1/status
Merge two PDFs and save the result:
curl -X POST https://greatautomate.com/api/v1/tools/merge \
-H "X-API-Key: $GA_KEY" \
-F "[email protected]" \
-F "[email protected]" \
-o merged.pdf -D headers.txt
Service info
/api/v1/infoDescribes the service and lists the endpoints. Does not require a key, so it is handy as a health check.
curl https://greatautomate.com/api/v1/info
{
"service": "GreatAutomate API",
"version": "v1",
"docs": "https://greatautomate.com/api-docs",
"authentication": "X-API-Key: <key> or Authorization: Bearer <key>",
"endpoints": {
"info": "GET /api/v1/info",
"tools": "GET /api/v1/tools",
"status": "GET /api/v1/status",
"process": "POST /api/v1/tools/:id (multipart: files[], options=<JSON>)"
}
}
List tools
/api/v1/toolsReturns every tool you can call, with the file types it accepts, how many files it takes and the options it understands. Build your integration from this list rather than hard-coding it. No key is needed for this endpoint.
curl https://greatautomate.com/api/v1/tools
{
"tools": [
{
"id": "rotate",
"name": "Rotate PDF",
"category": "organize",
"accept": [".pdf"],
"minFiles": 1,
"maxFiles": 1,
"options": [
{ "name": "angle", "label": "Rotation", "type": "select", "default": "90",
"choices": [{ "value": "90", "label": "90° clockwise" }, ...] }
]
},
...
],
"categories": [ ... ]
}
| Field | Description |
|---|---|
id | Tool identifier used in POST /api/v1/tools/:id, for example merge, compress, rotate. |
accept | Accepted file extensions. |
minFiles / maxFiles | How many files the tool takes in one call. |
options | Option definitions: name, label, type, default, choices and an optional showIf condition. |
Key status
/api/v1/statusShows the allowance of the key you are using. Calling it does not count as a task.
curl -H "X-API-Key: $GA_KEY" https://greatautomate.com/api/v1/status
{
"success": true,
"timestamp": "2026-09-28T12:00:00.000Z",
"data": {
"key_name": "Production",
"daily_limit": 500,
"limit_period_days": 1,
"used_today": 12,
"used_in_period": 12,
"remaining_in_period": 488,
"remaining_today": 488,
"next_reset_at": "2026-09-29T00:00:00.000Z"
}
}
Process files
/api/v1/tools/:idRuns a tool and returns the resulting file as the response body (Content-Disposition: attachment). Tools that produce several files return a ZIP archive.
| Form field | Required | Description |
|---|---|---|
files | Yes | One or more files. Repeat the field for each file; order is kept (important for merge). |
options | No | A JSON string with tool options, for example {"angle":"90"}. Omitted options use their defaults. |
curl -X POST https://greatautomate.com/api/v1/tools/rotate \
-H "X-API-Key: $GA_KEY" \
-F "[email protected]" \
-F 'options={"angle":"90"}' \
-o rotated.pdf
Tool options
Options differ per tool. Read them from GET /api/v1/tools: send the option name as the key and one of the choices values (or a value of the given type) as the value. A few common examples:
| Tool | Example options |
|---|---|
rotate | {"angle":"180"} |
split | {"mode":"ranges","ranges":"1-3,4-6"} (returns a ZIP) |
compress | {"level":"recommended"} |
protect | {"password":"s3cret"} |
watermark | {"text":"CONFIDENTIAL"} |
Malformed options JSON is rejected with BAD_OPTIONS; a value a tool does not accept is rejected with BAD_OPTION (or a more specific code such as BAD_PAGE_RANGE) and a message explaining what is wrong.
Response headers
Successful processing responses include these headers alongside the file:
| Header | Description |
|---|---|
X-GreatAutomate-Job-Id | Unique ID of this task. Quote it when contacting support. |
X-GreatAutomate-Tool | The tool that ran. |
X-GreatAutomate-Filename | Suggested output file name, URI-encoded. |
X-GreatAutomate-Duration-Ms | Processing time in milliseconds. |
X-GreatAutomate-Meta | URI-encoded JSON with tool-specific details, such as page counts or size savings. |
Errors
Errors use standard HTTP status codes and a JSON body:
{
"error": "Authentication required",
"message": "API key is required. Provide it via X-API-Key header or Authorization: Bearer token.",
"code": "MISSING_API_KEY",
"timestamp": "2026-09-28T12:00:00.000Z",
"meta": {}
}
Branch on code; message is meant for people and may change.
| Status | Code | Meaning |
|---|---|---|
| 400 | NO_FILES, TOO_MANY_FILES, UNSUPPORTED_TYPE, EMPTY_FILE, BAD_OPTIONS, UPLOAD_FAILED | The request is invalid: check the files and the options JSON. |
| 400 | BAD_OPTION, BAD_PAGE_RANGE, PDF_INVALID, PDF_ENCRYPTED, TOO_MANY_PAGES and other tool-specific codes | The tool rejected an option value or the file itself; message says what to fix. |
| 401 | MISSING_API_KEY, INVALID_API_KEY, INVALID_KEY_FORMAT | No key, or the key is not recognised. |
| 403 | KEY_EXPIRED, KEY_DISABLED | The key exists but can no longer be used. |
| 404 | UNKNOWN_TOOL | No tool with that id. |
| 413 | FILE_TOO_LARGE | A file exceeds the size limit. |
| 422 | NO_OUTPUT | The tool ran but produced nothing, for example an empty page selection. |
| 429 | RATE_LIMIT_EXCEEDED | Allowance or request rate exceeded. Wait for the reset shown in /status. |
| 500 | PROCESSING_FAILED, INTERNAL_ERROR | An unexpected error occurred while processing. Retry once; if it persists, contact support with the job ID. |
| 503 | TOOLS_DISABLED, TOOL_DISABLED, BUSY | Processing is paused for maintenance or the server is at capacity. Retry later with backoff. |
Limits
- Allowance: each key has its own task allowance per period; check it with
/status. Failed calls do not count. - Request rate: up to 60 requests per 15 minutes per IP address. The standard
RateLimit-*headers show where you stand. - File size: up to 200 MB per file on Pro, and up to 30 files per call (tools may take fewer; see
maxFiles). - Concurrency: send requests one after another or with a small pool. If you get
BUSY, retry with exponential backoff.
Code examples
Rotate a PDF by 90° and save the result with the suggested file name.
curl -X POST https://greatautomate.com/api/v1/tools/rotate \
-H "Authorization: Bearer $GA_KEY" \
-F "[email protected]" \
-F 'options={"angle":"90"}' \
-OJimport { readFile, writeFile } from 'node:fs/promises';
const form = new FormData();
form.append('files', new Blob([await readFile('scan.pdf')]), 'scan.pdf');
form.append('options', JSON.stringify({ angle: '90' }));
const res = await fetch('https://greatautomate.com/api/v1/tools/rotate', {
method: 'POST',
headers: { 'X-API-Key': process.env.GA_KEY },
body: form,
});
if (!res.ok) {
const err = await res.json();
throw new Error(`${err.code}: ${err.message}`);
}
const name = decodeURIComponent(res.headers.get('X-GreatAutomate-Filename'));
await writeFile(name, Buffer.from(await res.arrayBuffer()));import json, os, urllib.parse
import requests
with open("scan.pdf", "rb") as fh:
res = requests.post(
"https://greatautomate.com/api/v1/tools/rotate",
headers={"X-API-Key": os.environ["GA_KEY"]},
files=[("files", ("scan.pdf", fh, "application/pdf"))],
data={"options": json.dumps({"angle": "90"})},
)
if not res.ok:
err = res.json()
raise SystemExit(f"{err['code']}: {err['message']}")
name = urllib.parse.unquote(res.headers["X-GreatAutomate-Filename"])
with open(name, "wb") as out:
out.write(res.content)Need help?
Questions, higher limits or a key for your team? E-mail [email protected] or request a key. Include the X-GreatAutomate-Job-Id of any failing call.