Create an API Key
Free tier — no credit card, no purchase required. Get 100 API calls/day immediately.
My API Keys
Enter your email to view and manage your existing keys.
Plans & Pricing
Start free. Upgrade when you need more volume.
- 10 requests / minute
- Chat + Products APIs
- Up to 3 API keys
- No credit card required
- Works on free & purchased bots
- 30 requests / minute
- All APIs
- Up to 10 API keys
- Usage analytics dashboard
- Priority support
- 120 requests / minute
- All APIs
- Up to 50 API keys
- Custom rate limits available
- SLA guarantee
- Dedicated support
Quickstart — 3 Minutes to First Call
Get your free API key
Fill in the Create API Key form above — no purchase, no credit card. You'll receive a key starting with urb_dev_.
Make your first call
curl -X POST https://urbot.net/api/v1/chat \
-H "X-API-Key: urb_dev_your_key_here" \
-H "Content-Type: application/json" \
-d '{"bot_slug":"professor","message":"Explain quantum entanglement"}'
Use the response
{
"response": "Quantum entanglement is a phenomenon where...",
"bot_slug": "professor",
"conversation_id": "session-abc123",
"source": "qwen",
"credits_remaining": 99,
"response_time_ms": 780
}
Save conversation_id and pass it back on your next request to maintain context.
Authentication
All /api/v1/* endpoints authenticate via API key. Pass it in either of these headers:
X-API-Key: urb_dev_your_key_here
Authorization: Bearer urb_dev_your_key_here
Legacy auth (still supported)
The older X-API-Key + X-API-Secret pair from /api/developer/register continues to work. New projects should use the self-service key system above.
Endpoints Reference
Self-Service Key Management
v1 API
conversation_id. Returns credits_remaining and calls_today.{"status":"healthy"}. No auth required. Useful for uptime monitors.POST /api/v1/chat — Request Body
| Parameter | Type | Description | |
|---|---|---|---|
bot_slug | string | required | Bot identifier, e.g. medic, legal, professor |
message | string | required | User message. Max 4,000 characters. |
conversation_id | string | optional | Session ID from a previous response to continue the conversation. |
system_context | string | optional | Additional instructions injected into the bot's system prompt for this call. |
Code Examples
const response = await fetch('https://urbot.net/api/v1/chat', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'urb_dev_your_key_here'
},
body: JSON.stringify({
bot_slug: 'professor',
message: 'Explain quantum entanglement'
})
});
const data = await response.json();
console.log(data.response);
// "Quantum entanglement is a phenomenon where..."
console.log(`Credits remaining: ${data.credits_remaining}`);
let conversationId = null;
async function chat(botSlug, message) {
const res = await fetch('https://urbot.net/api/v1/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-API-Key': 'urb_dev_your_key' },
body: JSON.stringify({ bot_slug: botSlug, message, conversation_id: conversationId })
});
const data = await res.json();
conversationId = data.conversation_id; // persist for context
return data.response;
}
const r1 = await chat('engineer', 'How do I debounce in JavaScript?');
const r2 = await chat('engineer', 'Show me a React hooks example');
// r2 remembers the context from r1
import requests
API_KEY = 'urb_dev_your_key_here'
BASE_URL = 'https://urbot.net/api/v1'
def ask_bot(bot_slug, message, conversation_id=None):
r = requests.post(
f'{BASE_URL}/chat',
headers={'X-API-Key': API_KEY},
json={
'bot_slug': bot_slug,
'message': message,
'conversation_id': conversation_id,
}
)
r.raise_for_status()
return r.json()
# Single call
result = ask_bot('legal', 'What is an NDA?')
print(result['response'])
print(f"Credits remaining: {result['credits_remaining']}")
# Multi-turn
session = None
r1 = ask_bot('medic', 'What causes dehydration?')
session = r1['conversation_id']
r2 = ask_bot('medic', 'What are the best treatments?', session)
// urbot-client.js
const BASE = 'https://urbot.net/api/v1';
class URBotClient {
constructor(apiKey) {
this.apiKey = apiKey;
this.sessions = {};
}
async chat(botSlug, message, opts = {}) {
const sessionKey = opts.sessionKey || botSlug;
const res = await fetch(`${BASE}/chat`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': this.apiKey,
},
body: JSON.stringify({
bot_slug: botSlug,
message,
conversation_id: this.sessions[sessionKey] || null,
system_context: opts.systemContext || null,
}),
});
if (!res.ok) throw new Error(`URBot API error: ${res.status}`);
const data = await res.json();
this.sessions[sessionKey] = data.conversation_id;
return data;
}
clearSession(botSlug) {
delete this.sessions[botSlug];
}
}
// Usage
const client = new URBotClient(process.env.URBOT_API_KEY);
const r1 = await client.chat('chef', 'What pasta goes well with pesto?');
const r2 = await client.chat('chef', 'Give me a recipe for 4 people');
// r2 remembers r1 context automatically
curl -X POST https://urbot.net/api/v1/chat \
-H "X-API-Key: urb_dev_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"bot_slug": "medic",
"message": "What are symptoms of dehydration?"
}'
curl -X POST https://urbot.net/api/dev/keys \
-H "Content-Type: application/json" \
-d '{
"name": "My App",
"email": "you@example.com",
"plan": "free"
}'
curl "https://urbot.net/api/dev/keys?email=you@example.com"
curl -X DELETE \
"https://urbot.net/api/dev/keys/KEY_UUID_HERE?email=you@example.com"
curl -X POST \
"https://urbot.net/api/dev/keys/KEY_UUID_HERE/rotate?email=you@example.com"
curl "https://urbot.net/api/dev/usage/KEY_UUID_HERE"
curl "https://urbot.net/api/products"
curl "https://urbot.net/api/health"
Error Codes
| Status | Condition | Resolution |
|---|---|---|
| 401 | Missing or invalid API key | Check the X-API-Key header. Make sure the key is active. |
| 403 | Bot not accessible | For old-style accounts, purchase the bot at https://{slug}.urbot.net/ |
| 400 | Missing required field | Ensure bot_slug and message are present and non-empty. |
| 429 | Rate limit exceeded | Wait for the window to reset (per-minute) or upgrade your plan for higher limits. |
| 409 | Key already exists (old system) | Use the returned api_key or call POST /api/developer/rotate-key. |
| 500 | Internal server error | Retry with exponential backoff. Contact support if persistent. |
Ready to start building?
Free API key — 100 calls/day, no purchase required.
MCP — Add URBot to Claude Desktop
The Model Context Protocol (MCP) lets Claude Desktop call URBot tools directly inside your conversations. Ask Claude to "find a bot for tax advice" or "ask the Chef bot for a pasta recipe" — without leaving Claude.
What you get
Send messages to any specialist bot and get expert responses.
Find the right bot for any topic or question.
Browse all 114+ specialists by name or category.
Retrieve what a bot has learned about a user over time.
Look up bot pricing tiers and purchase options.
Setup — 3 steps
Get a free API key
Create an API key above — takes 30 seconds. You'll get a key like urb_dev_abc123...
Edit your Claude Desktop config
Open your Claude Desktop configuration file:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
Add the following block, replacing YOUR_API_KEY_HERE with your actual key:
{
"mcpServers": {
"urbot": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-fetch",
"https://urbot.net/api/mcp"
],
"headers": {
"X-API-Key": "YOUR_API_KEY_HERE"
}
}
}
}
If the file already has an mcpServers key, add the "urbot": {...} entry inside it.
Restart Claude Desktop
Quit and relaunch Claude Desktop. You should see URBot MCP appear in the tools panel. Try asking:
Ask the URBot medic bot: what are symptoms of dehydration?
Search URBot for a bot that can help with skiing advice.
Use the URBot chef bot to suggest a quick pasta recipe for 2 people.
MCP API Reference
The MCP server exposes a JSON-RPC 2.0 interface. All endpoints accept POST with a JSON-RPC envelope.
params.name and params.arguments.Raw JSON-RPC example
curl -X POST https://urbot.net/api/mcp/initialize \
-H "Content-Type: application/json" \
-H "X-API-Key: urb_dev_your_key_here" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","clientInfo":{"name":"my-app","version":"1.0"}}}'
curl -X POST https://urbot.net/api/mcp/tools/call \
-H "Content-Type: application/json" \
-H "X-API-Key: urb_dev_your_key_here" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "chat_with_bot",
"arguments": {
"botSlug": "chef",
"message": "Give me a quick pasta recipe for 2 people"
}
}
}'
curl -X POST https://urbot.net/api/mcp/tools/call \
-H "Content-Type: application/json" \
-H "X-API-Key: urb_dev_your_key_here" \
-d '{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "search_bots",
"arguments": { "query": "skiing safety" }
}
}'
const MCP_URL = 'https://urbot.net/api/mcp';
const API_KEY = 'urb_dev_your_key_here';
async function mcpCall(method, params = {}) {
const res = await fetch(`${MCP_URL}/${method.replace('/', '/')}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': API_KEY
},
body: JSON.stringify({ jsonrpc: '2.0', id: Date.now(), method, params })
});
const data = await res.json();
if (data.error) throw new Error(data.error.message);
return data.result;
}
// Initialize
const info = await mcpCall('initialize', {
protocolVersion: '2024-11-05',
clientInfo: { name: 'my-app', version: '1.0' }
});
console.log('Connected to', info.serverInfo.name);
// Chat with a bot
const result = await mcpCall('tools/call', {
name: 'chat_with_bot',
arguments: { botSlug: 'medic', message: 'What causes dehydration?' }
});
console.log(result.content[0].text);
// Search bots
const search = await mcpCall('tools/call', {
name: 'search_bots',
arguments: { query: 'legal advice' }
});
const bots = JSON.parse(search.content[0].text).bots;
console.log('Found:', bots.map(b => b.name).join(', '));
import requests, json
MCP_URL = 'https://urbot.net/api/mcp'
API_KEY = 'urb_dev_your_key_here'
_id = 0
def mcp(method, params=None):
global _id
_id += 1
endpoint = method.replace('/', '/')
r = requests.post(
f'{MCP_URL}/{endpoint}',
headers={'Content-Type': 'application/json', 'X-API-Key': API_KEY},
json={'jsonrpc': '2.0', 'id': _id, 'method': method, 'params': params or {}}
)
data = r.json()
if 'error' in data:
raise Exception(data['error']['message'])
return data['result']
# Initialize
info = mcp('initialize', {'protocolVersion': '2024-11-05', 'clientInfo': {'name': 'my-app'}})
print('Server:', info['serverInfo']['name'])
# Chat with chef bot
result = mcp('tools/call', {
'name': 'chat_with_bot',
'arguments': {'botSlug': 'chef', 'message': 'Best herbs for Italian cooking?'}
})
print(result['content'][0]['text'])
# List all bots
bots_result = mcp('tools/call', {'name': 'list_bots', 'arguments': {}})
bots = json.loads(bots_result['content'][0]['text'])['bots']
print(f'Total bots: {bots[\"total\"]}')