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 five fixed step types: fetch data, filter it, match it to an entry, generate a rewrite, and propose the change. 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
semantic_matchMatches each row to an entry via semantic search
ai_generateRewrites a field's text through the AI content model
propose_changeTurns a matched row into 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": "semantic_match",
        "templateId": "faq",
        "fieldKey": "answer",
        "queryField": "query"
      },
      {
        "type": "ai_generate",
        "instruction": "Rewrite as a direct, one-paragraph answer.",
        "sourceField": "query",
        "targetField": "generated"
      },
      { "type": "propose_change", "valueField": "generated", "mode": "append" }
    ]
  }
}

POST /agents runs the config schema plus each step's own validation before it ever creates the row — a bad templateId or non-text fieldKey comes back as a 400, not a broken agent you find out about after the first run. A semantic_match step's fieldKey must name a text or richText field — the matched value flows straight onto the entry on approval with no further type check, so a number, boolean, reference, or media field is rejected at validation time instead.

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 that loses its preceding semantic_match step 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, with one rule: a propose_change step needs a semantic_match step somewhere before it in the array, since that's what supplies the entry and field to update.

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.