xtract.bot

POST /api/image-caption10 quota units per call · cache hits free

Generate a natural-language caption for an image using LLaVA via Cloudflare Workers AI. Returns a sentence describing the scene, suitable for alt text, accessibility, or LLM-side chaining.

Generates a natural-language caption of the input image using the LLaVA 1.5 vision-language model. Useful for: - Auto-generating alt text for accessibility. - LLM-side chaining — feed a caption back into a text model for further reasoning without re-uploading the bytes. - Content moderation triage ("is this image describing X?"). The default prompt asks for a one-sentence description of the scene. Override `prompt` for a longer, more detailed caption or to extract specific details ("What text is visible in this image?"). **Cost: paid Cloudflare Workers AI inference.** LLaVA is a 7B- parameter model — each call is heavier than ResNet-based classification. Charges against your account's Workers AI budget plus 10 wasm-tool quota units per call.

Inputs

NameTypeDefaultDescription
image*fileImage to caption (PNG, JPEG, WebP, AVIF).
promptstring"Describe this image in one concise sentence."Instruction to pass to LLaVA. Override for longer captions or to ask specific questions.
maxTokensnumber (16…1024)256Maximum tokens to generate in the caption.

Response

Modes: json. Cache: yes (24h TTL).

Every response carries x-cache (HIT / MISS / BYPASS), x-cache-signature (stable across identical inputs), and the rate-limit headers listed below.

Quota & limits

Cost per call10 units against the 10,000-unit monthly quota. Cache hits are free — only cache misses decrement.
Burst limit200 requests per rolling minute, shared across all tools.
Max request size4 MiB (base64 inflates file payloads ~33% — the limit applies to the decoded bytes).
Max response size16 KiB
Timeout60s wall clock.
Rate-limit headersX-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Burst-Limit on every response; X-Quota-Warning once 80% of the monthly quota is spent; Retry-After on 429s.

Errors

Errors are JSON with an error string; schema failures add a details object (Zod's flattened field errors).

StatusWhenBody
400Input fails the tool's schema (wrong type, missing required field, malformed base64) or the file bytes can't be parsed as the expected format.{ "error": "invalid inputs", "details": { "fieldErrors": { … } } }
401Missing or invalid X-Api-Key / X-Account-Id headers (or no session when called from the browser).{ "error": "unauthorized" }
404Unknown tool id, or calling /api/* on the website hostname instead of api.xtract.bot.{ "error": "not found" }
413Request body over the tool's max request size, or an image header declaring more megapixels than the tool's pixel budget.{ "error": "…exceeds maxRequestBytes…" }
415Content-Type isn't application/json on the json-body transport.{ "error": "unsupported content-type; expected application/json" }
429Monthly quota or the 200/min burst limit exhausted. Check Retry-After and the X-RateLimit-* headers.{ "error": "monthly quota exceeded", "monthRemaining": 0, … }
5xxConversion engine failure. Safe to retry; if it persists, the input is hitting a bug — please report it.{ "error": "…" }

Code samples

Built from the default example.

# Download or substitute the example input:
#   curl -O https://xtract.bot/examples/image-align/sample.png
IMAGE=$(base64 -w0 < sample.png)

curl -X POST https://api.xtract.bot/api/image-caption \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H "X-Account-Id: $XTRACT_ACCOUNT_ID" \
  -H "X-Api-Key: $XTRACT_API_KEY" \
  -d '{
  "image": "'"$IMAGE"'"
}'