Quick start
- Add funds after signing in, then create an API key in API access. Keep the key in a
SYNTHID_API_KEYenvironment variable on your computer or server. - Save the downloadable Python helper or Node.js helper in your project. Neither helper needs third-party libraries. For help getting started, share https://removesynthid.com/developers/synthid-api/ with your AI agent.
- Place one of the examples below in the helper's directory, change the image paths and run it. Run the examples with Python 3.10+ or Node.js 22+. One function takes either a path or a list of up to 20 paths.
Each of a batch's 20 images may be as large as 15 MiB. The helper manages file-by-file transfers and confirmations. Completed results cost $0.20 per image at the server's automatically applied price. API uploads need prepaid balance, with no use of the website's free allowance.
Python
import os
from synthid_client import upload_images, wait_for_batch, download_result
options = {"origin": "https://removesynthid.com", "api_key": os.environ["SYNTHID_API_KEY"]}
# One path or a list of up to 20 paths; 15 MiB per image.
batch = upload_images(["image.png", "photo.jpg"], **options)
# Save these if your application needs to resume later.
print("Operation:", batch["id"], "Retry key:", batch["idempotencyKey"])
batch = wait_for_batch(batch, **options)
for item in batch["items"]:
if item["state"] != "ready":
print("Not ready:", item["ordinal"], item.get("code") or item["state"])
continue
if item.get("warning"):
print(item["warning"])
download_result(item["downloadUrl"], f"result-{item['ordinal'] + 1}.png", **options)
# Or download all ready images in one archive:
# download_result(batch["zipUrl"], "results.zip", **options)Node.js
import { uploadImages, waitForBatch, downloadResult } from "./synthid-client.mjs";
const options = { origin: "https://removesynthid.com", apiKey: process.env.SYNTHID_API_KEY };
// One path or a list of up to 20 paths; 15 MiB per image.
let batch = await uploadImages(["image.png", "photo.jpg"], options);
// Save these if your application needs to resume later.
console.log("Operation:", batch.id, "Retry key:", batch.idempotencyKey);
batch = await waitForBatch(batch, options);
for (const item of batch.items) {
if (item.state !== "ready") {
console.log("Not ready:", item.ordinal, item.code || item.state);
continue;
}
if (item.warning) console.warn(item.warning);
await downloadResult(item.downloadUrl, "result-" + (item.ordinal + 1) + ".png", options);
}
// Or download all ready images in one archive:
// await downloadResult(batch.zipUrl, "results.zip", options);The upload function finishes after the files are confirmed. The wait function keeps polling until every item is ready or has a terminal outcome. Read all warnings and inspect any failed or not-started items. Choose a fresh output folder or unique destination names because downloads never overwrite existing files.
Start with a small automation
For a first integration, connect one incoming file to one completed download. This makes it easier to verify credentials, funding and file handling before adding a loop over multiple records.
- In an HTTP automation step, send the image as multipart form data and keep the API key in the tool's secret store. Use a stable record identifier for the idempotency key.
- Add a delay before requesting status, then branch on the returned state. Save the file only when it is ready, and include any warning in the record that your automation updates.
- When several files belong to one record, use a helper or the JSON creation flow. Transfer the admitted files individually, confirm them, and inspect all per-image outcomes.
The Python and Node.js examples below cover the complete flow without installing an SDK. For n8n, Make or Zapier, the raw HTTP section explains the same operations without adding a separate integration service.
One image with cURL
A single image can be sent directly with multipart form data. Look in the response for the image's status URL. If you retry, use the request's original idempotency key.
curl "https://removesynthid.com/api/v1/images" \
-H "Authorization: Bearer $SYNTHID_API_KEY" \
-H "Idempotency-Key: my-upload-0001" \
-F "image=@image.png;type=image/png"
# Poll the returned statusUrl with the same API key.
curl "https://removesynthid.com/api/v1/images/IMAGE_ID" \
-H "Authorization: Bearer $SYNTHID_API_KEY"
# Once state is ready, download the returned downloadUrl.
curl "https://removesynthid.com/api/v1/images/IMAGE_ID/download" \
-H "Authorization: Bearer $SYNTHID_API_KEY" -o result.pngPricing and API keys
A finished image that is ready to download costs $0.20 USD. Completed warning results still incur the charge. There is no charge for failed work or work canceled before completion. Upload requests have no pricing parameter because the service sets the price.
Your API key permits requests against your prepaid account balance. Keep API keys in server storage or your automation tool's secret store. The key cannot start a sign-in or payment. Account supports creating up to five active keys and revoking them. Revocation blocks new requests but preserves access to accepted jobs through another active key for the account.
API processing can use promotional credit in your available balance at the usual image rate, after paid funds have been used.
Retries and interrupted uploads
The helpers assign one Idempotency-Key for each operation and reuse it for up to three retries of transient failures. To continue after a restart, supply the original file list and idempotencyKey in Node.js options or idempotency_key in Python. Do not change file contents, names or sequence.
Upload errors include the retry key as error.idempotencyKey in Node.js or error.idempotency_key in Python, along with the operation ID/status URL when known. File-transfer failures are listed in error.items. The helper completes independent transfers before returning an incomplete-upload error. Resolve the error and restart within the original ten-minute upload period; files already confirmed are skipped.
A metadata change returns status 409. Retries with identical data reuse the same operation, including after replacing an API key. The idempotency record retention period is seven days. Terminal failed or rejected items require a fresh operation; retries neither restart them nor repeat completed charges.
Raw HTTP: one image or a batch
POST /api/v1/images is used to create operations for one image or multiple images. Submit a JSON files array of 1–20 entries; one-image and multiple-image responses have the same batch structure. These steps are automated by the helpers shown above.
POST /api/v1/images
Authorization: Bearer YOUR_API_KEY
Idempotency-Key: my-upload-0001
Content-Type: application/json
{
"files": [
{ "filename": "image.png", "contentType": "image/png", "sizeBytes": 123456 },
{ "filename": "photo.jpg", "contentType": "image/jpeg", "sizeBytes": 234567 }
]
}- Review ordered
itemsfornot_startedoutcomes. Images are admitted only when your balance and queue space can cover them. - Transfer each admitted file with PUT to its entry in
uploads, using the supplied content type. Never attach your API key to the storage URL request. Keep concurrent file transfers at two or fewer. - Send an authenticated POST request to each
confirmUrlafter uploading. Confirmation validates the upload and reserves its processing charge. Processing begins when the admitted uploads have confirmation. Finish these steps within ten minutes. - Poll for updates at the batch
statusUrl. Save each ready image throughdownloadUrl, or collect all ready images withzipUrl.
The operation returned by creation is used by the existing batch status, confirmation, cancellation and ZIP routes. Send DELETE to the image status URL for cancellation or deletion. Cancel the remaining unfinished items with POST to /api/v1/batches/BATCH_ID/cancel. Deleting a completed image leaves its charge in place.
Polling and downloads
Schedule requests using pollAfterSeconds: usually 15 seconds in the queue and 5 during processing. When this value reaches zero, stop and inspect the items. Status and download URLs are relative paths under https://removesynthid.com and require an API key. More polling does not make processing faster or keep results longer.
Retrieve each finished image during its one-hour window. ZIP contains the ready images and streams without creating a stored archive. Image quality is central to processing; completion alone cannot verify that no provenance signals remain. Webhooks are not available in this version.
n8n, Make and Zapier
To submit one image, add an HTTP request step using a secret Bearer credential and POST multipart/form-data to /api/v1/images. Attach the binary file as image. Set a stable record ID as Idempotency-Key and allow the tool to generate the multipart boundary. You do not need a pricing field.
For more than one image, follow the JSON creation and individual PUT/confirmation sequence above. Choose an n8n Binary File field when configuring multipart uploads in n8n. Make uploads use the HTTP module's multipart file field. In Zapier, select binary multipart support or follow JSON creation with a separate binary PUT. Wait between status requests and save every ready download as a binary file. You do not need a dedicated connector.
Limits and errors
- Each JPEG, PNG or WebP image has a 15 MiB and 20-megapixel limit, with a maximum of 20 images per batch. Animated files and unnormalized EXIF rotation cannot be used. A 16 MiB total limit applies to the single-file multipart convenience request, not to combined batch size.
- Only one unfinished batch is allowed per account, including website uploads. The queue accepts a maximum of 40 outstanding images.
- All keys for an account share a per-minute allowance of six creation requests and 120 other API requests. Retry attempts count toward these limits. Follow
Retry-Afterwith 429 and 503 responses. - Uploads have ten minutes, processing admission has six hours, and completed results have a one-hour download window. Batch access expires at the processing deadline plus two hours.
Error responses provide a stable code and readable error. Interpret HTTP statuses as follows: 400 invalid input, 401 invalid or revoked key, 402 insufficient balance, 409 conflicting idempotency data or unfinished work, 410 expiry, 429 rate/concurrency limit, and 503 unavailable processing capacity. The helper exposes codes while keeping credentials and signed URLs out of logs.
Check your balance, current price and limits through GET /api/v1/account. Get the OpenAPI specification for the complete request and response schemas.