API

Everything the site does, it also does over HTTP. One key, one request, one job id to poll. The examples below are copy-paste ready: swap in your key and they run.

All our keys start with prk_. That prefix lets GitHub's secret scanning warn you if one is ever published by mistake.

Two-minute start

No key required. This is the first call to try when something looks wrong.

curl https://pdfremakeit.app/v1/status

Authentication

Every call carries your key in the Authorization header. A key is a password: never ship it in browser-side code, never commit it to a public repository.

Base URL : https://pdfremakeit.app

Authorization: Bearer prk_…

API keys

One key per use: a compromised environment can be revoked on its own.

You can hold up to 10 active keys.

Recent calls

No calls recorded yet. Calls show up here a few seconds later.

Call details are kept for thirty days.

Endpoints

CallKeyWhat it does
GET /v1Index of endpoints.
GET /v1/statusService health and capacity.
GET /v1/toolsCatalogue of server-side tools and accepted formats.
GET /v1/accountyesPlan, limits and usage.
GET /v1/logsyesRecent calls made with your keys.
POST /v1/tools/{outil}yesSubmit a document. Returns a job.
GET /v1/jobs/{id}yesJob status.
GET /v1/jobs/{id}/contentyesDownload the result.
GET /v1/workflowsyesYour saved workflows.
POST /v1/workflowsyesSave a workflow.
DELETE /v1/workflows/{id}yesDelete a workflow. Past runs are kept.
POST /v1/workflows/{id}/runyesRun a workflow on a document.
GET /v1/runsyesYour recent runs.
GET /v1/runs/{id}yesRun status, step by step.
GET /v1/runs/{id}/contentyesDownload the final result.
POST /v1/runs/{id}/replayyesRun an execution again on the same document.
POST /v1/ai/summarizeyesSummarise text.
POST /v1/ai/translateyesTranslate text.

Convert a document to PDF

The document goes in the request body, raw. The original name travels in the X-Source-Name header: its extension decides how the file is handled.

# 1. Envoyer le document. La réponse porte l'identifiant du travail.
curl -X POST https://pdfremakeit.app/v1/tools/office \
  -H "Authorization: Bearer prk_VOTRE_CLE" \
  -H "X-Source-Name: rapport.docx" \
  --data-binary @rapport.docx

# 2. Interroger le travail jusqu'à "done".
curl https://pdfremakeit.app/v1/jobs/JOB_ID \
  -H "Authorization: Bearer prk_VOTRE_CLE"

# 3. Récupérer le PDF.
curl -L https://pdfremakeit.app/v1/jobs/JOB_ID/content \
  -H "Authorization: Bearer prk_VOTRE_CLE" \
  -o rapport.pdf

Run OCR on a scan

Same flow as conversion: only the tool and its settings change. The language goes in the query string.

curl -X POST "https://pdfremakeit.app/v1/tools/ocr?langues=fra" \
  -H "Authorization: Bearer prk_VOTRE_CLE" \
  -H "X-Source-Name: scan.pdf" \
  --data-binary @scan.pdf

Summarise text

Summarisation takes text, not a file: extract it first — with the OCR tool above, or from your own source.

curl -X POST https://pdfremakeit.app/v1/ai/summarize \
  -H "Authorization: Bearer prk_VOTRE_CLE" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Le rapport annuel 2025 fait état d un chiffre d affaires de 184 000 euros...",
    "length": "short",
    "format": "bullets"
  }'

Translate as a stream

With "stream": true, the response is an NDJSON stream: one JSON object per line. That is what lets you display the text as it is written.

curl -N -X POST https://pdfremakeit.app/v1/ai/translate \
  -H "Authorization: Bearer prk_VOTRE_CLE" \
  -H "Content-Type: application/json" \
  -d '{"text": "Bonjour le monde.", "targetLanguage": "en", "stream": true}'

# {"t":"debut","blocs":1,...}
# {"t":"texte","v":"Hello"}
# {"t":"texte","v":" world."}
# {"t":"fin","caracteres":12}

Chain several tools

A workflow is saved once, then runs in a single call: each step's result becomes the next step's input. Paid plans only. Five steps at most, and only the first one may refuse PDF.

# 1. Enregistrer l'enchaînement. Rendu une fois pour toutes.
curl -X POST https://pdfremakeit.app/v1/workflows \
  -H "Authorization: Bearer prk_VOTRE_CLE" \
  -H "Content-Type: application/json" \
  -d '{"name":"Courrier scanné",
       "steps":[{"tool":"ocr","settings":{"langues":"fra"}},
                {"tool":"pdfa","settings":{"niveau":"2b"}}]}'

# 2. Le lancer sur un document. Le quota des deux étapes est réservé ici.
curl -X POST https://pdfremakeit.app/v1/workflows/WORKFLOW_ID/run \
  -H "Authorization: Bearer prk_VOTRE_CLE" \
  -H "X-Source-Name: courrier.pdf" \
  --data-binary @courrier.pdf

# 3. Suivre, puis récupérer le PDF de la dernière étape.
curl https://pdfremakeit.app/v1/runs/RUN_ID -H "Authorization: Bearer prk_VOTRE_CLE"
curl -L https://pdfremakeit.app/v1/runs/RUN_ID/content \
  -H "Authorization: Bearer prk_VOTRE_CLE" \
  -o archive.pdf

Run an execution again

Without re-uploading the document: it is still with us for as long as your plan's retention runs. After that, the call answers source_expired.

curl -X POST https://pdfremakeit.app/v1/runs/RUN_ID/replay \
  -H "Authorization: Bearer prk_VOTRE_CLE"

Read your quota

Call it before a batch rather than after a refusal: `resetsAt` says when the counter resets.

curl https://pdfremakeit.app/v1/account \
  -H "Authorization: Bearer prk_VOTRE_CLE"

Errors

Every error has the same shape. Test the code, never the message: the code is part of the contract, the message may be rewritten.

{
  "error": {
    "code": "quota_exceeded",
    "message": "The daily job quota for this account is exhausted.",
    "plan": "libre",
    "used": 3,
    "limit": 3,
    "resetsAt": 1787011200000,
    "documentation": "https://pdfremakeit.app/api#quota_exceeded"
  }
}
codeHTTPWhat happenedWhat to do
missing_api_key401No key was sent.Add the Authorization: Bearer header.
invalid_api_key401Unknown or revoked key.Check the key, or create a new one.
rate_limited429Too many calls this minute.Wait for the Retry-After header, then resume.
quota_exceeded429Daily quota exhausted.Resume at the time given by resetsAt, or upgrade the plan.
too_many_concurrent_jobs429Too many jobs running at once.Wait for a job to finish before starting another.
unknown_tool404No such tool.See GET /v1/tools.
unsupported_input415The tool does not accept this extension.Check the accepts field in the response.
missing_filename400Original file name missing.Add X-Source-Name, or ?filename=.
empty_body400Empty request body.Send the document as the raw body.
file_too_large413File over the size limit.See maxUploadBytes in the response.
invalid_request400Malformed JSON body.Check the text field.
text_too_short400Text too short — usually a scan with no text layer.Run the document through OCR first.
text_too_long413Text over the limit.Split the document and combine the results.
unsupported_language400Target language outside the model's range.See the supported field in the response.
job_not_ready409The job has not finished.Poll /v1/jobs/{id} until "done".
result_expired410Result deleted.Run the job again; see your plan's retention.
plan_required403Workflows are for paid plans only.Upgrade the plan, or call the tools one at a time.
invalid_workflow400Workflow refused: unknown step, too many steps, or a tool that does not accept PDF placed after the first step.See the details field, which names the offending step.
too_many_workflows409Maximum number of workflows reached.Delete a workflow you no longer use.
source_expired410The original document was purged: there is nothing left to replay.Run the workflow again, sending the file.
not_found404No such path or job.Check the identifier.
service_capacity503Service suspended while a traffic surge is absorbed.Retry later; paid plans are served first.
internal_error500Failure on our side.Nothing was charged: retry.

Quotas and rate limits

A key spends its account's quota: going through the API does not double what you are entitled to. Rate limits, however, are counted per key — your environments do not slow each other down.

  • 60 requests per minute per key.
  • Free plan: 3 jobs and 20,000 characters per day.
  • Pro plan: 3,000 jobs and 20,000,000 characters per day.

See plans

Libraries

Both libraries handle waiting for a job, typed errors and token-by-token streaming. Neither is required: the API is perfectly pleasant with curl.

npm install @pdfremakeit/sdk
pip install pdfremakeit