Skip to main content
The API has about a dozen objects. Most of them you never create directly — they appear as a side effect of asking for something. This page is the map. Every object carries an object field naming its type, so a response is always self-identifying:

Leads objects

List — a grid of prospects

A list holds rows (people) and columns (facts about them). It is the unit everything in Leads hangs off, and the thing you hand to a campaign.Comes from POST /leads/lists for an empty one, or POST /leads/searches, which creates a list and fills it in one call.
A list is what v1 and v2 called a table. Rows, columns, and credits work the same way; the URLs and field names changed.
A person in a list, plus their cells and status flags (relevance_score, is_deduplicated, is_excluded).Comes from a search or fetch that sources people, or from POST /leads/lists/{list_id}/rows/upsert when you bring your own data.
A column defines something you want to know about every row: their funding stage, whether they use Salesforce, a fit score. Cells are the values, one per row per column.Comes from the search that created the list (it picks columns from your brief), POST /leads/lists/{list_id}/columns for a static or score column, POST /leads/lists/{list_id}/enrich_custom to add one from instructions, or POST /leads/lists/{list_id}/columns/copy to reuse one from another list.Columns come in three flavors. Code columns run Origami’s own research and are the ones that spend credits — you get them by copying from another list. Score columns rate a row for fit and carry a relevance_weight. Static columns just hold values you write.
A search remembers the brief you wrote and how deep the matching pool still is (remaining_count, has_more, tam_known). Ask for more leads and it continues where it left off instead of starting over.Comes from POST /leads/searches or POST /leads/lists/{list_id}/fetch. A list has at most one active search.

Send objects

Campaign — a sequence plus everyone in it

A campaign bundles the people you’re contacting, the template they get, the senders it goes out from, and the schedule. It moves through draftactivepaused.Comes from POST /send/campaigns for a blank draft, or POST /send/campaigns/draft, which writes the schema and templates from a brief.
Each enrolled person has a sequence_id, contact details, per-step state, and the exact copy that was rendered for them. Most people operations address one by sequence_id.Comes from POST /send/campaigns/{campaign_id}/people, either by pointing at a list (list_id, optionally specific row_ids) or by passing people inline.
A list of { key, description, required } fields declaring what context each person carries into the template. { "fields": [] } means identity-only.Comes from PUT /send/campaigns/{campaign_id}/people/schema, or gets written for you by campaigns.draft. Set it before enrolling people so their context has somewhere to land.
A template is a set of variants (A/B arms). Each variant has an instructions steer and a list of steps: a channel (email, linkedin_message, linkedin_connect, linkedin_comment, linkedin_react, or manual), a body, a delay_days, and which parts should be personalized per recipient. Every variant keeps a variant_key that is never reused.Comes from PUT /send/campaigns/{campaign_id}/templates to replace the whole thing, or POST /send/campaigns/{campaign_id}/templates/sequences to add one variant at a time.
The template rendered against a specific person. Generate these before launch to read what will go out, and edit any step that isn’t right.Comes from POST /send/campaigns/{campaign_id}/examples. One LLM call per person, so it returns a Job.

Account objects

Sender — a mailbox or LinkedIn account that sends

Senders belong to the organization, not to a campaign. Connect one once, then add it to as many campaigns as you like. Each carries its own daily limit, signature, timezone, and gap settings.Comes from POST /account/senders/connect for Google, Microsoft, or LinkedIn (OAuth finishes in the browser — you get a handoff URL), or POST /account/senders/imap for any SMTP/IMAP mailbox. Credentials are write-only and never returned.
If you don’t want to burn your primary domain on cold outreach, buy lookalike domains through Origami and provision mailboxes on them. A provisioned mailbox becomes a sender.Comes from POST /account/domains/purchase (charges the card on file) and then POST /account/mailboxes.
Two lists, people and companies, checked before anyone is enrolled. Customers, competitors, churned accounts, anyone who asked to be left alone.Comes from POST /account/exclusion-lists/people and the matching companies endpoint. Each organization has one; a project can either share its parent’s or keep a private one.
A project isolates lists, campaigns, and chats — one per client, if you’re an agency. It draws on the parent’s credit wallet and can carry a monthly cap.Comes from POST /account/projects. Act inside one by sending x-origami-project: <project_id>.
The same agent as the Origami app. Send it a prompt and it does the work, creating lists and campaigns as it goes and linking them to the chat.Comes from POST /account/chats, then POST /account/chats/{chat_id}/messages. Each message returns a Job.
A webhook endpoint is a URL plus the event types it wants; it has a signing secret shown once at creation and rotatable later. An API key authenticates requests and carries a role (member or admin).Come from POST /account/webhooks and POST /account/keys. Both are admin-only.

The Job

Every slow operation — sourcing, enrichment, copy generation, domain purchase, chat — returns the same Job object instead of blocking. A Job tells you what it’s working on (operation, target, phase), how far along it is (progress), when to check again (next_poll_at), and what it cost (credits).

The Job object

Statuses, polling, cancelling, credits, and the questions a Job can ask you.