Developers

API quickstart

Every API-backed YATools tool is available over HTTP. No API keys, no signup — just call the endpoint.

Base URL & the deal

All browser calls go through https://yatools-tan.vercel.app/api/v1/* — you never talk to upstream providers directly. That gives you one stable interface, normalized errors, and built-in fallback cascades when a provider is down.

The service is free with fair-use limits. There are no keys to manage — usage is governed by per-IP daily quotas instead. Personal projects, side projects, and small apps are exactly what the API is for.

The response envelope

Every JSON endpoint returns the same envelope. provider names the backend that served the request (usually yatools); fallbackUsed is true when a fallback cascade kicked in after the primary failed.

success shape
{
  "ok": true,
  "provider": "yatools",
  "fallbackUsed": false,
  "data": { /* endpoint-specific payload */ }
}
error shape
{
  "ok": false,
  "provider": "yatools",
  "fallbackUsed": false,
  "error": {
    "code": "MISSING_URL",
    "message": "Human-readable explanation of what went wrong."
  }
}

Endpoints that return files on success — screenshots, PDFs, audio, generated images — stream bytes with the correct content-type plus X-Provider and X-Fallback-Used headers. They return the JSON error shape only when they fail, so always check the content-type before parsing — see the error reference.

Your first call

Screenshot of example.com in three languages:

cURL
# Full-page screenshot of any public URL
curl "https://yatools-tan.vercel.app/api/v1/websnap?url=https://example.com" \
  --output screenshot.png

# The response is a PNG. On error you get JSON instead:
# {"ok":false,"provider":"yatools","fallbackUsed":false,
#  "error":{"code":"RATE_LIMITED","message":"..."}}
JavaScript
const res = await fetch(
  "https://yatools-tan.vercel.app/api/v1/websnap?url=" +
    encodeURIComponent("https://example.com")
);

const contentType = res.headers.get("content-type") ?? "";

if (!res.ok || contentType.includes("application/json")) {
  // Normalized error shape: { ok, provider, fallbackUsed, error: { code, message } }
  const body = await res.json();
  throw new Error(body.error.message);
}

const png = await res.blob(); // screenshot bytes
Python
import requests

r = requests.get(
    "https://yatools-tan.vercel.app/api/v1/websnap",
    params={"url": "https://example.com"},
    timeout=60,
)

if "application/json" in r.headers.get("content-type", ""):
    # Normalized error: {"ok": False, ..., "error": {"code": ..., "message": ...}}
    raise SystemExit(r.json()["error"]["message"])

with open("screenshot.png", "wb") as f:
    f.write(r.content)  # PNG bytes

Endpoint reference

Twelve proxy routes, one per API-backed tool. Query parameters go in the URL for GET routes; POST routes take a JSON body.

MethodEndpointParametersPurpose
GET/api/v1/websnapurl (required)Full-page website screenshot — returns PNG bytes.
POST/api/v1/transcribeJSON: audio as data:audio/* data URL (required, ≤ 25 MB), language, timestampsTranscribe an uploaded audio file to text.
POST/api/v1/ttsJSON: text (required), voiceIndex, rate, pitchConvert text to spoken audio, including Urdu voices.
GET / POST/api/v1/handtext (required), font, style, paper, lang …Render typed text as handwriting on ruled paper (PNG).
GET/api/v1/wikipdfquery — Wikipedia article URL or title (required)Convert a Wikipedia article to a clean, selectable-text PDF.
GET/api/v1/n8nq, limit, category, complexity, triggerType, pageSearch n8n workflow templates by keyword.
POST/api/v1/ttiJSON: prompt, 1–500 chars (required), ratioGenerate an AI image from a text prompt (POST only).
GET/api/v1/msearchq (required)Search movies and TV shows — ratings, cast, posters.
POST/api/v1/certificateJSON: name, date, signature, details, templateId 1–8 (required), format pdf|jpg|pngGenerate a novelty certificate (not an official credential).
POST/api/v1/imgchatJSON: image as data:image/* data URL (required, ≤ 5 MB), userPrompt (required)Ask AI questions about an uploaded image.
GET/api/v1/alldlurl (required, public video/audio page URL)Get download links for a video/audio URL — only for content you own or have the right to save.
GET/api/v1/mailaction=create|inbox|read|delete; mail (address), id (message id) as required per actionTemporary receive-only email addresses. Addresses expire; never use for account recovery.

Daily quotas

Limits apply per tool, per IP, per day (resets at midnight UTC). The six client-side tools — QR Code Generator, Word Counter, JSON Formatter, Password Generator, Case Converter, Color Picker — run entirely in your browser and have no limits at all.

ToolRouteLimit (per IP / day)
Website Screenshot/api/v1/websnap20 / day
Audio to Text/api/v1/transcribe10 / day
Text to Speech/api/v1/tts30 / day
Wikipedia to PDF/api/v1/wikipdf20 / day
n8n Workflow Search/api/v1/n8n100 / day
AI Image Generator/api/v1/tti10 / day
Movie & TV Search/api/v1/msearch50 / day
Certificate Maker/api/v1/certificate10 / day
AI Vision Chat/api/v1/imgchat10 / day
Universal Downloader/api/v1/alldl10 / day
Temporary Email/api/v1/mail20 / day

What happens on 429

Exceed a quota and the API returns 429 Too Many Requests with a Retry-After header (seconds until the quota resets) and this body:

429 response
// HTTP 429 — also carries a Retry-After header (seconds)
{
  "ok": false,
  "provider": "yatools",
  "fallbackUsed": false,
  "error": {
    "code": "RATE_LIMITED",
    "message": "Daily limit reached for this tool — try again tomorrow."
  },
  "tool": "websnap"
}

The correct behavior is simple: back off, show the user a friendly message, and retry after the reset — don't hammer the endpoint. Full details on the rate limits page.

Keep reading

Building something public? Quotas are per IP and designed for personal projects and small apps. If you need more, get in touch — we'd rather talk than have you scrape.