Agent API
Agents are the core building block for deploying autonomous AI systems on SandBase. An agent combines a model, system prompt, tools, and configuration into a reusable, versioned resource.
Core Concepts
Agent (configuration)
├── Model (which LLM to use)
├── System Prompt (behavior instructions)
├── Tools (MCP servers, functions)
└── Sessions (conversation instances)
├── Events (messages, tool calls)
└── Environment (sandbox, variables)Create an Agent
import requests
response = requests.post(
"https://api.sandbase.ai/default/v1/agents",
headers={"Authorization": "Bearer sk-sb-YOUR_KEY"},
json={
"name": "Customer Support Agent",
"slug": "support-agent",
"model": {
"name": "claude-sonnet-4",
"max_tokens": 4096,
"temperature": 0.7
},
"system": """You are a helpful customer support agent for an e-commerce platform.
You can look up orders, process returns, and answer product questions.
Always be polite and concise.""",
"tools": [
{"type": "mcp", "server": "web-search"},
{"type": "mcp", "server": "database-query"}
],
"mcp_servers": [
{
"name": "web-search",
"url": "https://mcp.sandbase.ai/web-search"
}
]
}
)
agent = response.json()
print(f"Agent created: {agent['id']}")const response = await fetch('https://api.sandbase.ai/default/v1/agents', {
method: 'POST',
headers: {
'Authorization': 'Bearer sk-sb-YOUR_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'Customer Support Agent',
slug: 'support-agent',
model: {
name: 'claude-sonnet-4',
max_tokens: 4096,
temperature: 0.7,
},
system: `You are a helpful customer support agent...`,
tools: [
{ type: 'mcp', server: 'web-search' },
],
}),
});
const agent = await response.json();
console.log(`Agent created: ${agent.id}`);curl -X POST https://api.sandbase.ai/default/v1/agents \
-H "Authorization: Bearer sk-sb-YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Customer Support Agent",
"slug": "support-agent",
"model": {"name": "claude-sonnet-4", "max_tokens": 4096},
"system": "You are a helpful customer support agent...",
"tools": [{"type": "mcp", "server": "web-search"}]
}'Agent Configuration
| Field | Type | Required | Description |
|---|---|---|---|
name | string | ✅ | Human-readable name |
slug | string | ✅ | URL-safe identifier (unique) |
model | object | ✅ | LLM configuration |
system | string | ✅ | System prompt / instructions |
tools | array | ❌ | MCP tools to attach |
mcp_servers | array | ❌ | Custom MCP server connections |
metadata | object | ❌ | Custom key-value metadata |
visibility | string | ❌ | private (default) or template |
Model Configuration
{
"model": {
"name": "claude-sonnet-4", // Model identifier
"max_tokens": 4096, // Max response tokens
"temperature": 0.7, // Creativity (0-2)
"top_p": 0.9, // Nucleus sampling
"stop": ["\n\nHuman:"] // Stop sequences
}
}You can use any of the 1400+ models available on SandBase. Popular choices:
| Model | Best For |
|---|---|
claude-sonnet-4 | Complex reasoning, tool use |
gpt-4o | General purpose, multimodal |
deepseek/deepseek-v3 | Cost-effective, fast |
google/gemini-2.5-pro | Long context, multimodal |
Sessions
A session is a conversation instance with an agent. Sessions maintain state across multiple interactions.
Create a Session
session = requests.post(
"https://api.sandbase.ai/default/v1/sessions",
headers={"Authorization": "Bearer sk-sb-YOUR_KEY"},
json={
"agent_id": "agt_abc123",
"metadata": {
"user_id": "user_456",
"channel": "web"
}
}
).json()Send a Message
# Send a user message and get the agent's response
response = requests.post(
f"https://api.sandbase.ai/default/v1/sessions/{session['id']}/events",
headers={"Authorization": "Bearer sk-sb-YOUR_KEY"},
json={
"type": "message",
"role": "user",
"content": "I want to return order #12345"
}
).json()
# The agent processes the message, potentially calling tools
print(response["content"])Session Lifecycle
create → active → (messages back and forth) → archiveSessions persist until explicitly archived. You can resume any active session at any time.
Versioning
Agents are versioned resources. Every update creates a new version:
# Update an agent (creates version 2)
requests.patch(
f"https://api.sandbase.ai/default/v1/agents/{agent_id}",
headers={"Authorization": "Bearer sk-sb-YOUR_KEY"},
json={
"system": "Updated system prompt...",
"version": 1 # Optimistic lock — must match current version
}
)Existing sessions continue using the version they were created with. New sessions use the latest version.
List & Manage Agents
# List all agents
curl https://api.sandbase.ai/default/v1/agents \
-H "Authorization: Bearer sk-sb-YOUR_KEY"
# Get agent details
curl https://api.sandbase.ai/default/v1/agents/agt_abc123 \
-H "Authorization: Bearer sk-sb-YOUR_KEY"
# Archive an agent (soft delete)
curl -X POST https://api.sandbase.ai/default/v1/agents/agt_abc123/archive \
-H "Authorization: Bearer sk-sb-YOUR_KEY"Multiagent
SandBase supports multiagent architectures where agents can delegate tasks to other agents. Use the handoffs field to define which agents can be invoked, and the multiagent field to configure orchestration behavior.
Handoffs
Handoffs let an agent transfer control to a specialized sub-agent for a specific task, then resume when the sub-agent completes.
response = requests.post(
"https://api.sandbase.ai/default/v1/agents",
headers={"Authorization": "Bearer sk-sb-YOUR_KEY"},
json={
"name": "Orchestrator Agent",
"slug": "orchestrator",
"model": {"name": "claude-sonnet-4", "max_tokens": 4096},
"system": "You are a project manager that delegates tasks to specialists.",
"handoffs": [
{
"agent_id": "agt_research_001",
"name": "Research Agent",
"description": "Handles deep research tasks and fact-checking",
"trigger": "when the user asks for research or fact-checking"
},
{
"agent_id": "agt_code_002",
"name": "Code Agent",
"description": "Writes and reviews code",
"trigger": "when the user needs code written or reviewed"
}
]
}
)| Field | Type | Required | Description |
|---|---|---|---|
handoffs[].agent_id | string | ✅ | ID of the target agent |
handoffs[].name | string | ✅ | Display name for the sub-agent |
handoffs[].description | string | ❌ | What this agent specializes in |
handoffs[].trigger | string | ❌ | When to invoke this agent (used in system prompt context) |
Multiagent Configuration
The multiagent field controls how the orchestrator manages sub-agents:
{
"multiagent": {
"mode": "orchestrator",
"max_delegations": 5,
"parallel": false,
"context_sharing": "summary",
"timeout_per_handoff_ms": 60000
}
}| Field | Type | Default | Description |
|---|---|---|---|
mode | string | "orchestrator" | "orchestrator" (one controls many) or "swarm" (peer-to-peer) |
max_delegations | int | 10 | Max handoffs per session turn |
parallel | bool | false | Whether sub-agents can run concurrently |
context_sharing | string | "summary" | "full" (pass entire context) or "summary" (pass condensed context) |
timeout_per_handoff_ms | int | 60000 | Timeout for each delegated task |
Orchestrator Pattern
┌─────────────────────────────────────────┐
│ Orchestrator Agent │
│ - Receives user request │
│ - Decides which sub-agent to invoke │
│ - Collects results │
│ - Synthesizes final response │
└────────┬──────────┬──────────┬──────────┘
│ │ │
┌────▼───┐ ┌───▼────┐ ┌──▼─────┐
│Research│ │ Code │ │ QA │
│ Agent │ │ Agent │ │ Agent │
└────────┘ └────────┘ └────────┘Swarm Pattern
In swarm mode, agents communicate as peers. Any agent can hand off to any other agent in the group:
requests.post(
"https://api.sandbase.ai/default/v1/agents",
headers={"Authorization": "Bearer sk-sb-YOUR_KEY"},
json={
"name": "Support Triage",
"slug": "support-triage",
"model": {"name": "claude-sonnet-4", "max_tokens": 4096},
"system": "You handle initial customer inquiries. Route to specialists as needed.",
"handoffs": [
{"agent_id": "agt_billing", "name": "Billing Agent"},
{"agent_id": "agt_technical", "name": "Technical Agent"},
{"agent_id": "agt_escalation", "name": "Escalation Agent"}
],
"multiagent": {
"mode": "swarm",
"max_delegations": 3,
"context_sharing": "full"
}
}
)Skills
Skills are predefined behavior patterns that enhance how an agent operates. They add capabilities like structured planning, reflection loops, and long-running state management without requiring custom code.
Attaching Skills
Pass skill identifiers in the skills array when creating or updating an agent:
response = requests.post(
"https://api.sandbase.ai/default/v1/agents",
headers={"Authorization": "Bearer sk-sb-YOUR_KEY"},
json={
"name": "Research Agent",
"slug": "research-agent",
"model": {"name": "claude-sonnet-4", "max_tokens": 8192},
"system": "You are a deep research agent that produces comprehensive reports.",
"skills": [
"structured-planning",
"reflection-loop",
"long-running-state"
],
"tools": [
{"type": "mcp", "server": "web-search"},
{"type": "mcp", "server": "browser-use"}
]
}
)Available Skills
| Skill | Description | Best For |
|---|---|---|
structured-planning | Agent creates a step-by-step plan before executing, tracks progress | Complex multi-step tasks |
reflection-loop | Agent reviews its own output and iterates to improve quality | Writing, analysis, code review |
long-running-state | Maintains state across multiple iterations with checkpointing | Research, data processing |
web-browsing | Enhanced web navigation with page understanding and extraction | Research, monitoring |
code-execution | Runs code in sandbox, inspects output, iterates on errors | Development, data analysis |
file-management | Reads, writes, and organizes files in the sandbox filesystem | Document processing |
Skill Configuration
Skills can accept optional configuration via an object form:
{
"skills": [
"structured-planning",
{
"name": "reflection-loop",
"config": {
"max_iterations": 3,
"quality_threshold": 0.8
}
},
{
"name": "long-running-state",
"config": {
"checkpoint_interval_ms": 30000,
"max_state_size_kb": 512
}
}
]
}How Skills Work at Runtime
When a session starts, skills are injected into the agent's execution environment:
Session Start
├── Load agent config (model, system, tools)
├── Inject skills into sandbox
│ ├── structured-planning → adds planning prompts + state tracker
│ ├── reflection-loop → adds self-review step after each output
│ └── long-running-state → enables checkpointing
└── Begin execution loopSkills augment the agent's system prompt and add runtime behaviors. They don't replace your custom instructions — they layer on top.
Permission Policies
Permission policies control what an agent is allowed to do within its execution environment. Configure policies to restrict file access, network calls, and process execution.
Environment-Level Permissions
Permissions are set through the environment configuration when creating a session:
# Create an environment with restricted permissions
env = requests.post(
"https://api.sandbase.ai/default/v1/environments",
headers={"Authorization": "Bearer sk-sb-YOUR_KEY"},
json={
"name": "Restricted Research Env",
"config": {
"type": "cloud",
"base_template": "tpl_code_interpreter",
"resources": {
"cpu": 2,
"memory_mb": 2048,
"timeout": 600
},
"permissions": {
"network": {
"enabled": True,
"allowed_hosts": ["api.sandbase.ai", "*.wikipedia.org"],
"blocked_ports": [22, 25]
},
"filesystem": {
"writable_paths": ["/home/user", "/tmp"],
"read_only_paths": ["/data"],
"blocked_paths": ["/etc/shadow", "/root"]
},
"process": {
"allow_exec": True,
"blocked_commands": ["rm -rf /", "shutdown"],
"max_processes": 10
}
}
}
}
).json()Permission Fields
Network Permissions
| Field | Type | Default | Description |
|---|---|---|---|
network.enabled | bool | true | Whether outbound network access is allowed |
network.allowed_hosts | array | ["*"] | Whitelist of allowed hostnames (supports wildcards) |
network.blocked_ports | array | [] | Ports the agent cannot connect to |
Filesystem Permissions
| Field | Type | Default | Description |
|---|---|---|---|
filesystem.writable_paths | array | ["/home/user", "/tmp"] | Directories the agent can write to |
filesystem.read_only_paths | array | [] | Directories the agent can read but not modify |
filesystem.blocked_paths | array | [] | Directories the agent cannot access at all |
Process Permissions
| Field | Type | Default | Description |
|---|---|---|---|
process.allow_exec | bool | true | Whether the agent can spawn processes |
process.blocked_commands | array | [] | Commands that are blocked from execution |
process.max_processes | int | 20 | Maximum concurrent processes |
Preset Permission Profiles
For convenience, use a preset profile instead of configuring individual fields:
{
"config": {
"type": "cloud",
"base_template": "tpl_code_interpreter",
"resources": {"cpu": 2, "memory_mb": 2048, "timeout": 300},
"permission_profile": "restricted"
}
}| Profile | Network | Filesystem | Process | Use Case |
|---|---|---|---|---|
unrestricted | Full access | Full access | Full access | Trusted internal agents |
standard | Outbound only | Home + tmp writable | All commands | General purpose |
restricted | Whitelist only | Limited write paths | Blocked dangerous commands | Customer-facing agents |
isolated | No network | Read-only except /tmp | No exec | Data analysis only |
Agent-Level Tool Permissions
You can also restrict which tools an agent is allowed to call:
{
"name": "Safe Assistant",
"slug": "safe-assistant",
"model": {"name": "claude-sonnet-4"},
"system": "You are a helpful assistant with limited capabilities.",
"tools": [
{"type": "mcp", "server": "web-search"},
{"type": "mcp", "server": "calculator"}
],
"metadata": {
"tool_policy": {
"allow_list": ["web-search", "calculator"],
"deny_list": ["database-query", "file-write"],
"require_confirmation": ["web-search"]
}
}
}| Field | Type | Description |
|---|---|---|
tool_policy.allow_list | array | Only these tools can be invoked (whitelist mode) |
tool_policy.deny_list | array | These tools are blocked (blacklist mode) |
tool_policy.require_confirmation | array | These tools require user approval before execution |
TIP
Use allow_list for maximum security (deny-by-default). Use deny_list when you want broad access with specific exclusions.
Next Steps
- MCP Tools — Attach tools to your agents
- Sessions — Manage conversation instances
- Sandboxes — Give agents code execution capabilities
- Templates — Use pre-built agent templates
- Sandbox API Reference — Full API docs

