§ Request shape
One shape, twenty-nine endpoints.
Every operation reads the same form fields, rejects the same way, and answers on the same connection. Learn it once and the rest of the API is a list of paths.
Authentication
A bearer token on every operation. Keys are created and revoked in the console, and an operation without one is 401 unauthenticated.
export OHMYWRAP_KEY=sk_live_...
curl -sS --fail-with-body -o out.pdf \
-H "Authorization: Bearer $OHMYWRAP_KEY" \
-F "file=@in.pdf" \
https://api.ohmywrap.com/pdf/optimizeSend a document’s password as a form field, never as a query parameter, where proxies and access logs capture it. We log the endpoint, timestamp, status, duration, and request id. We do not log file contents, filenames, or passwords.
The parts
POST only, multipart/form-data only. Any field name not in this table is 400 unknown_field.
| Field | Repeats | Purpose |
|---|---|---|
| file | yes | The input document, image, or text. Repeats where the operation takes several. |
| options | no | A single JSON object of operation options. Capped at 64KB. |
| password | no | A document’s open password. On /pdf/encrypt it is instead the password to set. |
| stamp | no | Auxiliary image, accepted only by /pdf/stamp and /pdf/pipeline. |
| overlay | no | Auxiliary image, accepted only by /image/composite and /image/pipeline. |
| newPassword | no | Replacement password, accepted only by /pdf/change-password. |
| mapping | no | The token map from /text/tokenize, accepted only by /text/restore. Its own part, because a real mapping outgrows the options cap. |
The options object
At most one, as JSON, in a form field named options. Unknown keys inside it are rejected, not ignored: a typo like {"rotaton":90} fails loudly as 422 invalid_options rather than silently doing nothing to your document and charging you for it.
curl -sS --fail-with-body -o rotated.pdf \
-H "Authorization: Bearer $OHMYWRAP_KEY" \
-F "file=@scan.pdf" \
-F 'options={"rotation":-90,"pages":["2-3"]}' \
https://api.ohmywrap.com/pdf/rotate/text/restore takes its token mapping as its own part rather than as an option: a real mapping passes 64KB long before the token ceiling does.Page selection
Accepted by pages on /pdf/rotate, /pdf/stamp, /pdf/extract and /pdf/remove-pages. Every form below is verified against a five-page document.
| Selection | Resolves to | Pages |
|---|---|---|
| ["2"] | page 2 | 1 |
| ["2-4"] | pages 2 through 4 | 3 |
| ["1","3","5"] | the union of the entries | 3 |
| ["odd"] | pages 1, 3, 5 | 3 |
| ["even"] | pages 2, 4 | 2 |
| ["3-"] | page 3 to the end | 3 |
| ["-2"] | the start through page 2 | 2 |
| ["2-99"] | clamped to the document | 4 |
A selection matching no page is 422 invalid_page_selection rather than an empty PDF. Exclusion syntax — ["!2"] — is not supported, and is reported the same way.
Idempotency-Key
Optional, and not needed for correctness: every operation is a pure function of its inputs, so retrying is always safe. What the header buys you is that a retry of yours is not charged twice.
Reusing a key is 409 idempotency_key_reused, and the original charge stands. It means “do not let a retry of mine be charged twice”, not “give me the same answer again” — we keep nothing, so replaying the first response is not something we could do. If you lost a response, retry with a new key and pay for the second call; that is the honest accounting when the first one was delivered and neither of us can prove otherwise.
Reading the response with curl
If an output file looks corrupt, run head -c 200 out.pdf before anything else. It is almost always a problem document reported as JSON, not a broken result.
Your first call takes one line of curl.
No plan to choose. No credits to model. No storage to configure.
10,000 calls for $10. No subscription, no expiry.