# Wiro API Integration > Wiro is a unified API platform for running AI models (video, image, audio, LLM, 3D) and deploying autonomous AI agents through a single API. Pay-per-use pricing, real-time streaming via WebSocket, webhook callbacks, and 9-language code examples. - Base URL: `https://api.wiro.ai/v1` - WebSocket: `wss://socket.wiro.ai/v1` - Dashboard: https://wiro.ai/panel - Models: https://wiro.ai/models - Full docs: https://wiro.ai/docs ## Docs - [Introduction](https://wiro.ai/docs/introduction): Platform overview and getting started - [Authentication](https://wiro.ai/docs/authentication): API key and HMAC signature auth methods - [Run a Model](https://wiro.ai/docs/run-a-model): Execute any AI model with a single POST call - [Tasks](https://wiro.ai/docs/tasks): Track model runs, check status, get outputs - [WebSocket](https://wiro.ai/docs/websocket): Real-time streaming for model outputs - [LLM & Chat Streaming](https://wiro.ai/docs/llm-chat-streaming): Token-by-token LLM response streaming - [Realtime Voice](https://wiro.ai/docs/realtime-voice-conversation): Two-way audio conversations with AI - [Files](https://wiro.ai/docs/files): Upload files for model inputs - [Pricing](https://wiro.ai/docs/pricing): Pay-per-use credit system - [Error Reference](https://wiro.ai/docs/error-reference): Error codes and troubleshooting ## Agent API Docs - [Agent Overview](https://wiro.ai/docs/agent-overview): Deploy and manage autonomous AI agents - [Agent Messaging](https://wiro.ai/docs/agent-messaging): Send messages and stream agent responses - [Agent WebSocket](https://wiro.ai/docs/agent-websocket): Real-time agent response streaming - [Agent Webhooks](https://wiro.ai/docs/agent-webhooks): Receive agent responses via HTTP callbacks - [Agent Credentials](https://wiro.ai/docs/agent-credentials): Configure OAuth and API key credentials - [Agent Skills](https://wiro.ai/docs/agent-skills): Configure preferences and scheduled automation tasks - [Agent Use Cases](https://wiro.ai/docs/agent-use-cases): Deployment patterns and architecture guides ## Integrations - [MCP Server](https://wiro.ai/docs/wiro-mcp-server): Model Context Protocol server for AI assistants - [Self-Hosted MCP](https://wiro.ai/docs/mcp-self-hosted): Run MCP server locally via npx - [Node.js Library](https://wiro.ai/docs/nodejs-library): Standalone API client for Node.js/TypeScript - [n8n Integration](https://wiro.ai/docs/n8n-wiro-integration): Wiro AI nodes for n8n workflows ## Optional - [Model Parameters](https://wiro.ai/docs/model-parameters): Parameter types and input formatting - [Concurrency Limits](https://wiro.ai/docs/concurrency-limits): Task limits based on balance - [Code Examples](https://wiro.ai/docs/code-examples): Examples in 9 languages - [FAQ](https://wiro.ai/docs/faq): Frequently asked questions --- ## Authentication Two methods (chosen when creating a project — cannot be changed afterward): ### Signature-Based (Recommended) HMAC-SHA256 for enhanced security. Ideal for client-side/mobile apps. Headers: - `x-api-key`: Your project API key - `x-signature`: HMAC-SHA256(key=API_KEY, message=API_SECRET + NONCE) - `x-nonce`: Unix timestamp or random integer ### API Key Only (Simple) Single header for server-side applications. Headers: - `x-api-key`: Your project API key ## Projects Create a project at https://wiro.ai/panel/project/new to get API key and secret. Each project has its own API key, optional API secret, and usage tracking. ## Endpoints ### List Models POST /Tool/List ```json { "start": "0", "limit": "20", "search": "", "categories": ["image-generation"], "hideworkflows": true, "summary": true } ``` ### Model Detail POST /Tool/Detail ```json { "slugowner": "stability-ai", "slugproject": "sdxl" } ``` Returns model info including `parameters` array with input definitions (types: text, textarea, select, range, fileinput, multifileinput, combinefileinput). ### Run a Model POST /Run/{owner-slug}/{model-slug} Content-Type: `application/json` (text inputs) or `multipart/form-data` (file inputs) Use JSON when model has no file parameters. Use multipart when model requires file uploads. File parameter URL rules: - `fileinput`/`multifileinput`: use `{paramId}Url` suffix for URLs (e.g., `inputImageUrl`). Send empty `{paramId}` when using URL, empty `{paramId}Url` when uploading file. - `combinefileinput`: pass URLs directly in `{paramId}` — no suffix needed. Files and URLs share the same field. - Any file parameter also accepts a URL directly in `{paramId}` if `{paramId}Url` doesn't exist. All models support optional `callbackUrl` for webhook notifications on completion. JSON example: ```json { "prompt": "A futuristic city at sunset", "width": 1024, "height": 1024 } ``` Multipart example: ``` -F "inputImage=@photo.jpg" -F "scale=4" ``` Response: ```json { "result": true, "errors": [], "taskid": "2221", "socketaccesstoken": "eDcCm5yyUfIvMFspTwww49OUfgXkQt" } ``` ### Task Detail POST /Task/Detail ```json { "tasktoken": "eDcCm5yyUfIvMFspTwww49OUfgXkQt" } ``` Or by ID: `{ "taskid": "534574" }` Response includes: `id`, `status`, `pexit`, `debugoutput`, `outputs`, `elapsedseconds`, `totalcost`, `modeldescription`, `modelslugowner`, `modelslugproject`. **Determining success:** Check `pexit` field. `"0"` = success, any other value = error. This is the most reliable indicator. For LLM models, the response is available as structured content in `outputs` (with `contenttype: "raw"` containing `prompt`, `raw`, `thinking`, `answer`) and as merged plain text in `debugoutput`. ### Cancel Task (queued only) POST /Task/Cancel — `{ "tasktoken": "..." }` ### Kill Task (running) POST /Task/Kill — `{ "tasktoken": "..." }` ### Delete Task Files (completed/cancelled only) POST /Task/InputOutputDelete — `{ "tasktoken": "..." }` Deletes all output and input files for a completed task from S3, local storage, and database. Invalidates CDN cache. Task must be in terminal state (task_postprocess_end or task_cancel). Idempotent. Errors: `task-not-exist`, `Task must be completed or cancelled before deleting files`. ### Create Folder POST /File/FolderCreate — `{ "name": "my-folder" }` (optional `parentid` for nested folders) ### Upload File POST /File/Upload (multipart/form-data) — Fields: `file`, `folderid`. Max 100MB. Response: `{ result, list: [{ id, name, contenttype, size, url, ... }] }` ## Agent Endpoints POST /Agent/List - List available agent templates (public, no auth required) POST /Agent/Detail - Get agent template details by guid or slug (public) POST /UserAgent/Deploy - Deploy a new agent instance (supports prepaid wallet) POST /UserAgent/MyAgents - List your deployed agent instances POST /UserAgent/Detail - Get agent instance details POST /UserAgent/Update - Update agent configuration and credentials POST /UserAgent/Start - Start an agent instance POST /UserAgent/Stop - Stop an agent instance POST /UserAgent/CreateExtraCreditCheckout - Purchase extra credits (supports prepaid wallet) POST /UserAgent/CancelSubscription - Cancel a prepaid subscription at period end POST /UserAgent/UpgradePlan - Upgrade prepaid plan (starter → pro, prorated) POST /UserAgent/RenewSubscription - Renew expired prepaid subscription or undo cancel POST /UserAgent/Message/Send - Send a message to an agent (async, returns agenttoken) POST /UserAgent/Message/Detail - Get message details by guid or agenttoken POST /UserAgent/Message/History - Get conversation history with pagination POST /UserAgent/Message/Sessions - List conversation sessions POST /UserAgent/Message/DeleteSession - Delete a session and messages POST /UserAgent/Message/Cancel - Cancel an in-progress message POST /UserAgentOAuth/{Provider}Connect - Start OAuth flow for a provider POST /UserAgentOAuth/{Provider}Disconnect - Disconnect OAuth provider POST /UserAgentOAuth/{Provider}Status - Check OAuth connection status ## Task Statuses task_queue → task_accept → task_preprocess_start → task_preprocess_end → task_assign → task_start → task_output → task_output_full → task_end → task_postprocess_start → task_postprocess_end Additional: task_error (interim stderr log, not final failure), task_error_full (full stderr log), task_cancel Realtime only: task_stream_ready, task_stream_end, task_cost ## WebSocket Connect: `wss://socket.wiro.ai/v1` Register task: ```json { "type": "task_info", "tasktoken": "YOUR_SOCKET_ACCESS_TOKEN" } ``` Receive status messages as the task progresses. Listen for `task_postprocess_end` to get final results. ## LLM & Chat Streaming LLM responses are available in both `outputs` (structured, with `contenttype: "raw"`) and `debugoutput` (merged plain text). Streaming `task_output` messages contain structured objects: ```json { "type": "task_output", "message": { "raw": "full text...", "thinking": ["reasoning..."], "answer": ["response text..."], "isThinking": false, "speed": "12.4", "speedType": "words/s", "elapsedTime": "3s" } } ``` - `raw`: full accumulated output including thinking tags - `thinking`: chain-of-thought reasoning (may be empty) - `answer`: user-facing response - `isThinking`: whether the model is currently in a thinking phase - Both `thinking` and `answer` are arrays that grow with each streaming update ### Multi-turn Conversations Use `session_id` (UUID) to maintain chat history across requests. Server stores conversation context per session. ```json { "prompt": "What is quantum computing?", "session_id": "550e8400-e29b-41d4-a716-446655440000", "user_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7" } ``` Reuse the same `session_id` for follow-ups. New UUID = fresh conversation. Available LLM models: https://wiro.ai/models (filter by LLM category) ## Realtime Voice Conversation For two-way audio conversations with AI models. Flow: Run task → Connect WebSocket (task_info) → Wait for task_stream_ready → Stream mic audio as binary → Receive AI audio as binary → End with task_session_end Audio format: PCM Int16, 24kHz, mono. Binary frame: `tasktoken|pcm_audio_data` Events: task_stream_ready, task_stream_end, task_cost, task_output (TRANSCRIPT_USER:/TRANSCRIPT_AI: prefixes), task_end End session: ```json { "type": "task_session_end", "tasktoken": "YOUR_SOCKET_ACCESS_TOKEN" } ``` Parameters vary per model. Available realtime models: - https://wiro.ai/models/openai/gpt-realtime-mini - https://wiro.ai/models/openai/gpt-realtime - https://wiro.ai/models/elevenlabs/realtime-conversational-ai ## Parameter Types | Type | Description | |------|-------------| | text | Single-line text | | textarea | Multi-line text (prompts) | | select | Dropdown options | | range | Numeric slider | | fileinput | Single file or URL | | multifileinput | Multiple files/URLs | | combinefileinput | Up to N entries (files, URLs, or mixed) | Use /Tool/Detail to discover parameters for any model. ## Quick Start (curl) ```bash export API_KEY="your-api-key" # Run a model curl -X POST "https://api.wiro.ai/v1/Run/{owner-slug}/{model-slug}" \ -H "Content-Type: application/json" \ -H "x-api-key: ${API_KEY}" \ -d '{"prompt": "Hello, world!"}' # Check result curl -X POST "https://api.wiro.ai/v1/Task/Detail" \ -H "Content-Type: application/json" \ -H "x-api-key: ${API_KEY}" \ -d '{"tasktoken": "TOKEN_FROM_RUN_RESPONSE"}' ``` ## Quick Start (Python) ```python import requests API_KEY = "your-api-key" headers = {"x-api-key": API_KEY, "Content-Type": "application/json"} # Run a model run = requests.post( "https://api.wiro.ai/v1/Run/{owner-slug}/{model-slug}", headers=headers, json={"prompt": "Hello, world!"} ).json() # Check result detail = requests.post( "https://api.wiro.ai/v1/Task/Detail", headers=headers, json={"tasktoken": run["socketaccesstoken"]} ).json() print(detail) ``` ## Quick Start (Node.js) ```javascript const axios = require('axios'); const API_KEY = 'your-api-key'; const headers = { 'x-api-key': API_KEY, 'Content-Type': 'application/json' }; // Run a model const run = await axios.post( 'https://api.wiro.ai/v1/Run/{owner-slug}/{model-slug}', { prompt: 'Hello, world!' }, { headers } ); // Check result const detail = await axios.post( 'https://api.wiro.ai/v1/Task/Detail', { tasktoken: run.data.socketaccesstoken }, { headers } ); console.log(detail.data); ``` ## Supported Languages Code examples in 9 languages: curl, Python, Node.js, PHP, C#, Go, Swift, Kotlin, Dart ## Error Codes All API responses return HTTP 200. Check `result` field and error `code`: - Code 0: General/validation errors (missing params, server errors) - Code 1: Not found (model, task) - Code 96: Concurrent task limit reached - Code 97: Insufficient balance - Code 98: Authentication required (sign in) - Code 99: Bearer token invalid/expired Auth errors return HTTP 401: invalid API key, missing signature, IP not allowed. ## Pricing Prepaid credits, pay-per-use. Pricing info in `dynamicprice` field of Tool/List and Tool/Detail responses. Billing methods: - Fixed-rate: cpr (per request), cps (per second), cpo (per output), cpt (per token) - Usage-based: cp-pixel (per pixel tier/1MP), cp-audiosecondslength (per audio second), cp-promptlength (per character), cp-outputVideoLength (per output video second) - Special: cp-realtimeturn (per realtime voice turn), cp-readoutput (model-reported cost) Dynamic pricing: `dynamicprice` field contains pricing tiers with `inputs` (parameter combo), `price` (USD), `priceMethod` (billing code), optional `priceExtra` and `priceInput`. Empty inputs = flat rate. Fallback: when no dynamicprice, cost = elapsed_seconds × cps. `approximatelycost` field = average run time × cps (pre-run estimate). Only successful runs billed (pexit "0"). Server errors, queue time, cancelled tasks = free. Pricing page: https://wiro.ai/product/pricing ## Concurrency Limits Limits apply when balance is $250 or below. Concurrent tasks = max(1, floor(balance * 0.10)). Examples: $50 = 5 concurrent, $150 = 15 concurrent, $251+ = unlimited. Error code 96 returned when limit reached. Error code 97 for insufficient balance. ## MCP Server Wiro provides an MCP (Model Context Protocol) server for AI assistants. ### Hosted (mcp.wiro.ai) Endpoint: https://mcp.wiro.ai/v1 Transport: Streamable HTTP (stateless) Auth: `Authorization: Bearer apiKey:apiSecret` (signature) or `Bearer apiKey` (apikey-only) — plain text, no base64 ### Self-Hosted (npx) ```json { "command": "npx", "args": ["-y", "@wiro-ai/wiro-mcp"], "env": { "WIRO_API_KEY": "...", "WIRO_API_SECRET": "..." } } ``` ### MCP Tools (11 total) - `search_models`: Search/browse models by keyword, category, or owner (POST /Tool/List) - `get_model_schema`: Get model parameters, types, and pricing (POST /Tool/Detail). Use clean model slug - `recommend_model`: Describe what you want to build, get models ranked by relevance (POST /Tool/List) - `explore`: Browse curated models organized by category (POST /Tool/Explore). No parameters needed. - `run_model`: Run any model, wait for result or get task token (POST /Run/{cleanslugowner}/{cleanslugproject}) - `get_task`: Check task status, outputs, cost (POST /Task/Detail) - `get_task_price`: Get cost of a completed task — only successful tasks (pexit "0") are billed (POST /Task/Detail) - `cancel_task`: Cancel a queued task (POST /Task/Cancel) - `kill_task`: Kill a running task (POST /Task/Kill) - `upload_file`: Upload a file from URL to Wiro for model input (POST /File/Upload) - `search_docs`: Search Wiro documentation for guides, API references, and examples ## Node.js Library Use `WiroClient` from `@wiro-ai/wiro-mcp/client` as a standalone API client in Node.js/TypeScript — no MCP required. ```bash npm install @wiro-ai/wiro-mcp ``` ```javascript import { WiroClient } from '@wiro-ai/wiro-mcp/client'; const client = new WiroClient('API_KEY', 'API_SECRET'); const run = await client.runModel('google/nano-banana-pro', { prompt: '...' }); const result = await client.waitForTask(run.socketaccesstoken); ``` Methods: `searchModels()`, `getModelSchema()`, `explore()`, `runModel()`, `waitForTask()`, `getTask()`, `cancelTask()`, `killTask()`, `uploadFile()`. ## Agent API Autonomous AI agents in isolated containers. Two layers: Agent templates (catalog) and UserAgent instances (your deployments). Same auth (`x-api-key`). Lifecycle: Browse → Subscribe (prepaid wallet) → Deploy → Configure credentials → Start → Running → Chat Statuses: 0=Stopped, 1=Stopping, 2=Queued, 3=Starting, 4=Running, 5=Error, 6=Setup Required ### Catalog (Public, No Auth) POST /Agent/List — `{ search, category, sort, order, limit, start }` → `{ result, total, agents: [{ guid, title, slug, headline, cover, categories, pricing, skills, status }] }` POST /Agent/Detail — `{ guid }` or `{ slug }` → same plus `ratelimit`, `configuration.credentials` ### Management (Auth Required) POST /UserAgent/Deploy — `{ agentguid, title, useprepaid?, plan? }` → `{ result, useragents: [{ guid, status }] }`. When `useprepaid: true`, pass `plan` ("starter" or "pro") to pay from wallet. Deducts plan price and creates a 30-day subscription. POST /UserAgent/MyAgents — `{ sort, order, limit, start }` → `{ result, useragents: [{ guid, title, status, setuprequired, subscription, agent, extracredits }] }` POST /UserAgent/Detail — `{ guid }` → full instance + subscription. Subscription includes `provider` ("prepaid"). POST /UserAgent/Update — `{ guid, title?, description?, categories?, configuration? }` → Only `_editable` fields accepted. Running agents restart. POST /UserAgent/Start — `{ guid }` → Queues agent (status 2). Requires subscription + credits. POST /UserAgent/Stop — `{ guid }` → Stops or moves to Stopping. POST /UserAgent/CreateExtraCreditCheckout — `{ useragentGuid, pack, useprepaid? }` → `{ result }`. Pro plan only. Deducts pack price from wallet and activates credits immediately. POST /UserAgent/CancelSubscription — `{ guid }` → `{ result, cancelsAt }`. Sets subscription to cancel at period end (not immediate). POST /UserAgent/UpgradePlan — `{ guid, plan }` → `{ result, plan, proratedCharge, newMonthlyCredits }`. Upgrades starter → pro with prorated wallet charge for remaining days. POST /UserAgent/RenewSubscription — `{ guid }` → `{ result, action, plan?, amount? }`. If active with pending cancel: undoes cancel (`action: "undo-cancel"`). If expired: charges wallet and creates new 30-day subscription (`action: "renewed"`). ### Messaging POST /UserAgent/Message/Send — `{ useragentguid, message, sessionkey?, callbackurl? }` → `{ result, messageguid, agenttoken, status: "agent_queue" }` POST /UserAgent/Message/Detail — `{ messageguid }` or `{ agenttoken }` → `{ result, data: { guid, sessionkey, content, response, debugoutput, status, metadata, createdat, startedat, endedat } }` POST /UserAgent/Message/History — `{ useragentguid, sessionkey?, limit?, before? }` → `{ result, data: { messages, count, hasmore } }` POST /UserAgent/Message/Sessions — `{ useragentguid }` → `{ result, data: { sessions: [{ sessionkey, messagecount, updatedat, lastmessage }] } }` POST /UserAgent/Message/DeleteSession — `{ useragentguid, sessionkey }` POST /UserAgent/Message/Cancel — `{ messageguid }` or `{ agenttoken }`. Only cancellable in agent_queue/agent_start/agent_output. Message statuses: agent_queue → agent_start → agent_output (multiple) → agent_end. Also: agent_error, agent_cancel. ### Agent WebSocket Same server: wss://socket.wiro.ai/v1. Subscribe: `{ "type": "agent_info", "agenttoken": "..." }` Events: agent_subscribed (status + debugoutput), agent_start, agent_output (streaming: raw, thinking, answer, isThinking, speed, tokenCount, wordCount), agent_end (final), agent_error (string or object), agent_cancel. `result: true` for success events, `false` for error/cancel. Output contains full accumulated text (replace, don't append). ### Agent Webhooks Include `callbackurl` in Message/Send. Wiro POSTs when agent finishes: `{ messageguid, status, content, response, debugoutput, metadata: { raw, thinking, answer, speed, wordCount, ... }, endedat }` For error/cancel: `metadata` is `{}`. Retry: 3 attempts, 2s delay. Must return HTTP 200. ### Credentials API Key: Set via Update `configuration.credentials.`. Services: brevo (apiKey), sendgrid (apiKey), wordpress (url, user, appPassword), firebase (accounts array with appName, serviceAccountJsonBase64, apps, topics), gmail (account, appPassword), apollo (apiKey, masterApiKey), lemlist (apiKey), telegram (botToken, allowedUsers, sessionMode), website (urls array of {websiteName, url}), appstore (keyId, issuerId, privateKeyBase64, appIds — or apps array for ads agents), googleplay (serviceAccountJsonBase64, packageNames — or apps array for ads agents), newsletter (testEmail). OAuth: POST /UserAgentOAuth/{Provider}Connect — `{ userAgentGuid, redirectUrl, authMethod: "wiro"|"own" }` → `{ authorizeUrl }`. White-label: user sees only your app + provider consent screen, never wiro.ai. Providers: X, TikTok, Instagram, Facebook, LinkedIn, Google Ads, Meta Ads, HubSpot, Mailchimp. POST /UserAgentOAuth/{Provider}Status — `{ userAgentGuid }` → `{ connected, username, connectedAt, tokenExpiresAt }` POST /UserAgentOAuth/{Provider}Disconnect — `{ userAgentGuid }` POST /UserAgentOAuth/TokenRefresh — `{ userAgentGuid, provider }` → `{ accessToken, refreshToken }` ## Links - [Wiro Platform](https://wiro.ai): Main website - [Dashboard](https://wiro.ai/panel): Manage projects and API keys - [Create Project](https://wiro.ai/panel/project/new): Get API key and secret - [Explore Models](https://wiro.ai/models): Browse all available AI models - [Full Documentation](https://wiro.ai/docs): Interactive API documentation - [Full Markdown Export](https://raw.githubusercontent.com/wiroai/Wiro-Docs/main/markdown/full-documentation.md): All docs in a single markdown file - [MCP GitHub](https://github.com/wiroai/Wiro-MCP): MCP server source code - [MCP npm](https://www.npmjs.com/package/@wiro-ai/wiro-mcp): MCP server package