Manage External Agents Programmatically — SDK Quickstart
Register, trigger, schedule, and cost-track CrewAI / LangChain / custom AI agents from your code. Step-by-step SDK guide using @dobbyai/sdk v0.2.0+.
What you will learn
- Install @dobbyai/sdk (JS) or dobby-ai-sdk (Python) and authenticate with a gateway service key
- Register an external agent (CrewAI / LangChain / custom) without using the dashboard
- Trigger an agent on demand and read back its trigger history
- Create, pause, and delete a recurring schedule for an agent
- Query month-to-date and daily cost for any registered agent
- Choose between SDK, MCP, and REST when building automation
Why Manage Agents Programmatically?
The Dobby dashboard is the easiest way to set up an external agent for the first time. But once an agent is part of your platform, you usually want it to live in code — checked into your repo, deployed by your CI pipeline, monitored by your on-call automation. v0.2.0 of the SDK gives you the full surface to do that.
Every change to an external agent's endpoint, schedule, or auth secret requires a human to log into the dashboard, find the agent, click edit, save. Cost queries mean opening a chart and reading numbers off the screen.
Agent definitions live in your IaC. CI registers them on first deploy and updates them on subsequent deploys. A nightly script reads costs from the SDK and posts a Slack summary. A coordinator AI agent registers and triggers subordinates on demand.
Step 1 — Install + Authenticate
Pick the SDK that matches your stack. Both packages share the same surface, just the language convention differs (camelCase in JS, snake_case in Python).
// JavaScript / TypeScript
npm install @dobbyai/sdk
// Python
pip install dobby-ai-sdkCreate a service gateway key at dobby-ai.com → Gateway → API Keys. Pick `gk_svc_*` (500 RPM) and grant scopes `agents:read`, `agents:manage`, `agents:trigger` (or just `agents:*`). Copy the key — it is shown only once.
Set DOBBY_API_KEY in your environment. The SDK reads it automatically; you can also pass it as `apiKey` / `api_key` to the constructor.
Org-scoped vs tenant-scoped keys: a key with no tenant_id can operate across all tenants in the org. A tenant-scoped key is sandboxed — cross-tenant requests return 404. Use tenant-scoped keys when sharing a key with a single team.
Step 2 — Register Your First Agent
The response includes a fresh gateway key the agent uses to call back into Dobby (events, LLM proxy). Save it in your secret store immediately — it cannot be retrieved later.
import { DobbyClient } from '@dobbyai/sdk';
const dobby = new DobbyClient({ apiKey: process.env.DOBBY_API_KEY });
const { data } = await dobby.agents.register({
display_name: 'Research Crew',
framework: 'crewai',
protocol: 'webhook',
endpoint_url: 'https://app.crewai.com/api/v1/crews/abc/kickoff',
capabilities: ['research', 'summarize'],
auth_config: {
method: 'api_key',
header: 'Authorization',
prefix: 'Bearer',
key: process.env.CREWAI_KEY,
},
});
const agentId = data.agent.agent_id;
const agentKey = data.gateway_key; // SAVE NOW — cannot be retrievedfrom dobby_sdk import DobbyClient
import os
with DobbyClient(api_key=os.environ['DOBBY_API_KEY']) as dobby:
reg = dobby.agents.register(
display_name='Research Crew',
framework='crewai',
protocol='webhook',
endpoint_url='https://app.crewai.com/api/v1/crews/abc/kickoff',
capabilities=['research', 'summarize'],
auth_config={
'method': 'api_key',
'header': 'Authorization',
'prefix': 'Bearer',
'key': os.environ['CREWAI_KEY'],
},
)
agent_id = reg['data']['agent']['agent_id']
agent_key = reg['data']['gateway_key'] # save thisStep 3 — Trigger and Track
Trigger payloads are framework-specific. CrewAI expects an `inputs` object whose keys match the crew's declared input fields. n8n / Make / custom webhooks pass through the inputs as the request body.
// Fire it now
const result = await dobby.agents.trigger(agentId, {
inputs: { topic: 'AI agent governance' },
});
console.log(result.data.trigger_id, result.data.status);
// → trig_abc123 sent
// Read history with stats
const history = await dobby.agents.triggers(agentId, {
page: 1,
page_size: 10,
include_stats: true,
}) as any;
console.log(`${history.data.stats.completed} completed of ${history.data.stats.total}`);
// Retry a specific failed trigger
await dobby.agents.retryTrigger(agentId, 'trig_failed_001');Triggers are synchronous on the wire (the SDK call waits for the agent's webhook to respond, up to 120s). For long-running CrewAI crews, this is fine — the response carries the result. For short-running agents, the call returns immediately with status='sent' and the agent posts events back via its callback URL.
Step 4 — Schedule Recurring Runs
One schedule per agent. The schedule_config supports daily / weekly / monthly with optional time-of-day. Pass overlap_policy='skip' to prevent overlapping runs, 'queue' to queue them, or 'allow' to run in parallel.
dobby.agents.create_schedule(
agent_id,
name='Daily research',
task_title='Research AI trends',
schedule_config={
'frequency': 'daily',
'time': '09:00',
},
trigger_payload={'topic': 'AI safety'},
overlap_policy='skip',
)
# Pause before a deploy window
dobby.agents.update_schedule(agent_id, paused=True, pause_reason='deploy window')
# Resume after
dobby.agents.update_schedule(agent_id, paused=False)
# Delete (soft — sets enabled=false)
dobby.agents.delete_schedule(agent_id)Step 5 — Monitor Costs
Cost data comes from the gateway's LLM request log — every LLM call routed through Dobby contributes to the agent's MTD cost. Daily breakdown is available for the last 90 days.
const costs = await dobby.agents.getCosts(agentId, { days: 7 }) as any;
console.log(`Last 7 days: $${costs.data.cost_mtd_usd.toFixed(2)}`);
console.log(`Requests: ${costs.data.mtd_requests}`);
console.log(`Tokens in: ${costs.data.mtd_input_tokens}`);
console.log(`Tokens out: ${costs.data.mtd_output_tokens}`);
for (const day of costs.data.daily) {
console.log(` ${day.day}: $${day.cost_usd.toFixed(4)} (${day.request_count} req)`);
}If your agent uses its own LLM keys (not routed through the Dobby Gateway), cost will show 0. Route LLM calls through the Gateway endpoint to get unified cost tracking — it is the same one-line change as in the CrewAI Gateway integration.
When to Use Which Surface
- SDK — for any code you check in: scripts, services, CI jobs, IaC, AI coordinators
- MCP tools — for chat-driven ops in Claude Desktop / Cline (12 tools, full parity with SDK)
- REST API — for languages without an SDK (Go, Rust, Ruby, etc.) — same paths as SDK uses internally
- UI — for visual monitoring, ad-hoc fixes, onboarding new agents the first time
Error Handling
Both SDKs raise typed errors so you can branch on them cleanly. Catch DobbyAuthError on missing/invalid keys, DobbyNotFoundError on missing agents (or cross-tenant probes — Dobby returns 404 instead of 403 to avoid leaking existence), DobbyConflictError when a schedule already exists, DobbyRateLimitError on plan limits, and DobbyServerError on agent webhook failures (502/504).
import { DobbyClient, DobbyNotFoundError, DobbyBudgetExceededError } from '@dobbyai/sdk';
try {
await dobby.agents.trigger(agentId, { inputs });
} catch (err) {
if (err instanceof DobbyNotFoundError) {
console.error('Agent does not exist or is in another tenant');
} else if (err instanceof DobbyBudgetExceededError) {
console.error('Agent budget exhausted — wait for next period or raise the limit');
} else {
throw err;
}
}Breaking Change in v0.2.0 — Heads Up
register() now requires framework and protocol explicitly. Both were optional in v0.1.0 with defaults of 'custom' and 'rest', which silently masked typos. If you have existing code calling register() without them, add them — the migration is two lines.
Where to Go Next
- Read the full SDK guide: dobby-ai.com/docs/sdk/external-agents
- Hook the SDK into your CI: register a temp agent → trigger with a known input → assert response → deregister
- Connect the same surface as MCP tools to Claude Desktop or Cline (see the MCP Protocol Tutorial)
- Use the REST API directly if you operate in a language without an SDK (see the REST API Quickstart)