Bots
Create and configure a Bot, bind it to a credential, and preview its token usage. Read the Bots guide.
Before reading any other page in these docs, understand the four entities and how they fit together. Every other page assumes you’ve read this one.
| Entity | Owner | Purpose |
|---|---|---|
| MCP Template | Crafted AI | Curated catalog of MCP servers (GitHub, Linear, Stripe, Zoom, …) installable in one click. Becomes a plugin when installed for your org. Source: CRA-222, CRA-244 |
| Skill | Org-editable | Prompt-shaping unit — instructions + typed variables, in always or on_demand mode. Attached to a Bot. Source: CRA-227 |
| Industry Pack | Crafted AI | Recipe: a set of MCP templates + Skills + a recommended model + a system prompt + compliance flags. Installing a pack creates the integrations, skills, and a Bot in one transaction. Source: CRA-231 |
| Bot | Org-editable | Channel-agnostic hub: (model, credential, system prompt, skills[], plugins[], gating mode). The always-on resolver for every gateway request and every inbound WhatsApp thread. Source: CRA-219, CRA-225 |
┌────────────────────────────────────────────────────────────────┐│ Industry Pack ──install──▶ creates ││ │ ││ ▼ ││ ┌─ Bot ─────────────────────────────────────────────┐ ││ │ model · credential · system prompt │ ││ │ skills[] ◀── compose from Skill templates │ ││ │ plugins[] ◀── compose from MCP templates + │ ││ │ first-party (WhatsApp, …) │ ││ │ gating: always-on, with token-budget guard │ ││ └──────────────────────────────────────────────────┘ ││ │ ││ ├── bound to a gateway credential ──▶ /v1/chat/completions│ └── bound to a WhatsApp number ──▶ inbound reply worker │└────────────────────────────────────────────────────────────────┘A Bot is the nexus. MCPs and Skills are components that slot into it. Industry Packs are pre-assembled configurations that create a fully wired Bot in one step.
When a chat-completions request arrives at the gateway, the BotResolver runs before the request reaches the upstream model provider. Source: CRA-225
Identify the bot. The resolver checks metadata.crafted.botId (if the credential’s bot_override_allowed is true) and then falls back to the credential’s default_bot_id. If neither is set, the request flows through without a bot and none of the steps below apply.
Prepend the system prompt. The bot’s system prompt is prepended to the message list, followed by any always-mode skill instructions.
Filter plugins. Only plugins in the bot’s allowedPluginIds list are eligible for tool injection. Plugins installed for the org but not in the bot’s allowlist are invisible to this request.
Apply tool gating. In all_at_once mode, all allowed plugin tools are exposed to the model directly. In on_demand mode, tools collapse to {name, description} stubs and three meta-tools take over discovery (see Skills).
Run the token-budget guard. Before calling upstream, the gateway computes injectedTokens (system prompt + skill instructions + tool schemas). If limits are exceeded, the request is rejected with a structured 400.
The gateway enforces two limits before every upstream call when a bot is resolved. Source: CRA-226
injectedTokens ≤ model.contextWindow × tokenBudgetPct / 100toolCount ≤ toolCountCaptokenBudgetPct (1–50, integer) and toolCountCap are configured on the Bot. The budgetTokens ceiling ensures the bot’s injected context never crowds out the conversation itself.
Violations return a structured 400 error:
{ "error": "bot_overhead_exceeded", "message": "Bot system prompt and skill instructions exceed the configured token budget.", "details": { "injectedTokens": 4200, "budgetTokens": 4096, "tokenBudgetPct": 10, "modelContextWindow": 40960 }}{ "error": "bot_tool_overflow", "message": "Bot allowlist contains more tools than the configured cap.", "details": { "toolCount": 35, "toolCountCap": 20 }}The pre-flight token preview endpoint lets you check these numbers before a request is sent, which is useful for surfacing limits in client UIs.
A credential can allow the caller to switch bots on a per-request basis by setting bot_override_allowed = true on the credential. Source: CRA-229
Send the override in the request body:
{ "metadata": { "crafted": { "botId": "<bot-uuid>" } }, "messages": [...]}The gateway strips metadata.crafted before forwarding to the upstream provider. Other namespaces inside metadata (e.g. metadata.openai) pass through unchanged. This contract is stable — the field name and location will not change.
Bots
Create and configure a Bot, bind it to a credential, and preview its token usage. Read the Bots guide.
Skills
Understand always vs on_demand mode and the three meta-tools that power progressive tool
discovery. Read the Skills guide.
Marketplace
Install an Industry Pack or an MCP template from the Marketplace. Browse the Marketplace guide.
Gateway API
Full request/response reference for POST /v1/chat/completions. Browse the
reference.