API reference

Sync and async

Watermark files synchronously or asynchronously with the Etchv API. Wait for a result or submit a background job, then poll, use webhooks or retry safely.

Sync and async requests watermark files the same way. They use the same checks and cost the same credits. The only difference is how your app gets the result.

Choose an endpoint

ModeWhat happens
Sync · standard endpointWaits for the result. Returns 202 if watermarking or video detection takes longer than 20 seconds
Async · append /asyncReturns a 202 receipt once the upload is checked and safely stored. Poll for the result or use a webhook
Sync · standard endpoint
What happens
Waits for the result. Returns 202 if watermarking or video detection takes longer than 20 seconds
Async · append /async
What happens
Returns a 202 receipt once the upload is checked and safely stored. Poll for the result or use a webhook

Sync detection of images and PDFs always returns JSON directly. It never turns into a pending job. Upload, checking and download time add to processing time. An async request still waits until the upload is checked and stored.

All six endpoint pairs
OperationSynchronous endpoint
Embed imagePOST /watermarks/images
Detect imagePOST /watermarks/images/detect
Embed PDFPOST /watermarks/documents
Detect PDFPOST /watermarks/documents/detect
Embed videoPOST /watermarks/videos
Detect videoPOST /watermarks/videos/detect
Embed image
Synchronous endpoint
POST /watermarks/images
Detect image
Synchronous endpoint
POST /watermarks/images/detect
Embed PDF
Synchronous endpoint
POST /watermarks/documents
Detect PDF
Synchronous endpoint
POST /watermarks/documents/detect
Embed video
Synchronous endpoint
POST /watermarks/videos
Detect video
Synchronous endpoint
POST /watermarks/videos/detect

Add /async to the end of any endpoint above. There is no /sync suffix. Use a key with watermarks:embed or watermarks:detect to match the operation. Fields, format limits and credit prices are the same in both modes.

Watermark a file synchronously

Shell
curl --fail-with-body https://api.etchv.com/watermarks/documents \
  -H "X-API-Key: $ETCHV_API_KEY" \
  -H 'Idempotency-Key: document_delivery_001' \
  -F 'file=@document.pdf' \
  --form-string 'data={"delivery":"delivery_001"}' \
  -D response-headers.txt --output response-body
  • 200: save the file with its Content-Disposition filename. Keep the watermark ID from X-Watermark-ID.
  • 202: read the JSON receipt and fetch result_url later. Do not save this body as a media file.
  • Error: the job can be refused for invalid input, a webhook or storage destination that is unknown, disabled or unverified, or too few credits.

SDK embed methods wait for pending jobs for you.

Watermark a file asynchronously

Use /watermarks/documents/async with the same headers and fields. The response is a receipt. Save its request_id, status_url and result_url.

Example acceptance receipt
JSON
{
  "request_id": "req_0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
  "status": "queued",
  "operation": "embed",
  "format": "PDF",
  "frame_count": 2,
  "credits": 2,
  "attempts": 0,
  "webhook_id": null,
  "asset_id": null,
  "source_asset_id": null,
  "status_url": "/watermarks/jobs/req_0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
  "result_url": "/watermarks/jobs/req_0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef/result",
  "error_code": null,
  "result_expires_at": null
}

The Location header points to the status URL. URLs are relative to https://api.etchv.com. To use them, you need a key from the same Organization with the matching scope. Receipts also show the accelerator you asked for, the one that ran, and any storage you selected.

Retrieve a pending result (either mode)

  1. GET status_url with your API key. Wait as long as Retry-After says: 6 seconds on Trial/Launch, 2 seconds on other plans.
  2. If the status is queued, running or retrying, keep waiting.
  3. On succeeded, GET result_url. Embedding returns the media file; detection returns JSON.
  4. On failed, record request_id and error_code. Credits held for the job are refunded.

A detection can succeed and still report watermarked: false, meaning no watermark was found.

Receive an async webhook instead of polling

Create an enabled webhook endpoint and save its signing secret. Then pass the endpoint’s webhook_id in the async request:

Shell
curl "https://api.etchv.com/watermarks/images/async?webhook_id=$ETCHV_WEBHOOK_ID" \
  -H "X-API-Key: $ETCHV_API_KEY" \
  -H 'Idempotency-Key: image_delivery_001' \
  -F 'file=@image.png' \
  --form-string 'data={"delivery":"delivery_001"}'

Only the endpoint you select gets this job’s final event. Webhooks are optional.

Retry safely

An idempotency key is a value you choose and send in the Idempotency-Key header. If a request is sent twice with the same key and the same inputs, Etchv runs it only once. The retry gets the first job back instead of a second job and a second charge. The same key with different inputs returns 409.

SituationAction
Timeout or lost responseRepeat the same file, data, operation and options with the same Idempotency-Key
Same key, changed input/options409; use a new key for a new operation
Async replayReturns a 202 receipt for the existing job, even if it has finished. Check its status
Final failureA retry with the same key returns the same failure. Use a new key to try again on purpose
Timeout or lost response
Action
Repeat the same file, data, operation and options with the same Idempotency-Key
Same key, changed input/options
Action
409; use a new key for a new operation
Async replay
Action
Returns a 202 receipt for the existing job, even if it has finished. Check its status
Final failure
Action
A retry with the same key returns the same failure. Use a new key to try again on purpose

Save your key before you upload. It must be 8–128 letters, digits, hyphens or underscores. An accepted job keeps running if you disconnect. Retries and result downloads do not add a charge or send another webhook event. To get an event again, ask for a webhook redelivery.

Processing guarantees and retention
  • Up to five processing attempts, with a growing wait between them. Each attempt uses the original input and the same watermark.
  • If a worker crashes, another picks up the job once the first worker’s claim expires. Image and PDF jobs have a 30-minute deadline. Video jobs add 15 seconds per frame, up to 90 minutes. Jobs past their deadline are closed and refunded when workers recover.
  • The checked output, asset records and credit charge are saved together, or not at all. A failure refunds the credits held for the job.
  • Job results last 24 hours. After that, a download returns 410. The idempotency key stays on record.
  • Etchv keeps library files for up to 1 year while your subscription is active (30 days on the trial). If you choose your own bucket, your bucket controls how long output is kept. Records stay until deleted. Detection adds nothing to the library.
  • Encrypted processing copies become due for deletion after 7 days. Job and billing metadata stay for accounting and to block repeated jobs. The original embedding JSON is not kept.

Try either mode in the dashboard

In Watermark media or Detect watermark, select Request mode. Sync waits for pending jobs for you. Async shows a receipt. Use Check result later or select a webhook. The copyable code examples match the mode you choose.

SDKs

Regular methods wait for the result. Submit methods return a receipt right away and do not poll.

SDKSubmit embed / detection
Node.js, JavasubmitEmbed / submitDetection
Python, Rustsubmit_embed / submit_detection
GoSubmitEmbed / SubmitDetection
C#SubmitEmbedAsync / SubmitDetectionAsync
Node.js, Java
Submit embed / detection
submitEmbed / submitDetection
Python, Rust
Submit embed / detection
submit_embed / submit_detection
Go
Submit embed / detection
SubmitEmbed / SubmitDetection
C#
Submit embed / detection
SubmitEmbedAsync / SubmitDetectionAsync

In C#, Async in a method name means the call does not block your thread. Submit is what starts a background job on the server.

Choose where results are stored

Embedding accepts the storage_destination_id query and an optional storage_key query. Delivery retries reuse the already checked file and do not add a charge. Storage options.

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