Two Tensors API v1

Validate and clean AI images from your pipeline.

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.

Base URL https://twotensors.ai/api/v1
Authentication Authorization: Bearer tt_live_...
15 MB Max image
image/* Content type
5 min Download URL

Start here

Getting Started

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 validated bash
# 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".

Headers

Authentication

Account lookup curl
curl https://twotensors.ai/api/v1/me \
  -H "Accept: application/json" \
  -H "Authorization: Bearer tt_live_your_token"

Tokens use the tt_live_ prefix and are shown only once when created. Invalid, revoked, or missing tokens return 401 invalid_api_token.

Responses

Error Format

Error response json
{
  "error": "invalid_request",
  "message": "Provide upload_id, image, or image_url."
}
Status Error Meaning
401 invalid_api_token The bearer token is missing, invalid, or revoked.
403 api_access_required The current plan does not include API access.
409 idempotency_conflict The same idempotency key was reused for a different request.
422 invalid_request A required field is missing or an input is not valid.
409 busy_credits Credit accounting is temporarily busy.
429 concurrent_job_limit The account has reached its concurrent job limit. The work was not accepted; any returned upload remains reusable.

Reference

Endpoints

GET

/me

Returns the authenticated account, plan, available credits, and concurrent job limit.

Response json
{
  "account": { "uuid": "account-uuid", "email": "you@example.com" },
  "plan": {
    "code": "pro",
    "name": "Pro",
    "monthly_credits": 1000,
    "concurrent_jobs": 2,
    "api_access": true
  },
  "credits": { "available": 850 },
  "concurrent_job_limit": 2
}
POST

/uploads/presign

Creates an API upload record and returns a presigned S3 form. The form expires after 15 minutes.

Request curl
curl https://twotensors.ai/api/v1/uploads/presign \
  -H "Authorization: Bearer tt_live_your_token" \
  -H "Content-Type: application/json" \
  -d '{
    "filename": "sample.jpg",
    "content_type": "image/jpeg",
    "byte_size": 123456
  }'
Response json
{
  "upload": {
    "uuid": "upload-uuid",
    "status": "awaiting_upload",
    "upload_method": "presigned"
  },
  "presigned_post": {
    "url": "https://...",
    "fields": { "key": "incoming/..." },
    "key": "incoming/...",
    "bucket": "uploads-bucket"
  }
}
POST

/validations

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.

Presigned upload curl
curl https://twotensors.ai/api/v1/validations \
  -H "Authorization: Bearer tt_live_your_token" \
  -H "Content-Type: application/json" \
  -d '{ "upload_id": "upload-uuid" }'
Multipart upload curl
curl https://twotensors.ai/api/v1/validations \
  -H "Authorization: Bearer tt_live_your_token" \
  -F "image=@sample.jpg;type=image/jpeg"
URL import curl
curl https://twotensors.ai/api/v1/validations \
  -H "Authorization: Bearer tt_live_your_token" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: validation-001" \
  -d '{ "image_url": "https://example.com/sample.jpg" }'
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.
Response json
{
  "upload": {
    "uuid": "upload-uuid",
    "status": "validating",
    "upload_method": "multipart",
    "original_filename": "sample.jpg",
    "content_type": "image/jpeg",
    "byte_size": 123456,
    "image_uuid": null
  },
  "status_url": "/api/v1/image_uploads/upload-uuid"
}
GET

/image_uploads/:uuid

Fetches the current upload status and validation result for an API upload UUID.

Request curl
curl https://twotensors.ai/api/v1/image_uploads/upload-uuid \
  -H "Authorization: Bearer tt_live_your_token"
POST

/bypasses

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.

Request curl
curl https://twotensors.ai/api/v1/bypasses \
  -H "Authorization: Bearer tt_live_your_token" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: bypass-001" \
  -d '{
    "api_image_upload_id": "upload-uuid",
    "strength": "strong",
    "synthid_strength": "high",
    "downscale_to_longest_side": 1024,
    "detector_bypass": true,
    "remove_synthid_watermark": true
  }'
Response json
{
  "bypass": {
    "bypass_job_uuid": "job-uuid",
    "uuid": "job-uuid",
    "status": "queued",
    "strength": "strong",
    "synthid_strength": "high",
    "detector_bypass_requested": true,
    "credit_cost": 6,
    "output_url": null
  },
  "status_url": "/api/v1/bypasses/job-uuid"
}
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.

Request curl
curl https://twotensors.ai/api/v1/bypasses/job-uuid \
  -H "Authorization: Bearer tt_live_your_token"
GET

/bypasses/:uuid/download

Redirects with 303 See Other to a presigned download URL for the final cleaned output of a succeeded bypass job.

Request curl
curl -I https://twotensors.ai/api/v1/bypasses/job-uuid/download \
  -H "Authorization: Bearer tt_live_your_token"
DELETE

/images/:uuid

Deletes an API upload or its validated user image. Pass either an API upload UUID or the linked image UUID.

Request curl
curl -X DELETE https://twotensors.ai/api/v1/images/upload-or-image-uuid \
  -H "Authorization: Bearer tt_live_your_token"
Response json
{ "success": true }