Skip to main content

Creating Agents

This guide walks you through creating, configuring, and deploying an AI agent on Orbit — from defining its behavior to connecting it to live channels.

Step 1: Define the Agent

Create an agent with a name, instructions, and model selection.

Step 2: Add Tools

Tools give your agent the ability to take actions — look up orders, create tickets, check inventory, etc. There is no separate “add tool” endpoint. Tools are configured through the tools array on the agent’s create or update body. Each entry is one of:
  • A string referencing a built-in or registered tool by id (see GET /agents/tools for the catalog).
  • A function-call object with name, description, and a JSON-Schema parameters object — the standard function-calling contract the model receives.
The same tools array is accepted on POST /api/v1/agents at create time. A function-call entry tells the model the tool’s shape but does not, by itself, perform an outbound HTTP call.

Reusable HTTP tools (custom tools)

To register a reusable tool that calls an external HTTP endpoint, use the custom-tools surface. Custom tools are tenant-scoped, SSRF-validated, and can be referenced by name from any agent’s tools array.
Once registered, add the tool to an agent by its name in the tools array (e.g. "tools": ["lookup_order"]).

Managing custom tools

Beyond create, the custom-tools surface is a full CRUD API rooted at /api/v1/agents/custom-tools. Every endpoint is tenant-scoped and requires the owner, admin, or developer role for writes. A custom tool is returned in this shape. The plaintext executor_secret is never echoed back — executor_secret_set reports whether one is stored:
List all custom tools
Returns { "tools": [...], "total": <count> }. Get a single custom tool
Returns 404 NOT_FOUND if the tool does not exist in your tenant. Update a custom tool PATCH applies a partial update — send only the fields you want to change. Accepts description, json_schema, executor_url, executor_secret, enabled, timeout_ms, and confirmation. For executor_secret: send a new value to rotate it, send null to clear it, or omit it to leave it unchanged. A changed executor_url is re-validated against the SSRF rules before it is saved.
Delete a custom tool Deleting a tool also removes it from every agent that referenced it, so no agent is left pointing at a dead tool.
Returns { "id": "tool_abc123", "deleted": true }. Test a custom tool (dry run) Fire a one-off request at the tool’s executor_url with sample args to confirm it is wired up correctly. This never persists anything and forwards the live response back to you. Optionally override the URL, secret, or timeout to test an unsaved change without first updating the tool.
The response reports the outcome of the call to your executor:
When the call fails, ok is false, error carries a short reason (for example a timeout or an HTTP 500 from your endpoint), and status is the HTTP status your executor returned (or 0 when no response was received).

Built-in Tools

Orbit provides several built-in tools that agents can use out of the box. The authoritative list is returned live by GET /api/v1/agents/tools: Reference a built-in tool by its ID in the tools array when creating an agent (for example, "tools": ["search_knowledge"]). To ground search_knowledge in your own content, attach documents via knowledge_base_ids (see Step 3).

Step 3: Connect Knowledge Base

Knowledge lives in a knowledge base (KB) — a reusable container of documents that you create once and then link to one or more agents. There is no per-agent upload endpoint; instead you create a KB, upload documents to it, and attach the KB to the agent by ID.

3a. Create a knowledge base

The response includes the new KB’s id (e.g. kb_xyz789). Use it in the next two steps.

3b. Upload documents

Upload each document to the KB with a multipart request. The file part is required; type is optional and inferred from the file extension when omitted.
Orbit chunks, embeds, and indexes documents in Qdrant for fast retrieval. Embeddings are handled by Orbit’s internal pipeline — you don’t manage embedding API keys. Attach one or more KBs to the agent with the knowledge_base_ids array on create or update. IDs are validated against your tenant — an unknown ID returns 422 INVALID_KNOWLEDGE_BASE_IDS.

Step 4: Configure Guardrails

Set safety boundaries for your agent’s behavior. Guardrails are part of the agent itself — there is no separate guardrails endpoint. Send safety_config and escalation_triggers on the create (POST /agents) or update (PUT /agents/:id) body.
safety_config accepts: blocked_topics, max_response_length, content_policy, pii_redaction, pii_detection, harmful_content, prompt_injection, content_filter, and approval_required. Each escalation_triggers entry is one of { "type": "keyword", "value": "<string>" }, { "type": "sentiment_below", "value": <0–1> }, or { "type": "turn_count_above", "value": <positive integer> } (replacing the old flat escalation_keywords / max_turns fields).

Step 5: Deploy

Deploying is how you bind an agent to a channel — there is no channels field on the agent itself, and channels are never assigned on the create or update body. Activate your agent to start handling live conversations. Each deploy call targets one channel, so call the endpoint once per channel you want to go live on. The request body requires a channel field — one of webhook, sms, whatsapp, voice, or rcs. A bodyless POST is rejected with 422 Unprocessable Entity. phone_number is required when channel is voice and optional for the other phone-backed channels (sms, whatsapp, rcs); supply webhook_url for the webhook channel. Deploy to WhatsApp:
Deploy to the webhook channel (provide webhook_url so Orbit can post agent events to your endpoint — it must be an https:// URL):
To go live on multiple channels (for example SMS, voice, and RCS), repeat the call once per channel:

Testing

Test your agent before going live without sending real messages or incurring channel/outbound costs. Use the dry-run endpoint to replay a scripted scenario in sandbox mode — mutative tools are short-circuited and no live side effects occur (note: the agent still calls the LLM, so model/token cost applies):
The dry-run response returns a turn-by-turn trace and (optionally) an assertion verdict — supply expected_tool_calls, must_contain, or must_not_contain inside scenario to gate the run. For an interactive single-turn test against the live agent runtime, use the chat endpoint instead. This is a real turn — it incurs LLM cost — but it is not channel-routed, so no outbound message is sent: