Skip to main content

API

Submission tools API

Every response includes schemaVersion, requestId, status and structured errors.

Machine-readable contract

Download the OpenAPI 3.1 document to generate your own client or agent tools.

/api/openapi.jsonMCP calling guide
Shared tool catalog

inspect_file

public · sync · 70s

Inspect uploaded bytes by fileId, or normalize explicitly supplied file facts.

upload_file

user · sync · 70s

Store an authenticated input file for later tool jobs.

validate_file

public · sync · 70s

Compare file facts with explicit submission rules.

compress_image

user · async · 70s

Compress an image to a verified byte target with optional downsampling.

inspect_image

user · async · 70s

Decode an uploaded image and inspect pixels, DPI and privacy metadata.

convert_image

user · async · 70s

Convert an image to JPEG, PNG, WebP or AVIF and remove private metadata.

resize_image

user · async · 70s

Resize an image proportionally with contain or cover fit.

crop_image

user · async · 70s

Crop an orientation-corrected image using validated pixel coordinates.

compress_pdf

user · async · 70s

Optimize a PDF and verify its actual output size and rules.

convert_image_to_pdf

user · async · 70s

Place one or more images into a checked PDF.

merge_pdfs

user · async · 70s

Merge PDFs in an explicit order and validate the result.

split_pdf

user · async · 70s

Split a PDF by a validated page range.

rotate_pdf

user · async · 70s

Rotate selected PDF pages and re-check the output.

create_submission_package

user · async · 70s

Build a named material package with a manifest and report.

get_job

user · sync · 70s

Read an authenticated asynchronous job status.

list_jobs

user · sync · 70s

List authenticated asynchronous jobs with cursor pagination.

cancel_job

user · sync · 70s

Cancel an authenticated non-terminal asynchronous job.

download_artifact

user · sync · 70s

Create an authenticated short-lived artifact download.

save_rule

user · sync · 70s

Save an authenticated reusable submission rule template.

list_rules

user · sync · 70s

List authenticated owner-scoped submission rule templates.

get_rule

user · sync · 70s

Read one authenticated owner-scoped submission rule template.

delete_rule

user · sync · 70s

Delete one authenticated owner-scoped submission rule template.

get_entitlements

user · sync · 70s

Read authenticated daily usage, quota and tool limits.

Uploads, jobs and processing

Image input: JPEG/PNG/WebP/AVIF/HEIC/HEIF/GIF/TIFF. Output: JPEG/PNG/WebP/AVIF. Supports compression, conversion, resize, crop, orientation, metadata removal and JPEG/PNG DPI. Multi-frame inputs use the first frame with a warning.

PDF supports inspection, merge, page selection, rotation, image layouts and embedded-image compression. Limits: 25 MB, 100 pages and 40 MP images. Strict mode requires all rules to pass; best-effort returns actual candidates with warnings.

Inputs expire after 24 hours; artifacts use their returned expiresAt. Set input.execution=async when posting jobs, then poll after HTTP 202. Failure reports live in job.result.error.details. Use Idempotency-Key for replay and DELETE jobs?id=JOB_ID to cancel.

Packages accept namingTemplate with name/index/type/date/ext tokens and a rule snapshot. ZIPs include a manifest and per-file JSON/Markdown reports. Templates must end with .{ext}; strict mode rejects failing materials.

node scripts/tools-cli.mjs run convert_image --input '{"fileId":"FILE_ID","format":"webp"}' --wait

The CLI reads ATTACHREADY_BASE_URL and ATTACHREADY_API_KEY, supports tools/upload/run/job/cancel/download and emits JSON. MCP inspect_file with fileId inspects actual bytes; supplied file facts remain caller assertions.

Quick start
curl -X POST "$BASE_URL/api/tools/validate" \
  -H 'Content-Type: application/json' \
  --data '{"file":{"name":"passport.png","mimeType":"image/png","bytes":180000},"rules":{"maxBytes":200000}}'

File upload and job endpoints require a session or Better Auth API key.

curl -H "Authorization: Bearer $API_KEY" \
  "$BASE_URL/api/tools/artifacts?id=ARTIFACT_ID"
const response = await fetch('$BASE_URL/api/tools/validate', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    file: { name: 'passport.png', mimeType: 'image/png', bytes: 180000 },
    rules: { maxBytes: 200000 },
  }),
});
const result = await response.json();
import requests

result = requests.post(
    '$BASE_URL/api/tools/validate',
    json={
        'file': {'name': 'passport.png', 'mimeType': 'image/png', 'bytes': 180000},
        'rules': {'maxBytes': 200000},
    },
).json()