sayintel
Docs

Authentication.

Two ways in, same permissions model underneath. A token for scripts and headless agents, an OAuth connection for MCP clients that sign a human in.

API tokens

Mint one in the app under Settings, Agent access. Tokens start with si_, are shown once, and are scoped to the account that created them.

Authorization: Bearer si_live_...

Scopes

  • read — list and inspect campaigns, speakers, drafts, QA state, credits.
  • write — create campaigns, start runs, curate selections, edit drafts, request rewrites.
  • send — push approved sequences to a sending tool. Only ever granted deliberately, and a human still arms the sending campaign.

Ask a key what it may do, rather than guessing:

curl https://sayintel.com/api/public/v1/capabilities \
  -H "Authorization: Bearer $SAYINTEL_TOKEN"

OAuth, for MCP clients

Claude, ChatGPT and other connector-based clients use the OAuth door at https://sayintel.com/mcp. The client registers itself, the human approves it on a consent screen, and tools then run as that user with read and write. Send stays off the OAuth path by design. MCP setup.

Idempotency

Every POST accepts an Idempotency-Key header. Retrying with the same key and payload replays the first result instead of doing the work twice, which matters for anything that spends credits.

Idempotency-Key: 5c1b2f0e-2a9c-4a4b-9a3a-3c8a1f7b1d21

Dry runs and cost

Spending actions accept dry_run: true and always return a cost_preview, so an agent can show its human the bill before committing.

Rate limits

Limits are per token and per capability kind. Over the limit you get 429 with error.code = rate_limited. Back off and retry; do not hammer. Prefer webhooks or the event stream over polling.