OXYGENOxygen/ Docs
Providers

Waterfalls

Ordered provider attempts that stop at the first usable result.

A waterfall tries providers in order until one returns a usable result.

Waterfalls find a value the row is missing. To check an address the row already has, see Email verification — a different chain with its own catch-all escalation.

Capabilities

--capability takes work_email, mobile_phone, or linkedin_url. Each writes the value, a match confidence, and the provider that produced it. mobile_phone adds --verify-phone (line type and carrier); linkedin_url gates every hit through name-and-company identity validation.

Which provider each chain tries first and what it falls back to is listed under Waterfall defaults. Override the order for one run with --provider-order.

Previewing an enrichment

oxygen enrich-column preview <contacts-table> \
  --capability work_email \
  --linkedin-url-column linkedin_url \
  --company-domain-column domain \
  --limit 10 \
  --json

Preview calls no provider and spends 0 credits. It returns the resolved provider profile, per-provider preflight, and the credit estimate that sizes --max-credits.

Per-cell provenance

An enrichment cell records the whole call trace — source is the tool that won:

{
  "value": "ada@acme.com",
  "source": "leadmagic.email_finder",
  "confidence": "verified",
  "attempts": [
    { "provider": "hunter", "operation": "email_finder", "status": "no_result", "latency_ms": 412 },
    { "provider": "leadmagic", "operation": "email_finder", "status": "success", "latency_ms": 380, "billing": { "credits_used": 1 } }
  ]
}

Attempt status is success, no_result, skipped, error, or incomplete_async (the provider took the request async and is polled later — not a failure). A skipped attempt carries a reason such as missing_input or credit_ceiling_reached. Inspect a cell with oxygen cells inspect.

Cost behavior

Billing depends on the intent. Work-email and phone waterfalls charge only the lane that returns a value, so a row that resolves early costs less than one that exhausts the list. LinkedIn-URL and company-field waterfalls charge every managed lane they attempt, whether or not it finds anything — see tool costs. --max-credits is required on a live run and caps total spend either way.

Lanes priced above 500 credits per row are pre-skipped unless you pass --allow-premium-lanes, so an unattended run cannot bill-shock. They appear in the trace as skipped with reason premium_lane_not_opted_in — that, not an empty chain, is why an expensive mobile_phone provider never fires by default.

Running live

oxygen enrich-column run <contacts-table> \
  --capability work_email \
  --linkedin-url-column linkedin_url \
  --company-domain-column domain \
  --limit 100 \
  --approved \
  --max-credits 100 \
  --json

Company field enrichment has its own helper. run defaults to live mode, so it needs --approved and --max-credits:

oxygen companies enrich preview <accounts-table> --missing-fields headcount,industry --limit 10 --json
oxygen companies enrich run <accounts-table> --missing-fields headcount,industry --limit 100 --approved --max-credits 100 --json
  • Provider reference — the default and fallback provider for every chain.
  • Columns — enrichment columns and materialized outputs.
  • Cells — inspecting per-attempt history.

On this page