Upload an image, start a bypass job, and download the finished output through simple JSON endpoints. Validation and bypass run asynchronously: each POST returns immediately with a status_url you poll until the work reaches a terminal state.
API access is checked against your current plan on every request. Create and manage tokens from API tokens.
Recommended path
Workflow
1
Check account state
Call GET /me to confirm API access, plan details, credits, and concurrency.
2
Submit the upload
Send multipart, URL import, or a presigned S3 upload to POST /validations. It returns 202 Accepted right away with a status_url.
3
Poll until validated
Repeatedly call the upload's status_url (GET /image_uploads/:uuid) every 2–3 seconds until status is validated or failed.
4
Submit the bypass
Pass the validated upload UUID to POST /bypasses. Add remove_synthid_watermark when needed, or set detector_bypass to false for SynthID-only output. This also returns 202 Accepted with a status_url.
5
Poll until succeeded
Repeatedly call the bypass's status_url (GET /bypasses/:uuid) every 2–3 seconds until status is succeeded or failed.
6
Download output
Use the returned output_url or follow GET /bypasses/:uuid/download for the final cleaned image.
Never hold a request open waiting for a result. Both POST /validations and POST /bypasses return 202 Accepted immediately with a status_url; poll that GET endpoint on an interval until you see a terminal status. Polling every 2–3 seconds is plenty. Only poll work that was accepted with 202 — a 429 concurrent_job_limit means the work was not started, so retry the submission later instead of polling.
Poll until validatedbash
# POST returns 202 with { "upload": { "uuid": "..." }, "status_url": "/api/v1/image_uploads/upload-uuid" }
upload_uuid="upload-uuid"
while true; do
status=$(curl -s https://twotensors.ai/api/v1/image_uploads/$upload_uuid \
-H "Authorization: Bearer tt_live_your_token" | jq -r '.upload.status')
echo "validation status: $status"
case "$status" in
validated) break ;;
failed) echo "validation failed"; exit 1 ;;
*) sleep 2 ;;
esac
done
# Then POST /bypasses and poll its status_url the same way until status is
# "succeeded" (then download) or "failed".
Submits image validation and returns immediately with the current upload state and a status_url.
Poll GET /image_uploads/:uuid until the upload is validated or failed.
Provide exactly one input: upload_id, multipart image, or image_url.
URL imports must use HTTPS, resolve to a public address, return image/*, and stay under the upload size limit. Visible Gemini logo removal runs automatically during validation and does not require a request parameter.
Poll only work accepted with 202; a 429 concurrent_job_limit response means validation was not started.
Submits a cleaning job for a validated upload and returns immediately with the current bypass state and a status_url.
Poll GET /bypasses/:uuid until the job is succeeded or failed, then download only after success.
Supported detector strengths are strong and medium.
The aliases balanced and subtle map to those values.
detector_bypass defaults to true, while remove_synthid_watermark defaults to false.
Set remove_synthid_watermark to true to run SynthID removal, and set synthid_strength to low, medium, high, or x_high.
synthid_strength defaults to medium. Set detector_bypass to false when you only want the SynthID stage.
SynthID removal adds 3 credits. When detector_bypass is false, the job runs only the SynthID stage and the final output_url points to that WebP output. Requests with both stages disabled are rejected.
A 429 concurrent_job_limit response means the bypass was not accepted and should not be polled.
GET
/bypasses/:uuid
Returns bypass job status, processing dimensions, cost, errors, and a temporary output_url when the job succeeded.