API reference

Large files

Upload large files to Etchv once with a signed URL, then watermark them or detect watermarks in delivered files up to 192 MB by upload ID.

Send large files to Etchv in two steps: upload the file once to a signed URL, then pass its upload_id to any watermarking or detection endpoint instead of the file. Use this for files over 40 MB, and to check delivered files larger than a single request can carry. The SDKs do it for you.

Upload host
uploads.etchv.com
Upload URL
Valid 6 hours
Upload
Used once · kept 24 hours

Create an upload

Declare what the file is for and its exact size in bytes. Use a key with watermarks:embed for image, document or video, and watermarks:detect for detect.

Shell
curl https://api.etchv.com/uploads \
  -H "X-API-Key: $ETCHV_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"kind":"image","filename":"campaign.png","size":46137344}'
FieldMeaning
kindimage, document or video to watermark; detect to check a delivered file
filenameUsed for the watermarked file's name
sizeThe file's exact length in bytes
kind
Meaning
image, document or video to watermark; detect to check a delivered file
filename
Meaning
Used for the watermarked file's name
size
Meaning
The file's exact length in bytes

The 201 response has an upload_id, a status of pending and an upload object with the PUT URL and when it expires.

Upload the file

Send the bytes to upload.url with PUT. The URL is signed: do not add your API key, and do not change the URL.

Shell
curl -X PUT "$UPLOAD_URL" --upload-file campaign.png

A 200 means the file arrived. A file larger than its kind allows is refused with 413 before it is stored. Browsers can upload from etchv.com only.

Use the upload

Send upload_id in place of file, with the same fields and options as a normal request. Every embed and detect endpoint accepts it, sync or async.

Shell
curl https://api.etchv.com/watermarks/images/async \
  -H "X-API-Key: $ETCHV_API_KEY" \
  -H 'Idempotency-Key: campaign-acme-2026-10' \
  -F upload_id=upl_… \
  -F 'data={"recipient":"acme"}'

The result is the same as uploading the file directly: the same watermark, credits and idempotency. An upload is used by exactly one request. A retry with the same Idempotency-Key and the same fields returns that request's job; anything else is refused with 409 upload_consumed.

Upload status

GET /uploads/{upload_id} reports where an upload stands.

StatusMeaning
pendingWaiting for the file, or not checked since it arrived
receivedThe file arrived with the declared size
consumedUsed by the request in request_id
rejectedThe file could not be used; error says why. Create a new upload
expiredNot used within 24 hours
pending
Meaning
Waiting for the file, or not checked since it arrived
received
Meaning
The file arrived with the declared size
consumed
Meaning
Used by the request in request_id
rejected
Meaning
The file could not be used; error says why. Create a new upload
expired
Meaning
Not used within 24 hours

Limits

KindLargest file
image50 MB
document20 MB
video20 MB
detect192 MB images, 64 MB PDFs, 100 MB video
image
Largest file
50 MB
document
Largest file
20 MB
video
Largest file
20 MB
detect
Largest file
192 MB images, 64 MB PDFs, 100 MB video

Image and PDF detection that answers in the same request takes files up to 95 MB. For larger delivered files, use /watermarks/images/detect/async or /watermarks/documents/detect/async; the sync endpoint answers 413 and keeps the upload for that request. Video detection always runs as a job and takes the full 100 MB.

Errors

StatusCodeWhat to do
409upload_not_receivedFinish the PUT, then retry the request
409upload_in_useAnother request is using it; wait for that one
409upload_consumedCreate a new upload, or retry with the original Idempotency-Key
409upload_rejectedThe file could not be used; fix it and create a new upload
410The upload expired; create a new one
422The upload was created for another kind of request; it is rejected
503Too many large files at once; retry after Retry-After seconds
409
Code
upload_not_received
What to do
Finish the PUT, then retry the request
409
Code
upload_in_use
What to do
Another request is using it; wait for that one
409
Code
upload_consumed
What to do
Create a new upload, or retry with the original Idempotency-Key
409
Code
upload_rejected
What to do
The file could not be used; fix it and create a new upload
410
Code
What to do
The upload expired; create a new one
422
Code
What to do
The upload was created for another kind of request; it is rejected
503
Code
What to do
Too many large files at once; retry after Retry-After seconds

A file the API cannot use, such as an unsupported format, rejects the upload with the same error a direct upload would get. Refusals you can retry, such as your plan's concurrency limit or credits, leave the upload ready to use again.

SDKs

Every SDK sends files over 40 MB through an upload automatically, retries with the same upload and waits for large detection jobs. Each also has an explicit upload method. See Node.js, Python, Go, Rust, C# and Java.

View source on GitHub

Your privacy, your choice

We use essential cookies to keep Etchv working. Optional analytics helps us improve the site. Analytics is on by default; you can turn it off in preferences. PostHog loads only if you accept all. Privacy policy

ETCHV

Privacy preferences

Choose what you allow on this browser. Analytics is enabled by default. You can turn it off, and change your choice at any time.

Essential

Always active

Supports secure sign-in, account sessions, site security, and remembering your privacy choice. These are needed for Etchv to work.

Analytics

Helps us understand visits and improve the website using page-view and device statistics, which do not use cookies. PostHog also measures visits and campaigns and may set cookies; it loads only after you save a choice with analytics on. Turning this off stops future analytics events.

We do not load advertising scripts. Meeting calendars load only when you open them. These preferences do not change your account, watermarking requests, or asset storage.

Your choice is remembered for 180 days on this browser. Privacy policy