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.