For the complete documentation index, see llms.txt. This page is also available as Markdown.

Authentication & API keys

API keys, permission scopes, environments, and rate limits.

Every API call authenticates with an API key passed as a bearer token:

Authorization: Bearer inpk_live_...

There are no session cookies on the API: one key, one header. Dashboard features (building surveys, managing members, organisation settings) are not reachable with an API key by design. The one place sign-in based access exists is the AI-assistant connection flow, which uses OAuth instead of a key; see Connect AI assistants.


Creating and managing keys

Keys live in the dashboard under Integrations → Developer tools → API Keys (admin-only). Each key has:

  • A label, so you can tell your CRM sync from your data-warehouse export.

  • An environment: inpk_live_* for production traffic, inpk_test_* for staging integrations. They behave identically; the split exists so you can revoke staging without touching production. Test keys are never charged usage.

  • A permission scope (below).

  • A per-key rate limit, 60 requests/minute by default, adjustable between 1 and 300 at creation or later.

  • Per-key usage statistics, including real response status codes, so you can spot a failing integration from the dashboard.

The secret is shown once at creation. Store it like a password; rotate it from the same screen if it leaks or when a teammate with access leaves.


Permission scopes

Scope what each integration can do; don't hand every system an all key.

Scope
What it allows

push

Push feedback to existing sources, and everything push implies: bulk status, file upload, feedback listing and erasure, analysis reads.

create

Everything push can, plus creating and publishing sources with their fields inside existing feedback groups.

send

Trigger survey-invite emails (Sending invites). Deliberately separate: emailing humans is a bigger deal than pushing data.

mcp_read

Read-only access for the MCP endpoint, so an AI assistant can query analytics but never write. See Connect AI assistants.

all

Everything above, plus creating feedback groups (POST /feedback_groups/create), which no narrower scope can do.

Every write operation in the API reference states the scope it requires. A call outside the key's scope returns 403 with the code INSUFFICIENT_PERMISSION.

send is additionally gated on a verified sending domain: API sends never ride the shared BAI Analytics sender, so automated volume runs on your own sending reputation. See Sending invites.

mcp_read keys are bound to the person who created them. On every MCP request the platform re-checks that this person still has an active account and is still a member of the organisation; if not, the key stops working immediately (403 MCP_KEY_UNBOUND) and shows as stopped in the dashboard. Integration keys (push, create, send, all) are organisation keys and outlive their creator, so an ETL pipeline keeps running after the engineer who set it up leaves.


Introspection: GET /me

An integration can discover its own capabilities without dashboard access:

The response includes the key's name, environment, and permissions, the organisation's id and org_name (handy as the label of a stored connection), the effective rate limits, the organisation's usage status under credits, and the webhook event types available for subscription. It charges nothing, which also makes it the right target for connection tests.


Rate limits

Defaults: 60 requests/minute per key, 300 requests/minute per organisation, and 600 per minute per IP address. Windows are fixed 60-second windows anchored at the first request: a request rejected with 429 does not extend the wait, so Retry-After is exact. Your key's numbers are in GET /me; the per-key limit can be raised up to 300 when the key is created or edited.

When you hit a limit the API returns 429 with a Retry-After header, and every response carries X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset. Back off and retry; for sustained volume, prefer the bulk endpoints (one call for thousands of items) over per-item calls.


Response envelope

Today, 2xx responses carry the payload directly, as shown in every example of the reference, together with Deprecation and Sunset headers. Those headers announce one thing only: after the sunset date, success payloads will be wrapped as {"data": {...}}, as the schemas already declare. No endpoint is being deprecated. Errors are always {"error": {"code": "...", "message": "..."}} with an optional details object.


Good practices

  • One key per integration. Revoking a compromised system shouldn't take down the others.

  • Scope down. A CRM sync needs push, not all.

  • Use Idempotency-Key on writes. Any push can be retried safely within 24 hours.

  • Rotate on staff changes. Same policy as passwords.

Last updated