OXYGENOxygen/ Docs
Guides

First sequence

Build a multichannel sequence, load leads without sending anything, then launch it behind a preview and a spend cap.

A sequence is one journey per lead, mixing email, LinkedIn, WhatsApp, rep call tasks, and CRM tasks. Building it and enrolling leads spends nothing and sends nothing; only starting it dispatches.

Attach a sender first

Sidebar → Sequencer → Accounts (/sequencer/accounts). Tabs: Senders, LinkedIn, Email, WhatsApp, Phone numbers.

  • Email tab → Add inboxes
  • LinkedIn tab → Connect LinkedIn account
  • Senders tab → New sender — one person's inboxes plus their LinkedIn and WhatsApp accounts as one sending identity.

oxygen senders list --json and oxygen mailboxes list --json show what is connected. oxygen senders connect --country DE mints a shareable hosted-auth link, valid 10 minutes; --country is the account owner's normal LinkedIn login country, not your target market.

Build it in the app

Sidebar → Sequencer (/sequencer) → New sequence opens /sequencer/sequences/<id>: an empty draft with four stages — Leads → Sequence → Senders → Launch. The Next: … button at the bottom moves through them.

Leads. Import leads offers Upload a file (CSV, JSON, JSONL, or XLSX), Copy from a table, or HubSpot list. Imported rows are deduped and enrolled automatically — there is no separate enroll button. On the toast N leads imported but not enrolled — no LinkedIn URL, open Identifiers beside the import button, map the LinkedIn column, and re-import.

Sequence. The canvas opens on Sequence start. Click the + between steps ("Add a step") and pick from the catalogue: Send email, Reply email, Send invite, Send message, Send InMail, WhatsApp message, Call task, Create CRM task, Wait, Wait for signal, Branch on signal or data. Copy fields interpolate {{column}} from the lead's row; use {{column|fallback}} where a value may be missing.

Senders. Add senders chooses who this sequence sends from.

Launch. Sending schedule (timezone, days, From/To) and Sending settings: Emails per day / Sends per day across every sender, blank for no limit, reset at UTC midnight. Profile views and other reads don't count.

Build it from the CLI

oxygen sequences create --name "Q3 founders" --slug q3-founders \
  --steps-file ./steps.json --table <table-id> --json

steps.json holds { "steps": [...] }, each step with its own id:

{
  "steps": [
    { "id": "s1", "channel": "email", "kind": "email_send",
      "subject_template": "{{company}} + inbound",
      "body_template": "Hi {{first_name|there}} — quick question." },
    { "id": "s2", "kind": "wait", "days": 3 },
    { "id": "s3", "channel": "email", "kind": "email_reply",
      "body_template": "Bumping this once, {{first_name}}." }
  ]
}

Enrolling is inert — no provider call, no credits, no message:

oxygen sequences enroll q3-founders --from-table --json

--from-table takes up to 500 not-yet-enrolled rows per run; re-run while from_table.has_more is true. For leads outside the bound table, pass --leads-file with { "leads": [{ "row_values": { "email": "…" }, "lead_name": "…" }] }. Attach senders with oxygen sequences update q3-founders --senders <ids>.

Set the do-not-contact list before launching

Sidebar → Sequencer → Do not contact (/sequencer/do-not-contact). Add entries takes pasted people, emails, phones, or company identities; Sync HubSpot pulls in a saved list. Enrollment always enforces this list.

oxygen suppressions add --lead <linkedin-provider-id> --reason manual
oxygen suppressions import --file ./dnc.txt --reason manual
oxygen suppressions addresses --json

import takes a mixed file of emails, bare domains, and LinkedIn URLs, up to 5000 entries. --reason is required when the file contains any domain — a domain block silences everyone at that company.

Launch

No flags means preview only: it activates nothing and sends nothing.

oxygen sequences start q3-founders --json

Read launch_readiness.blockers, copy_preview (exact rendered samples per lead), and the estimated credits.

--dry-run activates the sequence in simulated mode: every step advances, with no provider call, CRM write, or credit.

oxygen sequences start q3-founders --dry-run --json

This command sends real messages to real people.

oxygen sequences start q3-founders --approved --max-live-sends 200 --max-credits 5000 --json

--max-live-sends is a positive-integer ceiling on real external actions, required for any sequence with email, WhatsApp, or CRM-task steps — those cost 0 Oxygen credits, so --max-credits cannot bound them. Omitting it fails with sequence_send_cap_required. --max-credits bounds the LinkedIn track and is optional — omit it for an unbounded run. Every per-action LinkedIn charge is 0 credits today (pricing reference).

In the app the same gate is Review & start on the Launch stage: a dialog listing pending enrollments, estimated credits, rendered copy samples, and any blockers. Start live confirms, and stays disabled while a blocker is listed.

It is hidden until the draft has at least one step and — for LinkedIn or WhatsApp — at least one sender; the CLI reports these as sequence_no_steps and sequence_no_senders.

Watch it and pause it

A reply stops that lead's enrollment automatically, on every channel — nothing to configure. To stop the replier's colleagues too, create the sequence with --stop-on-reply-scope company_domain (freemail domains are never company-matched).

What you wantWhere
Funnel: enrolled, sent, replied, reply rateoxygen sequences stats q3-founders --json, or Sequencer → Analytics (/sequencer/analytics)
Every send, failure, deferral, open, click, reply, bounceoxygen sequences events q3-founders --limit 50 --json
Per-lead state and the last erroroxygen sequences enrollments q3-founders --json
The replies themselvesUnibox (/unibox)

oxygen sequences pause q3-founders stops new dispatches; oxygen sequences resume q3-founders restarts them, and enrollments pick up where they left off. In the app: Pause while active, Resume live while paused.

On this page