Developer API
The same engine the web app uses: upload, recognise, translate and export over REST.
Authentication
Send the key in the Authorization header. It is shown once at creation and stored only as a hash.
Authorization: Bearer lik_live_…Idempotency
Send an Idempotency-Key header when creating a job. Repeating the request returns the original job and never charges twice.
curl
curl -X POST "$API/api/v1/process" \
-H "Authorization: Bearer $PICGLOT_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-F "file=@invoice.pdf" \
-F 'options={"tool":"pdf-translator","target_language":"en","export_formats":["pdf_searchable"]}'JavaScript
const form = new FormData();
form.append('file', file);
form.append('options', JSON.stringify({
tool: 'image-translator',
target_language: 'ru',
export_formats: ['png'],
}));
const job = await fetch(`${API}/api/v1/process`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.PICGLOT_API_KEY}`,
'Idempotency-Key': crypto.randomUUID(),
},
body: form,
}).then((response) => response.json());
// Follow progress until the job reaches a terminal state.
const events = new EventSource(`${API}/api/v1/jobs/${job.id}/events`);
events.addEventListener('done', async () => {
events.close();
const result = await fetch(`${API}/api/v1/jobs/${job.id}`).then((r) => r.json());
console.log(result.output.exports);
});Python
import os, time, requests
API = os.environ["PICGLOT_API_URL"]
headers = {"Authorization": f"Bearer {os.environ['PICGLOT_API_KEY']}"}
with open("receipt.jpg", "rb") as handle:
job = requests.post(
f"{API}/api/v1/process",
headers=headers,
files={"file": handle},
data={"options": '{"tool":"receipt-scanner","export_formats":["json"]}'},
).json()
while True:
status = requests.get(f"{API}/api/v1/jobs/{job['id']}", headers=headers).json()
if status["status"] in {"completed", "partially_completed", "failed"}:
break
time.sleep(1.5)
print(status["output"])Job statuses
createduploadingqueuedpreprocessingdetectingrecognizingtranslatinginpaintingrenderingexportingcompletedpartially_completedfailedcancelledWebhooks
Every delivery is signed with HMAC-SHA256 over "timestamp.body". Verify the signature and reject stale timestamps.
X-PicGlot-Signature: t=1735689600,v1=<hex>
X-PicGlot-Event: job.completed
X-PicGlot-Event-Id: evt_…
X-PicGlot-Delivery: dlv_…Errors
Every error returns a stable machine-readable code. Switch on the code, never on the message text.
{
"error": {
"code": "page_limit_exceeded",
"message": "The document has more pages than your plan allows.",
"retryable": false,
"details": { "pages": 420, "limit": 300, "plan": "pro" },
"request_id": "req_01J…"
}
}