Ship your agent into anything.
One deployed Something agent gives you chat, persistent conversations, isolated customer data, real-time voice, and a typed MCP tool surface.
Build a product
Call the agent from your backend with JSON or stream responses over SSE.
Connect AI tools
Expose the same agent to Codex and Claude Code through one MCP endpoint.
Keep users isolated
A stable user id partitions conversations and datastore rows automatically.
Your first agent call in five minutes
Deploy an agent, mint an agent-scoped key, and send a backend request. You do not need an SDK to get started.
Deploy an agent
Build and publish from the Something workspace.
Open workspace2Create a secret
Choose that agent under Developer settings.
Create a key3Call chat
Keep the key server-side and send a Bearer header.
View endpointconst response = await fetch(
"https://trysomething.sh/api/v1/agents/AGENT_ID/chat",
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.SOMETHING_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
message: "Summarize today’s customer feedback.",
user: "customer_123",
}),
},
);
const { message, conversation_id } = await response.json();user value should be an opaque id from your own auth system—not an email or display name. Reuse it on every call for the same customer.Authenticate every request
API keys are shown once, stored as hashes, and scoped to one deployed agent. They spend the owner’s usage credits.
Server-side only
Store the key in a secret manager or environment variable. Never place it in browser JavaScript, a mobile binary, logs, or source control.
One key, one agent
A key cannot call a different agent id. Use separate keys for local development, staging, production, and each teammate.
Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxx/agents/agents/{agent_id}Connect Something to your coding agent
The Streamable HTTP endpoint discovers the agent attached to your Bearer key. No agent id is needed in individual MCP tool calls.
https://trysomething.sh/api/mcp[mcp_servers.something_agent]
url = "https://trysomething.sh/api/mcp"
bearer_token_env_var = "SOMETHING_API_KEY"
enabled = trueclaude mcp add --transport http \
--scope user something-agent \
https://trysomething.sh/api/mcp \
--header "Authorization: Bearer $SOMETHING_API_KEY"Tools exposed automatically
get_agentInspect agent identity and capabilities
chat_with_agentRun a chat turn and continue threads
list_agent_conversationsList one user’s recent threads
get_conversation_messagesRead a conversation transcript
list_agent_dataQuery rows from a named table
create_agent_dataInsert structured JSON data
Inspect the connected agent
Use the introspection endpoints to validate a key and discover whether its agent supports voice.
/agents/agents/{agent_id}{
"id": "7d1660ce5cfb",
"name": "Customer research copilot",
"description": "Synthesizes interviews and feedback",
"capabilities": {
"chat": true,
"voice": false,
"data": true
}
}Chat and stream responses
Send a message, optionally continue an existing conversation, and choose one JSON response or token-level Server-Sent Events.
/agents/{agent_id}/chatRequest body
messageRequireduserconversation_idstreamattachments{
"message": "The strongest theme is faster onboarding.",
"conversation_id": "5f3c9e4a-…",
"usage": { "input_tokens": 812, "output_tokens": 47 },
"credits": { "credits": 3, "balance_after": 49872 }
}Streaming events
Set stream: true and accept text/event-stream. The conversation id arrives first, followed by text, usage and credits, then done.
event: conversation
data: {"conversation_id":"5f3c9e4a-…"}
event: text
data: {"text":"The strongest theme"}
event: credits
data: {"credits":3,"balance_after":49872}
event: done
data: {"stop_reason":"end_turn"}Manage conversation history
Every message belongs to a thread. The same user value used for chat must be supplied when reading, renaming, or deleting that user’s conversation.
/agents/{agent_id}/conversations?user={user}&limit=100/agents/{agent_id}/conversations/agents/{agent_id}/conversations/{id}/messages?user={user}/agents/{agent_id}/conversations/{id}/agents/{agent_id}/conversations/{id}?user={user}curl https://trysomething.sh/api/v1/agents/AGENT_ID/conversations \
-H "Authorization: Bearer $SOMETHING_API_KEY" \
-H "Content-Type: application/json" \
-d '{"user":"customer_123","title":"Q3 feedback review"}'Use the agent data store
Each agent includes a schemaless, per-user JSON store—the same persistence surface used by generated agent interfaces.
/agents/{agent_id}/data/{table}?user={user}&limit=50&order=desc/agents/{agent_id}/data/{table}/_count?user={user}/agents/{agent_id}/data/{table}/{row_id}?user={user}/agents/{agent_id}/data/{table}/agents/{agent_id}/data/{table}/{row_id}/agents/{agent_id}/data/{table}/{row_id}?user={user}{
"user": "customer_123",
"data": {
"title": "Review onboarding",
"status": "open"
}
}{
"user": "customer_123",
"patch": {
"status": "done"
}
}Start a voice session
Voice agents return LiveKit connection details that work with the web, iOS, Android, React Native, Flutter, and other LiveKit client SDKs.
/agents/{agent_id}/voice/sessionuserlanguageconversation_id{
"room_name": "a-3f2c…",
"livekit_url": "wss://voice.trysomething.sh",
"client_token": "eyJhbGci…"
}Request a session from your backend
Pass URL + token to Room.connect()
Publish the microphone track
Keep every customer isolated
Something never accepts a raw internal end-user key. Your API key id and user subject are combined server-side into a tenant boundary.
Embedding with your own JWT
For the hosted agent interface, configure End users → Authentication, mint a short-lived JWT on your server, and pass it as eu_token. The token is captured and removed from the URL on load.
const token = jwt.sign(
{ sub: user.id, email: user.email, name: user.name },
process.env.AGENT_SIGNING_SECRET,
{ algorithm: "HS256", expiresIn: "1h" },
);Errors are structured and actionable
REST endpoints use standard HTTP status codes. FastAPI validation failures may use a detail object; API-level failures expose an error code and message.
unauthorizedThe Bearer key is missing, invalid, or revoked.insufficient_creditsThe agent owner needs more use credits.forbiddenThe key is not scoped to the requested agent.not_foundThe agent, conversation, or datastore row does not exist.validation_errorA path, query, or request body field is invalid.rate_limitedThe per-key request window has been exceeded.agent_errorThe agent failed to complete the requested turn.{
"error": "rate_limited",
"message": "Rate limit of 120 requests/min exceeded.",
"retry_after_seconds": 18
}Rate limits and retries
Each API key has its own request window. The default is 120 requests per minute and can be adjusted for larger workloads.
Retry only requests that are safe for your application. Respect the Retry-After header and add randomized jitter to prevent synchronized retries.
Credits and billing
API traffic uses the same owner-funded use-credit pool as traffic through the hosted agent interface.
Chat
Metered by model tokens. The response includes usage and credit fields.
Voice
Metered by connected call time for supported voice agents.
Data + history
No model call, so reads and writes do not spend model credits.
Production checklist
A short review before your integration handles real customer traffic.
Build the agent. Connect the surface.
Create an agent-scoped credential and get a ready-to-paste setup prompt for Codex, Claude Code, or your backend.
Open Developer settings