{"version":"0.1.0","authentication":{"methods":[{"type":"api_key","description":"Create an API key via POST /tokens/ (requires JWT). Use it as: Authorization: Bearer faro_<key>","header":"Authorization","prefix":"Bearer faro_"},{"type":"jwt","description":"Obtain a JWT via POST /auth/login with email and password. Use it as: Authorization: Bearer <jwt>","header":"Authorization","prefix":"Bearer "},{"type":"partner_token","description":"Partner Token: Bearer faro_partner_... for partner integrations. Include X-Faro-User header to identify end users.","header":"Authorization","prefix":"Bearer faro_partner_"}],"note":"API keys (faro_ prefix) are recommended for programmatic access. JWTs expire after 60 minutes. Partner tokens (faro_partner_ prefix) are used for partner integrations with the X-Faro-User header.","fastest_start":"POST /auth/agent-signup with {\"email\": \"...\"} returns a usable faro_ API key in one call (no password, no human). The account starts unverified: self-hosted tools work immediately; verifying the emailed link unlocks the free data tier and paid tools."},"endpoints":[{"method":"POST","path":"/auth/agent-signup","description":"Self-serve agent signup. Email only, no password: creates an account and returns a usable faro_ API key plus a magic login_url for the human. Account starts unverified (self-hosted tools only) until the emailed link is clicked.","auth_required":false,"parameters":[{"name":"email","in":"body","type":"string","description":"Email for the account; receives the verification link"},{"name":"token_name","in":"body","type":"string","description":"Optional label for the issued API key"}]},{"method":"POST","path":"/auth/resend-verification","description":"Re-send the email-verification link for the authenticated account. Verifying unlocks the free data tier and paid namespaces.","auth_required":true,"parameters":[]},{"method":"POST","path":"/invoke/{namespace}/{tool_name}","description":"Invoke an MCP tool. Accepts both JWT and API key auth. Returns the tool result and billing info. Also accepts partner tokens (faro_partner_...) with X-Faro-User header for partner invocations.","auth_required":true,"parameters":[{"name":"namespace","in":"path","type":"string","description":"Namespace slug"},{"name":"tool_name","in":"path","type":"string","description":"Tool name (mcp_tool_name)"},{"name":"arguments","in":"body","type":"object","description":"Tool arguments matching the input_schema"},{"name":"idempotency_key","in":"body","type":"string","description":"Optional key to prevent duplicate invocations"}]},{"method":"GET","path":"/tools/search?q={query}","description":"Semantic search for tools across all active namespaces. Returns an envelope {items, returned, limit, query}; ranked top-k, so raise limit or refine the query if nothing fits (see `note`). Prefer this over listing all tools.","auth_required":false,"parameters":[{"name":"q","in":"query","type":"string","description":"Search query"},{"name":"limit","in":"query","type":"integer","description":"Max results (default 10, max 50)"}]},{"method":"GET","path":"/tools/","description":"List public tools from active namespaces. PAGINATED: returns an envelope {items, total, returned, limit, offset, has_more, next_offset}. There are hundreds of tools, so the default page (50) is NOT the full set; page with offset until has_more is false, or use /tools/search to find tools by intent.","auth_required":false,"parameters":[{"name":"limit","in":"query","type":"integer","description":"Page size (default 50, max 200)"},{"name":"offset","in":"query","type":"integer","description":"Pagination offset; use next_offset from the previous response"},{"name":"namespace","in":"query","type":"string","description":"Filter by namespace slug"}]},{"method":"GET","path":"/tools/{namespace}/{tool_name}","description":"Get details for a specific public tool.","auth_required":false,"parameters":[]},{"method":"GET","path":"/namespaces/public","description":"List active namespaces in the marketplace. PAGINATED: returns an envelope {items, total, returned, limit, offset, has_more, next_offset}. The default limit (200) returns the whole catalog in one call; if has_more is true, page with offset.","auth_required":false,"parameters":[{"name":"limit","in":"query","type":"integer","description":"Page size (default 200, max 200)"},{"name":"offset","in":"query","type":"integer","description":"Pagination offset; use next_offset from the previous response"}]},{"method":"GET","path":"/namespaces/public/{slug}","description":"Get full namespace detail including all public tools, README, and pricing.","auth_required":false,"parameters":[]},{"method":"GET","path":"/docs/namespaces/{slug}","description":"Get agent-friendly documentation for a namespace and its tools.","auth_required":false,"parameters":[]},{"method":"GET","path":"/docs/namespaces/{slug}/{tool_name}","description":"Get agent-friendly documentation for a single tool with curl example.","auth_required":false,"parameters":[]},{"method":"GET","path":"/credits/balance","description":"Get current credit balance.","auth_required":true,"parameters":[]},{"method":"POST","path":"/credits/purchase","description":"Start a credit top-up via Paddle checkout. Returns a Paddle transaction ID for the overlay.","auth_required":true,"parameters":[{"name":"amount_usd","in":"body","type":"integer","description":"Whole US dollars to top up (e.g. 20 → 20,000 credits)"}]},{"method":"GET","path":"/invocations/","description":"List your past invocations.","auth_required":true,"parameters":[]},{"method":"POST","path":"/tokens/","description":"Create an API key for programmatic access.","auth_required":true,"parameters":[{"name":"name","in":"body","type":"string","description":"Descriptive name for the token"}]},{"method":"POST","path":"/partners/","description":"Request to become a Faro partner.","auth_required":true,"parameters":[]},{"method":"GET","path":"/partners/me","description":"Get partner dashboard (balance, users, usage).","auth_required":true,"parameters":[]},{"method":"POST","path":"/partners/me/token/regenerate","description":"Regenerate partner API token.","auth_required":true,"parameters":[]},{"method":"POST","path":"/partners/users","description":"Provision a user with optional credit budget.","auth_required":true,"parameters":[]},{"method":"GET","path":"/partners/users","description":"List all provisioned users.","auth_required":true,"parameters":[]},{"method":"GET","path":"/partners/users/{external_id}","description":"Get specific user details and balance.","auth_required":true,"parameters":[]},{"method":"PATCH","path":"/partners/users/{external_id}/budget","description":"Adjust a user's credit budget.","auth_required":true,"parameters":[]},{"method":"GET","path":"/partners/users/{external_id}/usage","description":"Get per-tool usage breakdown for a user.","auth_required":true,"parameters":[]}],"pagination":{"summary":"List endpoints (/tools/, /namespaces/public) return a paginated envelope, NOT a bare array. A full page is not necessarily the full result set.","envelope_fields":{"items":"The array of results for this page.","total":"Total number of results matching the query.","returned":"Number of items in this page.","limit":"Page size used.","offset":"Offset used.","has_more":"true when more results exist beyond this page.","next_offset":"Offset to request for the next page (null when has_more is false).","note":"Present only when has_more is true: a plain-language instruction for fetching the rest."},"how_to_page":"If has_more is true, repeat the request with offset=next_offset (same limit) until has_more is false. To find tools without paging the whole catalog, use GET /tools/search?q=<intent>.","search_note":"/tools/search is relevance-ranked top-k (no offset): it returns {items, returned, limit, query}. If the page is full and nothing fits, raise limit (max 50) or refine the query."},"credits":{"exchange_rate":"1,000 credits = $1.00 USD (1 credit = $0.001)","free_tier":"Self-hosted tools and tools flagged free_tier cost 0 credits within a monthly allowance (larger once the account is verified) and run even at a $0 balance. Beyond the allowance the normal price applies.","minimum_purchase":"Credits are purchased via Paddle checkout at POST /credits/purchase (amount_usd in whole US dollars).","billing":"Credits are deducted per tool invocation based on the tool's pricing configuration.","pricing_modes":{"fixed_per_request":"A fixed number of credits per invocation.","tool_returned":"Credits determined by the tool's response (e.g., based on token usage)."}},"verification":{"summary":"Namespaces are tiered by access_tier: 'unverified' (self-hosted, no external provider), 'verified' (free proxied external data), 'paid' (priced). A new account is unverified and may only invoke 'unverified' namespaces; anything else returns 403 until the email is verified. A completed purchase also counts as verified. Partner traffic is always treated as verified.","verify":"Click the link from POST /auth/agent-signup (or registration), or call POST /auth/resend-verification for a fresh one."},"errors":{"401":"Unauthorized, missing or invalid authentication token.","402":"Insufficient credits, purchase more credits before invoking.","403":"Forbidden, the account's email is not verified for this namespace. Verify via the emailed link or POST /auth/resend-verification.","404":"Not found, namespace, tool, or resource does not exist.","409":"Conflict, duplicate idempotency key or concurrent update.","502":"Bad gateway, the upstream MCP tool server returned an error."},"cli":{"name":"askfaro-cli","install":"pip install askfaro-cli","description":"Command-line client that wraps every endpoint in this API. Outputs JSON when stdout is not a TTY (agent-friendly), with stable exit codes for errors.","buyer_commands":["faro auth login","faro search '<natural language query>'","faro describe <namespace>/<tool>","faro invoke <namespace>/<tool> --params '<json>'"],"publisher_commands":["faro publisher register --display-name '<name>'","faro ns quick-setup --namespace <slug> --mcp-url <url>","faro init <slug>            # writes faro.yaml","faro push --publish         # save listing + submit for review","faro ns check <slug>        # local readiness check"],"agent_usage_hint":"Recommended for agents that can run shell commands, `faro search` returns the tool's input_schema in the same call, so you can invoke without a second lookup."}}