Skip to content

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

python
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']}")
javascript
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}`);
bash
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

FieldTypeRequiredDescription
namestringHuman-readable name
slugstringURL-safe identifier (unique)
modelobjectLLM configuration
systemstringSystem prompt / instructions
toolsarrayMCP tools to attach
mcp_serversarrayCustom MCP server connections
metadataobjectCustom key-value metadata
visibilitystringprivate (default) or template

Model Configuration

json
{
  "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:

ModelBest For
claude-sonnet-4Complex reasoning, tool use
gpt-4oGeneral purpose, multimodal
deepseek/deepseek-v3Cost-effective, fast
google/gemini-2.5-proLong context, multimodal

Sessions

A session is a conversation instance with an agent. Sessions maintain state across multiple interactions.

Create a Session

python
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

python
# 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) → archive

Sessions persist until explicitly archived. You can resume any active session at any time.

Versioning

Agents are versioned resources. Every update creates a new version:

python
# 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

bash
# 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.

python
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"
            }
        ]
    }
)
FieldTypeRequiredDescription
handoffs[].agent_idstringID of the target agent
handoffs[].namestringDisplay name for the sub-agent
handoffs[].descriptionstringWhat this agent specializes in
handoffs[].triggerstringWhen to invoke this agent (used in system prompt context)

Multiagent Configuration

The multiagent field controls how the orchestrator manages sub-agents:

json
{
  "multiagent": {
    "mode": "orchestrator",
    "max_delegations": 5,
    "parallel": false,
    "context_sharing": "summary",
    "timeout_per_handoff_ms": 60000
  }
}
FieldTypeDefaultDescription
modestring"orchestrator""orchestrator" (one controls many) or "swarm" (peer-to-peer)
max_delegationsint10Max handoffs per session turn
parallelboolfalseWhether sub-agents can run concurrently
context_sharingstring"summary""full" (pass entire context) or "summary" (pass condensed context)
timeout_per_handoff_msint60000Timeout 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:

python
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:

python
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

SkillDescriptionBest For
structured-planningAgent creates a step-by-step plan before executing, tracks progressComplex multi-step tasks
reflection-loopAgent reviews its own output and iterates to improve qualityWriting, analysis, code review
long-running-stateMaintains state across multiple iterations with checkpointingResearch, data processing
web-browsingEnhanced web navigation with page understanding and extractionResearch, monitoring
code-executionRuns code in sandbox, inspects output, iterates on errorsDevelopment, data analysis
file-managementReads, writes, and organizes files in the sandbox filesystemDocument processing

Skill Configuration

Skills can accept optional configuration via an object form:

json
{
  "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 loop

Skills 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:

python
# 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

FieldTypeDefaultDescription
network.enabledbooltrueWhether outbound network access is allowed
network.allowed_hostsarray["*"]Whitelist of allowed hostnames (supports wildcards)
network.blocked_portsarray[]Ports the agent cannot connect to

Filesystem Permissions

FieldTypeDefaultDescription
filesystem.writable_pathsarray["/home/user", "/tmp"]Directories the agent can write to
filesystem.read_only_pathsarray[]Directories the agent can read but not modify
filesystem.blocked_pathsarray[]Directories the agent cannot access at all

Process Permissions

FieldTypeDefaultDescription
process.allow_execbooltrueWhether the agent can spawn processes
process.blocked_commandsarray[]Commands that are blocked from execution
process.max_processesint20Maximum concurrent processes

Preset Permission Profiles

For convenience, use a preset profile instead of configuring individual fields:

json
{
  "config": {
    "type": "cloud",
    "base_template": "tpl_code_interpreter",
    "resources": {"cpu": 2, "memory_mb": 2048, "timeout": 300},
    "permission_profile": "restricted"
  }
}
ProfileNetworkFilesystemProcessUse Case
unrestrictedFull accessFull accessFull accessTrusted internal agents
standardOutbound onlyHome + tmp writableAll commandsGeneral purpose
restrictedWhitelist onlyLimited write pathsBlocked dangerous commandsCustomer-facing agents
isolatedNo networkRead-only except /tmpNo execData analysis only

Agent-Level Tool Permissions

You can also restrict which tools an agent is allowed to call:

json
{
  "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"]
    }
  }
}
FieldTypeDescription
tool_policy.allow_listarrayOnly these tools can be invoked (whitelist mode)
tool_policy.deny_listarrayThese tools are blocked (blacklist mode)
tool_policy.require_confirmationarrayThese 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