{"openapi":"3.0.3","info":{"title":"IteraTools API","version":"1.0.0","description":"AI-powered tools API with x402 micropayments on Base. 73 tools for images, video, web, audio, utilities, geolocation, currency, DNS, WHOIS, WhatsApp (send, reply, market research, agentic research agent), SMS, spreadsheets, code execution, cryptographic hashing, barcode generation, LLM chat proxy, presentation generation, text diff comparison, HTTP proxy, and more.","contact":{"email":"fred@iteratools.com"},"license":{"name":"Proprietary"}},"servers":[{"url":"https://api.iteratools.com","description":"Production"}],"security":[{"BearerAuth":[]},{"x402Payment":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"Admin API key"},"x402Payment":{"type":"apiKey","in":"header","name":"X-Payment","description":"x402 micropayment proof"}}},"paths":{"/health":{"get":{"summary":"Health check","responses":{"200":{"description":"OK"}}}},"/image/generate":{"post":{"summary":"Generate image with Flux 1.1 Pro","tags":["Image"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"prompt":{"type":"string"},"width":{"type":"integer","default":1024},"height":{"type":"integer","default":1024}},"required":["prompt"]}}}},"responses":{"200":{"description":"Image URL"},"402":{"description":"Payment required"}}}},"/image/fast":{"post":{"summary":"Fast image with Flux Schnell","tags":["Image"],"responses":{"200":{"description":"Image URL"},"402":{"description":"Payment required"}}}},"/image/rembg":{"post":{"summary":"Remove image background","tags":["Image"],"responses":{"200":{"description":"Image without background"},"402":{"description":"Payment required"}}}},"/image/resize":{"post":{"summary":"Resize image","tags":["Image"],"responses":{"200":{"description":"Resized image base64"},"402":{"description":"Payment required"}}}},"/image/compress":{"post":{"summary":"Compress image with quality control","tags":["Image"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"image_url":{"type":"string","description":"Public HTTPS URL of the image"},"image_base64":{"type":"string","description":"Base64 data URL (data:image/jpeg;base64,...)"},"quality":{"type":"integer","default":80,"minimum":1,"maximum":100,"description":"Compression quality (1-100)"},"format":{"type":"string","enum":["jpeg","png","webp","avif"],"description":"Output format (default: keep original)"},"max_width":{"type":"integer","description":"Max width in pixels; resizes if wider (keeps aspect ratio)"}}}}}},"responses":{"200":{"description":"Compressed image base64 with stats","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"image_base64":{"type":"string"},"original_size":{"type":"integer"},"compressed_size":{"type":"integer"},"reduction_pct":{"type":"number"},"format":{"type":"string"},"width":{"type":"integer"},"height":{"type":"integer"}}}}}},"400":{"description":"Invalid input"},"402":{"description":"Payment required"}}}},"/image/edit":{"post":{"summary":"Image editing operations (crop, rotate, flip, blur, sharpen, watermark, grayscale, tint, border)","tags":["Image"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"image_url":{"type":"string","description":"Public HTTPS URL of the image"},"image_base64":{"type":"string","description":"Base64 data URL (data:image/...;base64,...)"},"operations":{"type":"array","maxItems":10,"description":"Array of operations to apply in order","items":{"type":"object","properties":{"type":{"type":"string","enum":["crop","rotate","flip","flop","blur","sharpen","grayscale","negate","tint","resize","watermark","border"]}},"required":["type"]}},"format":{"type":"string","enum":["png","jpeg","webp","avif"],"default":"png"},"quality":{"type":"integer","minimum":1,"maximum":100,"default":80}},"required":["operations"]}}}},"responses":{"200":{"description":"Edited image base64 with metadata","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"data":{"type":"object","properties":{"image_base64":{"type":"string"},"width":{"type":"integer"},"height":{"type":"integer"},"format":{"type":"string"},"size_bytes":{"type":"integer"},"operations_applied":{"type":"array","items":{"type":"string"}}}}}}}}},"400":{"description":"Invalid input"},"402":{"description":"Payment required"}}}},"/image/ocr":{"post":{"summary":"Extract text from image (OCR)","tags":["Image"],"responses":{"200":{"description":"Extracted text"},"402":{"description":"Payment required"}}}},"/image/describe":{"post":{"summary":"Describe image with GPT-4o vision","tags":["Image"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["image"],"properties":{"image":{"type":"string","description":"Base64 data URL (data:image/jpeg;base64,...) or public HTTPS URL"},"prompt":{"type":"string","description":"Custom prompt (default: describe in detail)"}}}}}},"responses":{"200":{"description":"Description, tags, model used","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"data":{"type":"object","properties":{"description":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"model":{"type":"string"}}}}}}}},"400":{"description":"Invalid input"},"402":{"description":"Payment required"}}}},"/video/generate":{"post":{"summary":"Generate video","tags":["Video"],"responses":{"200":{"description":"Video URL"},"402":{"description":"Payment required"}}}},"/screenshot":{"post":{"summary":"Take webpage screenshot","tags":["Video"],"responses":{"200":{"description":"Screenshot base64"},"402":{"description":"Payment required"}}}},"/video/frames":{"post":{"summary":"Extract video frames","tags":["Video"],"responses":{"200":{"description":"Frame images"},"402":{"description":"Payment required"}}}},"/video/transcribe":{"post":{"summary":"Transcribe video from URL (YouTube or MP4)","tags":["Video"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","description":"YouTube URL or direct MP4/video URL"},"language":{"type":"string","default":"auto","description":"Language code (auto, en, pt, es, etc)"},"format":{"type":"string","enum":["text","srt","json"],"default":"text","description":"Output format"}},"required":["url"]}}}},"responses":{"200":{"description":"Transcription result"},"402":{"description":"Payment required"}}}},"/video/analyze":{"post":{"summary":"Analyze video content (transcript, frame descriptions, timestamps, summary)","tags":["Video"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","description":"YouTube URL or direct MP4/video URL"},"tasks":{"type":"array","items":{"type":"string","enum":["transcript","describe","timestamps","summary"]},"default":["transcript","summary"],"description":"Analysis tasks to perform"},"max_duration":{"type":"number","default":300,"description":"Max video duration in seconds (default 300, max 900)"},"language":{"type":"string","default":"auto","description":"Language code for transcript"}},"required":["url"]}}}},"responses":{"200":{"description":"Analysis result with requested fields"},"402":{"description":"Payment required"}}}},"/scrape":{"post":{"summary":"Scrape webpage content","tags":["Web"],"responses":{"200":{"description":"Page content"},"402":{"description":"Payment required"}}}},"/search":{"post":{"summary":"Web search via Brave","tags":["Web"],"responses":{"200":{"description":"Search results"},"402":{"description":"Payment required"}}}},"/search/deep":{"post":{"summary":"Deep web search with full content + LLM synthesis (Tavily-style)","tags":["Web"],"description":"Search the web and return full extracted page content plus an AI-generated answer. Uses Brave Search for URLs, Readability to extract content, and GPT-4o-mini to synthesize a direct answer. $0.008/request.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["query"],"properties":{"query":{"type":"string","description":"Search query"},"max_results":{"type":"integer","default":5,"minimum":1,"maximum":10,"description":"Max results to scrape (default 5, max 10)"},"include_answer":{"type":"boolean","default":true,"description":"Generate a synthetic LLM answer from results (default true)"},"include_raw_content":{"type":"boolean","default":false,"description":"Include raw HTML of each page (default false)"},"search_depth":{"type":"string","enum":["basic","advanced"],"default":"basic","description":"basic = scrape up to 8KB per page; advanced = up to 20KB + Readability extraction"}}}}}},"responses":{"200":{"description":"Deep search results with answer and full page content","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"query":{"type":"string"},"answer":{"type":"string","nullable":true,"description":"LLM-generated synthesis answer (null if include_answer=false)"},"results":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string"},"title":{"type":"string"},"content":{"type":"string","description":"Extracted page content"},"score":{"type":"number","description":"Relevance score 0-1 (based on search ranking)"},"published_date":{"type":"string","nullable":true},"raw_content":{"type":"string","nullable":true,"description":"Raw HTML (only when include_raw_content=true)"}}}}}}}}},"400":{"description":"Missing query"},"402":{"description":"Payment required"},"503":{"description":"Search unavailable or OpenAI not configured"}}}},"/search/content":{"post":{"summary":"Web search with full page content","tags":["Web"],"description":"Search the web and return FULL page content (not just snippets). Uses Brave Search for URLs then scrapes each page. $0.005/request.","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["query"],"properties":{"query":{"type":"string","description":"Search query"},"max_results":{"type":"integer","default":5,"minimum":1,"maximum":10,"description":"Max results to return (default 5, max 10)"},"include_images":{"type":"boolean","default":false,"description":"Include image references in content_text (default false)"}}}}}},"responses":{"200":{"description":"Search results with full page content","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"query":{"type":"string"},"count":{"type":"integer"},"provider":{"type":"string"},"results":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string"},"title":{"type":"string"},"content_text":{"type":"string","description":"Full extracted page text (up to 20KB per page)"},"snippet":{"type":"string","description":"Short description from search index"},"published_date":{"type":"string","nullable":true}}}}}}}}},"400":{"description":"Missing query"},"402":{"description":"Payment required"},"503":{"description":"Search unavailable"}}}},"/pdf/extract":{"post":{"summary":"Extract text from PDF","tags":["Web"],"responses":{"200":{"description":"PDF text"},"402":{"description":"Payment required"}}}},"/pdf/generate":{"post":{"summary":"Generate PDF from HTML","tags":["Web"],"responses":{"200":{"description":"PDF base64"},"402":{"description":"Payment required"}}}},"/tts":{"post":{"summary":"Text to speech","tags":["Audio"],"responses":{"200":{"description":"Audio base64"},"402":{"description":"Payment required"}}}},"/transcribe":{"post":{"summary":"Transcribe audio (DEPRECATED - use /audio/transcribe)","deprecated":true,"tags":["Audio"],"description":"Deprecated. Use POST /audio/transcribe instead.","responses":{"200":{"description":"Transcription (includes deprecated:true and successor field)"},"402":{"description":"Payment required"}}}},"/qrcode":{"post":{"summary":"Generate QR code","tags":["Utils"],"responses":{"200":{"description":"QR code dataURL"},"402":{"description":"Payment required"}}}},"/weather":{"get":{"summary":"Get weather data","tags":["Utils"],"parameters":[{"name":"location","in":"query","required":true,"schema":{"type":"string"}},{"name":"units","in":"query","schema":{"type":"string","default":"metric"}}],"responses":{"200":{"description":"Weather data"},"402":{"description":"Payment required"}}}},"/crypto/price":{"get":{"summary":"Get crypto price","tags":["Utils"],"parameters":[{"name":"coin","in":"query","required":true,"schema":{"type":"string"}},{"name":"currency","in":"query","schema":{"type":"string","default":"usd"}}],"responses":{"200":{"description":"Crypto price"},"402":{"description":"Payment required"}}}},"/url/shorten":{"post":{"summary":"Shorten URL","tags":["Utils"],"responses":{"200":{"description":"Short URL"},"402":{"description":"Payment required"}}}},"/email/validate":{"post":{"summary":"Validate email address","tags":["Utils"],"responses":{"200":{"description":"Validation result"},"402":{"description":"Payment required"}}}},"/email/send":{"post":{"summary":"Send email","tags":["Utils"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"to":{"type":"string"},"subject":{"type":"string"},"body":{"type":"string"},"from_name":{"type":"string","default":"IteraTools"},"html":{"type":"boolean","default":false}},"required":["to","subject","body"]}}}},"responses":{"200":{"description":"Email sent"},"402":{"description":"Payment required"}}}},"/email/inbox":{"get":{"summary":"List inbox emails via IMAP ($0.002)","description":"List emails from any IMAP inbox. User provides their own credentials per-request (no state stored). Supports Gmail (App Password required), iCloud, Outlook, Yahoo, and any standard IMAP provider. Auto-detects IMAP server from email domain.","tags":["Email"],"parameters":[{"name":"account","in":"query","required":true,"schema":{"type":"string"},"description":"Email address (e.g. user@gmail.com)"},{"name":"password","in":"query","required":true,"schema":{"type":"string"},"description":"Password or App Password (Gmail requires App Password)"},{"name":"limit","in":"query","schema":{"type":"integer","default":20,"maximum":100},"description":"Max emails to return (default 20, max 100)"},{"name":"filter","in":"query","schema":{"type":"string","enum":["all","unread","flagged"],"default":"all"},"description":"Filter: all, unread, or flagged"},{"name":"mailbox","in":"query","schema":{"type":"string","default":"INBOX"},"description":"Mailbox name (default INBOX)"},{"name":"imap_host","in":"query","schema":{"type":"string"},"description":"Override IMAP host (auto-detected from email domain)"},{"name":"imap_port","in":"query","schema":{"type":"integer"},"description":"Override IMAP port (default 993)"}],"responses":{"200":{"description":"Email list: emails[], total, unread, mailbox, filtered, returned","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"data":{"type":"object","properties":{"emails":{"type":"array","items":{"type":"object","properties":{"uid":{"type":"integer"},"message_id":{"type":"string"},"subject":{"type":"string"},"from":{"type":"object"},"to":{"type":"array"},"date":{"type":"string"},"is_read":{"type":"boolean"},"is_flagged":{"type":"boolean"},"has_attachments":{"type":"boolean"},"size_bytes":{"type":"integer"}}}},"total":{"type":"integer"},"unread":{"type":"integer"},"mailbox":{"type":"string"}}}}}}}},"401":{"description":"Authentication failed"},"402":{"description":"Payment required"}}}},"/email/read":{"post":{"summary":"Read full email content via IMAP ($0.003)","description":"Read the complete content of a single email including body (text + HTML), headers, and attachments metadata. Identify email by uid (from /email/inbox) or message_id. Gmail requires App Password.","tags":["Email"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["account","password"],"properties":{"account":{"type":"string","description":"Email address"},"password":{"type":"string","description":"Password or App Password"},"uid":{"type":"integer","description":"Email UID (from /email/inbox response)"},"message_id":{"type":"string","description":"Message-ID header value (alternative to uid)"},"mailbox":{"type":"string","default":"INBOX","description":"Mailbox name"},"mark_read":{"type":"boolean","default":false,"description":"Mark email as read after fetching"},"imap_host":{"type":"string","description":"Override IMAP host"},"imap_port":{"type":"integer","description":"Override IMAP port"}}}}}},"responses":{"200":{"description":"Full email: subject, from, to, cc, bcc, date, text, html, attachments[], headers, size_bytes"},"401":{"description":"Authentication failed"},"402":{"description":"Payment required"},"404":{"description":"Email not found"}}}},"/ip/geolocation":{"get":{"summary":"IP geolocation lookup","tags":["Utils"],"parameters":[{"name":"ip","in":"query","schema":{"type":"string"},"description":"IP address (IPv4 or IPv6). If omitted, uses request IP."}],"responses":{"200":{"description":"Geolocation data: country, region, city, lat/lng, timezone"},"402":{"description":"Payment required"}}}},"/currency/convert":{"get":{"summary":"Currency conversion via ECB rates","tags":["Utils"],"parameters":[{"name":"from","in":"query","schema":{"type":"string","default":"USD"}},{"name":"to","in":"query","schema":{"type":"string","default":"BRL"}},{"name":"amount","in":"query","schema":{"type":"number","default":1}}],"responses":{"200":{"description":"Converted amount with rate info"},"402":{"description":"Payment required"}}}},"/translate":{"post":{"summary":"Translate text (up to 5000 chars)","tags":["Utils"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string","maxLength":5000},"from":{"type":"string","default":"auto"},"to":{"type":"string"}},"required":["text","to"]}}}},"responses":{"200":{"description":"Translated text"},"402":{"description":"Payment required"}}}},"/chart/generate":{"post":{"summary":"Generate chart image","tags":["Utils"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","enum":["bar","line","pie","doughnut","radar","polarArea","scatter","bubble","horizontalBar"],"default":"bar"},"data":{"type":"object","description":"Chart.js data object with labels and datasets"},"options":{"type":"object","description":"Chart.js options object (optional)"},"width":{"type":"integer","default":600},"height":{"type":"integer","default":400},"format":{"type":"string","enum":["png","webp","svg"],"default":"png"}},"required":["type","data"]}}}},"responses":{"200":{"description":"Chart image URL and base64"},"402":{"description":"Payment required"}}}},"/whois":{"post":{"summary":"WHOIS domain lookup (registrar, expiration, nameservers)","tags":["Utils"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string","description":"Domain to query (e.g. example.com). https:// and paths are stripped automatically."}},"required":["domain"]}}}},"responses":{"200":{"description":"WHOIS data: registrar, creation/expiration dates, nameservers, status"},"402":{"description":"Payment required"}}}},"/dns/lookup":{"post":{"summary":"DNS record lookup (A, AAAA, MX, TXT, CNAME, NS, SOA)","tags":["Utils"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string","description":"Domain to query (e.g. example.com)"},"types":{"type":"array","items":{"type":"string","enum":["A","AAAA","MX","TXT","CNAME","NS","SOA","PTR"]},"default":["A","AAAA","MX","TXT","CNAME","NS"],"description":"Record types to query (max 8)"}},"required":["domain"]}}}},"responses":{"200":{"description":"DNS records per type"},"402":{"description":"Payment required"}}}},"/browser/act":{"post":{"summary":"Browser automation with Playwright actions","tags":["Web"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","description":"Starting URL"},"actions":{"type":"array","description":"Sequence of browser actions","items":{"type":"object","properties":{"type":{"type":"string","enum":["click","type","press","wait","waitForSelector","navigate","extract","screenshot","evaluate","select"]},"selector":{"type":"string"},"text":{"type":"string"},"key":{"type":"string"},"ms":{"type":"integer"},"attribute":{"type":"string","default":"textContent"},"multiple":{"type":"boolean","default":false},"url":{"type":"string"},"script":{"type":"string"},"value":{"type":"string"}},"required":["type"]}},"waitUntil":{"type":"string","enum":["domcontentloaded","networkidle"],"default":"domcontentloaded"}},"required":["url"]}}}},"responses":{"200":{"description":"Action results array"},"402":{"description":"Payment required"}}}},"/extract":{"post":{"summary":"Structured web extraction (Readability + optional schema)","tags":["Web"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"},"schema":{"type":"object","description":"Optional CSS-selector schema to extract specific fields"},"wait_for":{"type":"integer","default":2000}},"required":["url"]}}}},"responses":{"200":{"description":"Extracted content: title, description, markdown, links, images, word_count"},"402":{"description":"Payment required"}}}},"/extract/structured":{"post":{"summary":"Extract structured data from URL using JSON schema + LLM","tags":["Web"],"description":"Scrape a URL and extract specific fields defined by a JSON schema using GPT-4o-mini. Perfect for extracting product info, prices, contact details, etc. from any webpage. $0.010/request.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url","schema"],"properties":{"url":{"type":"string","description":"URL of the page to extract data from"},"schema":{"type":"object","description":"JSON object describing fields to extract. Keys are field names, values are types (string, number, boolean, array)"},"instructions":{"type":"string","description":"Optional extra instructions for the extractor (e.g. \"prices should be in USD\")"}}}}}},"responses":{"200":{"description":"Extracted structured data","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"data":{"type":"object","description":"Extracted fields matching the provided schema"},"url":{"type":"string"},"model":{"type":"string"},"tokens":{"type":"integer"}}}}}},"400":{"description":"Missing url or schema"},"402":{"description":"Payment required"},"422":{"description":"Page content too short to extract"},"502":{"description":"Failed to scrape URL"},"503":{"description":"OpenAI not configured"}}}},"/crawl":{"post":{"summary":"Crawl website (BFS) and extract content from multiple pages","tags":["Web"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","description":"Starting URL"},"max_pages":{"type":"integer","default":5,"description":"Max pages to crawl (max 20)"},"same_domain":{"type":"boolean","default":true,"description":"Only follow same-domain links"},"include_pattern":{"type":"string","description":"Regex to include URLs (optional)"},"exclude_pattern":{"type":"string","description":"Regex to exclude URLs (optional)"}},"required":["url"]}}}},"responses":{"200":{"description":"Crawl results with pages array"},"402":{"description":"Payment required"}}}},"/audio/transcribe":{"post":{"summary":"Transcribe audio to text (OpenAI Whisper)","tags":["Audio"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","description":"Public URL of audio file"},"language":{"type":"string","default":"en"}},"required":["url"]}}}},"responses":{"200":{"description":"Transcription text"},"402":{"description":"Payment required"}}}},"/spreadsheet/generate":{"post":{"summary":"Generate Excel/CSV spreadsheet","tags":["Utils"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"format":{"type":"string","enum":["xlsx","csv"],"default":"xlsx"},"filename":{"type":"string"},"sheets":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"headers":{"type":"array","items":{"type":"string"}},"rows":{"type":"array"}}}}},"required":["sheets"]}}}},"responses":{"200":{"description":"Spreadsheet URL or base64"},"402":{"description":"Payment required"}}}},"/whatsapp/send":{"post":{"summary":"Send WhatsApp template message","tags":["WhatsApp"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"to":{"type":"string","description":"Phone number with country code"},"callback_url":{"type":"string"},"max_hours":{"type":"integer","default":24}},"required":["to"]}}}},"responses":{"200":{"description":"Message sent, conversation started"},"402":{"description":"Payment required"}}}},"/whatsapp/reply":{"post":{"summary":"Send reply in active WhatsApp conversation","tags":["WhatsApp"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"conversation_id":{"type":"string"},"message":{"type":"string"}},"required":["conversation_id","message"]}}}},"responses":{"200":{"description":"Reply sent"},"402":{"description":"Payment required"}}}},"/code_execute":{"post":{"summary":"Execute code in sandbox (Python/JS/Bash)","tags":["Utils"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"language":{"type":"string","enum":["python","javascript","bash"]},"code":{"type":"string"}},"required":["language","code"]}}}},"responses":{"200":{"description":"stdout, stderr, result"},"402":{"description":"Payment required"},"501":{"description":"Not yet implemented"}}}},"/calendar/holidays":{"get":{"summary":"Public holidays by country and year","tags":["Utils"],"parameters":[{"name":"year","in":"query","schema":{"type":"integer","default":2026},"description":"Year (defaults to current year)"},{"name":"countryCode","in":"query","schema":{"type":"string","default":"US"},"description":"ISO 3166-1 alpha-2 country code (e.g. US, BR, DE)"}],"responses":{"200":{"description":"List of public holidays with date, name, localName, types"},"402":{"description":"Payment required"}}}},"/sentiment":{"post":{"summary":"Analyze text sentiment","description":"Analyze sentiment of text (positive/negative/neutral) with AFINN score","tags":["Text"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["text"],"properties":{"text":{"type":"string","description":"Text to analyze (max 10000 chars)"}}}}}},"responses":{"200":{"description":"Sentiment result","content":{"application/json":{"schema":{"type":"object","properties":{"sentiment":{"type":"string","enum":["positive","negative","neutral"]},"score":{"type":"number"},"comparative":{"type":"number"},"positive":{"type":"array","items":{"type":"string"}},"negative":{"type":"array","items":{"type":"string"}}}}}}},"402":{"description":"Payment required"}}}},"/summarize":{"post":{"summary":"Extractive text summarization","description":"Extract key sentences from any text or URL using TF-IDF scoring. Returns top-N sentences in original order.","tags":["Text"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string","description":"Text to summarize (max 50000 chars)"},"url":{"type":"string","description":"URL to fetch and summarize (alternative to text)"},"sentences":{"type":"integer","description":"Number of sentences in summary (default 3, max 10)","default":3}}}}}},"responses":{"200":{"description":"Summary result","content":{"application/json":{"schema":{"type":"object","properties":{"summary":{"type":"string"},"sentences":{"type":"integer"},"original_length":{"type":"integer"},"compression_ratio":{"type":"number"}}}}}},"402":{"description":"Payment required"}}}},"/text/chunk":{"post":{"summary":"Split text into chunks for RAG pipelines","description":"Split any text into overlapping chunks using token, sentence, or paragraph strategies. Runs entirely locally - zero external API calls. Ideal as preprocessing step before /embeddings in RAG pipelines. Max 500,000 chars.","tags":["Text"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["text"],"properties":{"text":{"type":"string","description":"Text to chunk (max 500,000 chars)"},"chunk_size":{"type":"integer","default":500,"description":"Approximate tokens per chunk (1 token ≈ 4 chars), default 500"},"overlap":{"type":"integer","default":50,"description":"Approximate overlap tokens between consecutive chunks, default 50"},"strategy":{"type":"string","enum":["token","sentence","paragraph"],"default":"sentence","description":"Chunking strategy: token (fixed-size), sentence (group complete sentences), paragraph (group paragraphs)"}}}}}},"responses":{"200":{"description":"Chunked text","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"data":{"type":"object","properties":{"chunks":{"type":"array","items":{"type":"string"}},"count":{"type":"integer"},"strategy":{"type":"string"},"avg_length":{"type":"integer"}}}}}}}},"400":{"description":"Invalid input"},"402":{"description":"Payment required"}}}},"/text/stats":{"post":{"summary":"Text statistics analysis","description":"Analyze any text for statistics: word count, character count, sentence count, paragraph count, reading time, unique words, and average word length. Runs entirely locally - no external API calls.","tags":["Text"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["text"],"properties":{"text":{"type":"string","description":"Text to analyze (max 50000 chars)"}}}}}},"responses":{"200":{"description":"Text statistics","content":{"application/json":{"schema":{"type":"object","properties":{"words":{"type":"integer"},"characters":{"type":"integer"},"characters_no_spaces":{"type":"integer"},"sentences":{"type":"integer"},"paragraphs":{"type":"integer"},"unique_words":{"type":"integer"},"avg_word_length":{"type":"number"},"reading_time_seconds":{"type":"integer"},"reading_time_label":{"type":"string"}}}}}},"402":{"description":"Payment required"}}}},"/embeddings":{"post":{"summary":"Generate text embeddings (OpenAI)","description":"Generate vector embeddings for one or more text strings using OpenAI text-embedding-3-small (default) or text-embedding-3-large. Returns float arrays ready for semantic search, clustering, or RAG pipelines.","tags":["Text"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["text"],"properties":{"text":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"},"maxItems":100}],"description":"Text string or array of strings to embed (max 100 strings, 8191 tokens each)"},"model":{"type":"string","enum":["small","large"],"default":"small","description":"small = text-embedding-3-small (1536 dims, $0.001), large = text-embedding-3-large (3072 dims)"}}}}}},"responses":{"200":{"description":"Embeddings array","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"data":{"type":"object","properties":{"embeddings":{"type":"array","items":{"type":"array","items":{"type":"number"}}},"model":{"type":"string"},"tokens":{"type":"integer"},"dimensions":{"type":"integer"},"count":{"type":"integer"}}}}}}}},"400":{"description":"Invalid input"},"402":{"description":"Payment required"},"503":{"description":"OpenAI unavailable"}}}},"/memory/upsert":{"post":{"summary":"Upsert vector memory (RAG store)","description":"Store or update a text document with vector embedding in a namespace. Uses OpenAI text-embedding-3-small (1536 dims). Namespace is automatically isolated per API key. $0.003 per upsert.","tags":["Memory"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["namespace","id","text"],"properties":{"namespace":{"type":"string","description":"Logical namespace (e.g. my-agent, user-facts)"},"id":{"type":"string","description":"Unique document ID within namespace"},"text":{"type":"string","description":"Text content to embed and store"},"metadata":{"type":"object","description":"Optional metadata object (key-value pairs)"}}}}}},"responses":{"200":{"description":"Upserted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"data":{"type":"object","properties":{"id":{"type":"string"},"namespace":{"type":"string"},"tokens":{"type":"integer"},"dimensions":{"type":"integer"}}}}}}}},"400":{"description":"Missing required fields"},"402":{"description":"Payment required"},"503":{"description":"Embeddings service unavailable"}}}},"/memory/search":{"post":{"summary":"Search vector memory (semantic)","description":"Search stored documents by semantic similarity using cosine similarity on vector embeddings. Returns top_k most relevant results with scores. $0.002 per search.","tags":["Memory"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["namespace","query"],"properties":{"namespace":{"type":"string","description":"Namespace to search in"},"query":{"type":"string","description":"Natural language search query"},"top_k":{"type":"integer","default":5,"description":"Number of results to return (default: 5, max: 100)"}}}}}},"responses":{"200":{"description":"Search results","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"data":{"type":"object","properties":{"results":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"text":{"type":"string"},"score":{"type":"number"},"metadata":{"type":"object"}}}},"count":{"type":"integer"}}}}}}}},"400":{"description":"Missing required fields"},"402":{"description":"Payment required"},"503":{"description":"Embeddings service unavailable"}}}},"/document/ocr":{"post":{"summary":"AI Document OCR (Mistral)","description":"Extract text, markdown, and tables from images or PDFs using Mistral AI OCR (mistral-ocr-latest). Handles scanned PDFs, forms, invoices, and complex tables. Fallback to Google Vision if Mistral unavailable. $0.015/request.","tags":["Document"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"image":{"type":"string","description":"Image as base64 (data:image/... or raw) or public URL. Supports JPEG, PNG."},"pdf":{"type":"string","description":"PDF as base64 (data:application/pdf;base64,...) or public URL."},"pages":{"type":"array","items":{"type":"integer"},"description":"Optional page indices to process (0-based). Default: all pages."}}}}}},"responses":{"200":{"description":"OCR result","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"data":{"type":"object","properties":{"text":{"type":"string","description":"Plain text extracted"},"markdown":{"type":"string","description":"Markdown-formatted text (preserves tables, headings)"},"tables":{"type":"array","items":{"type":"object"},"description":"Extracted tables as structured objects"},"pages":{"type":"integer","description":"Number of pages processed"},"model":{"type":"string","description":"Model used (mistral-ocr-latest or google-vision-document-text)"}}}}}}}},"400":{"description":"Bad request (missing image/pdf or invalid params)"},"402":{"description":"Payment required"},"503":{"description":"No OCR provider available"}}}},"/document/sign/request":{"post":{"summary":"Create document signing envelope","description":"Create a signature request envelope and send to signers via email. Supports DocuSign, Dropbox Sign (HelloSign), or demo mode. $0.050/request.","tags":["Document"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["pdf_url","signers"],"properties":{"pdf_url":{"type":"string","description":"Public URL to the PDF document to sign"},"signers":{"type":"array","items":{"type":"object","required":["name","email"],"properties":{"name":{"type":"string"},"email":{"type":"string"},"role":{"type":"string","description":"Signer role (e.g. signer, approver). Default: signer"}}},"description":"List of signers (max 10)"},"title":{"type":"string","description":"Document title / email subject"},"message":{"type":"string","description":"Message to include in signing email"}}}}}},"responses":{"200":{"description":"Envelope created","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"data":{"type":"object","properties":{"envelope_id":{"type":"string"},"provider":{"type":"string","enum":["docusign","dropbox_sign","demo"]},"status":{"type":"string"},"signers":{"type":"array","items":{"type":"object"}},"created_at":{"type":"string"}}}}}}}},"400":{"description":"Invalid input"},"402":{"description":"Payment required"}}}},"/document/sign/status":{"get":{"summary":"Check document signing status","description":"Check the status of a signature request envelope. Returns signer statuses and completion info. $0.001/request.","tags":["Document"],"parameters":[{"name":"envelope_id","in":"query","required":true,"schema":{"type":"string"},"description":"Envelope ID returned from /document/sign/request"}],"responses":{"200":{"description":"Envelope status","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"data":{"type":"object","properties":{"envelope_id":{"type":"string"},"provider":{"type":"string"},"status":{"type":"string"},"signers":{"type":"array","items":{"type":"object"}},"created_at":{"type":"string"},"completed_at":{"type":"string","nullable":true}}}}}}}},"400":{"description":"Missing envelope_id"},"402":{"description":"Payment required"}}}},"/memory/clear":{"delete":{"summary":"Clear memory namespace","description":"Delete all stored vectors in a namespace. This action is irreversible. $0.001 per clear.","tags":["Memory"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["namespace"],"properties":{"namespace":{"type":"string","description":"Namespace to clear"}}}}}},"responses":{"200":{"description":"Namespace cleared","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"data":{"type":"object","properties":{"deleted":{"type":"integer"},"namespace":{"type":"string"}}}}}}}},"400":{"description":"Missing namespace"},"402":{"description":"Payment required"}}}},"/memory/kv/set":{"post":{"summary":"Set a KV memory entry","description":"Store a key-value pair in persistent memory, isolated per API key. Value can be any JSON-serializable data. Automatically generates embedding for semantic search. Namespace is optional (default: \"default\"). $0.001 per set.","tags":["Memory"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["key","value"],"properties":{"key":{"type":"string","description":"Unique key within namespace"},"value":{"description":"Any JSON-serializable value to store"},"namespace":{"type":"string","default":"default","description":"Logical namespace to scope the key"}}}}}},"responses":{"200":{"description":"Stored successfully","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"data":{"type":"object","properties":{"key":{"type":"string"},"namespace":{"type":"string"},"set":{"type":"boolean"}}}}}}}},"400":{"description":"Missing key or value"},"402":{"description":"Payment required"}}}},"/memory/kv/get":{"get":{"summary":"Get a KV memory entry","description":"Retrieve a previously stored key-value pair by key and namespace. Returns 404 if not found. $0.001 per get.","tags":["Memory"],"parameters":[{"name":"key","in":"query","required":true,"schema":{"type":"string"},"description":"Key to retrieve"},{"name":"namespace","in":"query","required":false,"schema":{"type":"string","default":"default"},"description":"Namespace to look up in"}],"responses":{"200":{"description":"Key found","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"data":{"type":"object","properties":{"key":{"type":"string"},"value":{"description":"Stored value (any type)"},"namespace":{"type":"string"},"created_at":{"type":"integer"},"updated_at":{"type":"integer"}}}}}}}},"400":{"description":"Missing key"},"402":{"description":"Payment required"},"404":{"description":"Key not found"}}}},"/memory/kv/delete":{"delete":{"summary":"Delete a KV memory entry","description":"Delete a specific key from persistent memory. Returns whether the key existed. $0.001 per delete.","tags":["Memory"],"parameters":[{"name":"key","in":"query","required":true,"schema":{"type":"string"},"description":"Key to delete"},{"name":"namespace","in":"query","required":false,"schema":{"type":"string","default":"default"},"description":"Namespace of the key"}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"data":{"type":"object","properties":{"deleted":{"type":"boolean"},"key":{"type":"string"},"namespace":{"type":"string"}}}}}}}},"400":{"description":"Missing key"},"402":{"description":"Payment required"}}}},"/memory/kv/search":{"post":{"summary":"Semantic search over KV memory","description":"Search your stored key-value pairs by semantic similarity. Uses OpenAI embeddings + cosine similarity to find the most relevant entries for the query. $0.002 per search.","tags":["Memory"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["query"],"properties":{"query":{"type":"string","description":"Natural language search query"},"namespace":{"type":"string","default":"default","description":"Namespace to search in"},"limit":{"type":"integer","default":10,"description":"Max results to return (max: 100)"}}}}}},"responses":{"200":{"description":"Search results","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"data":{"type":"object","properties":{"results":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"value":{"description":"Stored value"},"score":{"type":"number","description":"Cosine similarity score 0-1"}}}},"count":{"type":"integer"}}}}}}}},"400":{"description":"Missing query"},"402":{"description":"Payment required"}}}},"/sheets/read":{"get":{"summary":"Read data from Google Sheets","description":"Read rows from a Google Spreadsheet. Returns headers and rows as objects. Supports optional range parameter (e.g. Sheet1!A1:Z100).","tags":["Sheets"],"parameters":[{"name":"spreadsheet_id","in":"query","required":true,"schema":{"type":"string"},"description":"Google Spreadsheet ID (from the URL)"},{"name":"range","in":"query","required":false,"schema":{"type":"string"},"description":"Sheet range (e.g. Sheet1 or Sheet1!A1:Z100). Default: Sheet1"}],"responses":{"200":{"description":"Sheet data","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"data":{"type":"object","properties":{"headers":{"type":"array","items":{"type":"string"}},"rows":{"type":"array","items":{"type":"object"}},"total":{"type":"integer"},"range":{"type":"string"}}}}}}}},"400":{"description":"Missing spreadsheet_id"},"402":{"description":"Payment required"},"500":{"description":"API error"}}}},"/sheets/write":{"post":{"summary":"Write data to Google Sheets","description":"Write or append rows to an existing Google Spreadsheet. Use mode=overwrite (default) to replace data at range, or mode=append to add rows below existing data.","tags":["Sheets"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["spreadsheet_id","values"],"properties":{"spreadsheet_id":{"type":"string","description":"Google Spreadsheet ID"},"range":{"type":"string","description":"Sheet range (e.g. Sheet1!A1). Default: Sheet1"},"values":{"type":"array","items":{"type":"array"},"description":"2D array of values to write"},"mode":{"type":"string","enum":["overwrite","append"],"default":"overwrite","description":"Write mode: overwrite replaces, append adds rows"}}}}}},"responses":{"200":{"description":"Write result","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"data":{"type":"object","properties":{"updated_rows":{"type":"integer"}}}}}}}},"400":{"description":"Missing required fields"},"402":{"description":"Payment required"}}}},"/sheets/create":{"post":{"summary":"Create new Google Spreadsheet","description":"Create a new Google Spreadsheet with optional title and headers. Returns spreadsheet ID and shareable URL. Sheet is automatically made publicly viewable.","tags":["Sheets"],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string","description":"Spreadsheet title (default: IteraTools Sheet)"},"headers":{"type":"array","items":{"type":"string"},"description":"Optional column headers for first row"}}}}}},"responses":{"200":{"description":"Created spreadsheet","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"data":{"type":"object","properties":{"spreadsheet_id":{"type":"string"},"url":{"type":"string"},"title":{"type":"string"}}}}}}}},"402":{"description":"Payment required"}}}},"/calendar/event":{"post":{"summary":"Create Google Calendar event ($0.002)","description":"Create a new event in Google Calendar. Auth: pass google_service_account_json (base64 service account JSON) OR google_oauth_token (OAuth2 access token). No state stored server-side.","tags":["Calendar"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["title","start"],"properties":{"google_service_account_json":{"type":"string","description":"Base64-encoded Google Service Account JSON with calendar scope"},"google_oauth_token":{"type":"string","description":"OAuth2 access token with Google Calendar scope"},"calendar_id":{"type":"string","default":"primary","description":"Calendar ID (default: primary)"},"title":{"type":"string","description":"Event title (required)"},"start":{"type":"string","description":"ISO 8601 start datetime (required)"},"end":{"type":"string","description":"ISO 8601 end datetime (optional; if omitted, uses duration_minutes or defaults to 1h)"},"duration_minutes":{"type":"integer","description":"Duration in minutes (used if end is not provided)"},"description":{"type":"string"},"attendees":{"type":"array","items":{"type":"string"},"description":"Attendee email addresses"},"location":{"type":"string"},"timezone":{"type":"string","description":"IANA timezone (default: UTC)"}}}}}},"responses":{"200":{"description":"Event created"},"400":{"description":"Missing required fields or invalid auth"},"401":{"description":"Invalid Google credentials"},"402":{"description":"Payment required"}}}},"/calendar/event/{id}":{"delete":{"summary":"Delete Google Calendar event ($0.002)","description":"Delete a specific event from Google Calendar by its ID. Auth: google_service_account_json (base64) or google_oauth_token in request body.","tags":["Calendar"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Google Calendar event ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"google_service_account_json":{"type":"string"},"google_oauth_token":{"type":"string"},"calendar_id":{"type":"string","default":"primary"}}}}}},"responses":{"200":{"description":"Event deleted"},"400":{"description":"Missing auth"},"402":{"description":"Payment required"},"404":{"description":"Event not found"}}}},"/calendar/events":{"get":{"summary":"List Google Calendar events ($0.001)","description":"List events in a Google Calendar for a time range. Auth via query params: google_service_account_json (base64) or google_oauth_token.","tags":["Calendar"],"parameters":[{"name":"google_service_account_json","in":"query","schema":{"type":"string"},"description":"Base64-encoded service account JSON"},{"name":"google_oauth_token","in":"query","schema":{"type":"string"},"description":"OAuth2 access token"},{"name":"calendar_id","in":"query","schema":{"type":"string","default":"primary"}},{"name":"start","in":"query","required":true,"schema":{"type":"string"},"description":"Start datetime/date (ISO 8601 or YYYY-MM-DD)"},{"name":"end","in":"query","required":true,"schema":{"type":"string"},"description":"End datetime/date (ISO 8601 or YYYY-MM-DD)"},{"name":"max_results","in":"query","schema":{"type":"integer","default":50}},{"name":"q","in":"query","schema":{"type":"string"},"description":"Free-text search query"}],"responses":{"200":{"description":"Events list"},"400":{"description":"Missing required params"},"402":{"description":"Payment required"}}}},"/calendar/availability":{"get":{"summary":"List free slots in Google Calendar ($0.001)","description":"Check free/busy for a calendar and return both busy blocks and computed free slots. Auth via query params: google_service_account_json (base64) or google_oauth_token.","tags":["Calendar"],"parameters":[{"name":"google_service_account_json","in":"query","schema":{"type":"string"}},{"name":"google_oauth_token","in":"query","schema":{"type":"string"}},{"name":"calendar_id","in":"query","schema":{"type":"string","default":"primary"}},{"name":"days","in":"query","schema":{"type":"integer","default":7},"description":"Number of days ahead to check (default: 7)"},{"name":"start","in":"query","schema":{"type":"string"},"description":"Override start datetime (ISO 8601 or YYYY-MM-DD)"},{"name":"end","in":"query","schema":{"type":"string"},"description":"Override end datetime (ISO 8601 or YYYY-MM-DD)"},{"name":"timezone","in":"query","schema":{"type":"string","default":"UTC"},"description":"IANA timezone for slot computation"},{"name":"slot_minutes","in":"query","schema":{"type":"integer","default":60},"description":"Slot duration in minutes (default: 60)"}],"responses":{"200":{"description":"busy_slots, free_slots, is_free"},"400":{"description":"Missing auth"},"402":{"description":"Payment required"}}}},"/calendar/event/delete":{"delete":{"summary":"Delete Google Calendar event - alias ($0.002)","description":"Alias for DELETE /calendar/event/{id} when passing event_id in body. Auth: google_service_account_json (base64) or google_oauth_token.","tags":["Calendar"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["event_id"],"properties":{"google_service_account_json":{"type":"string"},"google_oauth_token":{"type":"string"},"calendar_id":{"type":"string","default":"primary"},"event_id":{"type":"string"}}}}}},"responses":{"200":{"description":"Event deleted"},"400":{"description":"Missing auth or event_id"},"402":{"description":"Payment required"},"404":{"description":"Event not found"}}}},"/markdown/render":{"post":{"summary":"Convert Markdown to HTML","description":"Convert Markdown text to HTML using the marked library. Supports standard CommonMark syntax including headings, bold, italic, lists, links, code blocks, and tables. Runs entirely locally - no external API calls.","tags":["Text"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["markdown"],"properties":{"markdown":{"type":"string","description":"Markdown text to convert (max 100000 chars)"},"sanitize":{"type":"boolean","default":true,"description":"Whether to sanitize output (default: true, marked v9+ is safe by default)"}}}}}},"responses":{"200":{"description":"HTML result","content":{"application/json":{"schema":{"type":"object","properties":{"html":{"type":"string","description":"Rendered HTML string"},"input_length":{"type":"integer","description":"Length of input markdown"},"output_length":{"type":"integer","description":"Length of output HTML"}}}}}},"400":{"description":"Missing or invalid markdown field"},"402":{"description":"Payment required"}}}},"/github/repo":{"get":{"summary":"Get GitHub repository details","description":"Fetch details for a GitHub repository including stars, forks, language, topics, and last commit. Uses system token if no user token provided.","tags":["GitHub"],"parameters":[{"name":"owner","in":"query","required":true,"schema":{"type":"string"},"description":"Repository owner (user or org)"},{"name":"repo","in":"query","required":true,"schema":{"type":"string"},"description":"Repository name"},{"name":"token","in":"query","required":false,"schema":{"type":"string"},"description":"GitHub PAT (optional, increases rate limit to 5000/h)"}],"responses":{"200":{"description":"Repository details: name, description, stars, forks, language, topics, last_commit"},"401":{"description":"Invalid token"},"402":{"description":"Payment required"},"403":{"description":"Rate limit exceeded"},"404":{"description":"Repository not found"}}}},"/github/search":{"get":{"summary":"Search GitHub repositories","description":"Search GitHub repositories using the GitHub Search API. Supports sorting by stars, forks, or updated date.","tags":["GitHub"],"parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string"},"description":"Search query (e.g. \"language:python stars:>1000\")"},{"name":"sort","in":"query","required":false,"schema":{"type":"string","enum":["stars","forks","updated","help-wanted-issues"],"default":"stars"},"description":"Sort field"},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","maximum":30,"default":10},"description":"Results per page (max 30)"}],"responses":{"200":{"description":"Search results: total_count, returned, items with name, url, stars, description"},"402":{"description":"Payment required"},"403":{"description":"Rate limit exceeded"}}}},"/github/issue":{"post":{"summary":"Create a GitHub issue","description":"Create a new issue on a GitHub repository. Requires a GitHub PAT with repo scope.","tags":["GitHub"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["owner","repo","title","token"],"properties":{"owner":{"type":"string","description":"Repository owner"},"repo":{"type":"string","description":"Repository name"},"title":{"type":"string","description":"Issue title"},"body":{"type":"string","description":"Issue body (markdown)"},"labels":{"type":"array","items":{"type":"string"},"description":"Labels to apply"},"token":{"type":"string","description":"GitHub PAT with repo scope (required)"}}}}}},"responses":{"200":{"description":"Created issue: issue_number, url, title, state"},"400":{"description":"Missing required fields"},"401":{"description":"Invalid token"},"402":{"description":"Payment required"},"403":{"description":"Forbidden (check token permissions)"},"404":{"description":"Repository not found"}}}},"/document/convert":{"post":{"summary":"Convert documents between formats","tags":["Document"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","description":"Public URL of document to convert"},"content":{"type":"string","description":"Document content (text or base64 for binary formats)"},"from_format":{"type":"string","enum":["docx","pptx","html","md","pdf"],"description":"Source format"},"to_format":{"type":"string","enum":["pdf","docx","html","md"],"description":"Target format"}},"required":["from_format","to_format"]}}}},"responses":{"200":{"description":"Converted document URL"},"402":{"description":"Payment required"}}}},"/github/file/read":{"post":{"summary":"Read file content from GitHub","description":"Read the decoded text content of a file in a GitHub repository. Uses system token for public repos if no user token provided.","tags":["GitHub"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["owner","repo","path"],"properties":{"owner":{"type":"string","description":"Repository owner"},"repo":{"type":"string","description":"Repository name"},"path":{"type":"string","description":"File path within repository (e.g. src/index.js)"},"ref":{"type":"string","description":"Branch, tag, or commit SHA (default: default branch)"},"token":{"type":"string","description":"GitHub PAT (optional for public repos)"}}}}}},"responses":{"200":{"description":"File content: path, sha, size, content (decoded text), url"},"400":{"description":"Missing required fields or path is a directory"},"401":{"description":"Invalid token"},"402":{"description":"Payment required"},"403":{"description":"Rate limit exceeded"},"404":{"description":"File not found"}}}},"/hash":{"post":{"summary":"Cryptographic hash generation","description":"Generate a cryptographic hash of any text using MD5, SHA-1, SHA-256, SHA-384, or SHA-512. Returns both hex and base64 encodings. Uses Node.js native crypto - no external API, zero latency.","tags":["Utilities"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["text"],"properties":{"text":{"type":"string","description":"Text to hash"},"algorithm":{"type":"string","enum":["md5","sha1","sha256","sha384","sha512"],"default":"sha256","description":"Hash algorithm (default: sha256)"}}}}}},"responses":{"200":{"description":"Hash result: hash, algorithm, input_length, hex, base64"},"400":{"description":"Missing text or invalid algorithm"},"402":{"description":"Payment required"}}}},"/time/convert":{"post":{"summary":"Timezone conversion","description":"Convert a datetime from one timezone to another using IANA timezone names. No external API - uses native Intl. Supports ISO 8601 input and ISO/unix/human output formats.","tags":["Utilities"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["datetime","from_tz","to_tz"],"properties":{"datetime":{"type":"string","description":"Datetime as ISO 8601 string (e.g. 2026-03-27T17:00:00) or Unix timestamp integer"},"from_tz":{"type":"string","description":"Source IANA timezone (e.g. UTC, America/New_York)"},"to_tz":{"type":"string","description":"Target IANA timezone (e.g. America/Sao_Paulo, Europe/London)"},"format":{"type":"string","enum":["iso","unix","human"],"default":"iso","description":"Output format: iso (default), unix (epoch seconds), human (readable string)"}}}}}},"responses":{"200":{"description":"Conversion result with input, output (datetime, utc_offset, display), and utc fields"},"400":{"description":"Missing or invalid parameters"},"402":{"description":"Payment required"}}}},"/time/timezones":{"get":{"summary":"List IANA timezones","description":"Return a curated list of valid IANA timezone names usable with /time/convert.","tags":["Utilities"],"responses":{"200":{"description":"Array of IANA timezone strings and count"},"402":{"description":"Payment required"}}}},"/text/regex":{"post":{"summary":"Test and extract with regex patterns","description":"Test regex patterns, find matches, extract groups, or perform replacements. Supports named capture groups, all JS regex flags. Runs entirely locally - zero external API calls.","tags":["Text"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["pattern","text"],"properties":{"pattern":{"type":"string","description":"Regex pattern (max 500 chars)"},"text":{"type":"string","description":"Text to match against (max 100KB)"},"flags":{"type":"string","default":"","description":"Regex flags (g, i, m, s, u, y)"},"mode":{"type":"string","enum":["test","match","matchAll","replace"],"default":"matchAll","description":"Operation mode"},"replacement":{"type":"string","description":"Replacement string (required for replace mode)"}}}}}},"responses":{"200":{"description":"Regex result"},"400":{"description":"Invalid pattern or input"},"402":{"description":"Payment required"}}}},"/text/detect-language":{"post":{"summary":"Detect text language","description":"Detect the language of input text using trigram analysis. Returns ISO 639-1/3 codes, language name, confidence score, and top candidates. Runs locally - no external API calls. Max 50,000 chars.","tags":["Text"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["text"],"properties":{"text":{"type":"string","description":"Text to detect language of (max 50000 chars)"},"count":{"type":"integer","default":3,"description":"Number of candidate languages to return (max 10)"}}}}}},"responses":{"200":{"description":"Language detection result","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"data":{"type":"object","properties":{"language":{"type":"string","description":"ISO 639-1 code"},"language_name":{"type":"string"},"iso639_3":{"type":"string"},"confidence":{"type":"number"},"text_length":{"type":"integer"},"candidates":{"type":"array","items":{"type":"object"}}}}}}}}},"400":{"description":"Invalid input"},"402":{"description":"Payment required"}}}},"/http/request":{"post":{"summary":"Generic HTTP request proxy ($0.003)","description":"Make any HTTP request through IteraTools. Useful for AI agents that need to call external APIs without local configuration. SSRF protection blocks private/internal IPs. Max timeout 30s, max response 5MB.","tags":["Web"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","description":"Target URL (must be public, no private IPs)"},"method":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE","HEAD","OPTIONS"],"default":"GET"},"headers":{"type":"object","description":"Custom request headers"},"body":{"description":"Request body (object for JSON, string for raw)"},"timeout":{"type":"integer","default":30000,"maximum":30000,"description":"Timeout in ms (max 30000)"},"follow_redirects":{"type":"boolean","default":true},"response_type":{"type":"string","enum":["json","text","base64"],"default":"json","description":"How to parse response body"}}}}}},"responses":{"200":{"description":"HTTP response","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"data":{"type":"object","properties":{"status":{"type":"integer"},"status_text":{"type":"string"},"headers":{"type":"object"},"body":{"description":"Parsed response body"},"url":{"type":"string"},"redirected":{"type":"boolean"},"elapsed_ms":{"type":"integer"},"size_bytes":{"type":"integer"}}}}}}}},"400":{"description":"Invalid URL or method"},"402":{"description":"Payment required"},"403":{"description":"SSRF blocked (private IP)"},"408":{"description":"Request timeout"},"413":{"description":"Response too large (>5MB)"}}}},"/sql/query":{"post":{"summary":"Execute SQL query on remote database ($0.003)","description":"Execute a SQL query against a user-provided database. Supports PostgreSQL (pg://), MySQL (mysql://), and SQLite (sqlite:path). When read_only=true (default), destructive queries (INSERT/UPDATE/DELETE/DROP/CREATE/ALTER/TRUNCATE) are blocked. 30s timeout on all queries. Connection strings are never logged.","tags":["Database"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["connection_string","query"],"properties":{"connection_string":{"type":"string","description":"Database connection string: postgresql://user:pass@host:5432/db, mysql://user:pass@host:3306/db, or sqlite:./file.db"},"query":{"type":"string","description":"SQL query to execute"},"read_only":{"type":"boolean","default":true,"description":"Block destructive queries (INSERT/UPDATE/DELETE/DROP/CREATE/ALTER/TRUNCATE). Default: true"},"limit":{"type":"integer","default":100,"maximum":1000,"description":"Max rows to return (default 100, max 1000). Auto-appends LIMIT if not present in query."}}}}}},"responses":{"200":{"description":"Query results","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"data":{"type":"object","properties":{"columns":{"type":"array","items":{"type":"string"}},"rows":{"type":"array","items":{"type":"object"}},"row_count":{"type":"integer"},"total_affected":{"type":"integer"},"db_type":{"type":"string","enum":["postgresql","mysql","sqlite"]},"read_only":{"type":"boolean"},"elapsed_ms":{"type":"integer"}}}}}}}},"400":{"description":"Missing or invalid parameters"},"402":{"description":"Payment required"},"403":{"description":"Destructive query blocked (read_only=true)"},"500":{"description":"Database error"}}}},"/text/diff":{"post":{"summary":"Compare two texts and get structured diff","description":"Compare two text inputs line-by-line or word-by-word and return a structured diff. Supports unified patch format, JSON array of changes, or inline word-level diff. Runs entirely locally - no external API calls. $0.001/request.","tags":["Text"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["text1","text2"],"properties":{"text1":{"type":"string","description":"Original text (max 100KB)"},"text2":{"type":"string","description":"Modified text (max 100KB)"},"format":{"type":"string","enum":["unified","json","inline"],"default":"unified","description":"Output format: unified (patch), json (structured array), inline (word-level)"}}}}}},"responses":{"200":{"description":"Diff result with stats","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"data":{"type":"object","properties":{"format":{"type":"string"},"identical":{"type":"boolean"},"diff":{"description":"Diff output (string for unified, array for json/inline)"},"stats":{"type":"object","properties":{"additions":{"type":"integer"},"deletions":{"type":"integer"},"unchanged":{"type":"integer"},"total_changes":{"type":"integer"}}}}}}}}}},"400":{"description":"Invalid input"},"402":{"description":"Payment required"}}}},"/barcode/generate":{"post":{"summary":"Generate barcode","tags":["Utils"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"string","description":"Data to encode"},"type":{"type":"string","enum":["code128","code39","ean13","ean8","upca","itf14","datamatrix"],"default":"code128"},"width":{"type":"integer","default":200},"height":{"type":"integer","default":80},"includetext":{"type":"boolean","default":true}},"required":["data"]}}}},"responses":{"200":{"description":"Barcode PNG as base64"},"402":{"description":"Payment required"}}}},"/sms/send":{"post":{"summary":"Send SMS via Twilio","description":"Send an SMS message to any phone number via Twilio. Supports USA/CA ($0.012/SMS) and BR/international ($0.018/SMS). Phone number must be in E.164 format (e.g. +5548999999999).","tags":["Messaging"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["to","message"],"properties":{"to":{"type":"string","description":"Recipient phone number in E.164 format (e.g. +5548999999999)"},"message":{"type":"string","description":"SMS text (max 160 chars per segment; longer messages split into multiple segments)"}}}}}},"responses":{"200":{"description":"SMS queued: { sid, to, status, segments, price_tier }"},"400":{"description":"Invalid phone number or missing fields"},"402":{"description":"Payment required"}}}},"/json/validate":{"post":{"summary":"Validate, format, or analyze JSON","description":"Validate JSON syntax, pretty-print with configurable indent, minify, get stats (depth, key count, types), or extract a value by dot-bracket path. Runs entirely locally - instant, zero external API calls.","tags":["Utilities"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["json"],"properties":{"json":{"type":"string","description":"JSON string to process (max 100KB)"},"mode":{"type":"string","enum":["validate","format","minify","stats","get"],"default":"validate","description":"Operation mode: validate (syntax check), format (pretty-print), minify (compact), stats (structure analysis), get (extract by path)"},"indent":{"description":"Indentation for format mode: number (default: 2) or \"tab\"","default":2},"path":{"type":"string","description":"Dot-bracket path for get mode (e.g. \"user.name\", \"items[0].id\")"}}}}}},"responses":{"200":{"description":"Result with valid flag and data (formatted/stats/value depending on mode)"},"400":{"description":"Missing json field or too large"},"402":{"description":"Payment required"}}}},"/rss/fetch":{"post":{"summary":"Fetch and parse RSS/Atom feed","description":"Fetch any RSS 2.0 or Atom feed URL and return normalized structured JSON with feed metadata and items. Perfect for AI agents monitoring news, blogs, podcasts, or any content feed.","tags":["Utilities"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","description":"RSS or Atom feed URL (e.g. https://dev.to/feed)"},"limit":{"type":"number","default":10,"description":"Max items to return (default: 10, max: 50)"}}}}}},"responses":{"200":{"description":"Feed metadata and items array with title, url, published, summary, author, categories"},"400":{"description":"Missing url or invalid feed"},"402":{"description":"Payment required"},"504":{"description":"Feed fetch timeout"}}}},"/whatsapp/research/start":{"post":{"summary":"Start WhatsApp market research","tags":["WhatsApp"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["numbers","questions"],"properties":{"numbers":{"type":"array","items":{"type":"string"},"description":"Phone numbers with country code"},"questions":{"type":"array","items":{"type":"string"},"description":"Questions to ask each contact"},"callback_url":{"type":"string","description":"Optional HTTPS webhook for completion notification"}}}}}},"responses":{"200":{"description":"Research started"},"402":{"description":"Payment required"}}}},"/whatsapp/research/status":{"get":{"summary":"Get WhatsApp research status by ID","description":"Use as GET /whatsapp/research/:id - returns total, responded, pending, contacts list.","tags":["WhatsApp"],"parameters":[{"in":"query","name":"id","required":true,"schema":{"type":"string"},"description":"Research ID (res_...)"}],"responses":{"200":{"description":"Research status and contacts"},"404":{"description":"Not found"}}}},"/whatsapp/research/answer":{"post":{"summary":"Record contact answer and advance questionnaire","description":"Use as POST /whatsapp/research/:id/answer - records answer and sends next question automatically.","tags":["WhatsApp"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["number","answer"],"properties":{"number":{"type":"string","description":"Contact phone number"},"answer":{"type":"string","description":"Contact reply text"}}}}}},"responses":{"200":{"description":"Answer recorded, next question sent"},"404":{"description":"Not found"}}}},"/whatsapp/research/report":{"get":{"summary":"Get WhatsApp research structured report","description":"Use as GET /whatsapp/research/:id/report - returns all Q&A pairs per contact.","tags":["WhatsApp"],"parameters":[{"in":"query","name":"id","required":true,"schema":{"type":"string"},"description":"Research ID (res_...)"}],"responses":{"200":{"description":"Structured research report with answers"},"404":{"description":"Not found"}}}},"/whatsapp/research/agent":{"post":{"summary":"Agentic WhatsApp market research (natural language task)","description":"Pass a natural language task → discovers contacts via Google Maps, extracts questions via LLM (GPT-4o-mini), runs full WhatsApp survey automatically. Returns research_id immediately, runs async. $0.050/contact, min $0.50/job.","tags":["WhatsApp"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["task"],"properties":{"task":{"type":"string","description":"Natural language research task (e.g. \"Pesquisa 10 funilarias em Florianópolis/SC: qual o prazo médio de reparo?\")"},"max_contacts":{"type":"integer","default":10,"maximum":50,"description":"Max contacts to discover and survey (default: 10, max: 50)"},"callback_url":{"type":"string","description":"Optional HTTPS webhook for completion/error notification"}}}}}},"responses":{"200":{"description":"Agent research started","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"research_id":{"type":"string","description":"Use GET /whatsapp/research/agent/:id to poll status"},"status":{"type":"string","enum":["discovering"]},"estimated_minutes":{"type":"integer"}}}}}},"400":{"description":"Invalid input"},"402":{"description":"Payment required"}}}},"/phone/validate":{"post":{"summary":"Validate and format phone number","description":"Validate any phone number worldwide and return validity, type (mobile/fixed), country, and formatted E.164/international/national forms. Uses libphonenumber-js - no external API, zero latency.","tags":["Utils"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["phone"],"properties":{"phone":{"type":"string","description":"Phone number to validate (e.g. \"+55 48 99999-9999\" or \"11 99999-9999\")"},"country":{"type":"string","description":"Default country hint ISO 3166-1 alpha-2 (e.g. \"BR\", \"US\"). Optional."}}}}}},"responses":{"200":{"description":"Validation result with valid, possible, number_type, country, international, national, e164, uri"},"400":{"description":"Missing phone"},"402":{"description":"Payment required"}}}},"/maps/reverse":{"post":{"summary":"Reverse geocode (lat/lon → address, OSM Nominatim)","description":"Convert lat/lon coordinates to a human-readable address using OpenStreetMap Nominatim. Respects 1 req/s courtesy limit. $0.001/request.","tags":["Maps"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["lat","lon"],"properties":{"lat":{"type":"number","description":"Latitude (-90 to 90)"},"lon":{"type":"number","description":"Longitude (-180 to 180)"},"lng":{"type":"number","description":"Alias for lon"}}}}}},"responses":{"200":{"description":"Address data: display_name, lat, lon, address object, osm_id, osm_type"},"400":{"description":"Invalid or missing coordinates"},"402":{"description":"Payment required"},"404":{"description":"No address found for coordinates"}}}},"/maps/places/nearby":{"post":{"summary":"Find nearby places (Google Places API)","description":"Search for places near a lat/lon using Google Places Nearby Search API. Requires GOOGLE_MAPS_KEY. Returns name, rating, opening hours, and more. $0.003/request.","tags":["Maps"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["lat","lon"],"properties":{"lat":{"type":"number","description":"Latitude"},"lon":{"type":"number","description":"Longitude"},"lng":{"type":"number","description":"Alias for lon"},"radius":{"type":"integer","default":500,"description":"Search radius in meters (max 50000)"},"type":{"type":"string","description":"Google Place type (e.g. restaurant, cafe, hospital, hotel, pharmacy)"},"keyword":{"type":"string","description":"Optional keyword to filter results"},"limit":{"type":"integer","default":10,"description":"Max results to return (max 20)"}}}}}},"responses":{"200":{"description":"Places list with name, place_id, lat, lon, distance_m, address, rating, open_now"},"400":{"description":"Missing or invalid coordinates"},"402":{"description":"Payment required"},"503":{"description":"Google Places API not configured"}}}},"/maps/distance":{"post":{"summary":"Calculate distance between two points (Haversine)","description":"Calculate the straight-line (great-circle) distance between two lat/lon coordinates using the Haversine formula. No external API required. Returns distance in meters, km, miles, and compass bearing. $0.001/request.","tags":["Maps"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"from":{"type":"object","description":"Origin point { lat, lon }","properties":{"lat":{"type":"number"},"lon":{"type":"number"},"lng":{"type":"number","description":"Alias for lon"}},"required":["lat"]},"to":{"type":"object","description":"Destination point { lat, lon }","properties":{"lat":{"type":"number"},"lon":{"type":"number"},"lng":{"type":"number","description":"Alias for lon"}},"required":["lat"]},"from_lat":{"type":"number","description":"Origin latitude (flat param alternative)"},"from_lon":{"type":"number","description":"Origin longitude (flat param alternative)"},"from_lng":{"type":"number","description":"Alias for from_lon"},"to_lat":{"type":"number","description":"Destination latitude"},"to_lon":{"type":"number","description":"Destination longitude"},"to_lng":{"type":"number","description":"Alias for to_lon"}}}}}},"responses":{"200":{"description":"Distance result: distance_m, distance_km, distance_mi, bearing_deg, compass (N/NE/E/SE/S/SW/W/NW)"},"400":{"description":"Missing or invalid coordinates"},"402":{"description":"Payment required"}}}},"/maps/geocode":{"get":{"summary":"Geocode address to coordinates (OSM Nominatim)","description":"Convert an address or place name to lat/lng coordinates using OpenStreetMap Nominatim. Returns up to 20 results with address details. $0.002/request.","tags":["Maps"],"parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string"},"description":"Address or place name to geocode"},{"name":"country","in":"query","schema":{"type":"string"},"description":"Filter by country (ISO 3166-1 alpha-2, e.g. BR, US)"},{"name":"limit","in":"query","schema":{"type":"integer","default":5},"description":"Max results (max 20)"}],"responses":{"200":{"description":"Geocoding results with lat, lng, display_name, address"},"400":{"description":"Missing q param"},"402":{"description":"Payment required"}}}},"/maps/places":{"get":{"summary":"Find nearby places (OSM Overpass)","description":"Search for places/businesses near a lat/lng coordinate using OpenStreetMap Overpass API. Supports: restaurant, cafe, hospital, hotel, pharmacy, school, bank, atm, parking, supermarket, bar, pub, gym, park, museum, gas_station, bus_stop. $0.003/request.","tags":["Maps"],"parameters":[{"name":"lat","in":"query","required":true,"schema":{"type":"number"}},{"name":"lng","in":"query","required":true,"schema":{"type":"number"}},{"name":"type","in":"query","required":true,"schema":{"type":"string"},"description":"Place type (restaurant, cafe, hospital, hotel, etc.)"},{"name":"radius","in":"query","schema":{"type":"integer","default":500},"description":"Search radius in meters (max 5000)"},{"name":"limit","in":"query","schema":{"type":"integer","default":10},"description":"Max results (max 50)"}],"responses":{"200":{"description":"Places with name, lat, lng, distance_m, address, phone, website, opening_hours"},"400":{"description":"Missing params"},"402":{"description":"Payment required"}}}},"/maps/directions":{"get":{"summary":"Get directions/route (OSRM)","description":"Get driving, walking, or cycling directions between two coordinates using OSRM. Returns distance, duration, turn-by-turn steps, and GeoJSON geometry. $0.002/request.","tags":["Maps"],"parameters":[{"name":"from_lat","in":"query","required":true,"schema":{"type":"number"}},{"name":"from_lng","in":"query","required":true,"schema":{"type":"number"}},{"name":"to_lat","in":"query","required":true,"schema":{"type":"number"}},{"name":"to_lng","in":"query","required":true,"schema":{"type":"number"}},{"name":"mode","in":"query","schema":{"type":"string","enum":["driving","walking","cycling"],"default":"driving"}}],"responses":{"200":{"description":"Route with distance_km, duration_min, steps, GeoJSON geometry"},"400":{"description":"Missing params or no route"},"402":{"description":"Payment required"}}}},"/slack/send":{"post":{"summary":"Send Slack message","description":"Send a message to Slack via Incoming Webhook URL (simple) or Bot Token (channel required). Supports plain text and Block Kit blocks. With webhook: $0.001. With bot token: $0.001.","tags":["Messaging"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"slack_webhook_url":{"type":"string","description":"Slack Incoming Webhook URL (simple, no scopes needed)"},"slack_token":{"type":"string","description":"Slack Bot Token (xoxb-...) - requires channels:write scope"},"channel":{"type":"string","description":"Channel ID or name (required when using slack_token)"},"text":{"type":"string","description":"Message text (plain or mrkdwn)"},"blocks":{"type":"array","description":"Optional Block Kit blocks array"},"username":{"type":"string","description":"Override bot display name"},"icon_emoji":{"type":"string","description":"Override bot icon emoji (e.g. :robot_face:)"}}}}}},"responses":{"200":{"description":"{ ok: true, method: \"webhook\"|\"bot_token\", ts?, channel? }"},"400":{"description":"Missing required fields"},"402":{"description":"Payment required"}}}},"/slack/messages":{"get":{"summary":"Read Slack channel messages","description":"Fetch latest messages from a Slack channel using a Bot Token with channels:history or groups:history scope.","tags":["Messaging"],"parameters":[{"in":"query","name":"channel","required":true,"schema":{"type":"string"},"description":"Channel ID (C...) or name"},{"in":"query","name":"limit","schema":{"type":"integer","default":20,"maximum":100},"description":"Max messages to return (default 20, max 100)"},{"in":"header","name":"Authorization","required":true,"schema":{"type":"string"},"description":"Bearer it-XXXX or it-admin-2026"}],"responses":{"200":{"description":"{ ok, channel, count, messages[] with ts/text/user/type }"},"400":{"description":"Missing channel or slack_token"},"402":{"description":"Payment required"}}}},"/cron/schedule":{"post":{"summary":"Schedule a webhook callback","description":"Schedule an HTTP callback (POST/GET) to be fired at a future time. Perfect for AI agents that need delayed actions or reminders. $0.002/job.","tags":["Utils"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url","run_at"],"properties":{"url":{"type":"string","description":"Webhook URL to call (must be public, no private IPs)"},"method":{"type":"string","enum":["GET","POST","PUT","PATCH","DELETE"],"default":"POST"},"headers":{"type":"object","description":"Custom headers to send"},"body":{"type":"object","description":"Request body (for POST/PUT/PATCH)"},"run_at":{"type":"string","description":"ISO 8601 timestamp for when to fire (max 30 days from now)"},"max_retries":{"type":"integer","default":0,"minimum":0,"maximum":3,"description":"Number of retries on failure (0-3)"}}}}}},"responses":{"200":{"description":"Job scheduled: { ok, data: { job_id, url, run_at, status } }"},"400":{"description":"Invalid URL or run_at"},"402":{"description":"Payment required"},"403":{"description":"SSRF blocked"}}}},"/cron/job/{id}":{"get":{"summary":"Get scheduled webhook job status","tags":["Utils"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Job status: { ok, data: { job_id, url, run_at, status, attempts, last_attempt_at, last_status_code } }"},"402":{"description":"Payment required"},"404":{"description":"Job not found"}}}},"/cron/job/{id}/cancel":{"delete":{"summary":"Cancel scheduled webhook job","tags":["Utils"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Job cancelled or already fired"},"402":{"description":"Payment required"},"404":{"description":"Job not found"}}}},"/social/tweet":{"post":{"summary":"Post tweet on X/Twitter","description":"Post a tweet using your own Twitter API credentials (OAuth 1.0a). Requires Twitter Developer account with Basic plan ($100/mo). Optional media_url for image/GIF attachment. $0.003/tweet.","tags":["Social Media"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["text","twitter_api_key","twitter_api_secret","twitter_access_token","twitter_access_secret"],"properties":{"text":{"type":"string","description":"Tweet text (max 280 chars)"},"media_url":{"type":"string","description":"Optional image/GIF URL to attach (< 5MB)"},"twitter_api_key":{"type":"string","description":"Twitter API Key (Consumer Key)"},"twitter_api_secret":{"type":"string","description":"Twitter API Secret (Consumer Secret)"},"twitter_access_token":{"type":"string","description":"Twitter Access Token"},"twitter_access_secret":{"type":"string","description":"Twitter Access Token Secret"}}}}}},"responses":{"200":{"description":"{ ok, tweet_id, text, url, media_id }"},"400":{"description":"Missing required fields"},"402":{"description":"Payment required"}}}},"/social/linkedin":{"post":{"summary":"Post on LinkedIn","description":"Post to LinkedIn using your own OAuth2 access token (w_member_social scope). Optional title and URL for article sharing. $0.004/post.","tags":["Social Media"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["text","linkedin_access_token"],"properties":{"text":{"type":"string","description":"Post text content"},"title":{"type":"string","description":"Optional article title (used with url)"},"url":{"type":"string","description":"Optional article URL to share"},"linkedin_access_token":{"type":"string","description":"LinkedIn OAuth2 access token (w_member_social scope)"}}}}}},"responses":{"200":{"description":"{ ok, post_id, text, title, url, author_urn }"},"400":{"description":"Missing required fields"},"402":{"description":"Payment required"}}}},"/slack/channel/create":{"post":{"summary":"Create Slack channel","description":"Create a public or private Slack channel using a Bot Token with channels:manage scope (admin). Channel name is auto-sanitized to lowercase alphanumeric + hyphens.","tags":["Messaging"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["slack_token","name"],"properties":{"slack_token":{"type":"string","description":"Slack Bot Token with channels:manage scope"},"name":{"type":"string","description":"Channel name (auto-sanitized: lowercase, no spaces, max 80 chars)"},"is_private":{"type":"boolean","default":false,"description":"Create as private channel"}}}}}},"responses":{"200":{"description":"{ ok, channel_id, name, is_private, created }"},"400":{"description":"Missing name or name_taken conflict"},"402":{"description":"Payment required"}}}},"/presentation/generate":{"post":{"summary":"Generate PPTX presentation from JSON","tags":["Documents"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["title","slides"],"properties":{"title":{"type":"string","description":"Presentation title"},"slides":{"type":"array","description":"Array of slide objects (max 50)","items":{"type":"object","required":["title","bullets"],"properties":{"title":{"type":"string"},"bullets":{"type":"array","items":{"type":"string"}},"image_url":{"type":"string","description":"Optional image URL for slide"},"notes":{"type":"string","description":"Optional speaker notes"}}}},"theme":{"type":"string","enum":["minimal","dark","corporate"],"default":"minimal","description":"Visual theme"},"output":{"type":"string","enum":["pptx","pdf"],"default":"pptx","description":"Output format"}}}}}},"responses":{"200":{"description":"Base64 encoded PPTX file","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"base64":{"type":"string"},"filename":{"type":"string"},"size_bytes":{"type":"integer"},"slides_count":{"type":"integer"},"format":{"type":"string"},"theme":{"type":"string"}}}}}}}},"400":{"description":"Invalid input"},"402":{"description":"Payment required"},"500":{"description":"Generation failed"}}}},"/ai/chat":{"post":{"tags":["AI"],"summary":"Chat with an LLM (GPT-4o-mini, Claude, Gemini, Pink)","operationId":"aiChat","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["message"],"properties":{"message":{"type":"string","description":"User message"},"model":{"type":"string","default":"gpt-4o-mini","description":"Model: gpt-4o-mini, gpt-4o, claude-haiku, gemini-flash, pink-auto, pink-general, pink-coding, pink-deep, or ollama:pink-*"},"system":{"type":"string","description":"Optional system prompt"},"max_tokens":{"type":"integer","default":512,"maximum":2048},"temperature":{"type":"number","default":0.7,"minimum":0,"maximum":2}}}}}},"responses":{"200":{"description":"Chat response","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"response":{"type":"string"},"model":{"type":"string"},"provider":{"type":"string"},"tokens":{"type":"object"}}}}}},"402":{"description":"Payment required"}}}},"/finance/quote":{"get":{"summary":"Stock/ETF/Crypto quote (Yahoo Finance)","description":"Get real-time or delayed stock quote for one or more symbols (max 10). Supports stocks, ETFs, indices, and crypto pairs (e.g. BTC-USD). No API key required. $0.001/request.","tags":["Finance"],"parameters":[{"name":"symbol","in":"query","required":true,"schema":{"type":"string"},"description":"Ticker symbol(s), comma-separated (e.g. AAPL or AAPL,GOOG,BTC-USD). Max 10."},{"name":"details","in":"query","required":false,"schema":{"type":"boolean","default":false},"description":"Include extra fundamentals: P/E ratio, market cap, 52w high/low, EPS, dividend yield, beta"}],"responses":{"200":{"description":"Quote data: symbol, name, price, currency, change, change_pct, open, high, low, prev_close, volume, market_state, exchange, type, timestamp. With details=true: also market_cap, pe_ratio, eps, dividend_yield, week_52_high/low, avg_volume_30d, beta."},"400":{"description":"Missing symbol or too many symbols (max 10)"},"402":{"description":"Payment required"},"404":{"description":"Symbol not found or lookup failed"}}}},"/stocks/price":{"get":{"summary":"Stock price + day change","description":"Current price, change, and change_pct for a single ticker (stocks, ETFs, indices). Uses Yahoo Finance - no API key required. $0.001/request.","tags":["Finance"],"parameters":[{"name":"symbol","in":"query","required":true,"schema":{"type":"string"},"description":"Ticker symbol (e.g. AAPL, PETR4.SA, ^GSPC)"}],"responses":{"200":{"description":"ok, data: {symbol, name, price, currency, change, change_pct, open, high, low, prev_close, volume, market_state, exchange, type, timestamp}"},"400":{"description":"Missing symbol"},"402":{"description":"Payment required"},"404":{"description":"Symbol not found"}}}},"/stocks/history":{"get":{"summary":"Stock OHLCV historical data","description":"Historical daily OHLCV candles for a stock symbol. Periods: 1d, 5d, 1mo (default), 3mo, 6mo, 1y, 2y, 5y. Uses Yahoo Finance - no API key required. $0.001/request.","tags":["Finance"],"parameters":[{"name":"symbol","in":"query","required":true,"schema":{"type":"string"},"description":"Ticker symbol (e.g. AAPL, MSFT, PETR4.SA)"},{"name":"period","in":"query","required":false,"schema":{"type":"string","default":"1mo","enum":["1d","5d","1mo","3mo","6mo","1y","2y","5y"]},"description":"Historical period (default: 1mo)"}],"responses":{"200":{"description":"ok, data: {symbol, period, period1, period2, count, candles: [{date, open, high, low, close, adj_close, volume}]}"},"400":{"description":"Missing symbol"},"402":{"description":"Payment required"},"404":{"description":"No data found"}}}},"/stocks/search":{"get":{"summary":"Search stocks by company name","description":"Find ticker symbols by company name or keyword. Returns matching equities, ETFs, indices. Uses Yahoo Finance - no API key required. $0.001/request.","tags":["Finance"],"parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string"},"description":"Company name or keyword (e.g. apple, petrobras, s&p 500)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":10,"maximum":20},"description":"Max results (default: 10, max: 20)"}],"responses":{"200":{"description":"ok, data: {query, count, results: [{symbol, name, exchange, type, sector, industry, score}]}"},"400":{"description":"Missing q parameter"},"402":{"description":"Payment required"}}}},"/tools/code_mode/search":{"get":{"summary":"Compact tool registry for Code Mode planning","description":"Returns tools in TypeScript-like signature form (compact discovery for multi-tool agent planning). ~44% fewer tokens than full /tools. Public, no auth.","tags":["Meta"],"parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string"},"description":"Keyword filter (matches id/label/tags)"},{"name":"category","in":"query","required":false,"schema":{"type":"string"},"description":"Category filter (e.g. image, web, finance)"},{"name":"rate_class","in":"query","required":false,"schema":{"type":"string","enum":["light","medium","heavy"]},"description":"Rate-class filter"}],"responses":{"200":{"description":"ok, count, tools: [{id, signature, method, endpoint, rate_class, price_usdc, supports_code_mode}]"}}}},"/tools/code_mode/execute":{"post":{"summary":"Execute a declarative plan chaining up to 10 tool-calls in one request","description":"Run a multi-step plan in one HTTP round-trip. Each step can reference prior outputs via `{{stepId.path}}` interpolation. Billing: each sub-tool charged normally + $0.001 plan overhead. Max 10 steps, 45s per step, 120s total. Recursion (tools/code_mode, credits/*) is blocked.","tags":["Meta"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["plan"],"properties":{"plan":{"type":"array","maxItems":10,"items":{"type":"object","required":["tool"],"properties":{"id":{"type":"string","description":"Optional step id for referencing output"},"tool":{"type":"string","description":"Tool id (e.g. crypto/price, text/hash)"},"args":{"type":"object","description":"Args for the tool, with optional {{stepId.path}} interpolation"},"timeout_ms":{"type":"integer","description":"Per-step timeout override (max 45000)"}}}},"continue_on_error":{"type":"boolean","default":false},"dry_run":{"type":"boolean","default":false,"description":"Validate plan without executing"}}}}}},"responses":{"200":{"description":"ok, total_ms, steps_executed, steps_planned, tokens_saved_est, results[]"},"207":{"description":"Partial success (some steps failed, continue_on_error)"},"400":{"description":"Invalid plan (too many steps, recursion, unknown tool)"},"402":{"description":"Payment required"}}}},"/storage/upload":{"post":{"summary":"Upload file to temporary public storage","tags":["Storage"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["file","filename","content_type"],"properties":{"file":{"type":"string","description":"Base64-encoded file content"},"filename":{"type":"string","description":"Filename (e.g. image.png, document.pdf)"},"content_type":{"type":"string","description":"MIME type (e.g. image/png, application/pdf)"},"ttl_hours":{"type":"integer","default":24,"minimum":1,"maximum":168,"description":"Time-to-live in hours (default 24, max 168)"}}}}}},"responses":{"200":{"description":"File uploaded with public URL","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"url":{"type":"string"},"file_id":{"type":"string"},"filename":{"type":"string"},"content_type":{"type":"string"},"size_bytes":{"type":"integer"},"expires_at":{"type":"string","format":"date-time"}}}}}},"400":{"description":"Missing fields or file too large"},"402":{"description":"Payment required"}}}}}}