Event pipelines
An event pipeline is a deterministic flow that receives an inbound event and does fixed work with it: a lead-form submission, a third-party webhook, or an in-app action arrives at the pipeline’s endpoint, gets normalized, and runs through an ordered list of actions — write the row to a dataset, send an email, call a connected integration, broadcast a live update, or return a custom response. Pipelines are how a page captures leads, and how Erdo enriches and routes them without an agent in the loop on every event. Each pipeline has:- a slug and name — a stable, human-readable handle (e.g.
acme-leads-a1b2c3d4), - a state —
active,disabled, orproposed, - a source kind —
browser_form,third_party_webhook,custom_http,internal, …, - an inbound endpoint URL — where events are POSTed,
- an auth mode — how inbound events are verified (HMAC, shared secret, provider signature, signed-in viewer, or public),
- the actions it runs and the datasets it writes to, and
- an execution log — every event it received, with status (
accepted/rejected/failed), a payload preview, the response, and any error.
Where data lands
A pipeline’sdataset.write actions persist rows to a dataset — per-row, SQL-queryable
storage. To see captured leads, query the dataset the pipeline writes to (shown as
write_target_datasets), not the pipeline itself. The pipeline’s execution log tells you
whether events are arriving and being accepted; the dataset holds the rows.
Emails a pipeline sends
A pipeline that emails on an event — a lead alert to your sales inbox, a confirmation back to the person who submitted the form — has Erdo compose the message. The pipeline supplies the content (a heading, the captured fields as label/value rows, a button through to the page the lead came from) and Erdo renders it in the standard Erdo styling, with a plain-text version alongside for clients that block HTML. Addresses and links in the fields become clickable, so a lead alert can be replied to from the notification itself.Pipeline purpose
Every pipeline declares apurpose — its role — so you can tell capture flows apart from
analytics infrastructure without guessing from names:
record_capture— a pipeline whose job is persisting submitted records to a dataset (it has at least onedataset.writeaction). This is how you find which datasets receive a flow’s records: filter pipelines bypurpose = record_captureand read theirwrite_target_datasets(each entry is a fully-qualifiedorg-slug.dataset-slug). You can set this explicitly when creating or updating a pipeline; acustompipeline that writes to a dataset is also promoted torecord_captureautomatically at save time.page_events— the managed first-party page-analytics pipeline described below. Reserved for Erdo’s own provisioning; you can’t set it.custom— everything else: a webhook or enrichment flow that doesn’t persist records.
record_capture pipelines and
read their write_target_datasets, then query that dataset.
Every dataset.write row is stamped at ingestion with columns your transform doesn’t set:
variant, artifact_id, page_url (from the page envelope), plus a set of request signals that
let you keep your metrics clean and segment them by who actually showed up:
is_test— a boolean, always present.truewhen the submission was tagged as test traffic (see Marking test traffic below), otherwisefalse. Filter it out to count real leads and conversions.device_type—"mobile","tablet","desktop", or empty, classified from the request’sUser-Agentat ingestion. Segment funnels by it to compare mobile vs desktop (a page can take most of your spend yet convert zero mobile visitors — this column surfaces that without parsing User-Agents by hand).browser— the coarse browser family ("chrome","safari","firefox","edge","samsung","opera","other", or empty), also from theUser-Agent.in_app— the in-app webview container the visit came from ("instagram","facebook","tiktok", and similar), or empty for a normal standalone browser. In-app webviews routinely break modals and payment flows, so this separates “converts badly on mobile” from “converts badly inside Instagram’s browser”.language— the visitor’s preferred language, the primary tag of theAccept-Languageheader (e.g."pt-BR"), or empty. Check that a Brazilian, Colombian, or French campaign is actually reaching PT/ES/FR speakers.country,region,city— the visitor’s coarse location: ISO-2 country (e.g."US"), ISO-3166-2 region code (e.g."NY"), and city name, from the serving edge. Empty when the request reaches the pipeline through an ingress that carries no edge geo. Segment by them to verify geo-targeted campaigns (e.g. “New Yorkers relocating to Miami”) landed where you paid for.
Marking test traffic
QA checks and automated evaluations submit to the same pipelines your real visitors do, so their rows would otherwise inflate lead and funnel counts. Tag a submission as test traffic and it lands withis_test = true, keeping it out of your real-traffic metrics. Two equivalent markers:
- Send the request header
X-Erdo-Test: 1(1ortrue), or - Include a top-level
"is_test": truefield in the JSON body.
is_test = true rows, so their funnel counts exclude test traffic automatically;
add the same is_test not_equals true default filter to your own lead datasets to get the same
behaviour on reads.
Auto-provisioned page-events pipelines
Alongside the pipelines you or your agents create, every published page gets one page-events pipeline automatically (itspurpose is page_events — see
Pipeline purpose above). It receives the page’s first-party analytics events — pageviews, scroll
milestones, section views, CTA clicks, form starts, leads, video plays — and writes them to your
organization’s shared Page events dataset, stamped with the page, experiment variant, session,
campaign attribution, is_test, device_type, browser, in_app, language, and geo
(country/region/city). Events with names outside that fixed vocabulary are rejected, which you
can see in the pipeline’s execution log. Disabling a page-events pipeline turns first-party
analytics off for that page; Erdo won’t re-create it. See
Pages → First-party page events for what’s captured and how to
query it.
Inspecting your pipelines
You can list your pipelines, read one’s configuration, and review its run history over MCP, the REST API, or the CLI. Everything is org-scoped — a caller only ever sees their own organization’s pipelines — and pipelines are referenced by slug (a UUID is also accepted).CLI
erdo login, erdo org).
MCP tools
Identity and RBAC ride the request context, so a caller can only reach their own org’s pipelines.
REST
Base URLhttps://api.erdo.ai. Authenticate with Authorization: Bearer <token> and select the
org with X-Organization-ID.
These are read endpoints — pipelines are created and edited from the page that owns them. To
confirm a pipeline is capturing events end-to-end, check its executions here, then query the
dataset it writes to.

