Skip to content
Console
Browse documentation
Guide

Native intake keys

Create separate project and source credentials for product capture and OTLP telemetry.

On this page

Public product capture and OTLP require purpose-bound API keys. A management key, Console sign-in session or bearer principal token cannot send telemetry, even when it has a write scope.

Choose the route

Key purpose Route Only permitted scope
browser_capture POST /api/v1/capture analytics:write
mobile_capture POST /api/v1/capture analytics:write
server_capture POST /api/v1/capture analytics:write
native_ingest OTLP HTTP /v1/traces, /v1/logs, /v1/metrics, or OTLP gRPC ingest:write

All four require one project and an active source. The server selects a stable default source for each project and purpose when source_id is omitted. To rotate within a source, reuse its ID. A source cannot change purpose or move to another project. A revoked default is not recreated. Browser and mobile capture record the credential's declared purpose; neither proves the caller's device or that an event represents a real person. Mobile capture uses mobile_product origin, not trusted server origin. A key distributed in an app is a public client credential.

Create keys in the Console

The setup guide creates a telemetry key and a separate capture key for your selected platform. In the Console, open Home, then Open the setup guide (/get-started). Choose your platform: browser uses browser_capture, mobile uses mobile_capture, and Node.js, Python, Go or an existing OpenTelemetry service use server_capture. Save the telemetry key as ANECTICO_INGEST_KEY and capture key as ANECTICO_CAPTURE_API_KEY in server development configuration, or pass the distinct SDK options on clients. Agent credentials remain separate.

Each key has its own create/retry operation. A failure in one does not recreate the other. Copy each secret before leaving. Retrying a committed request can recover metadata but never its secret; revoke that key before creating a replacement. If you leave during an uncertain request, check API keys under Agents and keys (/agents) for the key before starting another.

For individual keys, open Agents and keys in the Console, select Generate API Key and choose a purpose and project. Intake permissions are fixed. Optionally supply an existing source ID for the same project and purpose; leaving it empty resolves the stable default source. The key list shows the immutable purpose/source binding. Editing can disable intake by removing the one allowed permission, but cannot change that binding. Management / agent keys use separate permissions.

Create a key through the CLI or API

Authenticate the CLI with a management credential that has api_key:write, projects:read (to resolve the selected project), and the scope being granted. The CLI selects the only allowed scope for a native purpose. It also needs mcp:write, because every CLI write uses the server preview/confirmation flow. The first call shows complete current/proposed metadata, source binding and checked scopes without creating a credential or default source. Approve that preview, then repeat identical arguments with the printed --idempotency-key and --confirm-token. Only the confirmed response can contain the secret:

anectico --project PROJECT_UUID apikey create --name website --purpose browser_capture
anectico --project PROJECT_UUID apikey create --name mobile-app --purpose mobile_capture
anectico --project PROJECT_UUID apikey create --name backend-events --purpose server_capture
anectico --project PROJECT_UUID apikey create --name collector --purpose native_ingest

Add --source-id SOURCE_UUID to use an existing source of the same purpose. The response shows its source and purpose; anectico apikey list -o json returns ingress_purpose and ingress_source_id. Save each plaintext secret immediately: it is returned only at creation. Do not publish a server or management key in browser code or distributed mobile apps.

The equivalent POST /api/v1/account/api-keys body is:

{
  "name": "backend-events",
  "project_id": "11111111-1111-4111-8111-111111111111",
  "purpose": "server_capture",
  "scopes": ["analytics:write"]
}

The example UUID must be replaced with your project. Optional source_id must identify an active source in that project with the same purpose. Native keys forbid org_wide, extra scopes and management scope profiles. Missing purpose means a management key; it cannot enter intake. Expiry, containment and revocation apply to native keys as described in authentication. Scopes can be removed to disable a key but cannot be widened beyond its original write family.

Retry creation safely

Supply a stable idempotency_key in the API body, or --idempotency-key in the CLI:

anectico --project PROJECT_UUID apikey create --name backend-events \
  --purpose server_capture --idempotency-key backend-events-2026-09

Keep the same authenticated actor, project, name, purpose, source selection, scopes and expiry on retries. Use an explicit project; changing which default project is selected changes the request. Retry keys contain 1–128 printable ASCII characters without spaces. The CLI requires an explicit name and a fixed --expires-at or no expiry; --expires-in would change on every call. A new expiry must be in the future and at most 365 days away. An identical retry may refer to an already expired key.

Only the first committed response contains plaintext_key. Identical retries return current key metadata, replayed: true and an empty secret. The creation record survives cache expiry, key expiry and revocation; it never reactivates or creates a replacement key. Reusing that retry key with different creation arguments returns a conflict. Fresh permissions still apply. The CLI and MCP require a stable retry key; CLI generates and prints one if omitted on preparation. Direct account API creation without a key creates a new credential each time.

If the first response is lost, retry to recover the key ID, revoke that key, then create a new operation with a different retry key. A secret cannot be retrieved later. Keep your management credential available for recovery; the new intake key cannot manage credentials.

Manage keys through MCP

Use list_read_actions / execute_read_action for list_api_keys and get_api_key. They return metadata only and require mcp:read plus api_key:read. The list has an optional limit (1–500, default 50) and an opaque cursor; pass its next_cursor unchanged.

Discover create_intake_key and revoke_api_key with list_write_actions, then preview and confirm through execute_internal_action. Both require mcp:write, api_key:write and a stable idempotency_key. Creation also requires the purpose's single write scope and an explicit project_id. Revocation also requires api_key:read; confirmation binds the displayed current key metadata. A project-bound caller cannot operate outside that project.

Creation arguments are project_id, name, purpose, idempotency_key, and optional source_id / fixed RFC3339 expires_at. Only the initial committed MCP response text contains the secret. Structured receipts, stored replay results and audit records contain no secret. MCP's short-lived response cache can replay the original creation metadata; use get_api_key for current state. The durable creation record still prevents duplicate creation after that cache expires. Use the recovery procedure above if the first response is lost.

MCP native creation supports the four purposes above and optional agent_asset_id, matching CLI --agent. Management and experiment-delivery application keys use create_api_key through the same preview/confirmation door. Management creation names an exact project or org_wide: true and the complete caller-held scope set. Application creation needs experiments:launch and grants only experiments:deliver. Revocation is permanent; repeating it does not restore authority. These are credential controls, not source catalog editing.

Send and verify

Use X-Anectico-API-Key, X-API-Key or Authorization: ApiKey over HTTP. For OTLP gRPC, use x-anectico-api-key metadata. Do not send a bearer token alongside the key.

Configure collectors with the native_ingest key. Standalone product clients such as JavaScript AnalyticsClient and Go NewAnalytics take the capture key in their own apiKey/APIKey option. Keep it separate from the key used by an OTLP exporter and from management credentials used by replay, flag reads, CLI or MCP. Reading a flag and recording its exposure now use different credentials.

The JavaScript core client (init, initNode, initBrowser, AnecticoClient) now accepts apiKey / ANECTICO_API_KEY for native OTLP and captureApiKey / ANECTICO_CAPTURE_API_KEY for identity/group capture. Use server_capture in Node and browser_capture in the browser. Keys must differ. Without captureApiKey, a non-empty core identify/group call throws before changing identity or sending; denied product consent remains a no-op. Standalone AnalyticsClient continues to take its capture key in apiKey.

Go uses WithAPIKey / Config.APIKey for native OTLP and WithCaptureAPIKey / Config.CaptureAPIKey for server identity/group capture. Python uses api_key and capture_api_key (also Django ANECTICO["CAPTURE_API_KEY"]). Both SDKs read ANECTICO_API_KEY and ANECTICO_CAPTURE_API_KEY. Capture configuration is optional for telemetry-only clients, but keys must differ when supplied. Missing/malformed/shared capture credentials fail before identity changes or capture requests: Go returns an error; Python raises ValueError, including for sync_person. Standalone Python AnalyticsClient and Go NewAnalytics continue to take a capture key in their own API-key field. Go has no JWT intake mode.

iOS, Android, React Native and Flutter accept apiKey for native OTLP and a separate optional captureApiKey for mobile_capture. Without a capture key, product events and identify/group calls are no-ops before identity changes or queue admission; configuration logs a warning. Malformed or shared capture keys reject configuration. Queued product events remain pending without a capture key; flush reports false until drained or explicitly purged by consent withdrawal. Adding a key does not renew withdrawn consent. Explicit logout/reset behavior is unchanged.

Older repository test fixtures and demos are still being migrated to this separation. A client that reuses one credential for capture and OTLP cannot authorize both paths.

Each request rechecks the current credential and source without a successful-auth cache. Revoked keys or sources and wrong-purpose credentials are refused before parsing or publishing telemetry. Missing or malformed source authority and unavailable dependencies fail closed with a retryable unavailable response; concurrency limits remain retryable. An unavailable check never falls back to a management token or a development organization header.

The server stamps every admitted event with the key's source and its purpose-derived origin (browser_product, server_product, mobile_product or otlp). Event properties or OTLP attributes cannot grant a different origin or source. A browser or mobile purpose is a credential declaration, not proof of the device that sent the request. Revocation stops new admissions; a record accepted before revocation may still finish processing. Project or organization deletion stops that completion.

A successful capture response acknowledges queued delivery. To confirm stored evidence, follow verify your setup, or ask your agent to run the instrumentation doctor (instrumentation_doctor over MCP, or anectico doctor instrumentation). See Diagnose missing data and verify a customer story. Source-bound admission does not by itself establish event authenticity or browser consent. Identical message_id retries are counted once. See product capture admission.

Read one key with anectico apikey get KEY_ID or MCP get_api_key. Both return complete nonsecret metadata and mark customer-written names as untrusted.

The server key preview shows both the complete credential metadata and the complete intake source it will bind. If a default source is new, its before state is null; confirming creates that source and the key. An existing source appears unchanged in both states. Preparation creates neither.