Draftbase

Building custom agents

See the agents pillar page for what agents are and which plan you need before diving into the API.

A custom agent is a pipeline you build from fixed step types: fetch data, filter it, generate a rewrite, and propose a change (matching it to an entry and having the AI model apply it are one step). There's no arbitrary code to write or review — every step is a small, typed handler on our side, so the security boundary is the step list, not your pipeline logic. Custom agents are gated behind the Enterprise plan (customAgents feature key).

What is a custom agent?

An agent instance is one row: a type, a config, a frequency, and an enabled flag. For type: "custom", config.steps is an array of 1–20 steps. Rows flow through the array in order — each step reads fields other steps added and writes its own, the way a shell pipeline passes lines forward.

Step typeWhat it does
fetch_integration_dataPulls rows from a connected integration (Google Search Console today)
filterKeeps rows where a numeric field passes a comparison
ai_generateRewrites a field's text through the AI content model
propose_changeMatches each row to an entry via semantic search, then has the AI model merge the row into the target field and queues the result as a change proposal for review

How do I build the config for a custom agent?

Chain the five step types above into one steps array, then send it as config on POST /agents with type: "custom". A pipeline that turns high-impression, unanswered search queries into drafted FAQ answers:

POST /agents
{
  "envId": "production",
  "type": "custom",
  "name": "FAQ query miner",
  "frequency": "weekly",
  "config": {
    "steps": [
      {
        "type": "fetch_integration_data",
        "integrationType": "googleSearchConsole",
        "siteUrl": "https://example.com/",
        "windowDays": 28
      },
      { "type": "filter", "field": "impressions", "operator": "gte", "value": 500 },
      {
        "type": "propose_change",
        "templateId": "faq",
        "fieldKey": "answer",
        "instruction": "Draft a direct, one-paragraph FAQ answer for: {{query}}",
        "matchField": "query"
      }
    ]
  }
}

POST /agents runs the config schema plus each step's own validation before it ever creates the row — a bad templateId or unusable fieldKey comes back as a 400, not a broken agent you find out about after the first run. A propose_change step's fieldKey can be any field type except media or reference — the model is told the field's type and rules (length, min/max, pattern) and its output is re-checked against them before a proposal is ever queued.

What can I do with an existing custom agent?

MethodPathDoes
GET/agents/typesLists agent types, customAgents-locked or not, for the org's plan
GET/agentsLists agent instances in the current org
POST/agentsCreates an instance from a type + config
PATCH/agents/:idRenames it, edits config, toggles enabled, or changes frequency
POST/agents/:id/runTriggers a run immediately, even while disabled
GET/agents/:id/runsLast 50 runs, newest first, with proposedCount and aiTokensSpent

frequency is "daily" or "weekly". Editing config on PATCH /agents/:id re-validates the whole pipeline the same way POST /agents does — a propose_change step pointed at a templateId/fieldKey that no longer exists fails the patch instead of saving a pipeline that can't produce a proposal.

Why did my custom agent produce zero proposals?

Three causes, in order of how often they show up:

GET /agents/:id/runs returns proposedCount and error per run — a 0 with no error means the pipeline ran clean and nothing qualified, not that something broke.

Is a custom agent's step list a security boundary?

Yes. There's no eval, no user-supplied function, no arbitrary HTTP calls beyond the fixed googleSearchConsole integration path. Every step is one of the five typed handlers above, validated by its own schema before the pipeline saves — the attack surface is exactly as wide as those five step types, not as wide as whatever code an org could otherwise submit. See how the same model powers AI-driven edits more broadly on the MCP server pillar page.

FAQ

Does a custom agent write directly to an entry?

No. Every propose_change step ends in a change proposal, reviewed and approved the same way a prebuilt agent's proposals are — a custom agent never writes to an entry on its own.

Can I mix step types in any order?

Any order the config schema accepts. A propose_change step is self-contained — it matches the entry to update (via semantic search) and applies the change in the same step, so it has no ordering requirement relative to other propose_change or find_interlinks steps.

Which integrations can fetch_integration_data pull from?

Google Search Console only, as of the current API version.

Does ai_generate need a separate AI provider connection?

No. It runs against Draftbase's own AI content model — no separate API key or provider connection required, only the org's monthly AI token quota.