NewSee how
FirstSales
Home/Tutorials/Using FirstSales with Codex
Developer & CLI

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.

8 min read·Advanced·6 steps
  1. 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. 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. 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. 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. 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":"lead@acme.com","first_name":"Sam"}'
  6. 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

Hard-won shortcuts that keep warm-up on track.

1

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.

2

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.

3

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.

4

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.

Ready to put this into practice?

Start your FirstSales trial and launch a warmed, authenticated mailbox in minutes.

Start for $1