HTTP & LLM connectors

The two built-in connector adapters — generic HTTP and OpenRouter-compatible LLM — with worked mapper/combiner examples.

Two adapters ship built in and need no import: generic HTTP for any REST API, and LLM for OpenRouter-compatible chat completions. Both follow the connector model in the overview.

HTTP connector (generic-http)

requestMapper returns { body } plus optional path_params / query_params; responseCombiner receives { status_code, body, headers }.

// GET — read query params back from the response body
function getReq(ctx) { return { query_params: { id: ctx.vars.order_id } }; }
function getResp(ctx, response) {
  return { order: response.body, http_status: response.status_code };
}

connector("fetch_order", {
  connection: "generic-http",
  instance: "orders-api",
  operation: "get_order",
  requestMapper: getReq,
  responseCombiner: getResp,
  next: "review",
});
// POST — send a JSON body
function createReq(ctx) {
  return { body: { customer: ctx.vars.customer_id, total: ctx.vars.total } };
}
function createResp(ctx, response) { return { order_id: response.body.id }; }

connector("create_order", {
  connection: "generic-http",
  instance: "orders-api",
  operation: "create_order",
  requestMapper: createReq,
  responseCombiner: createResp,
  retryPolicy: { maxAttempts: 3, initialInterval: 1, backoffCoefficient: 2.0 },
  onError: "create_failed",
  next: "confirm",
});

Pair the call with a retryPolicy for transient failures and an onError step for the give-up case — see Errors & retries.

LLM connector

requestMapper returns an OpenRouter-style request ({ model, messages: [{ role, content }] }); responseCombiner receives { id, model, choices, usage }, with the text at response.choices[0].message.content.

function askReq(ctx) {
  return {
    model: "anthropic/claude-3.5-sonnet",
    messages: [
      { role: "system", content: "Summarize the ticket in one sentence." },
      { role: "user", content: ctx.vars.ticket_text },
    ],
  };
}
function askResp(ctx, response) {
  return {
    summary: response.choices[0].message.content,
    tokens: response.usage,
  };
}

connector("summarize", {
  connection: "llm",
  instance: "default",
  operation: "chat",
  requestMapper: askReq,
  responseCombiner: askResp,
  next: "store",
});
Confirm the exact shapes

Operation schemas can vary by how a connection is configured. Before writing the mapper/combiner, run flowctl conn schema <connection> <operation> to see the exact request_schema and response_schema, and match them.

LLM vs agent()

An LLM connector calls a model API directly with credentials you configure. The agent() step instead asks the Claude Code session that’s driving the run to do the thinking — no API key in the workflow, and the human/agent can intervene. Use the connector for unattended automation; use agent() when a run is driven interactively.

For services beyond plain HTTP, import any MCP server as a connector — see MCP connectors.