# ToolCall Store — Full Agent Documentation ToolCall Store is a machine-readable utility store for AI models and autonomous agents that need to call real-world services safely. Every product is exposed as a tool with a quote, an optional human approval, an execution step, a proof receipt, and a rollback path. Agents use the JSON and Markdown surfaces here; the HTML storefront is for humans. Base URL: https://toolcallstore.com API Base: https://toolcallstore.com/v1 Auth: Authorization: Bearer tc_live_... (production) | tc_test_... (sandbox) ## Machine-readable discovery files - /llms.txt — compact protocol summary (start here for a new integration) - /llms-full.txt — this file; full docs with worked examples - /catalog.json — all 9 tools: endpoints, scopes, providers, risk, pricing - /openapi.json — OpenAPI 3.1 spec (full schema for every request/response) - /pricing.json — metered pricing units per tool - /models.json — LLM provider routing table (model IDs, cost/token, capabilities) - /.well-known/agent-card.json — Google A2A protocol agent card - /.well-known/agent.json — alternate agent discovery - /.well-known/ai-plugin.json — ChatGPT plugin / MCP manifest (points to openapi.json) --- ## Capabilities ### Domains Availability search, alternative TLD suggestions, premium domain detection, quotes, registration, transfer, renewal — backed by OpenProvider as the primary registrar adapter. Every registration is irreversible; always requires a quote and human approval. ### DNS Named templates (email, website, app, agent-endpoint), individual record management, SPF/DKIM/DMARC/MX generation, propagation verification, and rollback snapshots on every change set. DNS changes are mutating but reversible via the rollback token in the receipt. ### Email Business mailbox creation, aliases, and routing — provisioned on self-hosted Stalwart SMTP with MX/SPF/DKIM/DMARC applied automatically. Credentials for auto-generated passwords are delivered in the receipt body (encrypted at rest). Monthly billing per mailbox. ### LLM routing Route requests to Anthropic (Claude) or OpenRouter (multi-model) by cost, quality, speed, privacy, or fallback policy. Supports BYOK: register your own provider key via POST /v1/providers/keys to reduce markup to the orchestration fee only. Model selection: "auto" picks the best fit for your max_cost_usd and the task complexity. ### Media generation Images via Stability AI, Together AI (FLUX.1.1-pro), or fal.ai. Video via fal.ai or Replicate. One endpoint per media type; the provider is selected by cost and availability unless you specify. Video generation requires a quote and approval because costs can spike. ### Safety and controls Tenant spend caps (daily and monthly), per-key scope enforcement, mandatory quote before billable/irreversible actions, human approval gates, idempotency on all mutating calls, and provider abuse/compliance pre-checks. A key with insufficient scope returns 403 immediately — the provider is never called. ### Receipts and audit Every executed action emits a proof receipt: provider order IDs, timestamps, DNS verification status (queried live), cost_usd, sell_usd, content policy results for media, and a rollback hint. Receipts are permanent and exportable. --- ## Execution protocol (required order) search → quote → [preview] → [approve] → execute → verify → receipt → [recover] 1. search — discover the right tool(s) for the agent's goal 2. quote — lock the price and determine if approval is required 3. preview — (optional) see the exact DNS records, mailboxes, or domains that will change 4. approve — required when quote.requires_approval == true 5. execute — run the action against the real provider 6. verify — confirm the real-world end state matches expectations 7. receipt — store the proof receipt for audit and billing records 8. recover — use rollback_hint if anything failed or needs to be undone --- ## Full endpoint reference POST /v1/tools/list — list every callable tool with scopes, risk, pricing unit POST /v1/tools/search — rank tools by natural-language intent POST /v1/quotes — price an action; returns quote_id, total_estimate_usd, requires_approval, expires_at, breakdown POST /v1/previews — show proposed DNS records, domains, mailboxes, and warnings for a quote POST /v1/domains/search — availability search and pricing via OpenProvider POST /v1/domains/register — register a domain; irreversible; requires approval_id and Idempotency-Key POST /v1/dns/templates/apply — apply a DNS template atomically; reversible via rollback snapshot; requires approval_id POST /v1/email/mailboxes — provision Stalwart mailboxes and deliverability DNS; requires approval_id POST /v1/llm/chat — route an LLM request; returns model used, usage, and cost POST /v1/media/images — generate images; returns media job with asset_urls POST /v1/media/videos — generate video; requires approval_id; returns media job POST /v1/approvals — create a pending human approval for a quote GET /v1/approvals/{id} — poll approval status (pending | granted | denied | expired) POST /v1/execute — execute an approved/quoted action; idempotent with Idempotency-Key POST /v1/verify — run post-execution verification (DNS propagation, mailbox login, asset reachable) GET /v1/receipts/{id} — fetch a proof receipt GET /v1/receipts — list receipts (paginated; ?page=&per_page=) GET /v1/account/balance — current balance_usd, plan, credit_remaining_usd GET /v1/providers/status — live provider health and routing status GET /v1/providers/keys — list stored BYOK keys (metadata only; keys not returned) POST /v1/providers/keys — register an encrypted BYOK key DELETE /v1/providers/keys/{id} — delete a BYOK key --- ## Authentication and scopes All requests require: Authorization: Bearer tc_live_ Scopes are enforced per API key. Grant only what each agent needs: domains:read — domain search and availability domains:buy — domain registration (irreversible; enforce strict) dns:write — DNS template apply and record management email:write — mailbox creation and alias management llm:call — LLM routing (metered per token) media:generate — image and video generation (metered per asset) approvals:create — create approval requests (required for any approval flow) receipts:read — fetch and list proof receipts providers:read — read provider health and routing status providers:keys — manage BYOK provider keys --- ## Idempotency Send an Idempotency-Key header (any UUID v4) on ALL mutating POSTs: - POST /v1/domains/register - POST /v1/dns/templates/apply - POST /v1/email/mailboxes - POST /v1/media/images - POST /v1/media/videos - POST /v1/execute A repeated key within 24 hours returns the original response and receipt without re-executing the action. A 409 Conflict means the key was already used — fetch GET /v1/receipts/{receipt_id} from the 409 response body instead of retrying. --- ## Quotes and approvals Quotes carry an expires_at (30 minutes from creation). If it has passed, re-quote before executing — passing an expired quote_id to /v1/execute returns 422 Unprocessable. When quote.requires_approval == true: 1. POST /v1/approvals with the quote_id 2. The human receives email or a webhook POST with the quote breakdown 3. Poll GET /v1/approvals/{id} every 10 seconds until status != "pending" 4. On "granted": proceed with POST /v1/execute using the approval_id 5. On "denied": stop. Report denial to the agent's caller. Do not retry. 6. On "expired": re-quote and re-request approval. --- ## Webhooks Configure a webhook URL on your account to receive signed events instead of polling: quote.created — a quote was generated approval.requested — a human has been notified of a pending approval approval.granted — human approved; approval_id is ready to use approval.denied — human denied; abort the workflow execution.completed — action executed successfully; receipt_id available execution.failed — action failed; see error and rollback_hint receipt.ready — proof receipt is finalized and queryable media.job.completed — async media generation finished; asset_urls available Each webhook POST includes ToolCall-Signature: sha256= computed from the raw body using your tenant webhook secret. Verify before trusting. --- ## Error codes All errors use: {"error": {"code": "...", "message": "...", "type": "...", "http": N, "request_id": "..."}} 400 invalid_request — malformed body, missing required field, or unknown tool_id 401 unauthorized — missing or invalid Bearer token 402 payment_required — spend cap exceeded or account balance insufficient → surface to human; do NOT retry; do NOT bypass 403 insufficient_scope — key lacks required scope for this tool → surface to human; do NOT escalate scope silently 403 approval_required — action needs approval_id before execute → call POST /v1/approvals first 404 not_found — receipt_id, approval_id, or domain not found 409 conflict — duplicate Idempotency-Key (already executed) → fetch the receipt_id from the response body 422 unprocessable — quote expired; re-quote with POST /v1/quotes 429 rate_limited — too many requests; back off 60 seconds before retrying 500 internal_error — provider error or internal failure; safe to retry once after 5s --- ## Recommended model behavior - Call /v1/tools/search or /v1/tools/list on startup; do not scrape HTML pages. - Never register a domain without an explicit approval_id — not even in "agentic mode." - Never change DNS without first calling POST /v1/previews to show the human what will change. - Never generate video without a quote; costs can be $5–$50+ for a single clip. - Prefer low-cost LLM routing (llm.route with max_cost_usd: 0.01) for classification and extraction. - Escalate to premium models for complex reasoning, legal/financial content, or low confidence. - After every /v1/execute, call GET /v1/receipts/{receipt_id} and confirm verified fields. - On 402 or 403, stop and surface the limit to the human; never escalate scope or bypass a cap. - On 429, wait exactly 60 seconds before one retry; after a second 429, surface to human. --- ## WORKED EXAMPLE: Register a domain, create 3 mailboxes, generate a logo ### Goal Agent needs to set up mysaas.io with business email and a logo image. ### Step 1 — Search for the right tools REQUEST: POST /v1/tools/search Authorization: Bearer tc_live_abc123 Content-Type: application/json { "intent": "register domain mysaas.io, create 3 mailboxes, generate a logo image" } RESPONSE: { "tools": [ { "tool_id": "domains.search", "endpoint": "/v1/domains/search", "scopes": ["domains:read"], "approval_required": false }, { "tool_id": "domains.register", "endpoint": "/v1/domains/register", "scopes": ["domains:buy"], "approval_required": true, "cost_estimate": { "typical_usd": "33.50", "note": ".io 1yr via OpenProvider" } }, { "tool_id": "email.create_mailbox", "endpoint": "/v1/email/mailboxes", "scopes": ["email:write"], "approval_required": true, "cost_estimate": { "typical_usd": "8.00", "note": "3 mailboxes x $2.67/mo" } }, { "tool_id": "media.image.generate", "endpoint": "/v1/media/images", "scopes": ["media:generate"], "approval_required": false, "cost_estimate": { "typical_usd": "0.04", "note": "1 image via Stability AI" } } ] } ### Step 2 — Check availability first (free, no quote needed) REQUEST: POST /v1/domains/search Authorization: Bearer tc_live_abc123 Content-Type: application/json { "domains": ["mysaas.io"], "suggest_alternatives": true } RESPONSE: { "results": [ { "domain": "mysaas.io", "available": true, "price_usd": "33.50", "renewal_usd": "33.50", "premium": false }, { "domain": "mysaas.com", "available": false }, { "domain": "mysaas.co", "available": true, "price_usd": "28.00", "renewal_usd": "28.00", "premium": false } ] } ### Step 3 — Quote (locks price, determines approval requirement) REQUEST: POST /v1/quotes Authorization: Bearer tc_live_abc123 Content-Type: application/json { "items": [ { "tool_id": "domains.register", "domain": "mysaas.io", "years": 1 }, { "tool_id": "email.create_mailbox", "domain": "mysaas.io", "mailboxes": ["hello", "support", "team"] }, { "tool_id": "media.image.generate", "prompt": "minimalist SaaS logo, teal and white", "provider": "stability", "count": 1 } ] } RESPONSE: { "quote_id": "q_9kXm2p", "total_estimate_usd": "41.54", "requires_approval": true, "expires_at": "2026-06-28T14:30:00Z", "breakdown": [ { "item": "domains.register mysaas.io 1yr", "usd": "33.50" }, { "item": "email.create_mailbox x3 (1 month)", "usd": "8.00" }, { "item": "media.image.generate x1 (Stability AI)", "usd": "0.04" } ] } NOTE: requires_approval is true because domains.register and email.create_mailbox both require it. The image generation would be executable immediately but is bundled in this quote. ### Step 4 — Request approval REQUEST: POST /v1/approvals Authorization: Bearer tc_live_abc123 Content-Type: application/json { "quote_id": "q_9kXm2p", "notify": "email", "message": "Agent request: set up mysaas.io with 3 mailboxes and generate a logo. Total: $41.54." } RESPONSE: { "approval_id": "appr_7zRqNw", "status": "pending", "notify_sent_to": "owner@yourdomain.com", "expires_at": "2026-06-28T15:00:00Z" } ### Step 5 — Poll for approval (every 10 seconds) REQUEST: GET /v1/approvals/appr_7zRqNw Authorization: Bearer tc_live_abc123 RESPONSE (after human approves via email link): { "approval_id": "appr_7zRqNw", "status": "granted", "granted_at": "2026-06-28T14:12:44Z", "granted_by": "owner@yourdomain.com" } ### Step 6 — Execute (with Idempotency-Key) REQUEST: POST /v1/execute Authorization: Bearer tc_live_abc123 Content-Type: application/json Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000 { "approval_id": "appr_7zRqNw" } RESPONSE: { "execution_id": "exec_4TrPkL", "status": "completed", "receipt_id": "rcpt_8mQvXj", "actions": [ { "tool_id": "domains.register", "provider": "OpenProvider", "provider_order_id": "OP-8812344", "domain": "mysaas.io", "status": "registered", "registered_until": "2027-06-28" }, { "tool_id": "email.create_mailbox", "provider": "Stalwart", "mailboxes_created": ["hello@mysaas.io", "support@mysaas.io", "team@mysaas.io"], "status": "provisioned", "dns_applied": ["MX", "SPF", "DKIM", "DMARC"] }, { "tool_id": "media.image.generate", "provider": "Stability AI", "model": "stable-diffusion-3.5-large", "status": "completed", "asset_urls": ["https://cdn.toolcallstore.com/media/exec_4TrPkL/logo_0.png"] } ] } ### Step 7 — Fetch proof receipt REQUEST: GET /v1/receipts/rcpt_8mQvXj Authorization: Bearer tc_live_abc123 RESPONSE: { "receipt_id": "rcpt_8mQvXj", "execution_id": "exec_4TrPkL", "quote_id": "q_9kXm2p", "approval_id": "appr_7zRqNw", "executed_at": "2026-06-28T14:13:01Z", "cost_usd": "41.54", "sell_usd": "41.54", "actions": [ { "tool_id": "domains.register", "provider": "OpenProvider", "provider_order_id": "OP-8812344", "domain": "mysaas.io", "registered_until": "2027-06-28", "nameservers": ["ns1.openprovider.nl", "ns2.openprovider.nl"], "dns_verified": true, "rollback_hint": null, "note": "Domain registration is irreversible. Contact support for transfer." }, { "tool_id": "email.create_mailbox", "provider": "Stalwart", "mailboxes": ["hello@mysaas.io", "support@mysaas.io", "team@mysaas.io"], "mx_verified": true, "spf_verified": true, "dkim_verified": true, "dmarc_verified": true, "rollback_hint": "DELETE /v1/email/mailboxes/batch?receipt=rcpt_8mQvXj" }, { "tool_id": "media.image.generate", "provider": "Stability AI", "model": "stable-diffusion-3.5-large", "asset_urls": ["https://cdn.toolcallstore.com/media/exec_4TrPkL/logo_0.png"], "content_policy_result": "pass", "cost_usd": "0.04", "rollback_hint": null } ] } Done. The agent now has: - mysaas.io registered (OpenProvider order OP-8812344, expires 2027-06-28) - 3 Stalwart mailboxes live with full deliverability DNS - A logo image at the CDN URL above - A permanent receipt for audit and billing --- ## Pricing Subscription plus metered usage. Plans: Free ($0), Starter ($19/mo), Builder ($49/mo), Agency ($149/mo), Enterprise (custom). Each paid plan includes a monthly usage credit that draws down before metered billing applies. Quotes lock the price for 30 minutes. Execution deducts from account balance. Receipts record both cost_usd (provider cost) and sell_usd (what is billed to your account). BYOK: register your own Anthropic, Stability AI, Together AI, or fal.ai key. LLM markup drops to orchestration fee only; media markup drops proportionally. Account balance: GET /v1/account/balance → {"balance_usd": "84.50", "plan": "builder", "credit_remaining_usd": "49.00"} See /pricing.json for per-unit pricing and /pricing.html for the human-readable pricing page.