Skip to content
NewSee how

Using FirstSales with Codex

Connect Codex to FirstSales over the REST API (or CLI in a shell). First whoami call, scoped keys, idempotent writes, and stopping on unsupported operations.

  1. Pick the right path for your Codex setup

    FirstSales offers two integration paths. If your Codex environment has a shell with npm, install the @firstsales.io/cli and drive it like any shell agent: it handles auth, JSON, and idempotency for you. If Codex runs without shell access (browser or sandboxed), call the Developer API directly over HTTPS. The docs group Codex with API-first agents for exactly this reason.

  2. Store the key as an environment secret

    Create a Developer API key in Settings → API and put it in your Codex environment's secret store as FIRSTSALES_API_KEY. Never paste the raw key into a prompt or commit it: reference the env var in code.

    # in your Codex task's environment
    FIRSTSALES_API_KEY=fs-key-...
    FIRSTSALES_BASE_URL=https://api.app.firstsales.io
  3. Verify identity first

    Whichever path, the first call confirms the key resolves to the org and workspace you expect:

    curl https://api.app.firstsales.io/api/v1/whoami \
      -H "Authorization: Bearer $FIRSTSALES_API_KEY"
  4. Read state before writing

    Have Codex inspect before it mutates. Resources are scoped to org and workspace:

    curl https://api.app.firstsales.io/api/v1/organizations/ORG_ID/workspaces/WS_ID/campaigns \
      -H "Authorization: Bearer $FIRSTSALES_API_KEY"
    
    curl https://api.app.firstsales.io/api/v1/organizations/ORG_ID/workspaces/WS_ID/contacts \
      -H "Authorization: Bearer $FIRSTSALES_API_KEY"
  5. Write idempotently

    On creates, send an Idempotency-Key header so a retried request never duplicates data: important for an autonomous agent that may retry on timeout:

    curl -X POST \
      https://api.app.firstsales.io/api/v1/organizations/ORG_ID/workspaces/WS_ID/contacts \
      -H "Authorization: Bearer $FIRSTSALES_API_KEY" \
      -H "Content-Type: application/json" \
      -H "Idempotency-Key: codex-lead-2026-01" \
      -d '{"email":"[email protected]","first_name":"Sam"}'
  6. Keep Codex on the public surface

    Instruct Codex to use only public /api/v1 endpoints. On an unsupported_operation response it must stop and report (never scrape the app or call private routes, provider callbacks, tracking pixels, unsubscribe handlers, or cron endpoints to force a result. Handle 401 (bad key), 422 (validation) body names the field), and 429 (back off) explicitly.

Pro tips

  • Shell available? Prefer the CLI

    If your Codex sandbox can run npm, the CLI removes a lot of boilerplate: auth, JSON, idempotency, and delete-confirmation are handled for you. Fall back to raw HTTP only when there's no shell.

  • Key lives in the environment, not the prompt

    Put FIRSTSALES_API_KEY in Codex's secret store and reference it. A key in the prompt ends up in logs and history.

  • whoami is the cheapest safety check

    One call confirms Codex is pointed at the right org and workspace before it writes anything. Skipping it is how data lands in the wrong workspace.

  • Idempotency-Key on every create

    Autonomous agents retry. A stable idempotency key turns a retried POST into a no-op instead of a duplicate contact or double charge.

Frequently asked questions

Should Codex use the CLI or the API?

If Codex has shell access with npm, use the CLI. If it runs in a browser or a shell-less sandbox, call the Developer API over HTTPS. The API path is the default for browser-based agents.

How do I give Codex the key safely?

Store it as FIRSTSALES_API_KEY in Codex's environment/secret store and reference the variable in code. Don't paste the raw key into prompts or commit it.

What's the base URL and first call?

Base https://api.app.firstsales.io, Bearer auth. First call GET /api/v1/whoami to confirm org and workspace context before any writes.

How do I prevent duplicate writes on retries?

Send an Idempotency-Key header on create requests. A replay with the same key returns the original result instead of creating a second record.

What must Codex never do?

Never call app-private routes, provider callbacks, tracking pixels, unsubscribe handlers, or internal cron endpoints, and never scrape the app UI. Stay on public /api/v1; stop and report on unsupported_operation.

Developer & CLI

Outreach that keeps going after you log off.Leads, emails, follow-ups and replies, handled.

Connect unlimited mailboxes and let AI agents find leads, write each email and follow up. Or send your own templates in manual mode. From $29/mo.

$1 for 3 days · Cancel anytime · No contract

Install with AI

Your coding agent sets up the FirstSales CLI and skills for you.

Prompt for Claude Code

I'm setting up FirstSales (https://firstsales.io), an AI outbound sales platform: campaigns, contacts, a reply inbox, deliverability and lead signals. Help me get my workspace sending real, good emails end to end, from Claude Code.

Read these first so you know how FirstSales works:
- Developer docs and API: https://developer.firstsales.io
- CLI: https://www.npmjs.com/package/@firstsales.io/cli
- Skills for coding agents: https://github.com/firstsalesio/firstsales-skills (read README.md and GUIDE.md)

Setup
1. Install the CLI: npm install -g @firstsales.io/cli
2. Install the FirstSales skills:
   claude plugin marketplace add firstsalesio/firstsales-skills
   claude plugin install firstsales@firstsales
3. Ask me if I already have a FirstSales account. If not, send me to https://app.firstsales.io to sign up.
4. Ask me to create an API key under Settings → API → API Keys, with only the scopes we need.
   Never ask me to paste the key into this chat. Tell me to run this in my own terminal, so the key stays hidden:
   read -rs FS_KEY && firstsales auth login --api-key "$FS_KEY"; unset FS_KEY
5. Run `firstsales whoami` and tell me which workspace and organisation we are connected to.

Then ask me about my business: what I sell, who I sell to (roles, company size, countries), my best customers, and what I use today for outbound (tools, lists, mailboxes). Walk me through:
1. Teaching FirstSales my business: website, offer, proof points and case studies in the knowledge base, so the AI writes like someone who knows the product.
2. Connecting my sending mailboxes and checking my sending domain: SPF, DKIM, DMARC and warm-up. If anything is unhealthy, tell me the exact DNS record to add.
3. Bringing in contacts: import my CSV or CRM export into a clean list, remove duplicates and bad emails, and block domains I must never email (customers, competitors, my own).
4. Building my first campaign: the right list, senders, steps and timing. Write the sequence with me, show me the drafts, and do not launch until I say yes.
5. Setting up Signals if it fits: find people engaging with LinkedIn posts about topics my buyers care about, and turn them into leads.
6. Inviting my team and giving each person the right access.

Once campaigns run, show me how to work the reply inbox from here: which replies need an answer, draft responses in my voice, and move good conversations into deals. If I use Cal.com, connect it so follow-ups can offer my booking link (not the first email).

Throughout, as you learn about my business, proactively suggest and help create:
- Reply templates for the questions and objections my prospects are likely to raise, based on my product, site and codebase if you can see them.
- Campaign ideas and segments worth testing, with the reason for each.

Safety rules:
- Show every change as a dry run (--dry-run) first and wait for my yes. Never send emails, launch campaigns or delete anything without my yes.
- Tell me before anything that spends credits, and how many.

Be opinionated. If the docs give a sensible default, just use it. Don't make me choose between five options.