# Noxtica documentation (full text)
> Every page of https://noxtica.com/docs/ as clean Markdown, in the order an integration follows it: install, consent, protected actions, backend verification, identity verification, webhooks, API reference, MCP, then the remaining topics. Each page starts after a `---` line with its canonical URL.
The generated per-operation API reference (10 pages under https://noxtica.com/docs/api/reference/) is not repeated here: read https://noxtica.com/docs/api/openapi.json, or fetch one area page as https://noxtica.com/docs/api/reference//index.md. The page index is https://noxtica.com/llms.txt.
---
Source: https://noxtica.com/docs/
Markdown: https://noxtica.com/docs/index.md
Last updated: 2026-10-24
# Noxtica Documentation
Use these docs to move from an activated account to a measured, reviewable policy. Noxtica provides browser and device intelligence, calibrated risk, bot and agent controls, and operator workflows; your team chooses where those outputs influence a customer journey.
Availability is account-specific. Backoffice visibility, API scopes, module status, and your service agreement determine which surfaces you can use. A capability described in the directory may still require entitlement, tenant or domain activation, a supported client, or privacy/legal review.
## Choose a path by task
| I need to… | Start here | Then use |
| ------------------------------------------------ | ------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| Install the browser collector | [Install & Browser Runtime](https://noxtica.com/docs/browser-runtime/) | [Getting Started](https://noxtica.com/docs/getting-started/) for the evaluation path and application responsibilities |
| Make a trusted backend decision | [Backend Integration](https://noxtica.com/docs/backend-integration/) | [Why Calibration, Not Verdicts](https://noxtica.com/docs/why-calibration/) for policy design |
| Verify a customer identity from my backend | [Identity verification integration](https://noxtica.com/docs/identity-verification-integration/) | [KYC Hosted Sessions](https://noxtica.com/docs/kyc-hosted-sessions/) for session lifetime and expiry |
| Call a server API from my backend | [API overview](https://noxtica.com/docs/api/) | [Authentication](https://noxtica.com/docs/api/authentication/), [Webhooks](https://noxtica.com/docs/api/webhooks/) and the [API reference](https://noxtica.com/docs/api/reference/) |
| Give an AI agent the docs or the API | [Integrate with an AI agent](https://noxtica.com/docs/ai-agents/) | The [OpenAPI files](https://noxtica.com/docs/api/openapi.json), [`/llms.txt`](https://noxtica.com/llms.txt) and the Markdown version of every page |
| Understand a score or reason | [Detection Signals](https://noxtica.com/docs/detection-signals/) | [Threat Categories](https://noxtica.com/docs/threat-categories/) and the fingerprint detail in Backoffice |
| Roll out challenge or block actions | [Use Cases](https://noxtica.com/docs/use-cases/) | [Engineering Principles](https://noxtica.com/docs/principles/) for shadow-first and low-confidence handling |
| Investigate related activity | [Capability Reference → Account linking](https://noxtica.com/docs/features/#account-linking-and-investigation) | Compare, investigation, analytics, and eligible export surfaces in Backoffice |
| Govern automated agents | [Capability Reference → Agent identity](https://noxtica.com/docs/features/#agent-identity-and-control) | [Agentic Security](https://noxtica.com/docs/concepts/agentic-security/) and [Know Your Agent](https://noxtica.com/docs/concepts/know-your-agent/) |
| Connect an AI agent or use the console assistant | [Capability Reference → AI operations](https://noxtica.com/docs/features/#ai-assisted-operations) | [MCP Integration](https://noxtica.com/docs/concepts/mcp-integration/) or [AI Assistant](https://noxtica.com/docs/concepts/ai-assistant/) |
| Review privacy and operating boundaries | [Engineering Principles](https://noxtica.com/docs/principles/) | [Capability Reference → Governance](https://noxtica.com/docs/features/#governance-and-data-controls) plus your contract and current legal pages |
| See everything customers can use | [Customer Capability Reference](https://noxtica.com/docs/features/) | Follow any of the twelve family anchors to configuration, outputs, value, eligibility, and limits |
| See what changed in a collector release | [SDK Changelog](https://noxtica.com/docs/changelog/) | [Install & Browser Runtime](https://noxtica.com/docs/browser-runtime/) for consent modes, events and the command queue |
## What is Noxtica?
Noxtica collects eligible browser, device, network, and interaction context, checks the available evidence for consistency, and returns a calibrated assessment. A result can help you recognize a returning browser installation, identify suspicious automation or infrastructure, verify supported agent identities, prioritize an investigation, or apply a route-specific policy.
The result is not proof that a visitor is a particular person, a guaranteed bot verdict, or a replacement for authentication. Read risk, confidence, and reasons together and combine them with the value and reversibility of the action your application is considering.
### Key Capabilities
- **Device and browser intelligence:** receive a tenant-scoped device handle and a calibrated assessment from an activated collector.
- **Bot, abuse, and network defense:** combine automation, consistency, infrastructure, and interaction reason families without making one signal decisive.
- **Risk and decisioning:** use score, five-level risk tier, confidence, and reasons in customer-owned allow, observe, challenge, review, or block policies.
- **Agent identity and control:** apply separate trust policies to supported signed agents and unknown automation when the module is enabled.
- **Investigation and operations:** review device records, trends, policy outcomes, audit history, alerts, and eligible exports in Backoffice.
- **Integrations:** consume browser events, scoped backend reads, SDKs, event delivery, exports, and eligible read-only MCP access.
See the [Customer Capability Reference](https://noxtica.com/docs/features/) for every public family, where it appears, what it produces, and what must be enabled.
### Platform Components
| Component | Customer purpose | Availability boundary |
| ----------------------- | --------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| **Browser collector** | Collect and submit an eligible assessment; return browser events and cache state | Requires an activated domain and Site Key; optional signal families have separate policy gates |
| **Collector service** | Score submissions and expose supported verification and lookup APIs | Endpoints, quotas, and modules vary by tenant and contract |
| **Backoffice** | Configure domains and eligible modules; review analytics, records, actions, access, and usage | Pages and actions are filtered by operator role, tenant scope, and entitlement |
| **Server API and SDKs** | Read results and make decisions from trusted backend code | Requires a secret key with the necessary scope; never place server credentials in the browser |
| **Integration outputs** | Deliver eligible events through webhooks, sinks, exports, or read-only MCP | Requires destination/token configuration and any applicable module, role, and data-policy review |
## Quick Start
### 1. Get Your Site Key
Request access through [Contact](https://noxtica.com/contact/). After your account is provisioned, sign in to [Backoffice](https://backoffice.noxtica.com), add the exact production or staging origin under **Domains**, and copy its Site Key. Keep environments separate; a Site Key is public but origin-bound.
### 2. Add the Collector
Copy your domain's snippet from **Backoffice → Integrations & API → Script & Consent**, then follow the [install walkthrough](https://noxtica.com/docs/browser-runtime/#install-core-on-every-page-extensions-after-consent). It is the single source for the core and extensions scripts, stable or pinned tags, the replay recorder head, CSP, consent modes, protected actions, and the check that it works.
### 3. Receive Risk Scores
Listen for the documented result event after successful collection or a cache hit:
```javascript
document.addEventListener('noxtica:collected', (event) => {
const { fingerprintId, score, risk_level, confidence, flags, fromCache } = event.detail;
// Send the device handle to your backend with the customer action.
// Treat score, confidence, and flags as policy inputs—not an identity verdict.
});
```
Do not put a secret Server API key in this handler. Use the browser result to shape reversible experience choices or send its device handle to your backend for a trusted lookup.
### 4. Server-side Lookups (Optional)
Create a Server API key in **Backoffice → API Config**, select the narrowest required scope, save the secret when shown, and call the supported endpoint from your backend:
```bash
curl -H "Authorization: Bearer sk_prod_your_api_key" \
"https://collect.noxtica.com/v1/device/DEVICE_ID"
```
Handle `401`, `403`, `404`, and `429` explicitly. A missing or expired device should follow your `unknown` path rather than being treated as safe or malicious. See [Backend Integration](https://noxtica.com/docs/backend-integration/) for response fields, caching, and error handling.
## Guides
### Integrate
- **[Getting Started](https://noxtica.com/docs/getting-started/):** account prerequisites, the evaluation path, and application responsibilities.
- **[Install & Browser Runtime](https://noxtica.com/docs/browser-runtime/):** the single install guide: core and extensions scripts, stable or pinned tags, replay recorder head, CSP, consent modes, protected actions, single-page apps, storage disclosure, and the check that it works.
- **[Backend Integration](https://noxtica.com/docs/backend-integration/):** scoped server keys, trusted lookups, errors, rate limits, and backend decision patterns.
### Decide and investigate
- **[Detection Signals](https://noxtica.com/docs/detection-signals/):** what each evidence layer contributes and how missing evidence affects confidence.
- **[Threat Categories](https://noxtica.com/docs/threat-categories/):** public reason families, appropriate uses, and common false-positive boundaries.
- **[Why Calibration, Not Verdicts](https://noxtica.com/docs/why-calibration/):** map risk and confidence to route-specific policy.
- **[Use Cases](https://noxtica.com/docs/use-cases/):** reference patterns for marketplaces, financial services, identity-sensitive flows, and agent governance.
### Operate and govern
- **[Customer Capability Reference](https://noxtica.com/docs/features/):** the complete customer-facing capability directory with surfaces, outputs, eligibility, and limits.
- **[Impact by Audience](https://noxtica.com/docs/impact-audiences/):** responsibilities and outcomes for security teams, platforms, end users, and agent owners.
- **[Platform Overview](https://noxtica.com/docs/platform-overview/):** the reference version of the home-page sections, from customer value and the platform tour to capability families, principles, replay context, AI guardrails, and next steps.
- **[Pricing Reference](https://noxtica.com/docs/pricing/):** the explanatory text behind the pricing page — billing disclosures, comparison dimensions, add-ons, KYC and metered-module notes, estimator definitions, and commercial FAQ.
- **[Engineering Principles](https://noxtica.com/docs/principles/):** the operational review checks behind defensible decisions.
- **[Concepts & Glossary](https://noxtica.com/docs/concepts/):** shared terms for device intelligence, agent controls, browser security, MCP, and the assistant.
## Browse by section
Every customer-facing feature has one task-oriented page with the same layout: what it is, prerequisites, steps, how to verify, troubleshooting and related pages. The Server APIs section is the generated API reference.
### Server APIs
- [Server API reference](https://noxtica.com/docs/api/): authentication, errors, rate limits, webhooks, the MCP server and the generated endpoint reference.
### Browser SDK
- **[Install & Browser Runtime](https://noxtica.com/docs/browser-runtime/):** The one install guide for the Noxtica collector: core and extensions scripts, stable or pinned tags, recorder head, CSP, consent, protected actions, and checks.
- **[Script attributes and client options](https://noxtica.com/docs/sdk/script-attributes/):** Every data-* attribute on the Noxtica script tag and every createClient or init option, with accepted values, defaults and effect.
- **[Client API, events and the command queue](https://noxtica.com/docs/sdk/client-api/):** The page globals, the methods of window.noxticaClient, every noxtica:* event, the window.noxtica command queue and the checkOnce result, as the loader implements them.
- **[Consent modes, GPC and Google Consent Mode](https://noxtica.com/docs/sdk/consent/):** Set a consent mode per domain, declare it on the tag, connect your banner to the four categories, handle GPC and DNT, bridge Google Consent Mode v2 and test it.
- **[Protected actions: client trigger and server check](https://noxtica.com/docs/sdk/protected-actions/):** Declare protected actions per domain, trigger the minimal check from a form or code, carry the request id to your backend and redeem it with the verify call.
- **[Single-page apps, frameworks and tag managers](https://noxtica.com/docs/sdk/single-page-apps/):** Load the Noxtica collector once in a single-page app, handle route changes and framework forms, and install it through a tag manager or a CMS theme.
- **[Content Security Policy, hosts and first-party relay](https://noxtica.com/docs/sdk/csp-and-relay/):** Allow the collector and ingest hosts in your Content Security Policy, know what degrades without WebAssembly, and serve the collector from your own subdomain.
- **[Browser SDK troubleshooting](https://noxtica.com/docs/sdk/troubleshooting/):** Match a browser collector symptom to its cause and fix: token errors, consent gating, extension load reasons, CSP, duplicate tags and browser limits.
- **[SDK family and availability: browser, server and mobile](https://noxtica.com/docs/sdk/family/):** What the browser script, the typed browser wrapper, the server and mobile SDKs, Postman and OpenAPI are for, their source versions and how to get access.
- **[SDK Changelog](https://noxtica.com/docs/changelog/):** Release notes for the Noxtica browser collector SDK: what changed in each version, who is affected, what to do, and which @noxtica/sdk version pairs with which collector release.
### Identity verification
- **[Identity verification integration](https://noxtica.com/docs/identity-verification-integration/):** Create a hosted identity verification session from your server, send the customer to the link, and read the outcome by status read or signed event.
- **[Self-hosted identity verification (direct API)](https://noxtica.com/docs/identity-verification-self-hosted/):** Call the identity verification API directly from your server: mint a nonce, run a verification, read the result, and learn what the direct route does and does not cover today.
- **[Invitations and hosted verification settings](https://noxtica.com/docs/identity-verification-invitations/):** Set up the hosted verification page in Backoffice, record the legal basis, send a customer a one-time verification link without code, and read the result.
- **[Identity verification events and webhooks](https://noxtica.com/docs/identity-verification-webhooks/):** Register a signed HTTPS endpoint in Backoffice, verify every delivery, and handle each identity verification event: when it fires, its fields, retries and duplicates.
- **[Noxtica Verification ID (NVID)](https://noxtica.com/docs/identity-verification-id/):** Read a Noxtica Verification ID from the session status or an event, understand its statuses and validity, share the public status link, and revoke or resend it in Backoffice.
- **[Business and merchant verification (KYB and KYM)](https://noxtica.com/docs/identity-verification-business/):** Create hosted business (KYB) and merchant (KYM) onboarding sessions, follow them in Backoffice and receive notify-only events. Availability depends on your organisation.
- **[Verification data: storage, access and deletion](https://noxtica.com/docs/identity-verification-data/):** What happens to identity, business and merchant verification details and evidence over time, who can see them, and how a tenant administrator deletes them.
- **[Identity verification FAQ and troubleshooting](https://noxtica.com/docs/identity-verification-faq/):** Short answers to the questions integrators ask about hosted identity verification: statuses, review, links, keys, events, the Verification ID and data, plus a five-step triage.
- **[Identity verification operations in Backoffice](https://noxtica.com/docs/identity-verification-operations/):** Work the Backoffice KYC pages day to day: read cases, decide the review queue, follow processes, manage policies, screening, recovery, delegations, evidence access and device trust.
- **[KYC Hosted Sessions](https://noxtica.com/docs/kyc-hosted-sessions/):** How long a hosted KYC verification link stays open, and what your backend sees once it expires.
### Observability: RUM, replay, APM and SEO
- **[Observability overview: RUM, replay, APM and ingest](https://noxtica.com/docs/observability/overview/):** Map each browser observability tool to what it measures, the Backoffice page that shows it, what you install, and the consent and legal-basis gates it needs.
- **[Real user monitoring and Web Vitals](https://noxtica.com/docs/observability/rum/):** Turn on real user monitoring for a domain, record its consent and Do Not Track decision, and read Web Vitals, errors and SDK health in Backoffice.
- **[Browser errors, console logs and source maps](https://noxtica.com/docs/observability/errors-and-source-maps/):** Capture redacted JavaScript errors and masked console logs, upload source maps from your build, and read grouped errors on the Issues page.
- **[Session replay: setup, masking and playback](https://noxtica.com/docs/observability/session-replay/):** Arm session replay for a domain, choose what is masked, set sampling and limits, then find and play back recorded sessions in Backoffice.
- **[Custom events, session tags and request tracing](https://noxtica.com/docs/observability/events-and-tracing/):** Send custom events, tag and identify sessions without sending raw ids, and join a browser request to your backend with W3C trace headers.
- **[Behavior analytics: heatmaps, journeys and funnels](https://noxtica.com/docs/observability/behavior-analytics/):** Switch on the tracker for a domain, then read click and scroll heatmaps, page-to-page journeys and app-event funnels in Backoffice.
- **[APM and the ingestion service (OTLP)](https://noxtica.com/docs/observability/apm-and-ingest/):** Mint an Ingestion API key in Backoffice, point an OpenTelemetry exporter at the ingestion service, send a test trace and a release marker, and find them in the APM explorers.
- **[SEO tools: page checks, site crawls and search score](https://noxtica.com/docs/observability/seo-tools/):** Prove you own a hostname, run a single-page SEO check or a bounded site crawl in Backoffice, read the issues and the search score, and see Core Web Vitals history.
- **[Connect Google Search Console for a domain](https://noxtica.com/docs/observability/search-console/):** Connect a domain to its own Google Search Console property with a service account key or your own OAuth client, test the connection, and use it as ownership proof for SEO tools.
- **[Uptime checks, alerts, status reports and the status page](https://noxtica.com/docs/observability/uptime-alerts-status/):** Add verified uptime checks, route alerts to Slack, Teams, Telegram, e-mail or a signed webhook, turn periodic status reports on or off, and follow the public status page and its Atom feed.
### Hunter, Spot and Pulse
- **[Hunter browser extension](https://noxtica.com/docs/hunter/extension/):** Run a local audit of which scripts on one page probe browser fingerprinting APIs, read and export the report, and optionally send one previewed report to your Noxtica workspace.
- **[Hunter reports in Backoffice](https://noxtica.com/docs/hunter/reports/):** Create a short-lived upload token, review Hunter page-audit reports your team sent to the workspace, download the stored JSON, and delete one report or every report from one reporter.
- **[Spot captures](https://noxtica.com/docs/hunter/spot/):** Connect the Spot extension with a short-lived token, record one tab or desktop capture with bounded developer context, then review, share and delete captures in Backoffice.
- **[Noxtica Pulse: endpoint telemetry overview](https://noxtica.com/docs/pulse/overview/):** Understand what Noxtica Pulse is, who sees what, how Backoffice configures it, what the desktop client and the player site do, and where the privacy controls and server API are.
- **[Pulse in Backoffice: applications, profiles, bundles and rollouts](https://noxtica.com/docs/pulse/backoffice/):** Register a Pulse application, author and validate a profile, publish it as a signed bundle, follow the staged rollout, and halt, resume or roll back from Backoffice.
- **[Pulse detections, response, devices and privacy](https://noxtica.com/docs/pulse/detections-and-privacy/):** Review Pulse detections with a person in the loop, answer appeals, set the response ladder, manage devices and attestation, read the privacy page, and use the tenant API and webhooks.
### Security administration and attestation
- **[Device and app attestation](https://noxtica.com/docs/security/attestation/):** Register Android and iOS apps for Play Integrity and App Attest, call the two mobile attestation routes from your backend, and read the results in Backoffice.
- **[Sign-in, SSO, SCIM, MFA and IP allowlist](https://noxtica.com/docs/security/sign-in-and-access/):** Set up how your team signs in to Backoffice: passwords, authenticator apps, security keys, SSO, SCIM, a tenant-wide MFA rule, IP allowlists, sessions and invitations.
- **[Roles and permissions](https://noxtica.com/docs/security/roles-and-permissions/):** See what the viewer, analyst, admin and billing roles can do in Backoffice, which actions need a step-up MFA check, and how admins manage users, disabling and MFA resets.
- **[Audit log and data export](https://noxtica.com/docs/security/audit-log-and-exports/):** Read who changed what in your Backoffice workspace, filter and export the audit log, run a data export, and review export history. Includes limits and the API export route.
### Backoffice guide
- **[Backoffice guide: navigation, roles and shortcuts](https://noxtica.com/docs/backoffice/overview/):** Find any Backoffice page, see which role can open it, and move faster with the command palette, G shortcuts, the workspace switcher and page help.
- **[Domains, site keys and the install card](https://noxtica.com/docs/backoffice/domains/):** Register a domain, copy its public site key, open the install card, and manage the per-domain settings, key rotation and deletion in Backoffice.
- **[Fingerprints, analytics and live monitoring](https://noxtica.com/docs/backoffice/fingerprints-and-analytics/):** Search device fingerprints, read a device record, watch live traffic, compare devices and use the analytics, geo-risk and hardware attestation views in Backoffice.
- **[Risk actions, investigations and entity lookup](https://noxtica.com/docs/backoffice/risk-actions-and-investigations/):** Use Risk Actions, Agentic Security, Bot Intelligence, Behavioral Corroboration, Investigations, Entity Lookup and Quality & Calibration to validate policy before you enforce it.
- **[Detection and collection settings](https://noxtica.com/docs/backoffice/detection-settings/):** Tune rules, risk scoring, client cost levels, verdict bands, honeypots, the collector refresh interval, probes and behavioral signals, and roll changes out in a safe order.
- **[Integrations and API pages](https://noxtica.com/docs/backoffice/integrations/):** A map of the Integrations & API sidebar group: what each page does, who can open it, which credentials it mints, and which documentation page covers it.
- **[Event sinks (SIEM export)](https://noxtica.com/docs/backoffice/event-sinks/):** Create an event sink that pushes signed verdict and audit events to your SIEM, arm it, send a test request, inspect deliveries and rotate its signing secret.
- **[AI assistant, MCP tokens and coding-agent keys](https://noxtica.com/docs/backoffice/ai-assistant-and-mcp/):** Open the Backoffice assistant, set model routing and provider keys, mint MCP tokens with read scopes, and create coding-agent keys, with the limits Backoffice shows.
- **[Workspace gates, feature flags, data operations and mobile operations](https://noxtica.com/docs/backoffice/workspace-settings/):** Use Workspace Gates, visitor Feature Flags, Data Operations, Mobile Operations and your personal Settings and Notifications in Backoffice, with the roles and MFA checks each needs.
### Billing and usage
- **[Plans, packages and add-ons](https://noxtica.com/docs/billing/plans-and-packages/):** Request a plan change or extra capacity, compare and subscribe to packages, turn module add-ons on, and read why an item is unavailable before you click it.
- **[Usage, quotas and metering](https://noxtica.com/docs/billing/usage-and-quotas/):** Read your usage against plan quotas in Backoffice: the Usage & Quotas tabs, the meters, how each quota counts, what happens at the limit, KYC usage, and how to set a quota alert.
- **[Wallet, invoices and reports](https://noxtica.com/docs/billing/wallet-invoices-reports/):** Add funds to your wallet, set a low-balance warning, read the ledger and AI credits, open invoices, review sent reports, and control status-report e-mails in Backoffice.
- **[Billing status, grace period and reminders](https://noxtica.com/docs/billing/status-grace-reminders/):** Understand the Backoffice billing banners, the package grace window and what pauses when it ends, and the schedule of billing reminder e-mails, so you can act before service pages pause.
### Compliance and legal
- **[Privacy and compliance controls in Backoffice](https://noxtica.com/docs/compliance/overview/):** Find every Privacy & Legal and Web Analytics & Privacy page in Backoffice, who can use it, what it records and which docs page explains it.
- **[Legal basis register and receipts](https://noxtica.com/docs/compliance/legal-basis/):** Record, change and withdraw the legal basis your organisation asserts for gated features, and learn which features refuse to start without a receipt.
- **[Data retention, raw IP storage and data locations](https://noxtica.com/docs/compliance/retention-and-locations/):** Set how long browser intelligence data is kept, decide whether full IP addresses are stored, and read where each kind of your data is stored.
- **[Data subject scope, erasure requests and account deletion](https://noxtica.com/docs/compliance/requests-and-deletion/):** Learn which deletion routes exist in Backoffice, how an administrator removes end-user data, and how identity verification data and accounts are deleted.
- **[Cookies, storage and consent categories for your site](https://noxtica.com/docs/compliance/cookies-and-storage/):** List the cookies and browser storage the Noxtica SDK writes, map each to a consent category, disclose them in your cookie policy and set DNT and GPC behaviour.
- **[DPA, sub-processors, DPIA pointers and assurance](https://noxtica.com/docs/compliance/assurance-and-subprocessors/):** Find the public DPA and sub-processor pages, accept the AI assistant as a sub-processor in Backoffice, and know where to ask for DPIA and assurance material.
## Risk Levels
Every assessment can include a numeric score and one of five plain-language levels. The fixed ranges below describe the current public response contract; they are not universal action thresholds.
| Score | Level | Interpret as | Common starting action |
| ------ | ---------- | ------------------------------------------------ | ------------------------------------------------------ |
| 0–19 | `minimal` | Little risk evidence in the available assessment | Allow; retain normal controls |
| 20–39 | `low` | Minor or explainable anomalies | Allow and observe |
| 40–59 | `medium` | Mixed or incomplete suspicious evidence | Observe or use a low-friction step-up |
| 60–79 | `high` | Strong suspicious evidence | Challenge, hold, or review |
| 80–100 | `critical` | Multiple or strong reason families agree | Strong challenge or block only under a reviewed policy |
Confidence answers a separate question: how much usable evidence supported the assessment. Low confidence should normally move a decision toward defer, collect more evidence, or a reversible challenge—not toward an irreversible block.
## Dashboard
Manage your activated account in **[Backoffice](https://backoffice.noxtica.com)**. Start with the selected tenant and domain, then use **Analytics** for population behavior, **Fingerprints** for individual records, **Risk Actions** for policy outcomes, and **Usage** for current limits. The pages you see depend on your role and enabled modules.
## At a Glance
- **Integration model:** domain-bound browser Site Key plus optional scoped server credentials.
- **Primary output:** score, five-level risk tier, confidence, named flags/reasons, and a tenant-scoped device handle.
- **Collection cadence:** cached and configurable; `checkOnce()` respects the applicable interval.
- **Decision owner:** your route-specific policy; Noxtica supplies evidence and eligible enforcement surfaces.
- **Availability:** plan, contract, role, tenant/domain configuration, client support, quota, and legal-basis gates can apply.
- **Performance:** measure your selected client, configuration, geography, network, and cache mix; this page makes no universal latency or availability commitment.
## Support
- **Access, provisioning, commercial eligibility, or technical support:** [Contact us](https://noxtica.com/contact/).
- **Before opening a ticket:** include the tenant and domain, timestamp, customer-visible symptom, relevant request or device handle, and whether the result was cached. Do not send Server API secrets or unnecessary personal data.
- **Capability question:** link the applicable [capability family](https://noxtica.com/docs/features/) and note whether its page or setting is visible in Backoffice.
---
Source: https://noxtica.com/docs/ai-agents/
Markdown: https://noxtica.com/docs/ai-agents/index.md
Last updated: 2026-10-28
# Integrate with an AI agent
Many Noxtica integrations are written with an AI coding agent or an AI assistant. This page shows how to give such an agent the documentation in a form it can read, the order of steps it follows, the rules it must keep, and prompts to start from. Everything the agent needs is published on these pages; it needs no private repository and no credential to read them.
Availability is account-specific, as everywhere in the documentation: the modules enabled for your organisation decide which steps apply to you.
## Give the agent the documentation
Every documentation page is published as clean Markdown, without navigation, search box, table of contents or footer text. Choose the surface that fits the agent's context window.
| Surface | URL | Use it when |
| --- | --- | --- |
| Index | [llms.txt](https://noxtica.com/llms.txt) | The agent should find the right page itself. Pages are grouped by task, in integration order, one line each. |
| Full text | [llms-full.txt](https://noxtica.com/llms-full.txt) | The agent can read the whole documentation in one go. The file is large: `llms.txt` states its size. It leaves out the generated API reference pages, which the OpenAPI files cover. |
| One page | `https://noxtica.com/docs//index.md`, for example [Getting Started](https://noxtica.com/docs/getting-started/index.md) | The task names a page. The body is the page text, with frontmatter (`title`, `description`, `canonical_url`, `last_updated`, `section`) and absolute links. |
| Content negotiation | The page URL with the request header `Accept: text/markdown` | The agent already has the page URL. The response is the same document as the `index.md` URL. |
| OpenAPI | [openapi.json](https://noxtica.com/docs/api/openapi.json) or [openapi.yaml](https://noxtica.com/docs/api/openapi.yaml) | The agent generates or checks client code. One document with every public operation, parameter and webhook of the published release. |
| One API | `https://noxtica.com/docs/api/openapi/.json` or `.yaml`, with `` one of `v1`, `kyc`, `pulse`, `mcp` | The task touches one API and a smaller file fits the context window. |
| API reference | [API reference](https://noxtica.com/docs/api/reference/) | A person or an agent needs the operations in prose and tables, one page per area. |
Every HTML documentation page also announces its Markdown twin with `` in the head and a `Link` response header.
```bash
# The same page, two ways.
curl -s https://noxtica.com/docs/getting-started/index.md
curl -s -H 'Accept: text/markdown' https://noxtica.com/docs/getting-started/
```
## Follow the integration steps in this order
Each step names the page that holds it. An agent that skips ahead tends to guess; give it one step at a time and let it read the linked page first.
1. **Choose one protected moment.** Pick a signup, login, checkout or recovery step, and decide what happens when no fresh evidence is available. See [Getting Started](https://noxtica.com/docs/getting-started/) and [Integration Flow](https://noxtica.com/docs/integration-flow/).
2. **Register the domain and read its public Site Key.** A person does this in Backoffice. See [Domains, site keys and the install card](https://noxtica.com/docs/backoffice/domains/).
3. **Install the browser collector.** Load the core script on every page and the extensions after consent. See [Install & Browser Runtime](https://noxtica.com/docs/browser-runtime/) and [Script attributes and client options](https://noxtica.com/docs/sdk/script-attributes/).
4. **Set the consent mode and connect your banner.** See [Consent modes, GPC and Google Consent Mode](https://noxtica.com/docs/sdk/consent/) and [Cookies, storage and consent categories for your site](https://noxtica.com/docs/compliance/cookies-and-storage/).
5. **Declare protected actions and trigger the check.** The browser hands your backend a request id. See [Protected actions: client trigger and server check](https://noxtica.com/docs/sdk/protected-actions/).
6. **Create a server key and authenticate.** A person creates the key in Backoffice; the server keeps it in its secret store. See [API authentication](https://noxtica.com/docs/api/authentication/).
7. **Verify on your server.** Redeem the request id or read the device from the backend, and keep the result states separate. See [Backend Integration](https://noxtica.com/docs/backend-integration/).
8. **Add identity verification when it is enabled for you.** Create a hosted session from the server and read the outcome. See [Identity verification integration](https://noxtica.com/docs/identity-verification-integration/).
9. **Receive webhooks.** Verify the signature of every delivery before you act on it. See [API webhooks](https://noxtica.com/docs/api/webhooks/).
10. **Handle errors and limits.** See [API errors](https://noxtica.com/docs/api/errors/) and [API rate limits](https://noxtica.com/docs/api/rate-limits/).
11. **Compare before you enforce.** Run the policy in observation mode and compare proposed actions with outcomes before any block or challenge. See [Getting Started](https://noxtica.com/docs/getting-started/).
12. **Optional: connect an MCP client.** See [Connect an MCP client](https://noxtica.com/docs/api/mcp/).
## Rules an agent must keep
Give the agent these rules in its instructions, next to the task.
### Credentials
- Use placeholders in code, prompts and examples: `pk_prod_your_site_key_here` for the public Site Key and `sk_prod_your_api_key` for a server key. Read the real value from an environment variable such as `NOXTICA_SERVER_KEY` at run time.
- Never put a real server key (`sk_…`), MCP token (`mcp_…`), ingestion key, webhook signing secret or Backoffice credential into a prompt, a chat, an issue, a log or a commit. If one reached an agent anyway, revoke it in Backoffice and create a new one.
- Keep server credentials out of browser code, URLs, client logs and analytics. The browser holds the public Site Key only.
- Create keys, tokens and webhook endpoints in Backoffice. An agent does not create them, and the documentation does not ask it to.
### Consent and people
- Do not grant consent on behalf of a visitor. Call `setConsent` only with the visitor's own choice, and do not switch a domain to a consent mode that skips the decision just to get past a failing check. The consent mode is a decision for your privacy owner.
- Do not create an identity verification session for a person who did not ask for one. The legal basis is recorded by an authorised person in your organisation before a session can be created.
- Treat a device identifier as a lookup handoff, not as an identity credential.
### Results and traffic
- Do not turn a score into a "bot or human" verdict. Read the risk, the confidence and the reasons, and keep `missing`, `invalid`, rate-limited and unavailable results distinct from low risk.
- Call only the hosts and operations the documentation and the OpenAPI files name. An operation that is not in them is not part of the public API.
- On HTTP `429`, wait for the number of seconds in `Retry-After`. Do not hard-code a limit: limits depend on the operation and on your account.
- Read a session status before you act on an event, and verify the signature of every webhook delivery.
- A write-capable MCP token only plans a change. A person approves each plan in Backoffice; an agent never applies one.
## Start from a prompt
Copy a prompt, replace the text in angle brackets, and add the rules above. Each prompt names the pages the agent must read first.
### Plan the integration
```text
You are integrating Noxtica into . Read https://noxtica.com/llms.txt, then
https://noxtica.com/docs/ai-agents/index.md, https://noxtica.com/docs/getting-started/index.md
and https://noxtica.com/docs/integration-flow/index.md.
Propose a plan for one protected moment: . List each step in the
order of the documentation, name the page that holds it, say which step a person must do in Backoffice,
and say what the application does when Noxtica returns no fresh evidence.
Do not write code yet. Use the placeholders pk_prod_your_site_key_here and sk_prod_your_api_key.
```
### Install the browser collector with consent
```text
Read https://noxtica.com/docs/browser-runtime/index.md and https://noxtica.com/docs/sdk/consent/index.md.
Add the Noxtica core script to every page of and load the extensions only after the
visitor consents through . Use the public Site Key placeholder pk_prod_your_site_key_here.
Show the Content Security Policy change from https://noxtica.com/docs/sdk/csp-and-relay/index.md.
Never call setConsent for a category the visitor has not chosen.
```
### Verify on the backend
```text
Read https://noxtica.com/docs/backend-integration/index.md, https://noxtica.com/docs/sdk/protected-actions/index.md
and https://noxtica.com/docs/api/authentication/index.md.
Write the server handler in that receives the request id from the browser,
redeems it with the server key from the environment variable NOXTICA_SERVER_KEY, and returns one of these
states: received, missing, invalid, rate limited, unavailable. Treat every state except received as "no
fresh evidence", never as low risk. On 429 honour Retry-After. Do not log the key.
```
### Create an identity verification session
```text
Read https://noxtica.com/docs/identity-verification-integration/index.md and
https://noxtica.com/docs/api/webhooks/index.md. Use https://noxtica.com/docs/api/openapi/kyc.json for the
request and response shapes.
Write the server code that creates a hosted session with my own opaque customer reference, redirects the
customer to the returned link, and reads the session status. Verify the signature of every
kyc.session.completed delivery and read the status before acting on it. Use the placeholder
sk_prod_your_api_key and never print it.
```
### Review an integration against the documentation
```text
Read https://noxtica.com/llms-full.txt. Review the Noxtica integration in this repository against it.
Report, per file: a server key reachable from browser code, a consent category granted without a visitor
choice, a result state treated as low risk, a missing Retry-After handling, a webhook handled without
signature verification. Quote the documentation page for each finding and propose the smallest fix.
```
## Connect an agent through MCP
An MCP client can read your workspace data with a scoped token. The endpoint is one HTTPS URL that speaks JSON-RPC 2.0; the token is a static bearer token that a person creates in Backoffice under Integrations & API, so configure the client with a custom `Authorization` header. Start with a read token and call `tools/list` to see what it may use. See [Connect an MCP client](https://noxtica.com/docs/api/mcp/) and [MCP integration](https://noxtica.com/docs/concepts/mcp-integration/).
## Common questions
### Do I need a key to read the documentation?
No. Every documentation page, `llms.txt`, `llms-full.txt` and the OpenAPI files are public. A key is needed only when the integration you build calls a server API.
### Can the agent create keys or change settings for me?
No. A person creates keys, tokens, webhook endpoints and consent settings in Backoffice. An MCP token with write access can only plan a change, and a person approves it.
### Which is authoritative, the Markdown or the HTML page?
The HTML page at its canonical URL. The Markdown is generated from the same source text, and every Markdown document names its `canonical_url` and the `last_updated` date.
### Where do I find the exact request and response shapes?
In the OpenAPI files and the [API reference](https://noxtica.com/docs/api/reference/). Each reference page names the OpenAPI release it comes from.
---
Source: https://noxtica.com/docs/getting-started/
Markdown: https://noxtica.com/docs/getting-started/index.md
Last updated: 2026-10-27
# Getting Started
This guide is the starting point for a Noxtica technical evaluation. The [developer overview](https://noxtica.com/developers/) links each step to the page that holds it.
## Before you integrate
Request a technical evaluation so the team can provision the exact browser origin, public Site Key, and server access needed for the evaluated path. Do not copy credentials or package names from private repositories, old examples, or another environment.
The current publicly verified browser release is the loader served from the Noxtica collector origin. No public npm package, framework wrapper, native SDK, server SDK, or Postman collection passed the 2026-09-20 release check, so this guide does not provide installation commands for them. They exist as private deliveries that your account team arranges: see [SDK family and availability](https://noxtica.com/docs/sdk/family/). The public API operations are published as an OpenAPI description at [openapi.json](https://noxtica.com/docs/api/openapi.json), and [Integrate with an AI agent](https://noxtica.com/docs/ai-agents/) shows how to hand these docs to an AI coding agent.
## Automatic collection (recommended)
Copy your domain's snippet from **Backoffice → Integrations & API → Script & Consent** and follow the [install walkthrough](https://noxtica.com/docs/browser-runtime/#install-core-on-every-page-extensions-after-consent), the single source for the scripts, CSP, consent modes, and checks.
## Shortest maintained path
1. Use the [browser sample](https://noxtica.com/docs/browser-runtime/#browser-handoff-sample) from the checked fixture.
2. Observe both the collection-complete and collection-error paths.
3. Send only the returned device identifier to your own backend.
4. Use the [server sample](https://noxtica.com/docs/backend-integration/#read-the-device-on-your-server) for the authenticated device lookup.
5. Exercise received, missing, invalid, rate-limited, and unavailable states with the [result-state sample](https://noxtica.com/docs/backend-integration/#keep-result-states-separate).
6. Compare proposed policy actions with outcomes in observation mode before enforcement.
## Application responsibility
The browser collector does not make your final signup, login, checkout, recovery, or access decision. Browser capability, tenant policy, privacy signals, and consent state can reduce or prevent collection. Your application must remain usable and apply its chosen fallback when no fresh evidence is available.
Keep server credentials out of browser code, URLs, client logs, and analytics. A device identifier is a lookup handoff, not an identity credential.
## Verify the evaluation
Confirm the exact origin is provisioned, collection can complete, the unavailable path remains usable, the backend can perform an authenticated read, and every non-success state stays distinct from low risk. Successful installation alone does not establish a production-ready policy.
Continue with [Install & Browser Runtime](https://noxtica.com/docs/browser-runtime/), [Backend Integration](https://noxtica.com/docs/backend-integration/), and [Integration Flow](https://noxtica.com/docs/integration-flow/).
---
Source: https://noxtica.com/docs/integration-flow/
Markdown: https://noxtica.com/docs/integration-flow/index.md
Last updated: 2026-10-24
# Integration Flow
The [developer overview](https://noxtica.com/developers/) is the short evaluator path and current support matrix. This guide expands the ownership checkpoints without creating a second set of snippets.
## 1. Customer client
Load the verified public browser collector for the provisioned origin, using the snippet from **Backoffice → Integrations & API → Script & Consent** and the [install walkthrough](https://noxtica.com/docs/browser-runtime/#install-core-on-every-page-extensions-after-consent). The client reports either a collection result or an unavailable state. When a result contains a device identifier, pass only that identifier to your backend with the customer action it will inform.
JavaScript disabled, blocked collection, reduced capability, tenant policy, and consent state can change what evidence is available. The customer journey must remain usable.
## 2. Noxtica processing
Noxtica processes evidence admitted by the evaluated browser and tenant configuration. A completed browser result can expose less than the authenticated server record. Do not infer low risk from an absent browser score.
## 3. Customer server
Keep the credential secret and perform the authenticated v1 device lookup. Preserve received, missing, invalid, rate-limited, and unavailable states. Apply a deadline rather than waiting indefinitely on a customer-facing operation.
## 4. Customer policy
Your application combines the lookup with context it already owns. It chooses whether to continue, observe, request additional verification, review, or deny. Noxtica does not autonomously make that final customer decision.
## 5. Investigation and measurement
Confirm collection and lookup behavior, calculate proposed actions in observation mode, label outcomes from your own systems, review false-positive cost, and only then promote a bounded policy. Keep an owner and rollback path.
## Evaluation checkpoints
1. Provision the exact origin and public Site Key.
2. Observe collection and unavailable behavior.
3. Pass the returned identifier to the customer backend.
4. Perform an authenticated read with a server-held credential.
5. Exercise every result state in the maintained fixture.
6. Evaluate policy in observation mode before enforcement.
Continue with [Install & Browser Runtime](https://noxtica.com/docs/browser-runtime/) or [Backend Integration](https://noxtica.com/docs/backend-integration/).
---
Source: https://noxtica.com/docs/browser-runtime/
Markdown: https://noxtica.com/docs/browser-runtime/index.md
Last updated: 2026-10-27
# Install & Browser Runtime
**Find your snippet in the Backoffice → Integrations & API → Script & Consent** ([`/integrations/script-consent`](https://backoffice.noxtica.com/integrations/script-consent)). Pick the domain and the page generates the tags with that domain's Site Key and the current collector build, plus the consent mode, protected actions, and a verification checklist. This page is the public walkthrough of the same content: what to install, in which order, and how to check that it works. Every Site Key on this page is a placeholder (`pk_prod_your_site_key_here`); never copy a key, hash, or build name from a document.
The [developer overview](https://noxtica.com/developers/) links the integration guides in order. Other docs pages link here instead of repeating install steps.
## Current public surface
The public collector loader is served from the Noxtica collector origin, `https://collect.noxtica.com` unless your account has a provisioned collector host. This page calls that origin "your collector host". No public npm package, framework wrapper, native SDK, or cross-platform wrapper passed the 2026-09-20 release check described in [Getting started](https://noxtica.com/docs/getting-started/#before-you-integrate), so those surfaces are omitted rather than inferred from private inventory.
## Install: core on every page, extensions after consent
The collector is two scripts. Load the core on every page; load the extensions only when your consent mode allows it.
- The **core** (`noxtica-collector-core.js`) needs no consent. It obtains the session token, submits the minimal security check, answers server-requested challenges, offers the consent API and the extensions loader, and runs [protected actions](https://noxtica.com/docs/browser-runtime/#protected-actions). In a consent-gated mode it stores nothing on the visitor's device.
- The **extensions** (`noxtica-collector-extensions.js`) need consent. They carry persistent device recognition, the full device fingerprint, analytics, real-user monitoring and console logs, session replay, and behavioral signals. Each module still runs only when its category is granted.
```html
```
| Attribute | Purpose |
| ---------------------- | ------------------------------------------------------------------------------------------------------------ |
| `data-site-key` | The public Site Key of the exact origin. Keys are origin-bound: a token request from another origin is refused with `403` and `{"error":"Origin mismatch"}`. |
| `data-auto-init` | Creates the client and assigns `window.noxticaClient`. |
| `data-auto-check-once` | Runs the cache-aware check (`checkOnce()`) once per page. |
| `data-extensions` | Optional. `"auto"` makes the core load the extensions itself; any other value keeps that off. |
| `async` | The core never needs to block rendering. |
Load the extensions in one of three ways:
- add `data-extensions="auto"` to the core tag: the core loads them immediately in `not_required` mode and on the first granted category in the `api` and cookie modes;
- call `await window.noxticaClient.loadExtensions()` after your page grants consent (see [Loading extensions](https://noxtica.com/docs/browser-runtime/#loading-extensions-and-its-result));
- inject `` yourself after consent. It carries no Site Key and attaches to the core already on the page.
Loading the extensions never grants consent by itself. You can also switch **Auto-load extensions** on per domain in Script & Consent. In `not_required` mode that loads the extensions for every visitor, including those who declined your own banner, so treat it as a decision about your banner, not a convenience.
**Existing installs.** The legacy URLs `https://collect.noxtica.com/collector/noxtica-collector.js` and `/collector/noxtica.js` now serve the core and load the extensions automatically: immediately in `not_required` mode, after the first grant in the gated modes. Set `data-extensions` to any other value to opt out. The original combined bundle is deprecated and no longer offered; new installs use the core tag above.
**Device-analysis engines.** The KHAN and Obsidian engines are split the same way (`khan-core` and `obsidian-core`, then the matching extensions) and load automatically with the core and the extensions. You never add their tags.
## Stable or pinned snippets
Script & Consent generates two variants of each tag from the collector's live manifest, `https://collect.noxtica.com/collector/asset-manifest.json`.
- **Stable (default).** The unhashed URL always serves the current build and carries no `integrity` attribute, so the tag never needs updating.
- **Pinned with Subresource Integrity.** Use it only if your security policy requires an `integrity` attribute. A pinned tag references one exact content-hashed build:
```html
```
Build it from the manifest: `assets["noxtica-collector-core.js"]` is the file name under `/collector/` and `integrity["noxtica-collector-core.js"]` is the `integrity` value. The extensions use the keys `noxtica-collector-extensions.js`. A pinned core loads the extensions with their own integrity hash, so you do not pin the extensions separately.
**How long a pin lasts.** The hashed core and extensions bundles of the last three previous releases keep resolving, byte-identical and immutable, and are listed in `previous[]` of the manifest. Copy the pinned tag again within three releases; after that the pinned file stops being served and the browser blocks it. Hashed files are never a substitute for the manifest: do not copy a hash from a document, including this one.
**The recorder head is the exception.** The early replay loader (`noxtica-recorder-head.js`) is not retained: its hashed URL stops resolving on the next recorder build, so the stable tag in the next section is the default.
## Replay recorder head
Session replay can start before the page paints. The recorder head is a small synchronous preloader that buffers a bounded early window in memory and has no transport. The asynchronous core drains it only after the configured replay admission checks allow capture; otherwise the queue is discarded. Sites that do not use replay may omit it.
```html
```
- It must be the **first executable script** in ``, before anything else that runs.
- Load it **synchronously**: never `async`, `defer`, or `type="module"`.
- `data-cfasync="false"` stops Cloudflare Rocket Loader from deferring it.
- It needs an **armed replay policy** for the domain (Backoffice → Session Replay) and a consent flow that calls `setConsent` with the `replay` category.
- A pinned variant comes only from the live manifest key `noxtica-recorder-head.js`; keep `crossorigin="anonymous"` and `data-cfasync="false"`.
## Content Security Policy
If your site sends a Content Security Policy, add only what the collector needs, and merge the sources into your own lists; do not paste a vendor policy over yours. Hosts below are your collector host (`collect.noxtica.com` by default) and the ingest host (`ingest.noxtica.com`, derived automatically from the default collector host).
| Directive | Allow | Why |
| ------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `script-src` | your collector host and `'wasm-unsafe-eval'` | Loads the core, extensions, and engine loaders. `'wasm-unsafe-eval'` lets the KHAN and Obsidian engines compile WebAssembly; it does not allow `eval()`. |
| `worker-src` | `blob:` (keep your own entries, such as `'self'`) | The engines start workers from `blob:` URLs. A worker script must be same-origin, so it cannot be served from the collector host. |
| `connect-src` | your collector host **and** the ingest host (only if your page declares one) | Token and submit calls go to the collector host. Analytics, RUM, console logs, and replay use the ingest host and fail over to the collector once, then stay there; a policy with only one of the two breaks half the traffic. |
If your domain uses server-requested challenges, also allow Cloudflare Turnstile as its documentation describes (`https://challenges.cloudflare.com`). The Script & Consent **CSP & storage** tab prints the same lines with your own hosts filled in.
```http
Content-Security-Policy:
script-src 'self' https://collect.noxtica.com 'wasm-unsafe-eval';
worker-src 'self' blob:;
connect-src 'self' https://collect.noxtica.com https://ingest.noxtica.com;
```
- **`'wasm-unsafe-eval'` is needed.** Without it the engines cannot start; the SDK fails open, collection continues with reduced evidence, and a structured error is reported.
- **`'unsafe-eval'` is not needed.** Noxtica does not need `'unsafe-eval'`, and a policy without it produces no `eval` violation from Noxtica. The only Noxtica code that ever called `new Function(...)` was an optional KHAN diagnostic lane in the extensions runtime: a one-line capability probe, `new Function('return 0')`, and nine diagnostic programs. No score, verdict, or device identifier depends on it. The lane runs only while the signed token arms it, and from release r32 (2026-10-24) it is disarmed for every domain, so the runtime no longer evaluates dynamic code. If a site still sees `eval` reports, it is on an older token or a cached copy: an enforcing `script-src` reports one violation (blocked URI `eval`, source `…/collector/noxtica/noxtica-khan.js`) and a report-only policy about ten per consented visit. Reload with a fresh page load to get a current token; no policy change is needed. Do not add `'unsafe-eval'` for Noxtica.
- **`chrome-extension:` reports are probe noise.** On Chromium, with the `behavioral` category granted, the extension probe requests a few `chrome-extension://…` resources through script tags. An enforcing `script-src` can report them. The probe reads a blocked or missing resource as "not installed", so do not allow `chrome-extension:` for Noxtica.
- **Hash or nonce next to `'unsafe-inline'`.** Browsers that see a hash or nonce ignore `'unsafe-inline'`, which breaks every other inline script. If your policy relies on `'unsafe-inline'`, do not add a hash or nonce for the inline listener without a full nonce migration; if you already use nonces, give the inline listener its nonce.
- **Probe periodically.** A permissive policy hides what it allows: with `'unsafe-inline'` and `'unsafe-eval'` listed, report-only telemetry sees no inline or eval use. Send a stricter policy as a second, report-only header for a day before you tighten the enforcing one, and read the reports. It changes nothing on the page:
```http
Content-Security-Policy-Report-Only: script-src 'self' https://collect.noxtica.com; worker-src 'self'; connect-src 'self' https://collect.noxtica.com https://ingest.noxtica.com; report-uri /csp-report
```
## Consent modes (tenant integration guide)
Consent modes let a domain split the collector into a consent-free core and consent-gated categories. New domains start in `api` mode: the page check is skipped (`noxtica:collected` carries `skipped: 'consent_required'`) and nothing persistent is written until your page calls `setConsent`. Domains that already existed keep the mode they have, so an existing install changes nothing. `not_required` remains an explicit choice that keeps the behavior from before consent modes existed.
### Choosing a mode
Set the mode per domain in **Backoffice → Integrations & API → Script & Consent** (the Consent & extensions tab), stored as the domain's `client_consent_mode`. The collector reads it when it issues the browser token.
| Mode | Behavior |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `not_required` | Not a consent gate. Domains created before the `api` default and never changed keep this mode, and you can choose it explicitly. Collection runs as configured today. An explicit `denied` from your page is still honored for that category. |
| `api` | The default for new domains. Every category starts denied. Your page grants or denies categories with `client.setConsent(...)`, usually from your consent management platform (CMP). |
| `cookie:` | The collector reads the first-party cookie ``. Present and non-empty means every category is granted; absent or empty means every category is denied. |
| `cookie:=` | The collector reads cookie ``, URI-decodes it, and grants every category when the decoded value contains ``. Otherwise every category is denied. This matches CMP strings, for example `cookie:OptanonConsent=C0002:1`. |
Cookie names may use letters, digits, `_`, `.`, and `-`; values may additionally use `:`, `%`, and `+`. Backoffice rejects anything else. A value that cannot be parsed is treated as `not_required`, so the domain keeps its current behavior.
**`not_required` is not a consent gate.** The persistent device identifier is written unless your page set `deviceId` to `denied`, and nothing waits for your banner. The extensions write it, so in this mode it applies from the moment they load: right away with `data-extensions="auto"`, the legacy URLs, or **Auto-load extensions**. The core alone never writes persistent storage. Pick `api` or a cookie mode when your visitors must decide first.
### Declaring the mode on the loader (optional)
The domain setting arrives with the first token. If your consent decision reaches the page by API, also declare the mode on the core tag so the client is strict from its first line, before that token returns:
```html
```
Accepted forms are `data-consent-mode="api"`, `data-consent-mode="cookie:name"` or `data-consent-mode="cookie:name=value"`, and the shorthand `data-consent-cookie="name"` or `data-consent-cookie="name=value"`. Programmatic clients pass the same value:
```javascript
const client = NoxticaCollector.createClient({ siteKey: 'pk_prod_your_site_key_here', consentMode: 'api' });
```
A declaration can only make the client stricter. The domain setting stays authoritative for server enforcement, and a tag can never relax it. Without the declaration, a call such as `setConsent` made in the window before the token is announced with `mode: "not_required"`. Up to SDK 3.8.0 the same event then reports `api` only once the token arrives; from SDK 3.8.1 the client dispatches a second `noxtica:consent-changed` with `mode: "api"` when the token resolves, and `getConsent()` and the event detail carry `modeResolved` (`false` until then). If your bridge ever sends a partial object, or calls `loadExtensions()` before `setConsent`, declare the mode.
### Core and extensions in a gated mode
In the `api` and cookie modes, keep the core on every page and load the extensions only after the visitor accepts (see [Install](https://noxtica.com/docs/browser-runtime/#install-core-on-every-page-extensions-after-consent)). With the `api` mode, grant the categories and then load the extensions:
```javascript
const client = window.noxticaClient;
client.setConsent({ deviceId: 'granted', analytics: 'granted', replay: 'granted', behavioral: 'granted' });
await client.loadExtensions(); // resolves { ok: true } once the extensions are active
```
Each value is the string `'granted'` or `'denied'`; any other value, including `true` or `false`, throws a `TypeError`. Adding `data-extensions="auto"` to the core tag makes the core load the extensions on the first granted category instead.
### Consent API
With `data-auto-init`, the client is available as `window.noxticaClient`. Programmatic clients use the object returned by `createClient`.
- `client.setConsent({ analytics, replay, deviceId, behavioral })` sets each listed category to `'granted'` or `'denied'`. Omitted keys keep their current state.
- `client.setConsent('granted' | 'denied')` is the legacy form. It changes `analytics` only.
- `client.setReplayConsent(true | false)` changes `replay` only.
- `client.getConsent()` returns the current state: `{ mode, analytics, replay, deviceId, behavioral, privacySignal }`, where `privacySignal` is `'gpc'`, `'dnt'` or `null`.
Example wiring with a generic CMP callback (OneTrust- or Cookiebot-style). Map your CMP's purposes to Noxtica categories as your privacy team decides:
```javascript
const client = window.noxticaClient;
const state = (allowed) => (allowed ? 'granted' : 'denied');
cmp.onConsentChanged((choices) => {
client.setConsent({
analytics: state(choices.statistics),
replay: state(choices.statistics),
deviceId: state(choices.preferences),
behavioral: state(choices.marketing),
});
});
```
In cookie modes the collector reads the cookie when it starts and again on `visibilitychange` and `focus`, so a decision made in your banner applies when the visitor returns to the tab. A grant applies to all categories at once. A missing or non-matching cookie denies all categories and purges the persistent device stores.
### Verify your consent mode the way the browser sees it
The authoritative mode lives in the domain's tenant settings, not in your page code, so a settings change can alter behavior without any deploy on your side. Check what the browser actually receives:
- `window.noxticaClient.getConsent().mode` reports the effective mode: `not_required`, `api`, `cookie:[=]`, or `gcm`. Read it after the first `noxtica:collected` event, because until the token arrives the client does not know the domain's mode.
- `collectorConfig.consent` in the `POST /client/token` response (DevTools → Network) carries the server-side mode.
Make this a release check on the live page, with the banner still unanswered:
```javascript
// Expect your configured mode ('api' here). 'not_required' means the domain setting changed or the wrong domain is selected.
document.addEventListener('noxtica:collected', () => {
console.assert(window.noxticaClient.getConsent().mode === 'api', 'Noxtica consent mode drifted');
});
```
With the mode `api` and nothing granted, you should see only the core script and `POST /client/token`, a `sessionStorage` token, and a `noxtica:collected` event with `skipped: 'consent_required'`. Before any decision every category must read `unknown` or `denied`, and `Object.keys(localStorage).filter((k) => k.startsWith('nox_'))` must be empty. Anything in `localStorage`, IndexedDB, or cookies before the visitor answers is a finding.
### Events and timing
Attach your listeners before the loader can run, and treat events as signals, not as data sources.
- **Listen early.** Put the `noxtica:collected` listener in an inline `` script **before** the core tag. `checkOnce()` announces a visit once and does not re-collect inside its TTL, and an event that already fired is not replayed.
- **Deliver consent on `noxtica:ready`** (SDK 3.6.0 and later), which fires once per tag after `window.noxticaClient` exists. Back it with a bounded poll for older cores, and let the latest choice win.
- **Never trust `event.detail.client`.** Any script can dispatch a forged `noxtica:ready`. Use the event as a signal and read `window.noxticaClient`, which the core assigns before it dispatches.
- **Prefer deciding consent in a `noxtica:ready` handler, not in the pre-init queue (`noxtica('setConsent', …)`).** Before SDK 3.8.1 the queue replays every command in order, so a grant followed by a withdrawal still runs `loadExtensions()`. From SDK 3.8.1 queued consent updates are folded into one (the later key wins), a queued `loadExtensions` is dropped when all four categories end denied (`noxtica:extensions-failed` with `consent_missing`), and one `noxtica:consent-changed` fires. Use the queue for one-time declarations either way.
- **Decide "is Noxtica on this page" by host or build configuration,** not by a DOM attribute: a client-side locale switch or framework remount can clear attributes on ``.
```html
```
```javascript
// Run when your consent choice is known; calls whenNoxticaReady once the client exists.
function whenNoxticaReady(callback, { timeoutMs = 15000 } = {}) {
if (window.noxticaClient) return callback(window.noxticaClient);
const started = Date.now();
const poll = setInterval(() => {
if (window.noxticaClient) { clearInterval(poll); callback(window.noxticaClient); }
else if (Date.now() - started > timeoutMs) clearInterval(poll); // fail open: no client, no collection
}, 250);
document.addEventListener('noxtica:ready', () => { clearInterval(poll); if (window.noxticaClient) callback(window.noxticaClient); }, { once: true });
}
```
| Event | `event.detail` | When |
| --------------------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| `noxtica:ready` | `{ client }` | `data-auto-init` created the client (SDK 3.6.0+). The first check has not started. |
| `noxtica:collected` | the check result, or `{ success: false, skipped: 'consent_required', consentMode }` | After each check, and when a check is deferred until consent. |
| `noxtica:cache-hit` | the same result with `fromCache: true` | Right after `noxtica:collected` when the TTL served the stored result. |
| `noxtica:consent-changed` | the `getConsent()` snapshot | A category really changed. |
| `noxtica:extensions-loaded` | `{ message: 'attached', ok: true, loaded }` | The extensions took over the client. |
| `noxtica:extensions-failed` | `{ message: 'not-loaded', ok: false, reason, code }` | A load attempt failed. A later `loadExtensions()` retries. |
| `noxtica:error` | `{ source, message }` | A failure the SDK reported; also stored in `window.noxticaLastError`. |
The `extensions-*` event details are objects from SDK 3.8.0 and strings before it.
### Browser handoff sample
This sample loads the core tag and hands your own code one of three states: `received` with a device identifier, `invalid` when the result carries no identifier, or `unavailable` when the collector reports an error. The browser never receives a server credential. Replace `pk_example_replace_me` with the public Site Key of the exact origin.
```html
```
The tag includes `data-extensions="auto"`; the attribute table under [Install: core on every page, extensions after consent](https://noxtica.com/docs/browser-runtime/#install-core-on-every-page-extensions-after-consent) says what it does, and loading the extensions never grants consent by itself. Send only the returned device identifier to your backend, as [Backend integration](https://noxtica.com/docs/backend-integration/#maintained-server-sample) shows.
### Loading extensions and its result
`loadExtensions()` never rejects. From SDK 3.8.0 it resolves `{ ok: true, loaded }` on success and `{ ok: false, reason, code }` on failure; up to 3.7.0 it resolved a boolean. An object is always truthy, so test the result, not its existence. Failures do not throw, so a retry guard that only clears on rejection never clears:
```javascript
let extensionsRequested = false;
async function requestExtensions() {
if (extensionsRequested) return;
extensionsRequested = true;
const res = await window.noxticaClient.loadExtensions();
const ok = res === true || res?.ok === true; // boolean up to 3.7, object from 3.8
if (!ok) extensionsRequested = false; // allow a retry on the next consent signal
}
```
| `reason` | Produced when |
| -------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `consent_missing` | You passed `{ requireConsent: true }` in a gated mode and no category is granted. Nothing is fetched. |
| `csp_blocked` | The browser reported an enforced CSP violation for the script URL. |
| `integrity_mismatch` | A pinned file's bytes differ from its `integrity` value. |
| `network` | An HTTP error or no response for the script (`http_`, `fetch_failed`). |
| `timeout` | Neither a load nor an error event within 20 seconds. A later call retries. |
| `already_loaded` | A `
```
Keep the file name. The loader binds a tag when its `src` contains `noxtica-collector` or `/noxtica.js` and the tag carries `data-auto-init`; a tag that misses either condition is ignored. This matters when you copy the script to your own path or serve it through a [first-party relay](https://noxtica.com/docs/sdk/csp-and-relay/).
### 2. Set the attributes you need
| Attribute | Accepted values | Default | Effect |
| --- | --- | --- | --- |
| `data-site-key` | Your Site Key | none, required | A tag without it is skipped: no client, no events. The key works on the origin registered for its domain. |
| `data-auto-init` | Boolean attribute | off | Creates the client for this tag, assigns `window.noxticaClient`, runs the `window.noxtica` command queue, then dispatches `noxtica:ready`. Without it the loader does nothing by itself. |
| `data-auto-check-once` | Boolean attribute | off | After `noxtica:ready`, runs `checkOnce()` once per page load and announces the result with `noxtica:collected`. Recommended. |
| `data-auto-collect` | Boolean attribute | off | Legacy. Runs `collectAndSubmit()` on every page load, without the cache. Ignored when `data-auto-check-once` is also present. |
| `data-ttl-seconds` | Positive integer | none | Cache window in seconds for the automatic check. Read together with `data-auto-check-once`; without that attribute it has no effect. Zero, negative and non-numeric values are ignored. |
| `data-check-interval-days` | Positive number | none | Cache window in days for every `checkOnce()` call of this client. Zero, negative and non-numeric values are ignored. |
| `data-api-url` | `https` URL, or any URL on `localhost` or `127.0.0.1` | `https://collect.noxtica.com` | Collector origin for the token, submit and visit calls. Any other value is ignored and a warning is logged. |
| `data-ingest-url` | `auto`, or an `https` URL (or a localhost URL) | `auto` | Origin for high-volume telemetry: RUM, RUM error detail, console logs, the client buffer, and the replay policy and upload calls. The interaction tracker stays on the collector. `auto` derives `https://ingest.noxtica.com` from the default collector host and keeps any other `data-api-url` host for telemetry too. An explicit URL wins; set it to the collector origin to keep telemetry on the collector. An invalid value is ignored and a warning is logged. |
| `data-consent-mode` | `api`, `cookie:`, `cookie:=`, `gcm`, `not_required` | none | Declares the consent mode before the signed token arrives. A declaration can make the client stricter; it never relaxes the mode saved for the domain. See [Consent modes](https://noxtica.com/docs/sdk/consent/). |
| `data-consent-cookie` | `` or `=` | none | Shorthand for `data-consent-mode="cookie:"`. Ignored when `data-consent-mode` is present and valid. |
| `data-extensions` | `auto` | manual | `auto` makes the core load the extensions script itself. Any other value keeps the extensions manual, and overrides the automatic default of the legacy script URLs. The domain setting **Load the extensions script automatically once consent is granted (immediately in Not required mode)** still applies. |
| `data-log-level` | `silent`, `error`, `warn`, `info`, `debug` | see step 5 | Highest-precedence console log level. An invalid value is ignored. |
| `data-debug` | Boolean attribute | off | Legacy switch. Behaves like log level `debug` when no explicit level is set anywhere. |
| `data-debug-upload` | Boolean attribute | off | Diagnostic. Replay chunk and finalize uploads are captured on the page instead of being sent. Do not leave it on in production. |
| `integrity`, `crossorigin="anonymous"` | SRI hash, as generated | none | The pinned variant of the tag. See [Stable or pinned snippets](https://noxtica.com/docs/browser-runtime/#stable-or-pinned-snippets). |
| `async` | Boolean attribute | none | Lets the page render while the core loads. |
Two attributes go on your own forms, not on the script tag:
| Attribute | Where | Default | Effect |
| --- | --- | --- | --- |
| `data-nox-protect=""` | A form, or a button or input inside one | none | Runs the protected-action check for the named action. The action must be declared for the domain. See [Protected actions](https://noxtica.com/docs/sdk/protected-actions/). |
| `data-nox-protect-timeout=""` | The same form | `6000` | How long a native form submit is held while the check runs. A value that is not a positive integer falls back to the default. |
### 3. Choose how often the page check runs
`checkOnce()` returns the cached result while the cache window is open and records a visit instead of collecting again. The loader picks the window in this order, and the earliest match wins:
1. `ttlSeconds` in the call. For the automatic check this is `data-ttl-seconds`.
2. `checkIntervalDays` in the call.
3. The client option `checkIntervalDays`, which `data-check-interval-days` sets.
4. The `checkIntervalDays` value in the domain policy delivered with the session token.
5. Seven days.
Call options for `checkOnce(options)`:
| Option | Default | Effect |
| --- | --- | --- |
| `ttlSeconds` | none | Cache window in seconds for this call. |
| `checkIntervalDays` | none | Cache window in days for this call. |
| `forceRefresh` | `false` | Clears the stored state and collects again. |
| `recordVisit` | `true` | Records a visit on a cache hit. With `false` the cached result comes back with `visitRecorded: false`. |
| `meta` | none | Metadata passed with the visit record. |
### 4. Create a client from code
Use `createClient` when a tag with `data-auto-init` does not fit, for example when your page decides at run time whether to start Noxtica. A client you create yourself does not set `window.noxticaClient`, does not dispatch `noxtica:ready` and does not read the command queue. Its results come back through the promises it returns.
```html
```
`createClient` throws `NoxticaCollector: siteKey is required` when it finds no Site Key, either in the `siteKey` option or on a collector tag with `data-site-key`.
| Option | Type and default | Effect |
| --- | --- | --- |
| `siteKey` | string | Your Site Key. Falls back to the `data-site-key` of a collector tag on the page. |
| `apiUrl` | `https` URL, default `https://collect.noxtica.com` | Collector origin. |
| `ingestUrl` | URL or `'auto'`, default `'auto'` | Telemetry origin; same rules as `data-ingest-url`. |
| `mode` | `'max'` (default) or `'lite'` | `max` collects the full signal set. `lite` skips the collectors that belong to `max` mode. Protected actions always run in minimal mode. |
| `checkIntervalDays` | number | Client-level cache window. |
| `signatureMode` | `'require'` (default), `'warn'`, `'disabled'` | What the client does when a signed server response is missing or altered. `require` rejects it, `warn` logs and continues, `disabled` skips the check. An unknown value falls back to `require`. Keep `require`. |
| `accountId` | string, up to 256 characters | Your own end-user account id, sent with the next submit. Use an opaque id, not an e-mail address. `client.setAccountId(id)` sets it later. |
| `consentMode` | `'api'`, `'cookie:'`, `'cookie:='`, `'gcm'`, `'not_required'` | Same as `data-consent-mode`. |
| `extensions` | `'auto'` | Same as `data-extensions="auto"`. |
| `logLevel` | `'silent'`, `'error'`, `'warn'`, `'info'`, `'debug'` | Same as `data-log-level`, one precedence step lower. |
| `debug` | boolean | Legacy form of log level `debug`. |
| `debugUploads` | boolean | Same as `data-debug-upload`. |
| `onChallenge` | function | Called with `{ status, method }` while the server asks for a step-up challenge. Advisory. |
| `onBlock` | function | Called with `{ status, mode }` when the page enforces a server block. Advisory. |
| `release`, `buildId`, `subjectHandle` | strings | Labels for browser error detail. They take effect when the extensions are loaded. See [Browser errors, console logs and source maps](https://noxtica.com/docs/observability/errors-and-source-maps/). |
The wrapper's `init(config)` accepts `siteKey`, `apiUrl`, `ingestUrl`, `mode`, `checkIntervalDays`, `signatureMode`, `accountId`, `debug`, `logLevel`, `onChallenge`, `onBlock`, `release`, `buildId`, `subjectHandle` and `observability`, plus options that are specific to the wrapper:
| Wrapper option | Default | Effect |
| --- | --- | --- |
| `script` | `'core'` | `'core'` injects the core script. `'combined'` injects the legacy combined script. |
| `extensions` | `'manual'` | `'manual'` waits for `loadExtensions()`. `'auto'` lets the core load them. `'never'` makes `loadExtensions()` reject, and cannot be combined with `script: 'combined'`. |
| `scriptUrl`, `pinnedLoader` | none | Inject a pinned core: set `scriptUrl` to the hashed file name from the collector manifest and `pinnedLoader.integrity` to its hash. The URL must be `https` on the default collector origin or your own `apiUrl` origin. |
`init()` does not pass `consentMode` to the loader. To declare a mode, put `data-consent-mode` on the tag or call `createClient` directly.
### 5. Set the log level
The loader writes nothing to the console by default. Four sources can change that. The highest one that holds a valid value wins:
1. The `data-log-level` attribute on the script tag.
2. The `logLevel` option of `createClient()` or `init()`, or `NoxticaCollector.setLogLevel(level)`.
3. The domain setting. In Backoffice open Domains, open the domain, then Configuration → **Client log level** → **Console log level**. The choices are SDK default, Silent, Error, Warn, Info and Debug. The value arrives with each session token, so a change applies from the next token.
4. The SDK default: silent, unless `data-debug`, the `debug` option or `window.NOXTICA_DEBUG = true` turns on `debug`.
`silent` means no console output from any Noxtica code path. Read the effective level with `window.NoxticaCollector.getLogLevel()`.
A `data-log-level` attribute applies before the loader reads the other attributes, so it also reveals the warnings from step 2, such as a rejected `data-api-url`. The domain setting arrives later, with the token.
## Verify it works
Run these in the browser console on a page that carries the tag:
```javascript
typeof window.noxticaClient; // 'object' when data-auto-init bound the tag
window.noxticaClient.siteKey; // your Site Key
window.noxticaClient.apiUrl; // the collector origin in use
window.noxticaClient.ingestUrl; // the telemetry origin in use
window.NoxticaCollector.VERSION; // the loader version, for example '3.8.1'
window.noxtica.v; // the same version, published for the duplicate-tag guard
window.NoxticaCollector.getLogLevel(); // the effective log level
```
In DevTools → Network you see `POST /client/token` on the collector host with status `200`. After consent, when the extensions run, and with `data-ingest-url` left at `auto` on the default collector, telemetry requests go to `ingest.noxtica.com`.
## Troubleshooting
| Symptom | Cause | Fix |
| --- | --- | --- |
| `window.noxticaClient` is undefined and no `noxtica:*` event fires | The tag lacks `data-auto-init` or `data-site-key`, or the `src` file name contains neither `noxtica-collector` nor `/noxtica.js` | Add the attributes, or keep the original file name when you copy or proxy the script. |
| `data-api-url` has no effect | The value is not `https` and not on `localhost` or `127.0.0.1`, or it is not a valid URL | Use an `https` URL. The warning appears at log level `warn` or higher. |
| Telemetry still goes to the collector host | `data-ingest-url` equals the collector origin, or `data-api-url` points at a host other than the default collector | Set `data-ingest-url` to the telemetry origin you want. |
| Changing an attribute in the console changes nothing | The loader read the attributes when the tag initialised | Reload the page, or create a client from code. |
| `getConsent().mode` differs from `data-consent-mode` | The mode saved for the domain wins once the token arrives | See [Consent modes](https://noxtica.com/docs/sdk/consent/). |
| `NX001: already loaded` in the console | A second core or combined tag is on the page, for example one pasted by hand and one from a tag manager | Remove the extra tag. The initial one keeps running. |
| `NoxticaCollector: siteKey is required` | `createClient` found no Site Key | Pass `siteKey`, or keep `data-site-key` on a collector tag. |
| `403` with `Origin mismatch` on `/client/token` | The page origin is not the origin registered for the Site Key | Use the key of the exact origin the page runs on. |
## Related
- [Install and Browser Runtime](https://noxtica.com/docs/browser-runtime/): install, pinned tags, CSP and the check list.
- [Client API, events and the command queue](https://noxtica.com/docs/sdk/client-api/): the methods and events these attributes feed.
- [Consent modes, GPC and Google Consent Mode](https://noxtica.com/docs/sdk/consent/): what `data-consent-mode` and `data-extensions` do at run time.
- [Browser SDK troubleshooting](https://noxtica.com/docs/sdk/troubleshooting/): a symptom table across the whole SDK.
- [SDK Changelog](https://noxtica.com/docs/changelog/): which release added or changed each setting.
---
Source: https://noxtica.com/docs/sdk/client-api/
Markdown: https://noxtica.com/docs/sdk/client-api/index.md
Last updated: 2026-10-27
# Client API, events and the command queue
This page is the reference for what the core script puts on your page: the globals, the client methods, the events on `document`, and the `window.noxtica(...)` command queue. Use it when you wire a consent banner, react to a step-up challenge, or queue calls before the script has loaded.
## What it is
Availability: Evaluation access. Availability depends on your plan, role and the modules enabled for your organisation.
A core tag with `data-auto-init` builds one client for the page. The client, the events and the command queue exist on tags that carry `data-auto-init`. A client you create with `NoxticaCollector.createClient()` returns its results through promises and does not fire `noxtica:ready`. See [Script attributes and client options](https://noxtica.com/docs/sdk/script-attributes/).
Until the extensions script attaches, the core runs a reduced lane. When the extensions attach, every public method of the client delegates to the extensions runtime; the core keeps `loadExtensions`, `getExtensionsState` and `destroy`. Loading the extensions never grants consent; see [Consent modes](https://noxtica.com/docs/sdk/consent/).
## Prerequisites
- The core tag with `data-site-key` and `data-auto-init`, as generated by Backoffice → Integrations & API → Script & Consent → Snippets.
- Your listeners registered before the core tag runs. Put them in an inline script in `` above the tag. An event that already fired is not replayed.
- Your own consent flow, if the domain uses the `api` mode: your page calls `setConsent`. See [Consent modes](https://noxtica.com/docs/sdk/consent/).
## Steps
### 1. Read the page globals
| Global | What it holds |
| --- | --- |
| `window.NoxticaCollector` | The loader object: `VERSION`, `SCHEMA_VERSION`, `SDK_VERSIONS`, `createClient(options)`, `autoDiscoverSiteKey()`, `setApiUrl(url)`, `setIngestUrl(url)`, `setLogLevel(level)`, `getLogLevel()`, and on the core script `BUNDLE` (`'core'`), `registerExtensions(ext)` and a static `loadExtensions()`. `setApiUrl` and `setIngestUrl` take effect for clients created afterwards and reject a URL that is not `https` (localhost excepted). Other members of the object are diagnostics, not part of the supported surface. |
| `window.noxticaClient` | The client of the `data-auto-init` tag. Properties `siteKey`, `apiUrl` and `ingestUrl`. |
| `window.noxtica` | The command function (step 4). `window.noxtica.v` holds the loader version once a core or combined script has claimed the page. |
| `window.noxticaResult` | The last result announced with `noxtica:collected`. |
| `window.noxticaLastError` | The last error the loader reported: `{ source, message, time }`. The message is cut to 200 characters. |
### 2. Call the client methods
**Page check and state**
| Method | Returns | Notes |
| --- | --- | --- |
| `checkOnce(options)` | Promise of a result (step 5) | Cache-aware page check. Options are in [Script attributes and client options](https://noxtica.com/docs/sdk/script-attributes/). In a gated consent mode without a `deviceId` grant it resolves a `skipped` result and runs again when the grant arrives. |
| `collectAndSubmit()` | Promise of a result | Collects and submits on every call, without the cache. |
| `collect()`, `submit(payload)`, `visit(deviceId, meta)` | Promises | Building blocks of the two methods above. Prefer `checkOnce`. |
| `getToken()` | Promise of the session token string, or `null` | Fetches or refreshes the token without submitting. |
| `getPolicy()` | Object or `null` | The policy delivered with the session token. |
| `getStoredState()`, `clearStoredState()` | State object or `null`; nothing | Read or delete the cached device state that `checkOnce` uses. |
| `getEffectiveTtlSeconds(options)` | Number | The cache window in seconds that a call with these options would use. |
**Lifecycle**
| Method | Effect |
| --- | --- |
| `pause()`, `resume()` | `pause` holds replay flushing, mutation processing and tracker and RUM uploads without ending anything; `resume` drains what was held. |
| `stop()`, `start()` | `stop` tears the lanes down but keeps consent state and device storage; `start` re-arms them. |
| `destroy()` | Stops timers and lanes and makes this client inert. Create a new client to continue. |
**Consent and extensions**
| Method | Effect |
| --- | --- |
| `setConsent(update)` | `update` is `{ analytics, replay, deviceId, behavioral }` with values `'granted'` or `'denied'`, or the legacy string `'granted'` / `'denied'`, which sets the `analytics` category. Any other shape throws a `TypeError`. |
| `getConsent()` | `{ mode, modeResolved, analytics, replay, deviceId, behavioral, privacySignal }`. |
| `enableGoogleConsentMode()` | Turns on the Google Consent Mode v2 bridge. |
| `setReplayConsent(boolean)` | Legacy switch for the `replay` category. |
| `getReplayConsentState()` | `UNINITIALIZED`, `DISABLED`, `AWAITING_CONSENT`, `DENIED` or `POLICY_READY`. |
| `getReplayRecorderState()` | `idle`, `loading`, `active`, `stopped` or `error`. |
| `loadExtensions(options)` | Promise of `{ ok: true, loaded }` or `{ ok: false, reason, code, … }`. Never rejects. See [Loading extensions and its result](https://noxtica.com/docs/browser-runtime/#loading-extensions-and-its-result). |
| `getExtensionsState()` | `'not-loaded'`, `'attached'`, or `'built-in'` on the legacy combined script. |
**Protected actions, identity and events**
| Method | Effect |
| --- | --- |
| `protect(name, { timeoutMs })` | Runs the protected-action check and resolves the result with a `requestId`. See [Protected actions](https://noxtica.com/docs/sdk/protected-actions/). |
| `setAccountId(id)` | Links the device to your own account id on the next submit. Non-string, empty and values over 256 characters are ignored. Use an opaque id. |
| `identify(id, { hint })` | Session identity: Noxtica receives a hash of the id and a two-character hint. Not the same as `setAccountId`. The typed wrapper calls this `identifySession()` and uses `identify()` for the account id. |
| `setTag(key, value)`, `event(name, value)`, `getMetadata(callback, options)`, `upgrade(reason)` | Session tags, timeline markers, the ids that join Noxtica data to yours, and starting replay with a reason. Limits and consent rules are on [Custom events, session tags and request tracing](https://noxtica.com/docs/observability/events-and-tracing/). `upgrade` returns `started`, `already_recording`, `pending_consent` or `refused`. |
| `track(name, properties)` | Custom application event. Names and properties that the domain allow-list does not list are dropped. |
| `withRequestSpan(url, callback)`, `spanFetch(url, init)` | W3C trace context for one request, for origins on the domain's trace allow-list. |
| `loadReplayPlugins()`, `loadReplayAssist()`, `debug({ uploads })` | Replay add-ons and the upload debug switch. See [Session replay](https://noxtica.com/docs/observability/session-replay/). |
The client object has more members, such as tracker and token-refresh controls. They are internal and not supported.
### 3. Listen to events
All events are dispatched on `document` with a `CustomEvent`. Register the listeners in `` before the core tag:
```html
```
| Event | `event.detail` | When |
| --- | --- | --- |
| `noxtica:ready` | `{ client }` | The `data-auto-init` tag created the client and ran the command queue. The automatic check has not started. Fires once per tag. |
| `noxtica:collected` | The check result, or `{ success: false, skipped: 'consent_required', fromCache: false, consentMode }` | After the automatic check, a check that waited for consent, and a queued `checkOnce`. Also sets `window.noxticaResult`. |
| `noxtica:cache-hit` | The same result with `fromCache: true` | Right after `noxtica:collected` when the cache answered. |
| `noxtica:consent-changed` | The `getConsent()` snapshot | A consent category really changed, or the signed mode differs from the page's declaration once the token arrives. |
| `noxtica:extensions-loaded` | `{ message: 'attached', ok: true, loaded }` | The extensions took over the client. |
| `noxtica:extensions-failed` | `{ message: 'not-loaded', ok: false, reason, code, … }` | A load attempt failed, or a queued `loadExtensions` was dropped because every category is denied. |
| `noxtica:error` | `{ source, message, time }` | The loader reported a failure. Known sources include `Auto-init failed`, `Auto-check-once failed`, `Auto-collect failed`, `Deferred page check failed` and `noxtica("") failed`. Also stored in `window.noxticaLastError`. |
| `noxtica:challenge` | `{ status, method }` | The server asked the browser for a step-up challenge. `status` is `started`, `solved`, `failed` or `unsupported`; `method` is `gpu-pow` or `turnstile`. Advisory: the server decides. |
| `noxtica:block` | `{ status, mode }` | The page enforced a server block. `status` is `blocked`, `redirected` or `failed`; `mode` is `overlay` or `redirect`. Advisory. |
| `noxtica:protected` | `{ action, requestId, success, source, reason, timedOut? }` | A protected-action check for a form or control settled. Dispatched on that element; it bubbles. `source` is `warm`, `click` or `submit`. |
| `noxtica:debug-upload` | The captured upload | Fires with `data-debug-upload` or `debug({ uploads })` and in no other case. |
`noxtica:challenge` and `noxtica:block` fire when the server issues a challenge or a block for the visit, and not otherwise. Whether your domain can issue them depends on your configuration. The page acts on a block directive when the signed result verifies and carries the same block id, so a forged directive does nothing.
With `createClient` options `onChallenge` and `onBlock` you get the same details through callbacks. A callback that throws never breaks collection.
`noxtica:extensions-*` details were strings before SDK 3.8.0. Read `detail.message` for the old value.
### 4. Queue calls before the script loads
The command queue follows the gtag pattern. Define the stub above the core tag, then call it:
```html
```
An array assigned to `window.noxtica` also works as a stub. The core replays the queued calls in order against the initial client it creates, then replaces the stub with a live function. Later calls, and a stub reference you kept, run at once and return the method's result.
| Command | Arguments | Runs |
| --- | --- | --- |
| `setConsent` | update object, or `'granted'` / `'denied'` | `client.setConsent` |
| `consent` | `'gcm'`, or an update object | `enableGoogleConsentMode()` or `setConsent` |
| `loadExtensions` | options | `client.loadExtensions` |
| `protect` | name, options | `client.protect` |
| `checkOnce` | options | `client.checkOnce`; the result is announced with `noxtica:collected` |
| `set` | key, value or list of values | `client.setTag` |
| `identify` | id, `{ hint }` | `client.identify` (session identity) |
| `event` | name, value | `client.event` |
| `metadata` | callback, `{ wait, recall }` | `client.getMetadata` |
| `upgrade` | reason | `client.upgrade` |
| `pause`, `resume`, `stop`, `start` | none | the lifecycle methods |
These are the 14 commands. Behaviour to rely on:
- An unknown command logs a warning and does nothing. A command that fails reports `noxtica:error` and never throws.
- Queued `setConsent` and `consent` updates are folded into one update, applied where the earliest of them stood (a later key wins), so you get one `noxtica:consent-changed`. A queued `loadExtensions` is dropped when the folded state denies all four categories. This applies to loader 3.8.1 and later; earlier loaders replayed every call in order.
- If `window.noxtica` is a plain object without a `q` array, the loader leaves it untouched and the commands are unavailable.
- Deciding consent in a `noxtica:ready` handler is more robust than queuing it. See [Events and timing](https://noxtica.com/docs/browser-runtime/#events-and-timing).
### 5. Read the `checkOnce` result
| Field | Present when | Meaning |
| --- | --- | --- |
| `success` | always | `true` when the check or the cache hit succeeded. |
| `fingerprintId` | success | Device id as the browser sees it. A hint: the core and the extensions runtimes can mint different ids for one browser. The authoritative id is the one from [the server-side verify call](https://noxtica.com/docs/sdk/protected-actions/). |
| `fromCache` | always | `true` when the cache answered. |
| `cachedResult` | cache hit | `{ score, risk_level, confidence, flags }` from the last check, or `null` when the cookie is the sole storage that survived. |
| `daysSinceSubmit`, `nextSubmitIn` | cache hit | Days since the last submit and days left in the window. |
| `visitRecorded` | `recordVisit: false` | `false`. |
| `acquiredFromAnotherTab` | another tab ran the check | `true`. A cross-tab lock keeps tabs from submitting twice; it times out after 30 seconds. |
| `forceRefreshed` | `forceRefresh: true` | `true`. |
| `skipped`, `consentMode` | gated mode without a `deviceId` grant | `skipped: 'consent_required'`; no `fingerprintId`. |
A numeric `score`, `risk_level` and `confidence` may be absent when the server withholds them. Treat a missing score as unknown, never as zero.
## Verify it works
Open the console on a page that has the tag and consent decided:
```javascript
window.noxticaClient.getConsent(); // { mode, modeResolved, analytics, replay, deviceId, behavioral, privacySignal }
window.noxticaClient.getExtensionsState(); // 'not-loaded' before the extensions attach, 'attached' after
window.noxticaResult; // the last result announced with noxtica:collected
window.noxtica.v; // the loader version
await window.noxticaClient.getToken(); // a token string once /client/token succeeded
```
Add a temporary listener for each event in step 3 and reload. A healthy consented page logs `noxtica:ready`, then `noxtica:consent-changed` and `noxtica:extensions-loaded` after your consent call, then `noxtica:collected`.
## Troubleshooting
| Symptom | Cause | Fix |
| --- | --- | --- |
| A listener never fires | It was registered after the event, or the tag lacks `data-auto-init` | Move the listener into `` above the tag. For a late page, read `window.noxticaClient` and `window.noxticaResult` directly. |
| `window.noxtica(...)` does nothing | `window.noxtica` is a plain object, or the tag lacks `data-auto-init` | Define the stub as a function or an array, and keep `data-auto-init`. |
| `setConsent` throws `NoxticaCollector.setConsent requires granted, denied, or { analytics, replay, deviceId, behavioral }` | The argument is `true`, `false` or another shape | Pass the strings `'granted'` or `'denied'`. |
| `setConsent` throws `unknown consent category` | A key other than `analytics`, `replay`, `deviceId`, `behavioral` | Remove the key. |
| `noxtica:collected` carries `skipped: 'consent_required'` | The domain is in a gated mode and `deviceId` is not granted | Call `setConsent({ deviceId: 'granted' })` after the visitor agrees. The check then runs again on the same page. |
| `protect()` resolves `error: 'undeclared_protected_action'` | The action name is not declared for the domain | Declare it in Script & Consent → Protected actions. |
| `identify()` did not link my account | `identify` is the hashed session identity | Use `setAccountId(id)`. |
| Two `noxtica:collected` events with different ids | A loader older than 3.8.1 | See [SDK Changelog](https://noxtica.com/docs/changelog/). Take the id from the server-side verify call. |
## Related
- [Script attributes and client options](https://noxtica.com/docs/sdk/script-attributes/): the options that configure the client.
- [Consent modes, GPC and Google Consent Mode](https://noxtica.com/docs/sdk/consent/): categories, precedence and the Google bridge.
- [Protected actions](https://noxtica.com/docs/sdk/protected-actions/): `protect()`, `noxtica:protected` and the server check.
- [Install and Browser Runtime](https://noxtica.com/docs/browser-runtime/): events and timing, extension load reasons.
- [Custom events, session tags and request tracing](https://noxtica.com/docs/observability/events-and-tracing/): the session API in depth.
- [Browser SDK troubleshooting](https://noxtica.com/docs/sdk/troubleshooting/): symptoms across the SDK.
---
Source: https://noxtica.com/docs/sdk/single-page-apps/
Markdown: https://noxtica.com/docs/sdk/single-page-apps/index.md
Last updated: 2026-10-27
# Single-page apps, frameworks and tag managers
A single-page app changes the URL without loading a new document, a framework re-renders its own markup, and a tag manager injects scripts on its own schedule. This page shows what the collector does in those setups and what you do to keep one clean install.
## What it is
Availability: Evaluation access. Availability depends on your plan, role and the modules enabled for your organisation.
The collector is a plain script. It needs one core tag per document, a Site Key that matches the page origin, and a `window` and `document` to run in. It does not depend on your framework. The core script watches client-side navigation through the History API when a protected action matches a page path, and it does nothing else on a route change. The page check belongs to the document, not to the route.
The typed `@noxtica/sdk` wrapper has React, Next.js and Vue helpers in its source. That package is not installable from the public registry today (the registry answered `E404` on 2026-10-27), so this page gives no install command for it. Ask your account team for access; see [SDK family and availability](https://noxtica.com/docs/sdk/family/). Every recipe below works with the script tag alone.
## Prerequisites
- A Site Key for the origin your app is served from. Staging and production origins have separate keys. A key used on another origin gets `403` with `Origin mismatch`.
- The core tag from Backoffice → Integrations & API → Script & Consent → Snippets. See [Install and Browser Runtime](https://noxtica.com/docs/browser-runtime/).
- Your consent mode decided. See [Consent modes](https://noxtica.com/docs/sdk/consent/).
- For tag managers: the right to publish tags that run on every page of the site.
## Steps
### 1. Load the core once, in the app shell
Put the tag in the document that the app mounts into: `index.html`, the root layout, or the theme's ``. Do not add it per route or per component.
```html
```
Register your `noxtica:*` listeners in a script that runs before the tag. An event that already fired is not replayed. If your framework cannot run code before the tag, queue calls with the `window.noxtica` stub instead, and read `window.noxticaClient` and `window.noxticaResult` after load. See [Client API, events and the command queue](https://noxtica.com/docs/sdk/client-api/).
If the core competes with the initial render or hydration, inject it after the `load` event and the next idle period. A ready-made snippet is in [Load timing and weight](https://noxtica.com/docs/browser-runtime/#load-timing-and-weight).
### 2. Pick a framework recipe
| Setup | What you do |
| --- | --- |
| Vite, Create React App or any bundler with an `index.html` | Add the tag from step 1 to `index.html`. |
| Vue | Add the tag to `index.html`. |
| Next.js, App Router | Render the tag with `next/script` in the root layout. |
| Angular | Add the tag to `index.html`. To keep the collector's timers out of change detection, load it outside the Angular zone; see [Single-page apps and frameworks](https://noxtica.com/docs/browser-runtime/#single-page-apps-and-frameworks). |
| Server-side rendering | Emit the tag in the HTML. The loader does nothing without a `document`, so a server render is not affected. Do not import or call the collector in server code. |
For Next.js, the markup below is what the wrapper's `NoxticaScript` component renders, taken from the wrapper source. `afterInteractive` is its default strategy. Test it in your own app:
```tsx
// app/layout.tsx
import Script from 'next/script';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
{children}
);
}
```
The wrapper's helpers, for accounts that have the package:
| Helper | What it does, from the 0.3.0 source |
| --- | --- |
| `NoxticaProvider`, `useNoxtica` (React) | The provider creates one client in an effect, so it runs in the browser and not on the server. `useNoxtica()` returns `{ client, loading, error }`. The provider destroys its client when it unmounts. |
| `useVerdict` (React) | Requests a verdict when the client is ready, unless you pass `auto: false`. Returns `{ verdict, loading, error, refresh }`. |
| `NoxticaScript` (Next.js) | Renders the tag through `next/script` with `data-site-key`, `data-auto-init` and `data-auto-check-once`. Options: `apiUrl`, `ingestUrl`, `scriptUrl`, `script`, `extensions`, `auto`, `checkIntervalDays`, `debug`, `logLevel`, `strategy`. It has no consent-mode option. |
| `createNoxtica`, `useNoxtica` (Vue 3) | A plugin and a composable. They return `client`, `loading`, `error`, `verdict`, `getVerdict` and `identify`. The plugin stays inert during server rendering. |
The wrapper's `init()` rejects outside a browser. Guard shared code with `isBrowser()`.
### 3. Handle route changes
A route change does not run a new page check. `data-auto-check-once` runs `checkOnce()` once for the document, and the cache answers later calls. What you can rely on:
- Protected actions that match a **Page path** run on the initial load and again when the History API changes the URL (`pushState`, `replaceState`, `popstate`). The core shares one wrapper per page and restores the original methods when no subscriber is left. It leaves your own wrappers in place.
- Calling `checkOnce()` on every route is allowed. With the default `recordVisit: true`, a cache hit records a visit with the collector, so each call sends a request. Pass `{ recordVisit: false }` when you do not want that.
- Call `checkOnce({ forceRefresh: true })` or `collectAndSubmit()` when a flow needs a fresh check, and not otherwise. Both collect again and submit.
- For application events and session tags, use `track`, `event` and `setTag` from [Custom events, session tags and request tracing](https://noxtica.com/docs/observability/events-and-tracing/).
Do not decide whether Noxtica is on a page from an attribute that your framework renders. A locale switch or a remount can clear attributes on ``. Decide from the host name or your build configuration.
### 4. Protect forms that your script submits
A script-submitted form (React, Vue, any `fetch` flow) cannot receive the hidden `nox_request_id` field. Read `form.dataset.noxRequestId` at the top of your submit handler, and call `protect` synchronously when the id is not there yet. The full handler is in [Protected actions](https://noxtica.com/docs/sdk/protected-actions/). The id is withdrawn when your handler returns, so a retry runs a fresh check.
### 5. Install through a tag manager or a CMS theme
A tag manager or a theme has to put the same script element on the page, and nothing more. The collector sees the element, not the tool. Check these points in your tool:
1. **Raw HTML.** Use the tag type that accepts a `
```
- Keep the file name `noxtica-collector-core.js`. The loader binds a tag by that name.
- `data-api-url` makes the token, submit and visit calls go to your hostname. With `data-ingest-url` left at `auto`, a host other than the default collector keeps its telemetry on itself, so one host serves everything.
- The extensions script is loaded from the folder of the core script, so it comes from your hostname too. The engine files named in the session token follow the host that issued the token.
- Update `script-src` and `connect-src` to your hostname. The Noxtica hosts are no longer needed for this domain unless you set `data-ingest-url` to one of them.
- The Backoffice snippets are generated for the default hosts. Replace the host in the generated tag yourself.
- Keep the Site Key of the domain that the hostname belongs to. The page origin must still match the domain; the relay hostname is the collector host, not your page origin.
- Switch a staging page before production, and run the checks in the next section.
### 7. Revoke a relay hostname
Select **Revoke** on the hostname row and confirm: "Revoke this relay hostname? Telemetry served on it will stop and the certificate will be removed." Switch your tags back to `collect.noxtica.com` before you revoke. Revoke the hostname in the Backoffice, then remove the DNS records.
## Verify it works
1. In DevTools → Network, filter by the collector host. The core script, `POST /client/token`, and after consent the extensions script and `POST /client/submit` come from that host. Telemetry calls go to the ingest host, or to your relay hostname.
2. The console shows no CSP violation that names a Noxtica host.
3. After consent, `window.noxticaClient.getExtensionsState()` is `'attached'`, and `window.NoxticaCollector.getKhanVmStatus()` reports no CSP error.
4. For a relay hostname, `window.noxticaClient.apiUrl` and `window.noxticaClient.ingestUrl` are your hostname.
5. In Backoffice → Domains → the domain → **Relay**, the hostname shows **Active**.
## Troubleshooting
| Symptom | Cause | Fix |
| --- | --- | --- |
| Console violation for the core or extensions script | `script-src` lacks the collector host or your relay hostname | Add the host. `loadExtensions()` answers `csp_blocked` with `script-src-elem` or `script-src`. |
| `WebAssembly blocked by Content Security Policy` | `script-src` lacks `'wasm-unsafe-eval'` | Add it. Collection continues with reduced evidence until you do. |
| Engine workers fail to start | `worker-src` lacks `blob:`, or it replaced your own entries | Add `blob:` next to `'self'`. |
| Telemetry calls are blocked, token and submit work | `connect-src` lists the collector host but not the ingest host | Allow both hosts, or set `data-ingest-url` to the collector origin. |
| `loadExtensions()` answers `network` while a CSP is in force | `connect-src` blocks the diagnostic request that classifies the failure | Allow the collector host in `connect-src`. |
| A Turnstile widget never appears | `challenges.cloudflare.com` is not allowed | Allow it as Cloudflare documents. |
| Relay: creating the hostname fails with `plan_feature_required` | Your plan has no relay hostnames | Change the plan or contact your account team. |
| Relay: "Relay provisioning is not yet enabled for this deployment" | Provisioning is not set up for your deployment | Contact your account team. |
| Relay: **Add hostname** is disabled | The hostname or domain is empty, the acknowledgement is not ticked, provisioning is unavailable, or the limit is reached | Complete the fields and the acknowledgement, or revoke an unused hostname. |
| Relay: stays on **Pending DNS** | The CNAME or TXT record is missing or wrong | Compare the records with the Backoffice values and select **Verify**. |
| Relay: **Verification failed** | The records did not verify | Correct the records and select **Verify** again. |
| Token call answers `403` with `Origin mismatch` | The page origin is not the one registered for the Site Key. A relay hostname does not change this. | Use the Site Key of the page origin. |
## Related
- [Install and Browser Runtime](https://noxtica.com/docs/browser-runtime/): the CSP section, stable and pinned tags, and the recorder head.
- [Script attributes and client options](https://noxtica.com/docs/sdk/script-attributes/): `data-api-url` and `data-ingest-url`.
- [Cookies, storage and consent categories for your site](https://noxtica.com/docs/compliance/cookies-and-storage/): update your notices before you enable a relay.
- [Domains, site keys and the install card](https://noxtica.com/docs/backoffice/domains/): domain ids and the Relay tab.
- [Browser SDK troubleshooting](https://noxtica.com/docs/sdk/troubleshooting/): symptoms across the SDK.
- [Subprocessors](https://noxtica.com/subprocessors/): who Noxtica uses to deliver the service.
---
Source: https://noxtica.com/docs/sdk/troubleshooting/
Markdown: https://noxtica.com/docs/sdk/troubleshooting/index.md
Last updated: 2026-10-27
# Browser SDK troubleshooting
Use this page when the collector does not start, does not collect, or collects less than you expect. Every symptom below comes from an error body, a result code, an event or a console message that the collector produces. Start with the console checks, then find your symptom in the tables.
## What it is
Availability: Evaluation access. Availability depends on your plan, role and the modules enabled for your organisation.
The core script fails open. A problem in the collector does not block your page, and most failures show up as a missing event, a `reason` and `code` in a result, a `noxtica:error` event, or an HTTP error on a `/client/*` call. This page maps those signals to causes. Concepts are on [Install and Browser Runtime](https://noxtica.com/docs/browser-runtime/); the full reference is on the other pages of this section.
## Prerequisites
- A browser with DevTools (Console and Network).
- The page that shows the problem, served from the origin registered for the Site Key.
- Your Site Key. It is public. Never post a Server API key (`sk_…`), a session token or a cookie value in a ticket.
- For consent questions, the consent mode of the domain: Backoffice → Integrations & API → Script & Consent → **Consent & extensions**.
## Steps
### 1. Read the loader state
Run this in the console of the affected page:
```javascript
({
version: window.noxtica && window.noxtica.v, // loader version, set by the initial core script
loader: typeof window.NoxticaCollector, // 'object' when a core script ran
client: typeof window.noxticaClient, // 'object' when a data-auto-init tag bound
consent: window.noxticaClient && window.noxticaClient.getConsent(),
extensions: window.noxticaClient && window.noxticaClient.getExtensionsState(), // 'not-loaded' | 'attached' | 'built-in'
lastResult: window.noxticaResult,
lastError: window.noxticaLastError, // { source, message, time }
logLevel: window.NoxticaCollector && window.NoxticaCollector.getLogLevel(),
});
```
To see more, set the log level to `debug` with `data-log-level="debug"` on the tag and reload. The loader is silent by default. See [Script attributes and client options](https://noxtica.com/docs/sdk/script-attributes/).
### 2. Check the Network tab
Filter by your collector host. A working page shows the core script and `POST /client/token` with status `200`. After consent in a gated mode it also shows the extensions script, engine files and `POST /client/submit`. An error body from the collector carries a `requestId`; keep it for support.
### 3. Check consent and the extensions
Read `getConsent()`: `mode`, `modeResolved` and the four categories. Then call `await window.noxticaClient.loadExtensions()` and read `ok`, `reason` and `code`. The tables below explain each value.
### 4. Check the policy
Open the console on a page with the policy in force and look for violations that name a Noxtica host. See [Content Security Policy, hosts and first-party relay](https://noxtica.com/docs/sdk/csp-and-relay/).
### 5. Collect what support needs
Send: your Site Key, the page URL without query strings, the loader version (`window.noxtica.v`), the output of step 1, the failing request with its status and `requestId`, and the time. Contact your account team or use [Contact](https://noxtica.com/contact/). Platform incidents are listed on `status.noxtica.com`.
### 6. Check the browser
The collector needs WebAssembly and `blob:` workers for its engines. GPU attestation also needs WebGPU: without it the loader logs `WebGPU not available` and skips that step. The Web Locks API is optional; a browser without it falls back to a `localStorage` lock for the cross-tab check. A privacy mode, an extension or a network rule that blocks cross-origin requests, storage, workers or WebAssembly reduces the evidence or stops collection, and the page keeps working.
Headless and automated browsers are scored as bots, and your CDN may challenge them. Do not compare risk scores from headless runs. Test on a lab page, as described in [Release checks, testing and versions](https://noxtica.com/docs/browser-runtime/#release-checks-testing-and-versions).
Noxtica does not publish a verified minimum browser version list in this documentation. Test the browsers and privacy modes your own application supports.
## Verify it works
After a fix, reload the page with a clean profile and check:
- `typeof window.noxticaClient` is `'object'` and `window.noxtica.v` holds a version.
- `POST /client/token` answers `200`.
- `window.noxticaLastError` is `undefined`.
- In a gated mode, `getConsent().modeResolved` is `true`; after consent `getExtensionsState()` is `'attached'`.
- Exactly one `noxtica:collected` event fires for the page.
## Troubleshooting
### The script does not start
| Symptom | Cause | Fix |
| --- | --- | --- |
| `window.noxticaClient` undefined and no `noxtica:*` events | The tag lacks `data-auto-init` or `data-site-key`, or the `src` file name has neither `noxtica-collector` nor `/noxtica.js` | Add the attributes and keep the file name. A tag without a Site Key is skipped silently. |
| `window.NoxticaCollector` undefined | The core script did not load: blocked by CSP or a network rule, a `404`, or an integrity failure | Read the failed request in Network and the console. See the CSP page. |
| Pinned tag blocked with an integrity error | The pin is more than three releases old, or the hash was copied from a document | Copy the tag again from Script & Consent → Snippets, or use the stable tag. |
| `NX001: already loaded (v…), duplicate tag v… ignored.` | A second core or combined tag on the page | Remove it. The initial tag keeps running and its version is `window.noxtica.v`. |
| `window.noxtica(...)` does nothing | `window.noxtica` is a plain object without `q`, or the tag lacks `data-auto-init` | Define the stub as a function or array. |
| `NoxticaCollector: siteKey is required` | `createClient` found no Site Key | Pass `siteKey` or keep `data-site-key` on a collector tag. |
| A relay or proxy path loads the script but nothing binds | The proxied file name lost `noxtica-collector` | Keep the file name when you proxy the script. |
### `POST /client/token` fails
| Status and body | Cause | Fix |
| --- | --- | --- |
| `403` `Origin not allowed` | The request had no `Origin` header, so it did not come from a normal browser page | Test from a real page on the registered origin. |
| `403` `Origin mismatch` | The page origin differs from the origin registered for the Site Key | Use the key of the exact origin. Staging needs its own domain and key. |
| `400` `Missing siteKey` | The request body had no Site Key | Check the tag's `data-site-key` or the `siteKey` option. |
| `401` `Invalid siteKey` | The Site Key is unknown or inactive | Copy the key again from Backoffice → Domains. |
| `403` `Tenant suspended` or `Domain disabled` | The account or the domain is not active | Contact your account team. |
| `429` `Rate limit exceeded`, with `Retry-After` | The tenant and client address hit the token rate limit | Wait for `Retry-After`. |
| `429` `quota_exceeded` with code `COLLECTOR_REQUESTS_QUOTA_EXCEEDED` | The monthly collector request quota is used up, when quota enforcement is enabled | Check usage in Backoffice and see [Usage, quotas and metering](https://noxtica.com/docs/billing/usage-and-quotas/). |
| `413` `Payload too large` or `415` `Content-Type must be application/json` | A custom client or proxy changed the request | Do not rewrite collector requests. |
### Consent and gated modes
| Symptom | Cause | Fix |
| --- | --- | --- |
| `noxtica:collected` has `skipped: 'consent_required'` | A gated mode and `deviceId` not granted | Call `setConsent({ deviceId: 'granted' })` after the visitor agrees. Not an error. |
| `getConsent().mode` is `not_required` on an `api` domain | `modeResolved` is `false`: the saved mode has not arrived | Wait for `noxtica:consent-changed`, or declare `data-consent-mode`. |
| `setConsent` throws `NoxticaCollector.setConsent requires granted, denied, or { analytics, replay, deviceId, behavioral }` | A boolean or another shape | Pass `'granted'` or `'denied'`. |
| `setConsent` throws `unknown consent category` or `… must be granted or denied` | A wrong key or value | Use the four category names with the two strings. |
| Extensions load for visitors who declined | Not required mode with automatic loading, or a legacy script URL | See [Consent modes](https://noxtica.com/docs/sdk/consent/). |
| Two `noxtica:collected` events with different ids | Loader older than 3.8.1 | Update to the current loader; take the id from the server verify call. |
| `fingerprintId` in the browser differs from the server | The core and the extensions mint different ids | Use the id from `POST /v1/protected-actions/verify`. |
### Extensions: `loadExtensions()` results
`loadExtensions()` never rejects. It resolves `{ ok: true, loaded }` or `{ ok: false, reason, code, … }`. A later call retries after a failure.
| `reason` | `code` | Cause | Fix |
| --- | --- | --- | --- |
| `consent_missing` | `consent_required` | You passed `{ requireConsent: true }` in a gated mode and no category is granted | Grant a category before you call it, or drop the option. |
| `consent_missing` | `consent_withdrawn` | A queued `loadExtensions` was dropped because the queued consent denies all four categories (loader 3.8.1 and later) | Call `loadExtensions()` after a grant. |
| `csp_blocked` | `script-src-elem` or `script-src` | An enforced CSP blocked the script | Allow the collector host in that directive. |
| `integrity_mismatch` | `sha384_mismatch` | A pinned file's bytes differ from its hash | Copy the pinned tag again. |
| `network` | `http_`, `fetch_failed` | The file returned an HTTP error or no response | Check the host, the proxy and `connect-src`. |
| `timeout` | `script_timeout` | No load or error event within 20 seconds | Retry. Check the network path. |
| `already_loaded` | `script_present` | A `
```
The Snippets tab adds this attribute with the switch **Add data-consent-mode="api" to the core snippet**. The shorthand `data-consent-cookie=""` or `data-consent-cookie="="` declares a cookie mode. An invalid declaration is ignored.
| Mode saved for the domain | Declaration on the tag | Mode the client uses |
| --- | --- | --- |
| `api` or `cookie:…` | any | The saved mode. A tag can neither relax it nor swap it. |
| `not_required`, or unset | `api` or `cookie:…` | The declared mode, so the client is gated before the token arrives. The collector does not enforce it on the server. |
| `not_required`, or unset | none, invalid or `not_required` | `not_required`. |
A declaration is a client-side measure. A domain that must be enforced on the server needs the mode saved in the Backoffice.
`getConsent()` and the `noxtica:consent-changed` event carry `modeResolved`. It is `false` until the saved mode arrived with the token, and `true` afterwards. Wait while it is `false`. A loader older than 3.8.1 does not send the field, so `undefined` means "keep using `mode`".
### 3. Connect your banner to the four categories
| Category | A grant enables |
| --- | --- |
| `analytics` | Real-user monitoring, console-log capture, the interaction tracker and the durable client buffer. |
| `replay` | Session replay recording and upload. |
| `deviceId` | Persistent device storage and the persistent device-recognition token. The full page fingerprint also waits for it. |
| `behavioral` | Behavioral biometrics, pointer and touch tracks, geolocation, cookie contents, favicon, extension and WebRTC probes. |
A granted category still depends on the features enabled for your domain. Consent never switches on a feature your configuration leaves off. For the legal classification of each feature, see [Install and Browser Runtime](https://noxtica.com/docs/browser-runtime/#legal-classification-not-legal-advice).
Call `setConsent` from your banner. Each value is the string `'granted'` or `'denied'`; omitted keys keep their value:
```javascript
function applyChoices(choices) {
const state = (allowed) => (allowed ? 'granted' : 'denied');
window.noxticaClient.setConsent({
analytics: state(choices.statistics),
replay: state(choices.statistics),
deviceId: state(choices.preferences),
behavioral: state(choices.marketing),
});
}
// Run when your decision is known and the client exists.
document.addEventListener('noxtica:ready', () => applyChoices(readMyChoices()), { once: true });
```
Then load the extensions, unless **Load the extensions script automatically once consent is granted** or `data-extensions="auto"` does it for you:
```javascript
const result = await window.noxticaClient.loadExtensions();
if (!result.ok) console.warn(result.reason, result.code);
```
Legacy forms keep working: `setConsent('granted' | 'denied')` sets `analytics`, and `setReplayConsent(true | false)` sets `replay`.
What a denial does:
- `deviceId` denied: the persistent device stores are deleted and the device id stays in memory and `sessionStorage`.
- `analytics` denied: the tracker and RUM stop and the buffered analytics events are purged.
- `replay` revoked while recording: the recorder detaches.
- A repeated call with the same values changes nothing and fires no `noxtica:consent-changed`.
In Not required mode a grant is not needed: an explicit `denied` is the sole value that blocks a category. When persistent device recognition is switched off for the domain, a gated mode never writes the persistent device id, even after `deviceId` is granted.
A page check that your banner has not yet allowed is skipped, not failed. `noxtica:collected` then carries `skipped: 'consent_required'`, and the check runs by itself when `deviceId` is granted later on the same page.
### 4. Decide how to treat GPC and DNT
The browser reports the signal in `getConsent().privacySignal`: `'gpc'` when `navigator.globalPrivacyControl` is `true`, `'dnt'` when `navigator.doNotTrack` is `'1'` or `'yes'`, otherwise `null`. The field is a local flag; the loader adds it to no request body. Browsers also send `Sec-GPC` or `DNT` request headers, and the collector reads those.
The domain policy decides what the signal does:
| DNT/GPC policy | A visitor who sends the signal |
| --- | --- |
| `Honor` (default) | The tracker (clicks, scroll dwell, page views and custom events), console-log capture and RUM do not run for that visitor. |
| `Documented override` | Those lanes run. Your tenant has recorded a legal basis that overrides the signal. |
Set the policy in Backoffice → Web Analytics & Privacy → Consent & Privacy. The page lists domains that still need a consent or privacy decision. For each one, set **Legal basis**, **Requires consent** and **DNT/GPC policy**. **Documented override** needs an approved legal basis and the checkbox **Acknowledge documented override**. Saving needs step-up MFA.
Session replay has its own **DNT/GPC policy**, with the same two values, in its replay policy under Backoffice → Web Analytics & Privacy → Capture Policies. See [Session replay](https://noxtica.com/docs/observability/session-replay/).
The collector backs the client up. With policy `Honor` and a request that carries `Sec-GPC: 1` or `DNT: 1`:
- `POST /client/tracker` answers `200` with `{ "ok": true, "eventsProcessed": 0, "reason": "dnt_gpc_honored" }`, and nothing is stored.
- Console-log upload is refused with `console_logs_dnt_gpc_honored`.
- For replay, the replay policy call answers `{ "ok": false, "enabled": false, "reason": "replay_dnt_gpc_honored" }` and no upload capability is issued.
The loader does not read the signal in the core steps: the session token, the minimal security check, the anti-automation counters and protected actions.
### 5. Bridge Google Consent Mode v2 (optional)
Use the bridge when your CMP already drives Google Consent Mode. Turn it on in one of four ways:
```html
```
```javascript
noxtica('consent', 'gcm'); // command queue; also client.enableGoogleConsentMode() or createClient({ consentMode: 'gcm' })
```
What the bridge does:
- It reads Google's consent state from `window.google_tag_data.ics`, listens for changes to `analytics_storage` and `ad_storage`, and picks up a decision made before the collector loaded. If Google's state is not on the page yet, nothing is granted, and the bridge checks once a second for about five minutes.
- `analytics_storage` maps to the `analytics` category and to nothing else. `replay`, `deviceId` and `behavioral` keep needing your explicit `setConsent`. `ad_storage` is read and ignored.
- It can tighten and cannot loosen. On a domain saved as `api` or `cookie`, Google can deny what your decision allowed, and can never grant what the saved mode withholds. On a domain saved as `not_required`, a tag that declares `gcm` makes the client behave as gated until Google says `granted`.
- `getConsent().mode` reads `gcm` while the bridge is on, and each real change fires one `noxtica:consent-changed`.
Google Consent Mode is a signal format. It is not a legal basis, and mapping it to a single category keeps a Google `analytics_storage` grant from being read as consent to replay or device recognition.
### 6. Test the result
1. Load the page in a clean profile with your banner unanswered. In DevTools → Network you see the core script and `POST /client/token`. `localStorage` holds no `nox_` keys, and `sessionStorage` holds the token.
2. Read the effective mode after the token arrived:
```javascript
document.addEventListener('noxtica:collected', () => {
const consent = window.noxticaClient.getConsent();
console.assert(consent.mode === 'api', 'unexpected consent mode', consent);
});
```
3. Answer the banner with consent. Expect `noxtica:consent-changed`, then `noxtica:extensions-loaded`, then a `noxtica:collected` with a `fingerprintId`. Collector requests now carry `nxc=` with one letter per granted category: `a` analytics, `r` replay, `d` deviceId, `b` behavioral.
4. Withdraw a category and confirm the matching storage disappears.
Once the extensions are loaded, the events `noxtica:consent-rejected` and `noxtica:consent-reset` on `window` purge the durable analytics buffer. Dispatch one from your banner when a visitor rejects or resets consent and you want that purge: `window.dispatchEvent(new CustomEvent('noxtica:consent-rejected'))`.
## Verify it works
- `getConsent()` shows the mode you saved and `modeResolved: true`.
- Before consent in a gated mode, the page makes no call to Noxtica other than the core script and `POST /client/token`, and `noxtica:collected` reports `skipped: 'consent_required'`.
- After consent, the extensions load, `nxc` appears on collector requests and `noxtica:collected` carries a `fingerprintId`.
- For a visitor with GPC on and policy `Honor`, `privacySignal` is `'gpc'` and no tracker or RUM request leaves the page.
## Troubleshooting
| Symptom | Cause | Fix |
| --- | --- | --- |
| `getConsent().mode` is `not_required` right after load on an `api` domain | The saved mode has not arrived. `modeResolved` is `false`. | Wait for `noxtica:consent-changed`, or declare `data-consent-mode="api"` on the tag. |
| The extensions load for visitors who declined your banner | The domain is in Not required mode, with **Load the extensions script automatically once consent is granted** on or a legacy script URL | Switch the domain to API or Cookie, or turn the switch off. |
| `setConsent` does nothing in Not required mode | In that mode `denied` is the sole value with an effect | Use API or Cookie mode when visitors must decide first. |
| `TypeError: NoxticaCollector.setConsent requires granted, denied, or { analytics, replay, deviceId, behavioral }` | You passed `true`, `false` or another shape | Pass the strings `'granted'` or `'denied'`. |
| Cookie mode never grants | The cookie name differs, the value is not contained in the decoded cookie, or the cookie is `HttpOnly` or set on another host | Match the name exactly and use a script-readable first-party cookie. |
| In cookie mode a banner change is seen late | The loader reads the cookie at start and on `visibilitychange` and `focus` | Reload, or switch tabs and return. |
| `noxtica:collected` has `skipped: 'consent_required'` | `deviceId` is not granted in a gated mode | Grant `deviceId` after the visitor agrees. This is not an error. |
| Google bridge grants nothing | Google's consent object is not on the page, or solely `ad_storage` changed | Make the Google consent default and update run on the page. The bridge reads `analytics_storage`. |
| The Backoffice says a setting is not available on the workspace's database version yet | The setting is not enabled for your organisation | Nothing is written. Try again later or contact your account team. |
| Saving asks for MFA | Changing the consent mode is a step-up action | Complete the prompt. |
| The consent controls are read-only | Your role is not workspace admin | Ask a workspace admin. |
## Related
- [Install and Browser Runtime](https://noxtica.com/docs/browser-runtime/): install, storage disclosure and the legal classification table.
- [Client API, events and the command queue](https://noxtica.com/docs/sdk/client-api/): `setConsent`, `getConsent` and the consent events.
- [Script attributes and client options](https://noxtica.com/docs/sdk/script-attributes/): `data-consent-mode`, `data-consent-cookie` and `data-extensions`.
- [Protected actions](https://noxtica.com/docs/sdk/protected-actions/): the minimal security check that runs without consent.
- [Cookies, storage and consent categories for your site](https://noxtica.com/docs/compliance/cookies-and-storage/): what to disclose in your cookie notice.
- [Legal basis register and receipts](https://noxtica.com/docs/compliance/legal-basis/): recording the basis behind a DNT/GPC override.
- [Cookie policy](https://noxtica.com/cookies/): Noxtica's own cookie notice.
---
Source: https://noxtica.com/docs/compliance/cookies-and-storage/
Markdown: https://noxtica.com/docs/compliance/cookies-and-storage/index.md
Last updated: 2026-10-27
# Cookies, storage and consent categories for your site
A privacy or web owner uses this page to disclose what the Noxtica browser SDK writes on a visitor's device. It lists each cookie and storage entry with its store, lifetime, writer and consent category. It also explains how Do Not Track (DNT) and Global Privacy Control (GPC) signals change what the collector accepts.
The tables are an engineering inventory, not legal advice. Your counsel decides how to classify each entry under the rules that apply to you. The cookie notice for Noxtica's own websites is at [Cookies](https://noxtica.com/cookies/).
## What it is
Availability: depends on your plan, role and the modules enabled for your organisation.
`` below is the Site Key of your domain. The SDK has two scripts. The **core** script runs on every page. The **extensions** script runs after your page allows it. The core writes no cookie, no localStorage and no IndexedDB. It writes per-tab sessionStorage entries and nothing else. Everything persistent comes from the extensions.
### Cookie and storage inventory
| Name | Store | Lifetime | Written by | Consent category |
| --- | --- | --- | --- | --- |
| `nox_fp_` | Cookie, localStorage, IndexedDB | 400 days | Extensions | `deviceId` |
| `nox_itp_canary_` | Cookie, localStorage, IndexedDB | 400 days | Extensions | `deviceId` |
| `nox_tri_` | Cookie, localStorage, IndexedDB | 400 days | Extensions | `deviceId` |
| `nox_kv_` | IndexedDB database that holds the three keys above | Same as the keys | Extensions | `deviceId` |
| `nox_lock_` | localStorage | At most 30 seconds | Extensions | `deviceId` |
| `nox_buf_` | IndexedDB | Undelivered events dropped after 72 hours | Extensions | `analytics` |
| `noxtica.session..token` | sessionStorage | Until the tab closes | Core | None, security session state |
| `noxtica.session..protect.` | sessionStorage | Until the tab closes, read once and removed | Core | None, security session state |
| `noxtica.session.khanvm`, `noxtica.session.gpuvm` | sessionStorage | Until the tab closes | Extensions | None |
| `__noxtica_khan_accel_v1` | sessionStorage | Until the tab closes | Extensions | None |
| `nx_replay_tab_id`, `nx_replay_session_v1` | sessionStorage | Until the tab closes, or 30 minutes idle by default | Extensions | `replay` |
| `cookietest`, `_nox_test` | Cookie, localStorage, sessionStorage | Removed in the same call | Extensions | None |
What each entry holds:
- `nox_fp_` is the device record: the device identifier, the last-submit time and the state schema version. The localStorage and IndexedDB copies also keep the last check result (score, risk level, confidence, flags). From SDK 3.8.1 the cookie copy holds only the schema version, the device identifier and the last-submit time, as URI-encoded JSON.
- `nox_itp_canary_` is a purge canary, a timestamp that tells the SDK a browser purged its storage.
- `nox_tri_` is a token refresh interval hint.
- `nox_lock_` is a cross-tab lock. It is used when the browser has no Web Locks API, and it is not written while persistent storage is closed.
- `nox_buf_` buffers real-user-monitoring and console-log events until they are delivered.
- `noxtica.session..token` caches the session token so later pages in the same tab skip a round trip.
### Cookie attributes
The three device cookies `nox_fp_`, `nox_itp_canary_` and `nox_tri_` are written by script with these attributes.
| Attribute | Value |
| --- | --- |
| Lifetime | 400 days |
| Path | `/` |
| Domain | Not set, so the cookie is host-only |
| SameSite | `Lax` |
| Secure | Added on https pages |
| HttpOnly | Not set. A script writes the cookie and the SDK reads it back to restore storage that a browser purged. |
### Consent categories
| Category | What a grant enables | Storage it governs |
| --- | --- | --- |
| `deviceId` | Persistent device storage and the persistent device-recognition token. | The three device keys, `nox_kv_` and `nox_lock_`. |
| `analytics` | Real-user monitoring, error detail, console-log capture, the interaction tracker and the durable event buffer. | `nox_buf_`. |
| `replay` | Session replay recording and upload. | `nx_replay_tab_id`, `nx_replay_session_v1`. |
| `behavioral` | Behavioral signals, pointer and touch tracks, geolocation, cookie contents, the extension probe, favicon detection and the WebRTC probe. | No storage entry. |
In a gated consent mode (`api` or a cookie mode), nothing persistent is written until `deviceId` is granted and the domain's persistent device recognition setting is on. Before that, the three device keys are held in memory and sessionStorage under the same names. When `deviceId` is withdrawn, the SDK deletes the three keys from localStorage and cookies and deletes the IndexedDB database `nox_kv_`. In the `not_required` mode the extensions write the device record as soon as they load, unless your page denies `deviceId`. See [Consent modes](https://noxtica.com/docs/sdk/consent/).
### Third-party network contacts
| Contact | When it happens |
| --- | --- |
| `challenges.cloudflare.com` | The SDK loads Cloudflare Turnstile when the server requests a challenge. |
| `stun.l.google.com` on port 19302 | The WebRTC probe uses this public STUN server. It runs when the `behavioral` category is allowed and the probe is enabled for your domain. |
### DNT and GPC
The SDK reports a visitor's browser signal in `getConsent().privacySignal`: `gpc` when `navigator.globalPrivacyControl` is true, `dnt` when `doNotTrack` is `1` or `yes`, otherwise `null`. Browsers send `Sec-GPC: 1` or `DNT: 1` on requests.
The collector acts on the signal according to the domain's DNT/GPC policy. Real-user monitoring, error detail, console logs and the interaction tracker follow the policy you set in Web Analytics & Privacy → Consent & Privacy. Session replay has its own DNT/GPC policy per domain in Web Analytics & Privacy → Capture Policies. New domains start on **Honor** in the Consent & Privacy decision, and the Capture Policies form starts on **Honor** too. With **Honor** and a signal present:
| Lane | What the collector does |
| --- | --- |
| Real-user monitoring | Refuses with HTTP 403 and "RUM not enabled for this domain". |
| Error detail | Refuses with HTTP 403 and `rum_error_detail_dnt_gpc_honored`. |
| Console logs | Refuses with HTTP 403 and `console_logs_dnt_gpc_honored`. |
| Session replay | Refuses with HTTP 403 and `replay_dnt_gpc_honored`. |
| Interaction tracker | Answers HTTP 200 with `{"ok":true,"eventsProcessed":0,"reason":"dnt_gpc_honored"}` and processes nothing. |
With **Documented override** the lane is not refused for the signal. For real-user monitoring, an override needs the approved legal basis `rum_observability` and your acknowledgement. This page does not state that a signal stops the core security check.
## Prerequisites
- A domain with the SDK installed. See [Install and browser runtime](https://noxtica.com/docs/browser-runtime/).
- Your consent mode chosen for the domain. See [Consent modes](https://noxtica.com/docs/sdk/consent/).
- The administrator role to read the CSP & storage tab and to save a consent decision.
- Your counsel's classification of each entry for your jurisdiction.
## Steps
### 1. Open the generated storage table
1. Open Backoffice → Integrations & API → Script & Consent.
2. Select your domain if the page asks for one, then the **CSP & storage** tab.
3. Read the table "Cookies and browser storage written by the collector". Backoffice generates it from the SDK source.
### 2. Choose the rows for your setup
1. If you run the core script alone, disclose the sessionStorage rows marked Core.
2. If you load the extensions, add the rows that match the categories you grant.
3. Add `nox_buf_` when you grant `analytics`, and the replay rows when you grant `replay`.
### 3. Map categories to your consent tool
Connect your consent tool to the four categories with `client.setConsent`. The mapping is your decision. Example:
```javascript
const client = window.noxticaClient;
const state = (allowed) => (allowed ? 'granted' : 'denied');
cmp.onConsentChanged((choices) => {
client.setConsent({
deviceId: state(choices.preferences),
analytics: state(choices.statistics),
replay: state(choices.statistics),
behavioral: state(choices.marketing),
});
});
```
### 4. Publish the disclosure
Copy the inventory into your cookie policy. State for each row the name, store, lifetime and purpose. Name the third-party contacts that apply to your setup.
### 5. Set the DNT and GPC policy
1. Open Web Analytics & Privacy → Consent & Privacy. Domains that still need a decision are listed. A domain whose decision is already recorded does not appear.
2. In the row of a listed domain, choose the **DNT/GPC policy**. Keep **Honor** unless your counsel advises otherwise. Session replay has a separate **DNT/GPC policy** in Web Analytics & Privacy → Capture Policies.
3. Save and complete the step-up check. A documented override also needs the legal basis and the acknowledgement.
### 6. Set your own console preference
Open Backoffice → Settings. In **Privacy & cookies**, switch **Analytics, session replay and device recognition** on or off for your own account. Turning it off stops collection and deletes what was stored on that device.
## Verify it works
With the consent mode `api` and nothing granted, check the page in your browser developer tools.
- Application → Cookies shows no `nox_` cookie.
- `Object.keys(localStorage).filter((k) => k.startsWith('nox_'))` returns an empty array.
- sessionStorage shows `noxtica.session..token`.
- After you grant `deviceId` and load the extensions, the three device cookies appear with `Path=/`, `SameSite=Lax` and a 400-day lifetime, and no `Domain` attribute.
- After you withdraw `deviceId`, the three keys and the `nox_kv_` database disappear.
- With a browser GPC signal on and the policy on Honor, a real-user-monitoring request returns HTTP 403, and a replay upload is refused.
## Troubleshooting
| Symptom | Cause | Fix |
| --- | --- | --- |
| A `nox_fp_` entry exists before consent. | The domain mode is `not_required`, or the entry is the sessionStorage copy held before `deviceId` is granted. | Check the mode with `getConsent().mode`. Choose a gated mode if visitors must decide first. |
| No device cookie appears after consent. | The extensions did not load, or persistent device recognition is off for the domain. | Check `noxtica:extensions-loaded` and the domain setting. |
| `nox_buf_` is missing. | `analytics` is not granted, or no monitoring event was buffered. | Grant `analytics`. |
| Monitoring requests return HTTP 403 for some visitors. | The policy is Honor and the visitor's browser sends a GPC or DNT signal. | This is intended. Choose a documented override when your counsel approves it. |
| A proxy breaks consent enforcement. | The loader adds an `nxc` query parameter to collector requests. A proxy that removes it makes the collector count nothing as granted. | Keep `nxc` in proxies and rewrite rules. |
| The cookie is larger than expected on an older loader. | Before SDK 3.8.1 the cookie also held the last check result. | Update the loader. |
## Related
- [Consent modes, GPC and Google Consent Mode](https://noxtica.com/docs/sdk/consent/): how consent modes and categories work in the SDK.
- [Install and browser runtime](https://noxtica.com/docs/browser-runtime/): install tags, the Content Security Policy and the consent matrix.
- [Legal basis register and receipts](https://noxtica.com/docs/compliance/legal-basis/): the per-domain consent decision.
- [Privacy and compliance controls in Backoffice](https://noxtica.com/docs/compliance/overview/): map of every privacy page.
- [Cookies](https://noxtica.com/cookies/) and [Privacy Policy](https://noxtica.com/privacy/): the public legal documents for Noxtica's own sites.
---
Source: https://noxtica.com/docs/sdk/protected-actions/
Markdown: https://noxtica.com/docs/sdk/protected-actions/index.md
Last updated: 2026-10-27
# Protected actions: client trigger and server check
A protected action is a step an attacker targets, such as login, sign-up, checkout or identity verification. This page shows how to declare one, how the browser starts its check, and how your backend redeems the result. You need this when the domain is in a consent-gated mode and you still want a device check on those steps.
## What it is
Availability: Evaluation access. Availability depends on your plan, role and the modules enabled for your organisation.
When a declared action runs, the core script runs a **minimal** device check even if the visitor has not consented. The check reads device and browser characteristics, stores nothing on the device, and runs no behavioral, WebRTC, geolocation, replay or analytics collection. The submission carries the reason `protected_action:`. Actions you do not declare are not exempt: an ordinary page view never runs the page fingerprint without consent in the `api` and cookie modes.
The browser receives a `requestId`. Your backend redeems that id with `POST /v1/protected-actions/verify` and learns what the collector decided. The id is single-use, and it is valid for 300 seconds. A missing id is "no client signal", not a pass. Whether a legal basis covers this check is your assessment; see [Consent modes](https://noxtica.com/docs/sdk/consent/).
## Prerequisites
- A domain with the core tag and `data-auto-init`. See [Install and Browser Runtime](https://noxtica.com/docs/browser-runtime/).
- Workspace admin access to Backoffice → Integrations & API → Script & Consent. Saving the list needs a step-up MFA confirmation.
- A Server API key (`sk_prod_…`) that carries the `read:device` scope, kept on your server. See [Authentication](https://noxtica.com/docs/api/authentication/).
- A backend route that receives the request id together with the protected request, for example the login post.
- Up to 16 protected actions per domain.
## Steps
### 1. Declare the actions
1. Open Backoffice → Integrations & API → Script & Consent and pick the domain.
2. Open the **Protected actions** tab.
3. Select **Add protected action** for each action. Fill **Name**, **Match by** and **Pattern**.
4. Check the preview **Resulting token configuration**, then select **Save script & consent settings** and confirm the MFA prompt.
| Field | Rule |
| --- | --- |
| **Name** | 1 to 32 characters: lowercase letters, digits, `-` or `_`, starting with a letter. Must differ from every other name in the domain. Suggested: `login`, `signup`, `checkout`, `kyc`, `password_reset`, `payment_method_add`, `withdrawal`. |
| **Match by** → `Page path` | A path glob that starts with `/`, up to 256 characters. `*` matches within one segment, `**` across segments. No spaces, no `?` or `#` (the query string is ignored), no `***`. Example: `/checkout/**`. |
| **Match by** → `Form or button (CSS selector)` | A selector of a form (the check runs on submit) or a button (on click), up to 256 characters, no control characters. Example: `form#login`. |
| **Match by** → `Page event` | The name of a `CustomEvent` your page dispatches on `window`: 1 to 64 letters, digits, `.`, `:`, `-` or `_`. A digit may come first. |
The Backoffice warns, without blocking the save, when a path matches every page (`/**`, `/*`). The check would then run on every page view without consent. Use the path of the step you protect.
A path match runs when the page loads and again on client-side navigation, because the core watches the History API. Changes reach pages with their next session token.
### 2. Start the check from the page
**A form that navigates.** Add the action name to the form. The check starts when the visitor focuses or presses inside the form, so it has usually finished at submit. A run that settled less than 30 seconds earlier is reused.
```html
```
On a native submit the core holds the submit for up to 6 seconds, adds a hidden field `nox_request_id`, and submits again. `data-nox-protect-timeout=""` on the form changes the 6 seconds. If the check is slow or fails, the form goes without the id; the visitor is never blocked.
**A button, a route change or code.** Call `protect` and read the id:
```javascript
try {
const result = await window.noxticaClient.protect('checkout', { timeoutMs: 6000 });
if (result.success) sendWithOrder(result.requestId);
else sendWithOrder(null); // timedOut, undeclared_protected_action, client_destroyed: no client signal
} catch (error) {
sendWithOrder(null); // the check itself failed: no client signal
}
```
`protect` rejects with a `TypeError` when the name is not a valid action name. An explicit call starts a fresh check unless one for the same action is already running. The result is `{ success, requestId, reason: 'protected_action:', … }` on success, and `{ success: false, timedOut: true, reason }` when `timeoutMs` elapsed.
**A form that your script submits** (React, any `fetch` flow). Your handler calls `preventDefault()`, so a hidden field cannot reach the request. A capture-phase listener starts the check before your handler and publishes the result on the form as `form.dataset.noxRequestId`. A bubbling `noxtica:protected` event fires on the form when the check settles. Read the id synchronously at the top of the handler, and call `protect` synchronously to join a check that is still running:
```javascript
async function onSubmit(event) {
event.preventDefault();
const form = event.currentTarget;
// Both lines run before the initial await: the id is withdrawn when this handler returns.
const ready = form.dataset.noxRequestId;
const pending = ready ? null : window.noxticaClient.protect('login', { timeoutMs: 6000 });
const requestId = ready ?? (await pending).requestId; // undefined on timeout or a blocked script
await fetch('/api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-Request-Id': requestId ?? '' },
body: JSON.stringify(credentials),
});
}
```
The id is scoped to one attempt because it is single-use on the server. After your handler returns, the id is removed, and a retry runs a fresh check.
**A page event.** Dispatch the event that you declared, then call `protect` for the same name to receive the id:
```javascript
window.dispatchEvent(new CustomEvent('app:signup-submit'));
```
### 3. Send the request id to your backend
Send the id with the protected request: the hidden `nox_request_id` field of a native form, or a header or body field that you choose in a script-submitted flow. The backend, not the browser, redeems it. Never put a Server API key in browser code.
### 4. Redeem the id on your server
```bash
curl -X POST "https://collect.noxtica.com/v1/protected-actions/verify" \
-H "Authorization: Bearer sk_prod_your_api_key" \
-H "Content-Type: application/json" \
-d '{"requestId":"","action":"login","expectedDomain":"www.example.com"}'
```
| Body field | Rule |
| --- | --- |
| `requestId` | Required. The UUID that the browser received. |
| `action` | Required. The action name. An id minted for `login` cannot satisfy a `checkout` check. |
| `expectedDomain` | Optional. A hostname, origin or URL of the page that ran the action, up to 269 characters. The check compares hostnames. |
The body is limited to 2048 bytes. A `200` response carries:
```json
{
"ok": true,
"requestId": "",
"action": "login",
"fingerprintId": "",
"verdict": "low",
"score": 12,
"confidence": 0.9,
"domain": "www.example.com",
"issuedAt": "2026-10-27T10:00:00.000Z",
"expiresAt": "2026-10-27T10:05:00.000Z",
"consumed": true,
"consumedAt": "2026-10-27T10:00:02.000Z"
}
```
`verdict` is one of `minimal`, `low`, `medium`, `high` or `critical`. The values above are an illustration of the shape, not a typical result.
| Status | Body | Meaning |
| --- | --- | --- |
| `200` | `ok: true` and the fields above | Redeemed now. The id is spent. |
| `400` | `invalid_body`, `invalid_request_id`, `invalid_action` or `invalid_expected_domain` | The request is malformed. |
| `401` | The standard API-key error | The key is missing or invalid. |
| `403` | The key lacks the `read:device` scope | Use a key with that scope. |
| `404` | `request_not_found` | The id is unknown, older than 300 seconds, or belongs to another tenant. |
| `409` | `already_consumed`, with `consumed: true` and `consumedAt` | A replay inside the window. Refuse. |
| `413` | `payload_too_large` | The body is over 2048 bytes. |
| `422` | `action_mismatch` or `domain_mismatch` | The action or the hostname differs. The id is not spent; fix the call. |
| `429` | `Rate limit exceeded`, with a `Retry-After` header | Slow down. See [Rate limits](https://noxtica.com/docs/api/rate-limits/). |
| `500` | `Internal server error` | Treat it as no client signal. |
Error bodies from this route look like `{ "ok": false, "error": "", "requestId": "" }`. For the shared error format, see [Errors](https://noxtica.com/docs/api/errors/).
A server example:
```javascript
// Runs on your server. The key never goes to the browser.
async function verifyProtectedAction(requestId, action, expectedDomain) {
const response = await fetch('https://collect.noxtica.com/v1/protected-actions/verify', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.NOXTICA_SERVER_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ requestId, action, expectedDomain }),
signal: AbortSignal.timeout(3000),
});
const body = await response.json().catch(() => ({}));
return { status: response.status, ...body };
}
const result = await verifyProtectedAction(req.body.nox_request_id, 'login', 'www.example.com');
if (result.status === 200 && result.ok === true) {
// result.fingerprintId is the authoritative device id for this action.
// result.verdict and result.score are signals; you decide what to do with them.
} else {
// 404, 409, 422, 5xx or a missing id: no client signal. Apply your own step-up. Never treat it as a pass.
}
```
Use the `fingerprintId` from this response as the device id for the action. A device id that the browser sends in a header or in an event is a hint. The server SDKs have no wrapper for this call today; use plain HTTP as above (see [SDK family and availability](https://noxtica.com/docs/sdk/family/)). The full contract is in the [API reference](https://noxtica.com/docs/api/reference/).
### 5. Find the runs in Backoffice
Open Backoffice → Fingerprints, open a device, and open its **Events** tab. A protected-action submission shows the badge **Protected action: login**. A run after consent shows **Consented**. Every change to the list is in the audit log.
## Verify it works
1. Open the page with the banner unanswered in a gated mode. In the console run `await window.noxticaClient.protect('login')`. The result has `success: true`, a `requestId` and `reason: 'protected_action:login'`.
2. Send that id to the verify call within 300 seconds. You get `200` with `consumed: true` and a `fingerprintId`.
3. Send the same call again. You get `409` with `already_consumed`.
4. Send the call with another `action`. You get `422` with `action_mismatch`, and the original id still works.
5. In Fingerprints → device → Events, the submission shows **Protected action: login**.
## Troubleshooting
| Symptom | Cause | Fix |
| --- | --- | --- |
| `protect()` resolves `error: 'undeclared_protected_action'` | The name is not declared for the domain, or the page still holds an older token | Declare it in Script & Consent → Protected actions and reload. |
| `data-nox-protect` does nothing | The domain has no declared action, so the core installs no trigger | Declare the action with the same name. |
| A native form submits without `nox_request_id` | The check took longer than the hold time, or the script was blocked. The form is released by design. | Treat a missing id as no client signal. Raise `data-nox-protect-timeout` if needed. |
| The id is missing inside a script-submitted handler | The handler read it after an `await` | Read `form.dataset.noxRequestId` and call `protect` before any `await`. |
| Every page view runs a check | A catch-all path such as `/**` | Narrow the path to the protected step. |
| `404 request_not_found` | The id is older than 300 seconds, belongs to another tenant, or is not a protected-action id | Redeem it right after the protected request, with a key of the same tenant. |
| `409 already_consumed` | The id was redeemed before, or the form posted twice | Refuse the request and run a fresh check for the next attempt. |
| `422 action_mismatch` or `domain_mismatch` | The `action` or `expectedDomain` differs from the browser run | Send the same action name and the hostname of the page that ran it. |
| `403` from the verify call | The key lacks the `read:device` scope | Use a key with that scope. |
| The Backoffice says the setting is not available on the workspace's database version yet | The setting is not enabled for your organisation. Nothing was written. | Try again later or contact your account team. |
## Related
- [Consent modes, GPC and Google Consent Mode](https://noxtica.com/docs/sdk/consent/): why protected actions exist and how they differ from consent.
- [Client API, events and the command queue](https://noxtica.com/docs/sdk/client-api/): `protect()` and the `noxtica:protected` event.
- [Single-page apps, frameworks and tag managers](https://noxtica.com/docs/sdk/single-page-apps/): route changes and framework forms.
- [Backend Integration](https://noxtica.com/docs/backend-integration/): device lookup from your server.
- [Authentication](https://noxtica.com/docs/api/authentication/): Server API keys and scopes.
- [Errors](https://noxtica.com/docs/api/errors/) and [Rate limits](https://noxtica.com/docs/api/rate-limits/): shared API behaviour.
- [Browser SDK troubleshooting](https://noxtica.com/docs/sdk/troubleshooting/): symptoms across the SDK.
---
Source: https://noxtica.com/docs/backend-integration/
Markdown: https://noxtica.com/docs/backend-integration/index.md
Last updated: 2026-10-27
# Backend Integration
This guide covers the server side of the evaluated path. The [developer overview](https://noxtica.com/developers/) links the browser, server, and policy guides in order. The maintained server sample is below.
## Trust boundary
The browser passes a returned device identifier to your backend. The backend calls the authenticated device lookup with a server-held credential. The browser must never receive the credential, an Authorization header, or a secret environment variable.
The public v1 device route rejects an unauthenticated request. Evaluation access and an appropriately scoped credential are required before the lookup can return a tenant-scoped record.
A protected-action `requestId` is redeemed the same way, from the backend with a server credential; see [Protected actions](https://noxtica.com/docs/browser-runtime/#protected-actions).
## Handle transport before risk
Your server must preserve these outcomes:
- **Received:** a response contains the fields your evaluated policy requires.
- **Missing:** no record is present for that identifier in the current tenant and retention window.
- **Invalid:** a response exists but lacks fields required by your policy.
- **Rate limited:** the service rejected request frequency; follow the supplied operational guidance.
- **Unavailable:** authentication, authorization, network, or service failure prevented a usable read.
Only a complete received record belongs in a numeric comparison. Missing, invalid, rate-limited, and unavailable states are not score zero and are not low risk.
## Maintained server sample
Send the device identifier to your backend, then call the authenticated v1 route with a server-held key. Replace every synthetic value with credentials and identifiers issued for your evaluation. An automated test checks these samples against fixtures kept with the documentation.
### Read the device on your server
```javascript
export async function lookupDevice({ deviceId, apiKey, fetchImpl = fetch }) {
const response = await fetchImpl(
`https://collect.noxtica.com/v1/device/${encodeURIComponent(deviceId)}`,
{ headers: { Authorization: `Bearer ${apiKey}` } },
);
if (response.status === 404) return { state: 'missing' };
if (response.status === 429) return { state: 'rate_limited' };
if (!response.ok) return { state: 'unavailable' };
return { state: 'received', record: await response.json() };
}
```
### Keep result states separate
The function below applies the rule above. A record counts as complete when it carries a numeric `score` and `confidence`; every other outcome keeps its own state.
```javascript
export function classifyLookup(result) {
if (!result || result.state === 'unavailable') return { state: 'unavailable' };
if (result.state === 'rate_limited') return { state: 'rate_limited' };
if (result.state === 'missing') return { state: 'missing' };
const record = result.record;
if (!record || typeof record.score !== 'number' || typeof record.confidence !== 'number') {
return { state: 'invalid' };
}
return {
state: 'received',
score: record.score,
riskLevel: record.riskLevel,
confidence: record.confidence,
};
}
```
## Customer policy
Combine the lookup with the protected operation and the account, authentication, transaction, and abuse context your application already owns. Begin in observation mode. Compare the proposed action with confirmed outcomes before adding step-up or deny behavior.
Set an application deadline and choose a fallback for each protected surface. A successful API response does not prove that one threshold is appropriate for every route.
## Verification checklist
- The credential remains in the server secret store.
- Browser requests carry only the lookup identifier and customer-owned business input.
- Received, missing, invalid, rate-limited, and unavailable paths are exercised.
- Logs omit credentials and unnecessary identifiers.
- Policy changes have an owner, observation evidence, and rollback path.
Run the [maintained server sample](https://noxtica.com/docs/backend-integration/#maintained-server-sample) and then trace the complete [Integration Flow](https://noxtica.com/docs/integration-flow/).
---
Source: https://noxtica.com/docs/api/authentication/
Markdown: https://noxtica.com/docs/api/authentication/index.md
Last updated: 2026-10-27
# API authentication
Server API requests carry a credential in the `Authorization` header. Keep the credential on your server, load it from a secret store or an environment variable, and never put it in client-side code, a URL or a log line.
```http
Authorization: Bearer YOUR_API_KEY
```
## Keys and base URLs
Create and manage server API keys in the Backoffice under Integrations & API. The secret is shown once when a key is created or rotated, so store it immediately. Send each request to the base URL of the API you call:
| Environment | Base URL | Key prefix | APIs |
| --- | --- | --- | --- |
| Production | `https://collect.noxtica.com` | `sk_prod_` | [Identity verification API](https://noxtica.com/docs/api/reference/kyc/), [Risk scoring and agent trust API](https://noxtica.com/docs/api/reference/score/), [Protected actions API](https://noxtica.com/docs/api/reference/protected-actions/), [Device intelligence API](https://noxtica.com/docs/api/reference/device/), [Mobile and device identity API](https://noxtica.com/docs/api/reference/mobile/), [Telemetry ingestion API](https://noxtica.com/docs/api/reference/ingest/), [Observability query API](https://noxtica.com/docs/api/reference/observability/), [Health and public key endpoints](https://noxtica.com/docs/api/reference/status/) |
| Production ingest host | `https://ingest.noxtica.com` | | [Telemetry ingestion API](https://noxtica.com/docs/api/reference/ingest/), [Observability query API](https://noxtica.com/docs/api/reference/observability/) |
| Production | `https://backoffice.noxtica.com` | | [MCP server](https://noxtica.com/docs/api/reference/mcp/) |
| Production (not yet deployed) | `https://pulse.noxtica.com` | | [Pulse tenant API](https://noxtica.com/docs/api/reference/pulse/) |
## Credentials
### ApiKeyAuth
Format: `Authorization: Bearer sk_`.
Server-to-server tenant API key. Header: `Authorization: Bearer sk_...`. Scopes are self-mintable per tenant; the scope required by each operation is listed in that operation's `security` block. Recognized KYC/KYB/KYM scopes: `write:identity` (verify, batch, reverify, evidence, sessions, erasure and activate — all share this one scope, there is no separate `read:identity`), `write:kym` (KYM transactions).
Used by: [Identity verification API](https://noxtica.com/docs/api/reference/kyc/), [Risk scoring and agent trust API](https://noxtica.com/docs/api/reference/score/), [Protected actions API](https://noxtica.com/docs/api/reference/protected-actions/), [Device intelligence API](https://noxtica.com/docs/api/reference/device/), [Mobile and device identity API](https://noxtica.com/docs/api/reference/mobile/), [Observability query API](https://noxtica.com/docs/api/reference/observability/).
### SessionTokenAuth
Format: `Authorization: Bearer kycs..`.
Opaque hosted-session bearer token, minted once by the matching `POST .../sessions` S2S call and never re-issued. The tenant id rides inside the token itself. Additionally origin-enforced against the tenant's `ALLOWED_ORIGINS` allowlist — a missing or disallowed `Origin` header refuses with `403 origin_not_allowed` even given a valid token.
Used by: [Identity verification API](https://noxtica.com/docs/api/reference/kyc/).
### ApmIngestKeyAuth
Format: `Authorization: Bearer sk_apm_`.
Dedicated ingestion key (`sk_apm_...`, matching `^sk_apm_[A-Za-z0-9_-]{24,256}$`), created per project and environment under Integrations & API → Ingestion API keys. It carries an allowlist of signals chosen at creation and is the ONLY credential the ingestion operations accept: a server API key (`sk_...`), however broad its scopes, is rejected there, and an `sk_apm_` key is rejected on every other route.
Used by: [Telemetry ingestion API](https://noxtica.com/docs/api/reference/ingest/).
### CodingAgentKeyAuth
Format: `Authorization: Bearer cak_`.
Coding-agent read key (`Authorization: Bearer cak_...`, matching `^cak_[A-Za-z0-9_-]{24,256}$`), created under Integrations & API → Coding agent keys with a chosen set of scopes. It is accepted only by the coding-agent read operations, on the ingestion hosts; a server API key (`sk_...`) or an ingestion key (`sk_apm_...`) is rejected there.
Used by: [Observability query API](https://noxtica.com/docs/api/reference/observability/).
### McpTokenAuth
Format: `Authorization: Bearer mcp_`.
MCP token (`Authorization: Bearer mcp_...`) created under Integrations & API, MCP tokens. A static opaque bearer token, not OAuth. It is accepted only by this endpoint.
Used by: [MCP server](https://noxtica.com/docs/api/reference/mcp/).
### tenantKey
Format: `Authorization: Bearer sk_prod_<32 hex>`.
The platform's tenant API key (minted in the Backoffice; scopes `read:pulse`, `write:pulse`), for the tenant's own back-end on `/pulse/v1/tenant/*` only. Looked up through an HMAC hash; a device token or a web session is refused.
Used by: [Pulse tenant API](https://noxtica.com/docs/api/reference/pulse/).
## Scopes
Choose the narrowest scopes that cover what a key has to do. A key without the scope an operation requires is rejected.
| Scope | Credential | Grants | Operations |
| --- | --- | --- | --- |
| `erase:behavioral` | `ApiKeyAuth` | | [`v1EraseBehavioralSubject`](https://noxtica.com/docs/api/reference/device/#v1EraseBehavioralSubject) |
| `read:apm` | `ApiKeyAuth` | | [`v1ApmListProjects`](https://noxtica.com/docs/api/reference/observability/#v1ApmListProjects), [`v1ApmListProjectEnvironments`](https://noxtica.com/docs/api/reference/observability/#v1ApmListProjectEnvironments), [`v1ApmGetEnvironmentPolicy`](https://noxtica.com/docs/api/reference/observability/#v1ApmGetEnvironmentPolicy), [`v1ApmSearchTraces`](https://noxtica.com/docs/api/reference/observability/#v1ApmSearchTraces), [`v1ApmGetTrace`](https://noxtica.com/docs/api/reference/observability/#v1ApmGetTrace), [`v1ApmListServices`](https://noxtica.com/docs/api/reference/observability/#v1ApmListServices), and 2 more |
| `read:behavioral` | `ApiKeyAuth` | | [`v1GetBehavioralSubject`](https://noxtica.com/docs/api/reference/device/#v1GetBehavioralSubject), [`v1GetBehavioralSubjectTimeline`](https://noxtica.com/docs/api/reference/device/#v1GetBehavioralSubjectTimeline) |
| `read:device` | `ApiKeyAuth` | | [`getAgentPassport`](https://noxtica.com/docs/api/reference/score/#getAgentPassport), [`postAgentPassport`](https://noxtica.com/docs/api/reference/score/#postAgentPassport), [`postAgentVerify`](https://noxtica.com/docs/api/reference/score/#postAgentVerify), [`postIpReputation`](https://noxtica.com/docs/api/reference/score/#postIpReputation), [`postScore`](https://noxtica.com/docs/api/reference/score/#postScore), [`postProtectedActionsVerify`](https://noxtica.com/docs/api/reference/protected-actions/#postProtectedActionsVerify), and 8 more |
| `read:events` | `ApiKeyAuth` | | [`v1ListEvents`](https://noxtica.com/docs/api/reference/device/#v1ListEvents) |
| `read:export` | `ApiKeyAuth` | | [`v1ExportFingerprints`](https://noxtica.com/docs/api/reference/device/#v1ExportFingerprints), [`v1ExportEvents`](https://noxtica.com/docs/api/reference/device/#v1ExportEvents), [`v1ExportVisits`](https://noxtica.com/docs/api/reference/device/#v1ExportVisits), [`v1ExportScoredEvents`](https://noxtica.com/docs/api/reference/device/#v1ExportScoredEvents), [`v1GetEmergingThreats`](https://noxtica.com/docs/api/reference/device/#v1GetEmergingThreats), [`v1ApmGetExport`](https://noxtica.com/docs/api/reference/observability/#v1ApmGetExport), and 1 more |
| `read:fingerprints` | `ApiKeyAuth` | | [`v1ListDevices`](https://noxtica.com/docs/api/reference/device/#v1ListDevices), [`v1ListAccountDevices`](https://noxtica.com/docs/api/reference/device/#v1ListAccountDevices) |
| `read:privacy_request` | `ApiKeyAuth` | | [`v1ApmGetPrivacyExport`](https://noxtica.com/docs/api/reference/observability/#v1ApmGetPrivacyExport), [`v1ApmGetPrivacyErasure`](https://noxtica.com/docs/api/reference/observability/#v1ApmGetPrivacyErasure) |
| `read:pulse` | `tenantKey` | Read subject status and links. | [`pulseTenantSubjectStatus`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantSubjectStatus), [`pulseTenantListDecisions`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantListDecisions), [`pulseTenantGetDecision`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantGetDecision), [`pulseTenantGetLink`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantGetLink) |
| `read:reputation` | `ApiKeyAuth` | | [`v1VerifyReputation`](https://noxtica.com/docs/api/reference/score/#v1VerifyReputation) |
| `read:sealed_results` | `ApiKeyAuth` | | [`v1GetSealedResultsKey`](https://noxtica.com/docs/api/reference/device/#v1GetSealedResultsKey) |
| `read:visits` | `ApiKeyAuth` | | [`v1ListVisits`](https://noxtica.com/docs/api/reference/device/#v1ListVisits) |
| `write:apm` | `ApiKeyAuth` | | [`v1ApmUpdateEnvironmentPolicy`](https://noxtica.com/docs/api/reference/observability/#v1ApmUpdateEnvironmentPolicy), [`v1ApmCreateExport`](https://noxtica.com/docs/api/reference/observability/#v1ApmCreateExport) |
| `write:crawl_voucher` | `ApiKeyAuth` | | [`v1MintCrawlVoucher`](https://noxtica.com/docs/api/reference/score/#v1MintCrawlVoucher) |
| `write:generate` | `ApiKeyAuth` | | [`v1GenerateFingerprintBatch`](https://noxtica.com/docs/api/reference/device/#v1GenerateFingerprintBatch), [`v1GenerateSingleFingerprint`](https://noxtica.com/docs/api/reference/device/#v1GenerateSingleFingerprint) |
| `write:handoff` | `ApiKeyAuth` | | [`postHandoffMint`](https://noxtica.com/docs/api/reference/mobile/#postHandoffMint), [`postHandoffConsume`](https://noxtica.com/docs/api/reference/mobile/#postHandoffConsume) |
| `write:identity` | `ApiKeyAuth` | | [`kycVerify`](https://noxtica.com/docs/api/reference/kyc/#kycVerify), [`kycAddressDocumentCrossMatch`](https://noxtica.com/docs/api/reference/kyc/#kycAddressDocumentCrossMatch), [`kycVerifyBatchSubmit`](https://noxtica.com/docs/api/reference/kyc/#kycVerifyBatchSubmit), [`kycVerifyBatchStatus`](https://noxtica.com/docs/api/reference/kyc/#kycVerifyBatchStatus), [`kycVerifyBatchResults`](https://noxtica.com/docs/api/reference/kyc/#kycVerifyBatchResults), [`kycVerifyBatchCancel`](https://noxtica.com/docs/api/reference/kyc/#kycVerifyBatchCancel), and 19 more |
| `write:identity:trusted-subject` | `ApiKeyAuth` | | [`walletSuspend`](https://noxtica.com/docs/api/reference/mobile/#walletSuspend) |
| `write:kym` | `ApiKeyAuth` | | [`kymTransactionsReport`](https://noxtica.com/docs/api/reference/kyc/#kymTransactionsReport) |
| `write:labels` | `ApiKeyAuth` | | [`v1WriteLabel`](https://noxtica.com/docs/api/reference/device/#v1WriteLabel) |
| `write:passkey` | `ApiKeyAuth` | | [`postPasskeyChallenge`](https://noxtica.com/docs/api/reference/mobile/#postPasskeyChallenge), [`postPasskeyRegister`](https://noxtica.com/docs/api/reference/mobile/#postPasskeyRegister), [`postPasskeyAssert`](https://noxtica.com/docs/api/reference/mobile/#postPasskeyAssert) |
| `write:pulse` | `tenantKey` | Issue link codes, unlink and reverse decisions. | [`pulseTenantReverseDecision`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantReverseDecision), [`pulseTenantCreateLinkCode`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantCreateLinkCode), [`pulseTenantUnlink`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantUnlink) |
## Failed authentication
A missing, malformed or revoked credential, and a credential without the required scope, are rejected before the operation runs. See [Errors](https://noxtica.com/docs/api/errors/) for the status codes and bodies.
_This page is generated from the Noxtica OpenAPI specification release `v0.4.0`: `kyc.yaml` version `1.2.0-2026-10-27` (SHA-256 `c91a695cfde0`), `mcp.yaml` version `0.1.0-2026-10-27` (SHA-256 `1a4875efa736`), `pulse.yaml` version `0.9.0-2026-10-27` (SHA-256 `95196a58bb5b`), `v1.yaml` version `1.3.0-2026-10-27` (SHA-256 `3fd15257a022`). Do not edit it by hand._
---
Source: https://noxtica.com/docs/identity-verification-integration/
Markdown: https://noxtica.com/docs/identity-verification-integration/index.md
Last updated: 2026-10-27
# Identity verification integration
This guide takes a backend engineer from a provisioned account to a working hosted identity verification flow. Your server creates a session, your customer completes the steps on a page hosted by Noxtica, and your server reads the outcome by a status read or a signed event. Your server never receives the customer's answers or capture directly.
Results are automated signals. You decide what each outcome means for your customer; Noxtica hands you the evidence and an audit trail.
## Availability
Identity verification has **Controlled availability**. A tenant needs the module provisioned by the account team, and the account team confirms what applies to your tenant. Steps described here as optional apply only when they are enabled for your organisation. See the [product page](https://noxtica.com/products/identity-verification/) for the product overview and the limits of the result.
## Choose how to integrate
Three routes lead to a verification. Pick by who builds the capture experience and who sends the link.
| Route | Who creates the link | Who builds the capture experience | Guide |
| --- | --- | --- | --- |
| Hosted session from your server | Your server, by API | Noxtica hosts the page; you send the customer to it | This page |
| Invitation from Backoffice | A person in your organisation, in Backoffice | Noxtica hosts the page | [Invitations and hosted verification settings](https://noxtica.com/docs/identity-verification-invitations/) |
| Direct API from your server | Not applicable | Your own application | [Self-hosted identity verification (direct API)](https://noxtica.com/docs/identity-verification-self-hosted/) |
All three need the module provisioned for your tenant and, where an API is involved, a server key with the identity permission. Hosted sessions and invitations also need a recorded legal basis and share the settings described in [Invitations and hosted verification settings](https://noxtica.com/docs/identity-verification-invitations/).
## How the flow works
1. Your server creates a session with your own opaque customer reference. The response carries a `sessionId` and a single-use link. Store the `sessionId` next to your customer record.
2. You send the customer to the link: a full-page redirect, a new tab, an email or message, or a QR code.
3. The customer completes the steps on the hosted page in their own browser.
4. Noxtica processes the submission. A finished capture currently waits in the review queue in your Backoffice (`review_pending`) until someone in your organisation records a decision.
5. Your server learns the outcome by reading the session status, or from a signed `kyc.session.completed` event. Read the status before you act on an event.
6. If you set a return link, the customer can go back to your site from the hosted page after a completed outcome. The return link is a convenience, not proof that verification succeeded.
## Before you start
Complete these once per environment:
- **Module provisioned.** Your account team provisions identity verification for your tenant. Until then every request below receives a plain `404`.
- **Hosted verification page configured.** In the Backoffice, open Identity Verification → KYC Invitations → Settings and fill in the business name, privacy notice link and purpose text the customer sees. The KYC pages show a readiness checklist that names anything still missing. Until the page is configured the customer sees a "Verification isn't ready yet" message.
- **Legal basis recorded by your organisation.** An authorised person in your organisation records the legal basis for hosted identity verification in the same Settings page. Noxtica does not choose one for you. Until it is recorded, session creation is refused.
- **A server key with the identity permission.** In the Backoffice, open API & SDK → Server API Keys and create a key with the "Verify identity documents (KYC)" permission ticked. A new key defaults to a narrower permission that cannot create sessions. The secret is shown once, so save it in your server secret store. Server keys start with `sk_prod_`.
- **Approved return hosts (optional).** If you want a return link, add the host names of your return pages under "Approved return destinations" in the same Settings page. Saving that page asks for fresh step-up verification.
- **An events endpoint (optional).** If you do not want to poll, register an HTTPS endpoint under Integrations → Webhooks, subscribe it to the identity events you need, and save the signing secret when it is shown. The secret is shown once.
### Keys and base address
A key's prefix tells you what it is: server keys start with `sk_prod_`. Call `https://collect.noxtica.com` with it. A key that is missing, malformed, unknown or revoked is refused with `401 invalid_api_key`.
- Keep each key in its own secret store entry.
- A signing secret belongs to one endpoint.
- The Identity Verification → KYC Verifications → Integration tab shows ready-to-copy samples.
## Create a session
Send the request from your server. Never place the server key in a browser or a mobile app.
```http
POST https://collect.noxtica.com/v1/kyc/sessions
Authorization: Bearer sk_prod_your_server_key
Content-Type: application/json
Idempotency-Key: your-retry-key
```
### Request fields
The body is a JSON object. Field names are exact: an unknown field is ignored without an error, so a misspelt name silently falls back to its default.
| Field | Type | Required | Notes |
| ------------------ | ------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `subjectRef` | string | Yes | Your own opaque reference for the customer, 1 to 256 characters. Use an identifier from your system, not a name or an email address. Status reads return it to you; events never carry it. |
| `expiresInSeconds` | integer | No | How long an unopened link stays valid: 300 to 604800, default 86400. A value outside the range is rejected with a `400`, not adjusted. |
| `returnUrl` | string | No | An `https` address whose host exactly matches an approved return host, up to 2048 characters. Any other host is rejected with `return_url_not_allowed`. |
| `purpose` | string | No | Short text shown to the customer on the hosted page, up to 500 characters. When you omit it the default purpose from your hosted page settings is used. |
| `idType` | string | No | An optional hint for the document type. Leave it out unless your account team asks you to send it; the customer chooses on the page. |
| `hostedOptions` | object | No | Per-session switches for optional steps. Leave it out to use your defaults. If you send it, send the complete object your account team supplies; a partial object is rejected with a `400`. |
The request has no field for language, webhook address, or customer contact details. The hosted page follows the customer's browser language, and you register webhook endpoints in the Backoffice.
### Response
A new session returns `200` with this shape:
```json
{
"ok": true,
"sessionId": "",
"url": "https://verify.noxtica.com/s/",
"expiresAt": 1790848845000,
"requestId": ""
}
```
- `sessionId` is a UUID. Store it with your customer record.
- `url` is the single-use link. It is returned once, in this response, and no later call returns it again. Treat it as a secret: do not log it and do not put it in an analytics address.
- `expiresAt` is a time in epoch **milliseconds**, not seconds.
- `requestId` identifies the request. Quote it when you contact support.
### Idempotency
`Idempotency-Key` is optional and must be 8 to 128 characters when present. Without it, every call creates a new session. With it, a retry that carries the same key returns the same `sessionId` with `"replayed": true` and **no** `url`. The key alone identifies the session: a different body under the same key returns the original session.
If a request times out and you never saw the link, you cannot recover it. Create a new session with a new key and let the old one expire.
### Examples
```bash
curl -sS https://collect.noxtica.com/v1/kyc/sessions \
-H "Authorization: Bearer $NOXTICA_SERVER_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"subjectRef":"cust_example","returnUrl":"https://merchant.example.com/verification/return"}'
```
```js
const response = await fetch('https://collect.noxtica.com/v1/kyc/sessions', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.NOXTICA_SERVER_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({
subjectRef: 'cust_example',
returnUrl: 'https://merchant.example.com/verification/return',
}),
});
const body = await response.json();
if (!response.ok) throw new Error(`session creation failed: ${response.status} ${body.error}`);
// Store body.sessionId with your customer record, then send body.url to the customer.
```
```python
import json
import os
import urllib.request
import uuid
request = urllib.request.Request(
"https://collect.noxtica.com/v1/kyc/sessions",
data=json.dumps(
{
"subjectRef": "cust_example",
"returnUrl": "https://merchant.example.com/verification/return",
}
).encode(),
headers={
"Authorization": "Bearer " + os.environ["NOXTICA_SERVER_KEY"],
"Content-Type": "application/json",
"Idempotency-Key": str(uuid.uuid4()),
},
method="POST",
)
with urllib.request.urlopen(request) as response:
body = json.load(response)
# Store body["sessionId"] with your customer record, then send body["url"] to the customer.
```
## Send the customer to the link
Choose the delivery that fits your journey:
- **Redirect.** Send the customer's browser to `url` as a full page. This is the simplest path.
- **New tab.** Open `url` in a new tab or window from your own page.
- **Email or message.** Send the link through your own channel.
- **QR code.** Show the link as a QR code so the customer can continue on a phone. The hosted page also offers a QR code and a copy-link option for moving to a phone.
What the hosted page does and does not do:
- **It cannot be embedded.** The hosted page refuses to load inside an iframe. Open it as a full page or in a new tab.
- **It does not message your page.** The page does not post a message to the window that opened it, and it does not close itself. Do not wait for a script on your side to learn the outcome.
- **It follows the customer's language.** The language comes from the customer's browser. You cannot set it, and the link accepts no parameters beyond its own path.
- **Some browsers cannot be used.** Some in-app browsers are not supported. The page tells the customer how to continue in their regular browser.
### Return link
The return link is optional.
- Set `returnUrl` when you create the session. Its host must be on your approved return hosts.
- After a completed outcome, the hosted page shows a plain "Return to your business" link to exactly that address. There is no automatic redirect, and no query parameters are added, so the address carries no session id or status.
- The link is not shown after a review, unverified, error, cancelled or expired outcome.
- Invitations created from the Backoffice carry no return link.
Because a finished capture currently waits for a decision, most customers do not reach a return link straight away. Design your journey so that it does not depend on the customer coming back: show your own "we will let you know" state, and finish through the status read or the event. Correlate with the `sessionId` you stored, and never treat a visit to your return page as proof of completion.
### Lifetimes
An unopened link stays valid until its own expiry, one day by default. After the customer first opens the link, the customer has 30 minutes to finish, or until the original expiry if that comes sooner. A session that waits in `review_pending` does not expire while it waits for a decision. [KYC Hosted Sessions](https://noxtica.com/docs/kyc-hosted-sessions/) explains expiry and the `410` responses the hosted page itself returns.
## Get the outcome
Two routes lead to the outcome: a status read, and a signed event. Use both. The event saves you from polling, and the status read is the authority.
### Read the session status
```http
GET https://collect.noxtica.com/v1/kyc/sessions/{sessionId}
Authorization: Bearer sk_prod_your_server_key
```
A session you created always returns `200`, including an expired one, which reads `"status": "expired"`. A session id that does not exist, or that belongs to another organisation, returns `404`.
```json
{
"ok": true,
"session": {
"id": "",
"status": "review_pending",
"subjectId": "cust_example",
"expiresAt": 1790763900000,
"completedAt": 1790762445000,
"verificationId": "",
"reasonCodes": [""],
"returnUrl": "https://merchant.example.com/verification/return",
"decision": {
"outcome": "review_pending",
"reasonCodes": [""],
"decidedAt": 1790762445000
}
},
"requestId": ""
}
```
- Everything sits under `session`. `session.id` is the `sessionId` from creation, and `subjectId` is the `subjectRef` you sent.
- Timestamps are epoch milliseconds, or `null` when the moment has not happened.
- `decision` appears once the session has an outcome. Its `outcome` is `approved`, `rejected`, `review_pending` or `error`.
- `verificationId` identifies the verification case, so you can find it in the KYC pages of the Backoffice.
- When Noxtica Verification IDs are enabled for your organisation, the session also carries `nvid`.
- The response can carry more fields than this page lists. Ignore fields you do not use and do not fail on unknown ones.
Poll with a delay that grows between reads and stop at a final status. Do not poll in a tight loop; rate limits apply.
### Statuses
| Status | Meaning | Event |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
| `pending` | Created. The customer has not opened the link. | None |
| `opened` | The customer opened the link and is working through the steps. | None |
| `verifying` | The customer submitted and processing is running. | None |
| `review_pending` | Processing finished and a decision is needed in your Backoffice review queue. Not a rejection, and not an approval. | None yet. `kyc.session.completed` follows when a decision is recorded. |
| `completed` | A decision approved the session. | `kyc.session.completed` with status `completed` |
| `unverified` | Processing finished with a negative outcome. | `kyc.session.completed` with status `unverified` |
| `error` | Processing could not finish, because of a fault or a refusal. | `kyc.session.completed` with status `error` |
| `expired` | The link or the capture window lapsed before a decision. | None. Read the status to observe expiry. |
| `cancelled_by_user` | The customer chose to cancel on the hosted page. This applies when cancelling is enabled for your organisation. | `kyc.session.cancelled` |
Only `completed` is an approval. Treat every other status as not approved until you have read a later one.
## Receive events
Events are notifications. They save you from polling, and they are not the decision.
| Event | When it is sent |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `kyc.session.completed` | A session reaches `completed`, `unverified` or `error`. This includes the moment a reviewer decision resolves a `review_pending` session. |
| `kyc.session.cancelled` | The customer cancelled on the hosted page. Subscribe to it explicitly. It applies when cancelling is enabled for your organisation. |
Other identity event types exist. This page covers the two that describe a hosted session; [Identity verification events and webhooks](https://noxtica.com/docs/identity-verification-webhooks/) lists every identity event, its payload and when it is sent.
Review decisions are relayed on a periodic schedule, so allow a few minutes between a decision and its event. An expired session sends no event: use the status read to observe expiry.
The Backoffice "Send test" button sends a sample of a different event type. It cannot produce an identity event, so test your handler with a signed sample of your own.
Every delivery is an HTTPS `POST` with these headers:
| Header | Value |
| --------------------- | ---------------------------------------------------------------------- |
| `X-Noxtica-Signature` | `sha256=` followed by the lowercase hex signature |
| `X-Noxtica-Timestamp` | The time of this attempt, in epoch milliseconds |
| `X-Noxtica-Event` | The event type |
| `X-Noxtica-Delivery` | The delivery id, identical to the `id` in the body |
The body is a JSON envelope with `id`, `type`, `created_at`, `tenant_id` and `data`. `schemaVersion` sits inside `data`, not on the envelope.
```json
{
"id": ":",
"type": "kyc.session.completed",
"created_at": 1790762445000,
"tenant_id": "",
"data": {
"schemaVersion": "1",
"sessionId": "",
"status": "completed",
"verificationId": "",
"reasonCodes": [""],
"occurredAt": 1790762445000,
"deliveryId": ":"
}
}
```
```json
{
"id": ":",
"type": "kyc.session.cancelled",
"created_at": 1790762300000,
"tenant_id": "",
"data": {
"schemaVersion": "1",
"sessionId": "",
"status": "cancelled_by_user",
"cancelReason": "not_now",
"cancelledAt": 1790762300000,
"occurredAt": 1790762300000,
"deliveryId": ":"
}
}
```
- `cancelReason` is `null` or one of `not_now`, `privacy_concern`, `no_document`, `technical_problem` and `other`.
- When Noxtica Verification IDs are enabled for your organisation, a completed event also carries `data.nvid`. Other optional steps can add fields to `data`, so ignore fields you do not recognise.
- Events never carry your `subjectRef`. Match an event to your customer by `sessionId`.
### Verify the signature
The signature is an HMAC-SHA256 with your endpoint's signing secret over the timestamp, a dot, and the raw request body: `${timestamp}.${rawBody}`. Verify it before you parse or trust anything in the body.
- Use the body exactly as received. Do not parse and re-serialise it.
- Compare in constant time.
- Check the timestamp header, not `created_at`. Every retry is signed again with a fresh timestamp.
- Noxtica does not enforce a timestamp window on its side, so enforce your own. Five minutes is a sensible tolerance.
```js
import { createHmac, timingSafeEqual } from 'node:crypto';
const TOLERANCE_MS = 5 * 60 * 1000;
export function verifyNoxticaWebhook({ secret, timestamp, signature, rawBody, now = Date.now() }) {
const sentAt = Number(timestamp);
if (!Number.isSafeInteger(sentAt) || Math.abs(now - sentAt) > TOLERANCE_MS) return false;
const expected = createHmac('sha256', secret).update(`${timestamp}.${rawBody}`).digest('hex');
const provided = String(signature).replace(/^sha256=/, '').toLowerCase();
const expectedBytes = Buffer.from(expected);
const providedBytes = Buffer.from(provided);
return expectedBytes.length === providedBytes.length && timingSafeEqual(expectedBytes, providedBytes);
}
```
```python
import hashlib
import hmac
import time
TOLERANCE_MS = 5 * 60 * 1000
def verify_noxtica_webhook(secret: str, timestamp: str, signature: str, raw_body: bytes) -> bool:
if not (timestamp.isascii() and timestamp.isdigit()):
return False
if abs(time.time() * 1000 - int(timestamp)) > TOLERANCE_MS:
return False
signed = timestamp.encode() + b"." + raw_body
expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
provided = signature.removeprefix("sha256=").lower()
return hmac.compare_digest(expected, provided)
```
### Delivery, retries and duplicates
- A `2xx` response marks the delivery as delivered.
- Any `4xx` response is final. The delivery is not retried, including `408` and `429`. Return a `4xx` only when you mean it.
- A redirect, a `5xx` response, a timeout or a network error is retried, up to five more attempts. After that the delivery is marked failed and is not sent again. The retry spacing is not published, so do not build on it.
- Each attempt waits up to five seconds for your response, and redirects are not followed. Acknowledge quickly and process afterwards.
- Delivery is at least once. Deduplicate on `X-Noxtica-Delivery`, which stays the same across retries.
- Order is not fixed. Two events for the same session can arrive in either order.
### A notification is not authority
When an event arrives, verify it, record the delivery id, and then read `GET /v1/kyc/sessions/{sessionId}`. Act on the `status` that read returns, not on the event body. This keeps your state correct when events are late, repeated or out of order, and it means a forged or replayed event cannot approve anyone.
## Noxtica Verification ID
When Noxtica Verification IDs are enabled for your organisation, a session that completes or waits for review is given an ID in the form `NVID-XXXX-XXXX-XXXX-XXXX`. The customer sees it on the final page, and you read it from `session.nvid` or `data.nvid`. The ID is not a credential and does not sign anyone in. A person who has it can check its status on the verification site. That public lookup accepts requests only from the verification site itself, so your server cannot call it: read the ID from the session status or the event instead.
## Errors
Every error body is JSON and includes a `requestId`. Quote it when you contact support.
| Status | Error | Meaning | What to do |
| ------ | ----------------------------------------- | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| `400` | `invalid_request` | Malformed JSON, a missing or over-long `subjectRef`, a bad `expiresInSeconds`, `purpose` or `Idempotency-Key`. | Fix the request. Check field names and limits. |
| `400` | `invalid_hosted_options` | `hostedOptions` is not a complete, valid object. | Send the complete object or leave it out. |
| `400` | `invalid_id_type` | `idType` is not accepted for this session. | Leave `idType` out. |
| `400` | `return_url_not_allowed` | `returnUrl` is not `https` or its host is not an approved return host. | Add the host in the hosted page settings or leave `returnUrl` out. |
| `400` or `403` | an error ending in `_not_enabled`, or `email_verification_unavailable` | You asked for an optional step that is not enabled for your organisation. | Leave that step out of `hostedOptions`, or ask your account team. |
| `401` | `invalid_api_key` | The key is missing, malformed, unknown or revoked. | Check the `Authorization` header, and that the key matches the environment you call. |
| `403` | `API key does not have write:identity scope` | The key lacks the identity permission. | Create a key with "Verify identity documents (KYC)" ticked. |
| `403` | `kyc_legal_basis_receipt_required` | Your organisation has not recorded the legal basis for hosted identity verification. | Record it in the Backoffice, then retry. |
| `404` | `V1 endpoint not found` | The module is not provisioned for your tenant, or the path is wrong. A status read also returns it for an unknown session id. | Check the path and session id. If both are right, ask your account team. Do not retry in a loop. |
| `413` | `body_too_large` | The request body is too large. | Send a small JSON object. |
| `415` | `invalid_request` | The `Content-Type` is not JSON. | Send `Content-Type: application/json`. |
| `429` | `Rate limit exceeded` | Too many requests. | Back off and retry. Honour `retryAfter` or `Retry-After` when present. |
| `500` | `server_misconfigured` | A server-side configuration problem. | Contact support with the `requestId`. |
| `503` | `tenant_module_gate_unavailable`, `kyc_legal_basis_receipt_unavailable`, `invalid_request` with a `reason` | A temporary fault. | Retry with a growing delay, and honour `Retry-After` when present. |
| `503` | `hosted_verify_not_configured` | The hosted verification service is not set up for this environment. | Contact your account team. |
A status read can also return `400` with `Invalid sessionId` when the id cannot be decoded.
The shared error envelope, rate limits and key handling are described in [Errors](https://noxtica.com/docs/api/errors/) and [Authentication](https://noxtica.com/docs/api/authentication/).
## Who it fits
Use identity verification where your policy requires identity evidence and a person on your team owns the review.
- **Onboarding and account opening.** Collect supported identity evidence through a hosted flow, without building your own capture screens.
- **Exceptions and review queues.** Separate finished, expired, cancelled, and needs-review cases (see [Statuses](https://noxtica.com/docs/identity-verification-integration/#statuses)). Keep the exception path visible to your operators.
- **Deciding when to ask.** Pair verification with Device Intelligence and Risk Scoring to decide which journeys call for identity evidence. [Common questions](https://noxtica.com/docs/identity-verification-integration/#common-questions) explains how they differ.
## How teams connect
Identity verification has three surfaces: the server API, the hosted page, and the console with events. [Choose how to integrate](https://noxtica.com/docs/identity-verification-integration/#choose-how-to-integrate) shows which route fits your team. Operators set up the hosted page in [Invitations and hosted verification settings](https://noxtica.com/docs/identity-verification-invitations/), and your endpoints subscribe to session events as described in [Identity verification events and webhooks](https://noxtica.com/docs/identity-verification-webhooks/).
## Limits
Read these boundaries before you design the flow.
- **Controlled availability.** What applies depends on an eligible identity configuration, your jurisdiction, and your contract. Confirm with your account team before you plan around it. See [Availability](https://noxtica.com/docs/identity-verification-integration/#availability).
- **Not legal identity proof.** No result is legal identity proof outside the scope of the configured provider and contract. Results are probabilistic and can include false positives and false negatives. They are not statements of fact. Read the [disclaimer](https://noxtica.com/disclaimer/).
- **You decide.** A qualified person on your team should review adverse decisions. Noxtica is not a consumer reporting agency. Do not use output for credit, insurance, employment, or housing eligibility.
- **Your responsibilities.** You own the notices, consents, and legal basis for collecting identity evidence from your customers in each jurisdiction you serve. Plan a fallback for sessions that expire, are cancelled, or end in an error. The [Privacy Policy](https://noxtica.com/privacy/) and the [Security page](https://noxtica.com/docs/security/) describe how Noxtica handles personal data; no module-specific data-scope statement for identity verification is published yet.
## Common questions
Answers about statuses, review, links, keys, events and the Verification ID are in [Identity verification FAQ and troubleshooting](https://noxtica.com/docs/identity-verification-faq/). Two product questions are not covered there.
### Can I turn identity verification on myself?
No. It is provisioned per tenant under Controlled availability; see [Availability](https://noxtica.com/docs/identity-verification-integration/#availability). Contact your account team to discuss your use case and jurisdiction.
### How does it relate to Device Intelligence and Risk Scoring?
They answer different questions. Device and risk evidence describe a browser context and an interaction. Identity verification gathers evidence about a person for your decision. Device risk can support identity evidence, but neither replaces the other.
## Go-live checklist
- The readiness checklist in the Backoffice KYC pages shows no missing item, and a test session runs end to end.
- The legal basis is recorded by an authorised person in your organisation, and the notices and consents you owe your customers are in place.
- The server key has the identity permission, lives in a server secret store, and is never sent to a browser or an app.
- Your server creates every session, sends an `Idempotency-Key`, stores the `sessionId` with the customer, and never logs the link.
- Your return page makes no assumption about the outcome, and your journey works when the customer never comes back.
- Your events endpoint uses HTTPS, verifies the signature over the raw body, enforces a timestamp tolerance, deduplicates on the delivery id, answers quickly and reads the session status before it acts.
- A scheduled status read covers sessions that send no event, such as an expired session or one in `review_pending`.
- Your code handles every status. Only `completed` is an approval, and `review_pending` is neither an approval nor a rejection.
- A person in your organisation reviews any adverse decision before it affects a customer. Results can be wrong in either direction and are not legal proof of identity.
- Noxtica does not delete verification details or evidence automatically and sets no retention date for them: they stay until a tenant administrator deletes them. [Verification data: storage, access and deletion](https://noxtica.com/docs/identity-verification-data/) explains how an administrator deletes a verification in Backoffice.
- The [Privacy Policy](https://noxtica.com/privacy/) and the [Security page](https://noxtica.com/docs/security/) describe how Noxtica handles personal data. This page does not.
## Related reading
- [Invitations and hosted verification settings](https://noxtica.com/docs/identity-verification-invitations/) — the Backoffice settings every hosted link uses, and invitations without code.
- [Self-hosted identity verification (direct API)](https://noxtica.com/docs/identity-verification-self-hosted/) — the direct API as it works today.
- [Identity verification events and webhooks](https://noxtica.com/docs/identity-verification-webhooks/) — every identity event and its payload.
- [Noxtica Verification ID (NVID)](https://noxtica.com/docs/identity-verification-id/) — the shareable reference for a verification.
- [Identity verification FAQ and troubleshooting](https://noxtica.com/docs/identity-verification-faq/) — answers to the questions integrators ask most.
- [KYC Hosted Sessions](https://noxtica.com/docs/kyc-hosted-sessions/) — session lifetime, expiry and the `410` responses.
- [Backend Integration](https://noxtica.com/docs/backend-integration/) — keep the credential on your server and handle explicit response states.
- [Identity verification](https://noxtica.com/products/identity-verification/) — the product overview, availability and limits.
---
Source: https://noxtica.com/docs/identity-verification-self-hosted/
Markdown: https://noxtica.com/docs/identity-verification-self-hosted/index.md
Last updated: 2026-10-27
# Self-hosted identity verification (direct API)
This guide is for a backend engineer who wants to start identity verifications from a server without a link and without the page Noxtica hosts. Your server calls the direct API, receives a verdict, reason codes and a verification id, and keeps them next to your own customer record.
Read the limits first. The direct route is a smaller surface than hosted sessions, and one thing does not work today: it gives your own screens no way to capture a document and have it checked. The section "Capture in your own application" says exactly why and what to use instead.
## What it is
Availability: Controlled availability. Identity verification is provisioned per tenant by your account team, and the account team confirms which of the routes below apply to your tenant. See the [product page](https://noxtica.com/products/identity-verification/) for the overview and the limits of the result.
The direct API is a set of server-to-server routes under `https://collect.noxtica.com/v1/kyc/`. Every call uses your server key as a bearer token. What it provides today:
- **Admission and result.** `POST /v1/kyc/verify` mints a single-use nonce (`action: "mint"`), then runs one verification with that nonce (`action: "verify"`). The response carries a verdict, a verification level, reason codes and a `verificationId`.
- **Safe retries.** A repeated call with the same `Idempotency-Key` returns the stored response again instead of running a second verification.
- **Re-check a known subject.** `POST /v1/kyc/reverify` asks whether a subject is already verified, to at least a level you name, using your tenant's device registry.
- **Bulk admission.** `POST /v1/kyc/verify/batch` admits up to 500 rows from a JSON or CSV manifest, with status, results and cancel routes.
- **Evidence for a verification that already exists.** `POST /v1/kyc/evidence/handle` and `POST /v1/kyc/evidence/finalize` upload sealed evidence for an admitted verification. A proof-of-address cross-match builds on that upload.
- **An event when a verification finishes.** `kyc.verification.completed`, described in [Identity verification events and webhooks](https://noxtica.com/docs/identity-verification-webhooks/).
Results are automated signals. You decide what each outcome means for your customer, and a person in your organisation should review any adverse decision before it affects someone.
## Capture in your own application
Documents are captured on the page Noxtica hosts. The direct API does not replace that page, for two reasons you can check against the routes above:
- A verify request carries data only. It does not accept images, audio or other media, and the request body is limited to 32 KiB.
- An evidence handle is issued only for a verification that already exists in your tenant. The verify call creates that verification and returns its id in the same request that runs the check, so your application has no moment in which to upload a capture and then run the document check on it.
Until a route for this exists, use [hosted identity verification](https://noxtica.com/docs/identity-verification-integration/) when the customer must capture a document, or send an invitation from Backoffice ([Invitations and hosted verification settings](https://noxtica.com/docs/identity-verification-invitations/)). This section is where a future route for capture in your own application will be documented; nothing on this page promises one.
Plan your code for what the current document check returns. It hands its result to a person for review and reports the reason code `provider_manual_review`, so expect `unverified` together with that reason rather than an automatic `verified`. Handle every verdict.
## Prerequisites
- **The module is provisioned for your tenant.** Until it is, every route below returns the plain `404` with the body `V1 endpoint not found`. Two switches have to be on (a platform switch and your tenant's module), and the response is identical whichever one is off, so a `404` means "ask your account team", not "retry".
- **A server key with the identity permission.** In Backoffice open API & SDK → Server API Keys and create a key with "Verify identity documents (KYC)" ticked. A new key does not carry it by default. The secret is shown once; keep it in your server secret store and never in a browser or an app.
- **For evidence routes only:** raw evidence storage armed for your tenant and a data residency (`TR`, `EU` or `US`) set for it. Ask your account team. A request whose `jurisdiction` does not match your tenant's residency gets the same plain `404`.
- **A recorded legal basis where your organisation is required to have one.** Without it the verify route answers `403 kyc_legal_basis_receipt_required`. An authorised person records it in Backoffice → Identity Verification → KYC Invitations → Settings.
## Steps
### 1. Mint an admission nonce
The nonce is single-use, tied to your tenant and valid for 300 seconds. Mint it as close to the verify call as you can.
```bash
curl -sS -X POST https://collect.noxtica.com/v1/kyc/verify \
-H "Authorization: Bearer $NOXTICA_SERVER_KEY" \
-H "Content-Type: application/json" \
-d '{ "action": "mint" }'
```
```json
{ "ok": true, "nonce": "", "ttlSeconds": 300 }
```
### 2. Run the verification
Send the nonce within its lifetime, with an `Idempotency-Key` header of 8 to 128 characters. A missing or malformed key is rejected with `400 invalid_request` before anything runs.
```bash
curl -sS -X POST https://collect.noxtica.com/v1/kyc/verify \
-H "Authorization: Bearer $NOXTICA_SERVER_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"action": "verify",
"nonce": "",
"id_type": "passport",
"purpose": "identity_verification"
}'
```
```js
import { randomUUID } from 'node:crypto';
const base = 'https://collect.noxtica.com';
const headers = {
Authorization: `Bearer ${process.env.NOXTICA_SERVER_KEY}`,
'Content-Type': 'application/json',
};
const mint = await fetch(`${base}/v1/kyc/verify`, { method: 'POST', headers, body: JSON.stringify({ action: 'mint' }) });
if (!mint.ok) throw new Error(`mint failed: ${mint.status}`);
const { nonce } = await mint.json();
const idempotencyKey = randomUUID(); // store it with the customer; reuse it only to retry this same request
const verify = await fetch(`${base}/v1/kyc/verify`, {
method: 'POST',
headers: { ...headers, 'Idempotency-Key': idempotencyKey },
body: JSON.stringify({ action: 'verify', nonce, id_type: 'passport', purpose: 'identity_verification' }),
});
const result = await verify.json();
if (!verify.ok) throw new Error(`verify failed: ${verify.status} ${result.error}`);
// Store result.verificationId with your customer record. Read the verdict below.
```
| Field | Required | Notes |
| --- | --- | --- |
| `action` | No | `mint` or `verify`. When you leave it out the request is treated as `verify`. |
| `nonce` | Yes | From the mint call. Used once. A missing nonce is rejected with `400 missing_nonce`. |
| `id_type` (or `idType`) | Yes | The document type your customer presents. A missing value is rejected with `400 invalid_request`. |
| `purpose` | No | Defaults to `identity_verification`. Other values come from a closed list; an unknown value can be rejected with `400 invalid_request`. |
| `payload` | No | Data only, never media. What a payload may contain depends on the configured check; leave it out unless your account team specifies one. |
| `deviceContext` | No | `true` adds an advisory `deviceTrust` block to the response. |
A request that includes an `attachDeviceTrust` field, in any shape, is rejected with `400`: device trust cannot be asserted by the caller.
### 3. Read and store the result
A verdict is always returned with status `200`. A fault on Noxtica's side comes back as `"verdict": "error"`, never as a subject statement and never as a `5xx`.
```json
{
"ok": true,
"verdict": "unverified",
"verificationLevel": "partial",
"reasonCodes": ["provider_manual_review"],
"verificationId": "",
"requestId": ""
}
```
| Field | Meaning |
| --- | --- |
| `verdict` | `verified`, `unverified` or `error`. Act on `verified` as an approval only after your own checks; treat everything else as not approved. |
| `verificationLevel` | `verified`, `partial`, `unverified` or `inconclusive`. |
| `reasonCodes` | Closed-list codes that explain the outcome. Branch on codes, never on text, and ignore codes you do not know. |
| `verificationId` | Identifies the verification. Find it in Backoffice under Identity Verification → KYC Verifications. |
| `requestId` | Quote it when you contact support. |
A tenant policy that blocks or challenges can turn a provider `verified` into `unverified` and add `policy_blocked` or `policy_challenge_required` to the reason codes.
A repeated request with the same `Idempotency-Key` returns the stored response byte for byte, with no second verification. A different body under a key you already used is refused with `409 idempotency_conflict`. A request still running under that key answers `409` with the reason code `request_in_progress`; wait and retry with the same key.
### 4. Choose how you learn about later changes
`POST /v1/kyc/verify` answers when the check ends, so you do not need to poll for the result of that call. A verification that reaches a final state also sends a signed event, `kyc.verification.completed`. Register an endpoint under Integrations → Webhooks and verify the signature as described in [Identity verification events and webhooks](https://noxtica.com/docs/identity-verification-webhooks/). Treat the event as a notification: compare it with the verification you stored before you act. A person's review decision is visible in Backoffice under Identity Verification → KYC Review Queue and Identity Verification → KYC Verifications.
### 5. Re-check a subject you verified before (optional)
`POST /v1/kyc/reverify` answers one question: is this subject already verified, in your tenant's device registry, to at least the level you ask for. It needs the same key permission and a device registry module that your account team enables, it takes the opaque subject identifier your records use for the customer, and it always returns `200`.
```bash
curl -sS -X POST https://collect.noxtica.com/v1/kyc/reverify \
-H "Authorization: Bearer $NOXTICA_SERVER_KEY" \
-H "Content-Type: application/json" \
-d '{ "subjectId": "cust_example", "requiredLevel": "verified" }'
```
```json
{ "ok": true, "verified": true, "verificationLevel": "verified", "requestId": "" }
```
A missing `subjectId` or an unknown `requiredLevel` is rejected with `400 invalid_request`.
### 6. Admit rows in bulk (optional)
`POST /v1/kyc/verify/batch` accepts a JSON manifest (`{ "items": [{ "idType": "passport" }] }`) or a CSV with an `id_type` column, up to 500 rows and 256 KiB, with a required `Idempotency-Key` header. It answers `202` with a `batchId` and one status per row. Read progress with `GET /v1/kyc/verify/batch/{batchId}/status` and per-row outcomes with `GET /v1/kyc/verify/batch/{batchId}/results`, and stop work that has not started with `POST /v1/kyc/verify/batch/{batchId}/cancel`. The field-level reference is in the [identity API reference](https://noxtica.com/docs/api/reference/kyc/).
### 7. Attach evidence to an admitted verification (optional)
Evidence is uploaded as sealed ciphertext: `POST /v1/kyc/evidence/handle` returns a short-lived handle and the keys to seal with, and `POST /v1/kyc/evidence/finalize` redeems it. Your code does the sealing, so plan time for it and read the [identity API reference](https://noxtica.com/docs/api/reference/kyc/) before you start. The handle is valid for 15 minutes. Evidence kinds are a closed list, and kinds that the platform derives itself are refused with `400 invalid_request`.
## Verify it works
- The mint call returns `"ok": true` and a nonce, and the verify call returns status `200` with a `verificationId`.
- Repeating the verify call with the same `Idempotency-Key` and body returns the same response.
- The verification appears in Backoffice under Identity Verification → KYC Verifications with the `verificationId` you stored.
- If you registered an endpoint, your handler receives `kyc.verification.completed` with a valid signature.
## Troubleshooting
| Symptom | Cause | Fix |
| --- | --- | --- |
| `404` with `V1 endpoint not found` | The module is not provisioned for your tenant, the path is wrong, or an evidence request named a residency other than your tenant's. | Check the path, then ask your account team. Do not retry in a loop. |
| `401 invalid_api_key` | The key is missing, malformed, unknown or revoked. | Check the header and that the key is a current `sk_prod_` key. |
| `403` with `API key does not have write:identity scope` | The key lacks the identity permission. | Create a key with "Verify identity documents (KYC)" ticked. |
| `403 kyc_legal_basis_receipt_required` | Your organisation has no recorded legal basis. | Record it in Backoffice, then retry. |
| `403 tenant_inactive` | The tenant is suspended. | Contact your account team. |
| `400 missing_nonce` | The verify body has no nonce. | Mint a nonce and send it. |
| `400 invalid_request` | A missing `Idempotency-Key` or `id_type`, a malformed `purpose`, an `attachDeviceTrust` field, or evidence of a kind you may not upload. | Fix the request. |
| Verdict `unverified` with `provider_manual_review` | The check handed the result to a person. | A reviewer decides in Backoffice under Identity Verification → KYC Review Queue. |
| Verdict `error` | A fault on the verification side, not a statement about the subject. | Retry with a new nonce and a new `Idempotency-Key`. |
| `402 spend_cap_reached` | Your organisation's spending limit is reached. | Contact your account team. |
| `409 idempotency_conflict` | The key was used with a different request. | Use a new key for a new request. |
| `413 body_too_large` or `415 invalid_request` | The body is over the limit or not JSON. | Send a small JSON body with `Content-Type: application/json`. |
| `429 Rate limit exceeded` | More than 10 calls in 60 seconds with one key on these routes. | Back off and retry. Honour `Retry-After` when present. |
| `503 kyc_verify_unavailable` | A temporary fault. | Retry after the `Retry-After` delay. |
The shared error envelope and the rate-limit rules are described in [Errors](https://noxtica.com/docs/api/errors/) and [Authentication](https://noxtica.com/docs/api/authentication/).
## Related
- [Identity verification integration](https://noxtica.com/docs/identity-verification-integration/): hosted sessions, the route that captures documents for you.
- [Invitations and hosted verification settings](https://noxtica.com/docs/identity-verification-invitations/): send a hosted link from Backoffice without code.
- [Identity verification events and webhooks](https://noxtica.com/docs/identity-verification-webhooks/): every identity event and its payload.
- [Verification data: storage, access and deletion](https://noxtica.com/docs/identity-verification-data/): how verification data is kept and deleted.
- [Identity API reference](https://noxtica.com/docs/api/reference/kyc/): the generated field-level reference.
---
Source: https://noxtica.com/docs/identity-verification-invitations/
Markdown: https://noxtica.com/docs/identity-verification-invitations/index.md
Last updated: 2026-10-27
# Invitations and hosted verification settings
Every hosted verification link, whether your server creates it by API or a person creates it in Backoffice, shows the customer the page you configure under **Identity Verification → KYC Invitations → Settings**. This guide takes an administrator from an empty configuration to a working invitation, and a reviewer through reading the result. You do not write code for anything on this page.
If your server creates the links, set up the Settings tab here first and then follow [Identity verification integration](https://noxtica.com/docs/identity-verification-integration/).
## What it is
Availability: Controlled availability. Identity verification is provisioned per tenant by your account team; see the [product page](https://noxtica.com/products/identity-verification/) for the overview and the limits of the result.
The **KYC Invitations** page in Backoffice (route `/kyc/invitations`, in the Identity Verification group of the navigation) has three tabs. The active tab is kept in the address as `?tab=history`, `?tab=active` or `?tab=settings`.
| Tab | What it is for |
| --- | --- |
| History (the default) | The durable list of every invitation your tenant has started, plus a lookup by session id. |
| Active invitations | The one-time links you started in this browser tab. Links are shown here once and are not saved anywhere else. |
| Settings | The setup status, the verification steps, the hosted page configuration and the legal basis. |
Who can do what:
- An analyst or above can open the page and read the History tab.
- An administrator can create invitations, save the hosted configuration and record the legal basis. Creating an invitation and saving the configuration each ask for a fresh step-up verification of the signed-in person.
- Anyone who sees "KYC verification is not enabled" is working in a tenant whose module is not provisioned yet. Ask your account team.
A link created here carries no return link: after the customer finishes there is no "Return to your business" button. Return links belong to sessions created by API. Invitations created here cannot be re-sent or revoked from the page. When a link is lost or should no longer be used, start a new invitation and let the old one expire.
## Prerequisites
- **The identity verification module is provisioned** for your tenant. The Settings tab lists it at the top of the setup status when it is missing.
- **An administrator account** with fresh step-up verification available. A viewer or analyst can read but cannot create or save.
- **The text your customers will see:** your business name, the purpose of the verification in one plain sentence, the address of your privacy notice (a complete `https` address), a version label for that notice, and the documents you accept with their issuing countries.
- **The legal basis your organisation relies on.** An authorised person in your organisation records it. Noxtica does not choose one for you.
- **Optional:** the host names of your own pages if API-created sessions should offer a return link, a server key and an events endpoint if your server will also create sessions ([Identity verification integration](https://noxtica.com/docs/identity-verification-integration/)).
## Steps
### 1. Open the Settings tab and read the setup status
Open Backoffice → Identity Verification → KYC Invitations → Settings. The setup status lists what is done and what is missing, and each open row links to the control that fixes it.
| Row | What it checks |
| --- | --- |
| KYC verification module | The module is active for your organisation. |
| Hosted verification links | The deployment can issue signed hosted links. A message here means something only Noxtica operates is not ready; contact your account team. |
| Hosted verification page | Business name, privacy notice and accepted documents are saved. |
| Legal basis | An active legal basis covers hosted identity verification. |
| Return destination | Optional. A host name approved for return links on API-created sessions. |
| Server API key | Optional. A server key with the identity permission exists. |
| Webhook endpoint | Optional. An endpoint receives identity events. |
Until the required rows are done, a customer who opens a link sees "Verification isn't ready yet", and Backoffice does not let you create invitations.
### 2. Fill in the hosted verification configuration
Select **Edit configuration**. The form is prefilled and shows a customer preview beside it. Each prefilled value is labelled **Saved**, **From your workspace** or **Suggested — check it**, so you can see where it came from and confirm it before you save. When a value is wrong, for example an address without `https://`, the message under the field names the exact correction and offers it as one click. Fields marked with an asterisk are required.
| Field | Required | What it does |
| --- | --- | --- |
| Business name | Yes | The organisation name at the top of the verification page. |
| Verification purpose | Yes | A plain-language reason shown before the customer agrees to continue. |
| Privacy policy URL | Yes | A complete `https` address. The form tells you when a scheme is missing or wrong. |
| Privacy notice version | Yes | A short version or date that customers and audit records can identify. |
| Support URL | No | An `https` address for customers who need help. |
| Supported documents | Yes | Each document a customer may use, with its issuing countries as two-letter codes such as `TR` or `GB`. Select at least one. |
| Verification checks and mode settings | Per form | The remaining switches in the "Verification checks" section. The setup status and the Verification steps guide show what each does for your organisation. |
| Email verification | No | Whether customers confirm an email address: Off, Optional or Required. It applies to every link unless you choose otherwise when creating one, and is offered only when enabled for your organisation. |
| Allowed return hosts | No | Host names only, with no `https://`, path, port or wildcard. Used by API-created sessions that carry a `returnUrl`. |
Select **Save configuration**. Saving asks for a fresh step-up verification. The form shows the time of the last update.
### 3. Review the verification steps
The **Verification steps** guide on the same tab lists every step the hosted page can ask a customer to complete, whether it is on for your organisation, and a link to the control that switches it on. A step marked "Per invitation" is chosen each time you create an invitation. A step marked unavailable needs something Noxtica operates, or an approval of your own, before it can be used.
### 4. Record the legal basis
In the Legal basis section of the same tab, an authorised person records the lawful basis your organisation relies on for the hosted capture surface, and the additional condition your counsel requires, if any. Recording, superseding and revoking are separate actions and each is listed with its date. Until a basis is active, customers cannot submit a verification and an API-created session is refused with `kyc_legal_basis_receipt_required`.
### 5. Try it with a test invitation
In the configuration editor, use **Save & send test invitation to myself**. It saves the form, then starts an invitation for you under a customer reference that begins with `test-operator-`, so you can open it on your own device and see what a customer sees. The Integration tab's setup guide offers the same action as **Create a test invitation**. It is a real invitation: it appears in History and a finished capture waits in the review queue like any other.
### 6. Send a real invitation
1. Select **New invitation**.
2. Enter a **Customer reference**: your own opaque reference, 1 to 256 characters. Use an identifier from your system, not a name or a document number.
3. Choose the **Document type**.
4. Optional: set **Expires in (minutes)**. Leave it blank for the default of 24 hours. The accepted range is 5 to 10080 minutes; a value outside it is refused.
5. Optional: choose the email verification mode for this link. "Use organisation default" follows your configuration.
6. Select **Start verification**.
The page switches to Active invitations and shows the one-time link with a copy button and a QR code. Copy it now: it is shown once, in this browser tab, and is not saved. Send it to the customer through your own channel or show the QR code so the customer can continue on a phone.
A request is refused with "This organisation hasn't finished setting up KYC verification" (`kyc_not_ready`) when the setup status still shows a required row open.
### 7. Follow the invitation and read the result
Open the History tab. Each row shows the invitation status, its expiry and, once the customer cancels, the time and the reason they gave. The statuses are the same as in the session status read: `pending`, `opened`, `verifying`, `review_pending`, `completed`, `unverified`, `error`, `expired` and `cancelled_by_user`.
- Use **Check invitation status by id** when a session id reaches you outside the list, for example in a support ticket.
- A finished capture currently waits as `review_pending`. Select **Review this verification** to open the case under Identity Verification → KYC Verifications, or work from Identity Verification → KYC Review Queue. A reviewer with the manage permission and fresh step-up verification records the decision.
- "Completion is not the same as approval": an invitation that finished without a linked verification has nothing to review yet.
To be told when a decision is recorded, register an endpoint under Integrations → Webhooks and subscribe it to identity events ([Identity verification events and webhooks](https://noxtica.com/docs/identity-verification-webhooks/)).
## Verify it works
- The setup status shows no open required row, and the preview shows your business name and privacy notice.
- Your test invitation opens on your own device and shows your business name; the History tab lists it as `opened` and later `review_pending` or another final status.
- A real invitation appears in History within moments of **Start verification**.
- If you registered an endpoint, it receives an identity event after a decision.
## Troubleshooting
| Symptom | Cause | Fix |
| --- | --- | --- |
| "KYC verification is not enabled" | The module is not provisioned for this tenant. | Ask your account team. |
| The customer sees "Verification isn't ready yet" | The hosted page is not configured or no legal basis is active. | Complete the open rows in the setup status. |
| **New invitation** is disabled or refused with `kyc_not_ready` | A required setup row is still open. | Open the Settings tab and fix the rows it lists. |
| "Enter a valid expiry in minutes" (`invalid_ttl`) | The expiry is empty text, zero, negative or outside 5 to 10080 minutes. | Enter a number inside the range or leave it blank. |
| The form will not save | A required field is empty, the privacy address is not a complete `https` address, or a document has no issuing country. | Follow the message under the field; it names the exact fix. |
| The page asks for step-up again | Creating invitations and saving settings need a fresh check. | Complete it and repeat the action. |
| A link was lost | Links are shown once and cannot be shown again or revoked from the page. | Start a new invitation. |
| "Email verification is not available" | The option is not enabled for your organisation. | Choose "Use organisation default" or "Off", or ask your account team. |
| A message says the deployment cannot create hosted links | Something only Noxtica operates is not ready. | Contact your account team with the time of the attempt. |
## Related
- [Identity verification integration](https://noxtica.com/docs/identity-verification-integration/): create hosted sessions from your server.
- [Self-hosted identity verification (direct API)](https://noxtica.com/docs/identity-verification-self-hosted/): the direct API and its limits today.
- [Identity verification events and webhooks](https://noxtica.com/docs/identity-verification-webhooks/): every identity event and its payload.
- [Verification data: storage, access and deletion](https://noxtica.com/docs/identity-verification-data/): where verification data lives and how it is deleted.
- [KYC Hosted Sessions](https://noxtica.com/docs/kyc-hosted-sessions/): link lifetime, the capture window and expiry.
---
Source: https://noxtica.com/docs/kyc-hosted-sessions/
Markdown: https://noxtica.com/docs/kyc-hosted-sessions/index.md
Last updated: 2026-10-27
# KYC Hosted Sessions
A hosted KYC session is a one-shot verification link your backend mints server-side and hands to your end customer (redirect, email, or QR). The customer completes identity verification on Noxtica's hosted page; your backend never receives the session's bearer token or the customer's raw answers directly.
## Session lifetime
An unopened link keeps its normal default validity. Once the customer opens it, the capture window narrows to **30 minutes from that first open** — not from when your backend minted the link. Both the customer-facing session view and your backend's own session status read carry `openedAt` (when the customer first opened the link, or absent if they have not yet) and `expiresAt` (the session's current effective expiry), so either side can tell which state a session is in without guessing.
## After expiry
Once a session's capture window lapses, its 5 customer-facing routes — session view, progress, submit, evidence upload, and evidence finalize — each return an HTTP `410 Gone` with:
```json
{ "error": "session_expired", "code": "kyc_session_expired", "requestId": "..." }
```
Your backend's own session status read (`GET /v1/kyc/sessions/{sessionId}`) is **not** one of these: it keeps returning `200` with `status: "expired"`, so a polling backend can observe the terminal state without special-casing an error response.
Treat a `410` from any customer-facing route as terminal: stop polling or retrying against that session, and mint a new one if the customer still needs to complete verification.
## Related reading
- [Identity verification integration](https://noxtica.com/docs/identity-verification-integration/) — create a session, send the customer to the link, and read the outcome by status read or signed event.
- [Backend Integration](https://noxtica.com/docs/backend-integration/) — keep the credential on your server and handle explicit response states.
- [Integration Flow](https://noxtica.com/docs/integration-flow/) — trace a full evaluation from collection to customer policy.
---
Source: https://noxtica.com/docs/identity-verification-id/
Markdown: https://noxtica.com/docs/identity-verification-id/index.md
Last updated: 2026-10-27
# Noxtica Verification ID (NVID)
A Noxtica Verification ID (NVID) is a short reference that a hosted identity verification session receives when it completes or waits for review. Your customer sees it on the final hosted screen, your server reads it from the session, and anyone who holds it can check its status on a public page that shows no personal data. Backend engineers read it, and Backoffice administrators revoke or resend it.
## What it is
Availability: Controlled availability. The NVID is part of identity verification, and Noxtica issues it when it is enabled for your organisation. Your account team confirms whether it applies to you.
An NVID looks like `NVID-XXXX-XXXX-XXXX-XXXX`. It has 16 characters from the Crockford base32 alphabet (digits and letters, without I, L, O and U), and the last character is a check character, so most typing mistakes are rejected before any lookup.
| Fact | Detail |
| ---- | ------ |
| When it is issued | When a hosted session ends `completed` or `review_pending`. A session that ends `unverified` or `error` gets none, and neither does an expired or cancelled one. |
| How many | One NVID per session. It is never rotated or re-issued. |
| Validity | `verified` for 365 days from the session's completion time. For a session that waited in review, that time is when a reviewer's decision completed it. The status is worked out when it is read. |
| What it is not | It is not a credential and does not sign anyone in. It carries no personal data. Holding an NVID proves nothing about the person who presents it, because anyone with the ID can read its status. |
The public status is one of four values:
| Status | Label on the status page | Meaning |
| ------ | ------------------------ | ------- |
| `verified` | Verified | The session is `completed` and the validity period has not ended. |
| `pending` | Pending review | The session is in `review_pending`. It is not verified yet. |
| `expired` | Expired | The validity period has passed. |
| `revoked` | Revoked | An administrator revoked the ID. Revoked wins over every other status. |
Results are signals. An NVID shows that a verification happened and what its status is. You still decide what it means for your customer.
## Prerequisites
- Identity verification provisioned for your organisation, and Noxtica Verification IDs enabled for it. When they are not enabled, the status read has no `nvid` key and the hosted screen shows no ID.
- A server key with the identity permission to read the session status. See [Identity verification integration](https://noxtica.com/docs/identity-verification-integration/).
- To see the NVID in Backoffice: a user who can open KYC Verifications. To revoke or resend: a user with the administrator role who can complete step-up verification (MFA).
- For the optional "email me my ID" form: email delivery set up for your environment. Backoffice shows "Email delivery is not configured for this environment" when it is not.
## Steps
### 1. Read the NVID from your server
Read the session status (`GET https://collect.noxtica.com/v1/kyc/sessions/{sessionId}`) and take `session.nvid`:
```json
{
"ok": true,
"session": {
"id": "",
"status": "review_pending",
"nvid": "NVID-XXXX-XXXX-XXXX-XXXX"
},
"requestId": ""
}
```
Other `session` fields are left out of this excerpt.
- `nvid` is a string once an ID exists, and `null` when the session has none.
- The key is absent when NVIDs are not enabled for your organisation.
- A `kyc.session.completed` event carries `data.nvid` when an ID was issued. A revoke sends no event, so read the public status when you need the current one.
- Store the NVID next to your `sessionId`. Your `subjectRef` never goes to the public page.
### 2. Let your customer keep it
On the final hosted screen the customer sees "Your Noxtica Verification ID" with the ID, a "Copy ID" button, the current status and an "Open the status page" link. The screen explains that anyone the customer gives the ID to can open the status link, and that the link shows no personal data.
The screen can also offer "Email me my ID (optional)". The customer must tick an unticked consent box before "Send my ID" becomes active. Noxtica sends the ID and the status link to that address. The address is not shown to you. The hosted page accepts up to 3 sends per session, at least 60 seconds apart.
### 3. Share the status link
The status page is `https://verify.noxtica.com/v/`. Open it in a browser. It shows:
- the ID and its status, with a plain-language line such as "This verification is current."
- "Verified on" and "Valid until" for a verified ID, "Expired on" for an expired one and "Revoked on" for a revoked one. A pending ID shows no dates.
- "Requested by", the requesting business name, when one is available.
- a note that the page never shows a name, a document or a photo.
An ID that is malformed, unknown or no longer available shows the same "ID not found" screen. The page is not cached and is not for search engines.
The lookup behind the page is for browsers only. It accepts requests from the verification site's own pages and nowhere else, so a call from your server or from your own site is refused with `403 origin_not_allowed`. It also has a rate limit for each client IP address; bounds can change. To check an ID from your backend, use the session status in step 1.
### 4. Revoke or resend in Backoffice
Open Backoffice → Identity Verification → KYC Verifications, open the case, and select the Overview tab. In the "Session details" card you see "Noxtica Verification ID", "Verification ID status", "Verification ID issued", "Email on file for the ID", "Last emailed" and "Emails sent".
Administrators also see these actions. Each needs fresh step-up verification (MFA):
| Action | When it shows | Effect |
| ------ | ------------- | ------ |
| "Revoke ID" with a "Revoke reason" | An ID exists and is not revoked | The public status becomes "Revoked" immediately. The ID cannot be restored or re-issued. |
| "Resend ID email" | The customer left an address and the ID is not revoked | Backoffice emails the ID and the status link again. You never see the address. |
The revoke reasons are "Issued in error", "Fraud suspected", "Requested by the subject" and "Requested by the business". Revoking is recorded in the audit log. A session can be emailed up to 20 times in total, with at least 60 seconds between sends.
## Verify it works
1. Finish a hosted session. The status read returns `session.nvid` in the format above.
2. Open `https://verify.noxtica.com/v/` in a browser. While the session waits for review, the page shows "Pending review" and says the verification is not verified yet.
3. After a reviewer approves the case, reload the page. It shows "Verified" with "Verified on" and "Valid until".
4. After you revoke the ID in Backoffice, reload the page. It shows "Revoked" with "Revoked on". The status read keeps returning the same `nvid` string.
## Troubleshooting
| Symptom | Cause | Fix |
| ------- | ----- | --- |
| The status read has no `nvid` key | NVIDs are not enabled for your organisation. | Ask your account team. |
| `nvid` is `null` | The session has no ID: it has not been submitted, it ended `unverified`, `error`, expired or cancelled, or it finished before NVIDs were enabled. | Read `session.status`. Create a new session if you need an ID. |
| The status page shows "ID not found" | The ID is mistyped, unknown or no longer available. | Copy the ID from the session status or the event, not from a screenshot. |
| The status page shows "Pending review" for a long time | A reviewer has not decided yet. | Open Backoffice → Identity Verification → KYC Review Queue and record a decision. |
| Your server gets `403 origin_not_allowed` | The public lookup is for browsers on the verification site. | Use the session status. |
| The page says "Too many requests. Wait a minute and try again." | The rate limit for your IP address was reached. | Wait, then retry. |
| "Resend ID email" or "Revoke ID" is missing | You lack the administrator role, no address is on file, or the ID is already revoked. | Check the role and the "Email on file for the ID" row. |
| "The ID was emailed too recently or the send limit (20) has been reached." | A send happened within 60 seconds, or the session reached 20 sends. | Wait a minute and retry, or stop at the limit. |
| "This Verification ID is already revoked." | Someone revoked it earlier. | Nothing to do. A revoke cannot be undone. |
## Related
- [Identity verification integration](https://noxtica.com/docs/identity-verification-integration/) — create sessions and read the status.
- [Identity verification events and webhooks](https://noxtica.com/docs/identity-verification-webhooks/) — the `nvid` field on `kyc.session.completed`.
- [Identity verification FAQ and troubleshooting](https://noxtica.com/docs/identity-verification-faq/) — `review_pending` and review decisions.
- [Identity verification data](https://noxtica.com/docs/identity-verification-data/) — what is kept and how an administrator deletes it.
- [Privacy](https://noxtica.com/privacy/) — how Noxtica handles personal data.
---
Source: https://noxtica.com/docs/identity-verification-business/
Markdown: https://noxtica.com/docs/identity-verification-business/index.md
Last updated: 2026-10-27
# Business and merchant verification (KYB and KYM)
KYB (know your business) and KYM (know your merchant) extend hosted verification from people to businesses and merchants. Your server creates a one-shot link, the business or merchant completes onboarding on a Noxtica page, and your operators review the case in Backoffice. A backend engineer creates the sessions, and a Backoffice administrator follows them.
## What it is
Availability: In development. Business and merchant verification is not generally open, and nothing on this page is a commitment on scope, availability or date. Whether the calls and Backoffice pages below work for your organisation depends on your organisation; ask your account team. When it is not available, Backoffice shows "KYB is not available for this workspace yet." or "Merchant verification (KYM) is not available for this workspace yet.", and the API answers `404` with `V1 endpoint not found`.
- **KYB** is hosted business onboarding. The business representative enters business information, uploads documents, declares owners, reviews and submits. A submitted session goes to human review in Backoffice. This page describes no automated business-registry check.
- **KYM** is hosted merchant onboarding plus notify-only transaction monitoring. The merchant enters a profile, uploads documents, accepts a declaration, reviews and submits. Your server can also report transactions, which feed alert rules. An alert is a notification for a person to review. It never starts a payment action.
Both hosted pages open as a full page. They cannot be embedded in an iframe. Results are signals: your operators decide, and Backoffice keeps the case and its notes.
| | KYB | KYM |
| --- | --- | --- |
| Create a session | `POST /v1/kyb/sessions` | `POST /v1/kym/sessions` |
| Key permission | Verify identity documents (KYC), scope `write:identity` | Manage KYM merchant onboarding sessions and transactions, scope `write:kym` |
| Hosted page | `https://verify.noxtica.com/b/` | `https://verify.noxtica.com/m/` |
| Link validity, in seconds | 3600 to 2592000, default 604800 | 3600 to 1209600, default 259200 |
| Creates | A business entity in review | A merchant case in `open` status |
| Session statuses | `pending`, `in_progress`, `submitted`, `under_review`, `completed`, `expired`, `abandoned` | `pending`, `opened`, `submitted`, `under_review`, `completed`, `expired`, `abandoned` |
| Hosted steps | business info, documents, UBO declaration, review, submit | profile, documents, declaration, review, submit |
| Backoffice | KYB: Entities, Sessions, Workflows | KYM: Cases, Sessions, Alerts, Alert Definitions |
| Events | `kyb.entity.created`, `kyb.entity.under_review`, `kyb.entity.closed` | `kym.alert.created`, `kym.case.status_changed` |
## Prerequisites
- Confirmation from your account team that KYB or KYM is enabled for your organisation. Without it, every call below answers `404`.
- A Backoffice user with the administrator role for the KYB and KYM pages. Changes ask for fresh step-up verification (MFA).
- A server key with the right permission: "Verify identity documents (KYC)" for KYB, and "Manage KYM merchant onboarding sessions and transactions" for KYM. Create it in Backoffice → API & SDK → Server API Keys. The secret is shown once. Server keys start with `sk_prod_`. Keep the key on your server.
- The hosted verification service configured for your environment. If it is not, session creation answers `503 hosted_verify_not_configured`.
- For events: an endpoint registered as in [Identity verification events and webhooks](https://noxtica.com/docs/identity-verification-webhooks/).
## Steps
### 1. Create a KYB session
```http
POST https://collect.noxtica.com/v1/kyb/sessions
Authorization: Bearer sk_prod_your_server_key
Content-Type: application/json
```
The body is a JSON object and can be `{}`. Every field is optional, and the business can fill in the real details on the hosted page. Snake_case names such as `legal_name` are accepted too.
| Field | Meaning |
| ----- | ------- |
| `legalName` | Up to 200 characters. Without it, the session starts with the placeholder "Pending business information". |
| `registrationNumber` | Up to 64 characters. |
| `countryOfIncorporation` | Two uppercase letters. Without it, the placeholder `ZZ` is used. |
| `entityKind` | `company`, `partnership`, `trust`, `foundation` or `other`. The default is `company`. |
| `expiresInSeconds` | 3600 to 2592000. The default is 604800. A value outside the range is refused, not adjusted. |
```bash
curl -sS https://collect.noxtica.com/v1/kyb/sessions \
-H "Authorization: Bearer $NOXTICA_SERVER_KEY" \
-H "Content-Type: application/json" \
-d '{"legalName":"Example Co","countryOfIncorporation":"GB","entityKind":"company"}'
```
A new session returns `200`:
```json
{
"ok": true,
"sessionId": "",
"url": "https://verify.noxtica.com/b/",
"expiresAt": 1790848845000,
"requestId": ""
}
```
`url` is a one-shot link that carries the access token. It is returned once, in this response, and no later call returns it. Treat it as a secret and do not log it. `expiresAt` is in epoch milliseconds.
### 2. Create a KYM session
```http
POST https://collect.noxtica.com/v1/kym/sessions
Authorization: Bearer sk_prod_your_server_key
Content-Type: application/json
```
| Field | Meaning |
| ----- | ------- |
| `merchantName` | Up to 200 characters. Without it, the session starts with the placeholder "Pending merchant information". |
| `registrationNumber` | Up to 64 characters. |
| `country` | Two letters. Lowercase is changed to uppercase. Without it, the placeholder `ZZ` is used. |
| `expiresInSeconds` | 3600 to 1209600. The default is 259200. |
The response has the same shape as the KYB response, with a `url` that starts `https://verify.noxtica.com/m/`. KYB requires an uppercase country code, and KYM accepts either case.
### 3. Send the link and follow the session in Backoffice
Send the one-shot `url` to the business representative or merchant by redirect, email or QR code, as in [Identity verification integration](https://noxtica.com/docs/identity-verification-integration/). Store the `sessionId`.
These sessions have no server-side status read like the one for identity sessions. Follow them in Backoffice (the KYB hub is at `/kyb` and the KYM hub at `/kym`), or use events:
| Backoffice page | What it does |
| --------------- | ------------ |
| KYB → KYB Entities | Review business entities, ownership graphs, documents, screening, notes and decisions. |
| KYB → KYB Sessions | Start hosted business onboarding and follow each collection session. "Onboarding session history" lists session, entity, status, step, created and expiry. |
| KYB → KYB Workflows | Publish and review the task graphs and form definitions used by KYB cases. |
| KYM → Merchant Cases | Review merchant onboarding and monitoring cases, declared parties, checks and decisions. |
| KYM → KYM Sessions | Start hosted merchant onboarding and follow each session. The history includes the case. |
| KYM → Merchant Alerts | Triage, assign and resolve notify-only transaction-monitoring alerts. |
| KYM → Alert Definitions | Create and deactivate the rules that generate merchant alerts. |
On the two sessions pages, the "Just started — one-time link" table shows a new link once, with "Copy link", "Open hosted page", "QR code" and "Live status". It is not saved anywhere. "Create test session" starts a one-hour session with no real customer data. Its name begins "TEST session ".
### 4. Report merchant transactions (KYM)
Report one observed transaction for a merchant case that already exists. Take the `caseId` from the "Case" column on KYM Sessions or from Merchant Cases.
```http
POST https://collect.noxtica.com/v1/kym/transactions
Authorization: Bearer sk_prod_your_server_key
Content-Type: application/json
```
```json
{
"caseId": "",
"idempotencyKey": "txn-0001",
"amountMinor": 1000,
"currency": "EUR",
"occurredAt": "2026-10-27T09:30:00Z",
"counterpartyRef": "cp_example"
}
```
| Field | Meaning |
| ----- | ------- |
| `caseId` | Required, up to 512 characters. |
| `idempotencyKey` | Required, up to 255 characters. A repeat of the same key returns the original row. |
| `amountMinor` | Required whole number, zero or more, in the currency's minor unit. |
| `currency` | Required three-letter code. Lowercase is changed to uppercase. |
| `occurredAt` | Required timestamp that parses as a date, for example ISO 8601. |
| `counterpartyRef` | Optional reference of your own. |
A new row returns `201` with `{"ok": true, "eventId": "", "deduplicated": false, "requestId": ""}`. A repeat returns `200` with `"deduplicated": true`. The body can be at most 4096 bytes. The call only records the event for alert rules. It starts no payment.
### 5. Subscribe to events
Register an endpoint and tick the labels below under "Events to deliver" in Backoffice → Integrations & API → Webhooks. Signatures, headers and deduplication work as for identity events.
| Event | Label in Backoffice | Fires when |
| ----- | ------------------- | ---------- |
| `kyb.entity.created` | KYB entity created | An operator creates an entity in Backoffice. |
| `kyb.entity.under_review` | KYB entity under review | A hosted session is submitted, a session is started from Backoffice, or an operator moves an entity to review. |
| `kyb.entity.closed` | KYB entity closed | An operator closes the entity. |
| `kym.alert.created` | KYM alert created | A scheduled evaluation creates an alert. |
| `kym.case.status_changed` | KYM case status changed | A hosted session is submitted, or an operator changes the case status. |
The `data` objects carry no names, registration numbers or party details:
| Event family | `data` fields |
| ------------ | ------------- |
| `kyb.entity.*` | `schemaVersion`, `entityId`, `status` (`active`, `under_review`, `suspended` or `closed`, after the change), `occurredAt`, `deliveryId` |
| `kym.*` | `schemaVersion`, `caseId`, `alertId` and `severity` (for `kym.alert.created`, else `null`), `status` (`open`, `under_review`, `monitoring` or `closed`, for `kym.case.status_changed`, else `null`), `occurredAt`, `deliveryId` |
```json
{
"id": "",
"type": "kyb.entity.under_review",
"created_at": 1790762445000,
"tenant_id": "",
"data": {
"schemaVersion": "1",
"entityId": "",
"status": "under_review",
"occurredAt": 1790762445000,
"deliveryId": ""
}
}
```
These events are notifications, not decisions. Business and merchant events are not part of the identity delivery log, and Noxtica publishes no retry schedule for them. `kym.*` events are attempted once. Plan for a missed event: open the entity or case in Backoffice to see its current state.
## Verify it works
1. In Backoffice, open KYB → KYB Sessions (or KYM → KYM Sessions) and select "Create test session". A row appears under "Just started — one-time link". If you see "KYB is not available for this workspace yet.", the module is not enabled.
2. Select "Open hosted page", or scan the QR code, and walk through the steps.
3. Select "Live status" on the row. It shows the status and the step and refreshes by itself while the panel is open.
4. Call the create endpoint with your server key. A `200` response with `sessionId`, `url` and `expiresAt` means the module, the key and the hosted service are all in place.
5. After the session is submitted, find the entity under KYB Entities or the case under Merchant Cases.
## Troubleshooting
| Symptom | Cause | Fix |
| ------- | ----- | --- |
| `404` with `V1 endpoint not found` | The module is not enabled for your organisation, or the path is wrong. | Check the path, then ask your account team. Do not retry in a loop. |
| `404` with `case_not_found` on a transaction | No merchant case has that `caseId` in your organisation. | Copy the case id from Backoffice. |
| `403` with `API key does not have write:identity scope` (or `write:kym scope`) | The key lacks `write:identity` (KYB) or `write:kym` (KYM and transactions). | Create a key with the right permission. |
| `400` with `invalid_country` | KYB needs two uppercase letters. KYM needs two letters. | Use an ISO country code such as `GB`. |
| `400` with `invalid_ttl`, `invalid_legal_name`, `invalid_merchant_name`, `invalid_registration_number` or `invalid_entity_kind` | A field is outside the limits above. | Fix the field. A bad `expiresInSeconds` is refused. |
| `400` with `invalid_case_id`, `invalid_idempotency_key`, `invalid_amount`, `invalid_currency` or `invalid_occurred_at` | A transaction field is missing or malformed. | Fix the field. |
| `413` with `body_too_large` | The transaction body is over 4096 bytes. | Send the fields above and nothing else. |
| `415` with `invalid_request` | The content type is not JSON. | Send `Content-Type: application/json`. |
| `429` with `Rate limit exceeded` | Too many requests. | Wait for `retryAfter` or `Retry-After`. Bounds can change. |
| `503` with `hosted_verify_not_configured` | The hosted service is not set up for this environment. | Ask your account team. |
| The `url` was lost | The link is shown once. | Create a new session and let the old one expire. |
## Related
- [Identity verification events and webhooks](https://noxtica.com/docs/identity-verification-webhooks/) — register an endpoint and verify signatures.
- [Identity verification integration](https://noxtica.com/docs/identity-verification-integration/) — the same hosted-link pattern for individuals.
- [Identity verification data](https://noxtica.com/docs/identity-verification-data/) — Noxtica does not delete verification details or evidence automatically, and an administrator removes them.
- [Identity verification FAQ and troubleshooting](https://noxtica.com/docs/identity-verification-faq/) — common questions.
- [Identity verification](https://noxtica.com/products/identity-verification/) — the product overview and its limits.
- [Server API reference](https://noxtica.com/docs/api/reference/kyc/) — the generated endpoint reference.
---
Source: https://noxtica.com/docs/identity-verification-data/
Markdown: https://noxtica.com/docs/identity-verification-data/index.md
Last updated: 2026-10-27
# Verification data: storage, access and deletion
This page explains one thing: how long verification details and evidence stay in your tenant, and who can remove them. It applies to identity verification (KYC), business verification (KYB) and merchant verification (KYM) alike.
It describes the Backoffice controls and the platform's behaviour. It is not a statement of what personal data a verification captures and it is not legal advice; the [Privacy Policy](https://noxtica.com/privacy/) and the [Security page](https://noxtica.com/docs/security/) describe how Noxtica handles personal data.
## What it is
Availability: Controlled availability for identity verification; availability of business and merchant verification depends on your organisation, so ask your account team.
**Noxtica does not delete KYC, KYM or KYB verification details or evidence automatically, and it sets no retention date for them.** They stay in your tenant until a tenant administrator deletes them. Nothing expires them in the background, and no Backoffice setting schedules their removal.
Three things are easy to confuse with data expiry. None of them deletes anything:
| What expires | What it controls | What happens to the data |
| --- | --- | --- |
| A hosted link's validity (one day by default, set when the link is created) | Whether the customer can still open the link | Nothing is deleted. A session that reaches `expired` stays visible. |
| The capture window after the customer first opens the link (30 minutes) | How long the customer has to finish | Nothing is deleted. |
| A Noxtica Verification ID's validity | Whether the public status page reports the ID as valid | Nothing is deleted. See [Noxtica Verification ID (NVID)](https://noxtica.com/docs/identity-verification-id/). |
The retention schedules in Backoffice → Privacy & Legal → Data Retention govern other data, for example device events and the audit log. They do not schedule the deletion of verification details or evidence.
## Prerequisites
- **An administrator account** in your tenant. Deleting a verification, approving an erasure request, placing a legal hold, erasing a business entity or a merchant case, and reading sensitive evidence are administrator actions, and the deleting actions ask for a fresh step-up verification of the signed-in person.
- **A second administrator** for identity verification erasure requests. The person who submitted a request cannot approve it.
- **The module for the verification type provisioned** for your tenant. Without it the pages and routes below are not available.
- **A decision in your own organisation** on what you promise customers about deletion. Check with your account team what an approved erasure request covers for your tenant before you state a timeline to a customer.
## Steps
### 1. Decide who may see verification evidence
Reading the stored evidence of a verification is a separate, higher permission than reviewing a case. Backoffice → Identity Verification → Evidence Access is available to administrators only, and each read asks for a fresh step-up verification. Give that role to as few people as your process needs, and review the list under Users.
### 2. Delete identity verification data
For identity verification (KYC), a tenant administrator deletes data in two ways: delete the verifications you choose directly in Backoffice, or work a right-to-erasure request that a subject or an operator submitted.
#### Delete the verifications you choose
1. Open Backoffice → Identity Verification → KYC Verifications. Only administrators see the row checkboxes and the delete buttons.
2. To delete one verification, open its case and, on the Overview tab, select **Delete verification**. To delete several, tick the checkbox of each row on the list and select **Delete selected**. One request covers at most 25 verifications.
3. In the dialog, check the list of verifications and enter a reason of 3 to 500 characters. The reason is kept in the audit trail, so do not put personal data in it.
4. Type the confirmation phrase exactly as the dialog shows it: `delete 1 verification permanently` for one verification, `delete 3 verifications permanently` for three. The confirm button stays disabled until the phrase matches.
5. Select **Delete permanently** and complete the step-up verification when it asks.
What a delete does:
- It removes the verification and everything that belongs to it: its sessions, the evidence files and evidence records, the review decisions, the analysis signals and the webhook delivery records.
- Noxtica removes every evidence file first and confirms that each one is gone. Only then does it remove the records. If a file cannot be removed, the verification is kept and the dialog says so.
- It keeps the billing usage records, the legal-basis receipts, the opaque subject reference and the audit trail.
- It cannot be undone. Deleting a verification that is already deleted is harmless: Backoffice reports it as already deleted.
- It writes two audit entries, `kyc_verification_delete_requested` and `kyc_verification_deleted`, with your reason, who deleted it and how many records were removed from each table.
- It does not send the `kyc.erasure.completed` event. That event belongs to erasure requests.
- A legal hold in your tenant, or an open erasure request for the same subject, blocks the delete.
Deleting works only from a signed-in Backoffice session. No server API key can delete a verification.
#### Work an erasure request
1. Requests appear on the **KYC Erasure** page (Backoffice → Identity Verification → KYC Erasure, titled **KYC Erasure Requests**) after a subject or an operator submits a right-to-erasure request for your tenant. Each row shows the opaque subject reference, the status, whether a legal hold is in place, the requester, the approver and the timestamps. The page shows no raw evidence.
2. A different administrator than the requester approves the request (dual control). Approval by the same person is refused.
3. An administrator can place a legal hold on a request and release it later. While a hold is in place the request does not proceed to deletion.
4. Noxtica carries out an approved request. The **Deletion items** list on the request shows the progress of each stored item, with its receipt and the time it was deleted.
5. When a request completes, the platform sends the `kyc.erasure.completed` event to endpoints subscribed to it. The event carries the request id and the outcome only; it carries no subject identifier, and it is not sent for a request that completed only in part.
Approving, holding and releasing each ask for a fresh step-up verification. Erasure requests are keyed on the subject record that Noxtica creates for a verification, so ask your account team what a request covers for each kind of verification in your tenant before you rely on it for a customer who asks to be forgotten. To remove a specific verification yourself, delete it as described above.
There is no setting that deletes identity verification data on a schedule and no automatic expiry. A deletion is always an explicit action of a tenant administrator.
### 3. Delete a business or a merchant verification
Business (KYB) and merchant (KYM) verifications can be erased explicitly from their own pages, when the module is enabled for your organisation.
1. Open Backoffice → KYB → KYB Entities, or KYM → Merchant Cases.
2. Open the item. It must be in the closed state; an item that is still open cannot be erased.
3. Select **Erase entity** (KYB) or **Erase case** (KYM). The dialog asks for a reason of 3 to 500 characters and for a confirmation: type the legal name of the entity, or the merchant name of the case, exactly as shown.
4. Confirm and complete the step-up verification when it asks.
5. A KYB entity that another entity in your tenant still lists as a beneficial owner cannot be erased until that reference is removed.
Erasing is a hard delete. A KYB entity is removed with its uploaded documents and their stored files, notes, collection sessions, declared beneficial owners and ownership links. A KYM case is removed with its declared parties, alerts, transaction events, merchant sessions, and uploaded documents and their stored files. The audit entry keeps your reason and the number of records removed. The erased item cannot be restored.
If a stored file cannot be confirmed removed, Backoffice still reports the erase and warns you: "Erased, but N stored files could not be confirmed removed. Contact support to finish the cleanup."
### 4. Keep your own records consistent
Noxtica stores verification details for you; it does not tell your systems to forget. When you delete data in Noxtica, also remove or restrict the copies in your own systems, including the `sessionId` and `verificationId` values you stored next to your customer records and any events you logged.
## Verify it works
- A request appears under Identity Verification → KYC Erasure with its status, and moves forward after an administrator other than the requester approves it. Its Deletion items list shows each item's progress.
- A deleted verification no longer appears in KYC Verifications, its case address answers not found, and the audit log shows `kyc_verification_delete_requested` and `kyc_verification_deleted` with your reason.
- An erased KYB entity or KYM case no longer appears in its list, and the audit log shows the erase action with the reason.
- If you subscribed an endpoint to it, your handler receives `kyc.erasure.completed` for a completed erasure request with a valid signature ([Identity verification events and webhooks](https://noxtica.com/docs/identity-verification-webhooks/)).
## Troubleshooting
| Symptom | Cause | Fix |
| --- | --- | --- |
| The erasure page or action is missing | Your role is below administrator, or the module is not provisioned. | Sign in with an administrator account, or ask your account team. |
| The row checkboxes or **Delete verification** are missing on KYC Verifications | Your role is below administrator, or the identity verification module is not provisioned. | Sign in with an administrator account, or ask your account team. |
| **Delete permanently** stays disabled | The reason is shorter than 3 or longer than 500 characters, or the phrase does not match exactly, including the number and the singular or plural. | Enter a valid reason and type the phrase as shown. |
| "Blocked by a legal hold or an open erasure request." | A legal hold is in place in your tenant, or an erasure request for the same subject is still open. | Release the hold or let the request finish, then delete again. |
| "New evidence arrived while deleting", "The evidence store is unavailable" or "The evidence files could not be removed" | The delete did not complete. Records are removed only after every evidence file is confirmed gone, so the verification record is kept. | Try again. If it repeats, contact support. |
| "Deleting verifications is not available right now." | Verification delete is not switched on for your deployment, or the service is briefly unavailable. Nothing was changed. | Try again later, then ask your account team. |
| A request you expected is missing | Requests appear only after a subject or an operator has submitted one for your tenant. | Ask your account team how requests reach your tenant. |
| Approval is refused | The approver is the person who opened the request. | Ask a different administrator to approve. |
| The action asks for verification again | Deleting actions need a fresh step-up check. | Complete it and repeat the action. |
| **Erase entity** or **Erase case** is unavailable or refused | The item is not in the closed state, someone changed it since you opened it, or another entity still references it. | Close the item, reload and try again, and remove the reference first. |
| You expected old verifications to disappear | Nothing deletes verification data on a schedule. | Delete the verifications in KYC Verifications, open an erasure request, or erase the business or merchant item. |
## Related
- [Identity verification integration](https://noxtica.com/docs/identity-verification-integration/): hosted sessions and the link lifetimes that are not data expiry.
- [Invitations and hosted verification settings](https://noxtica.com/docs/identity-verification-invitations/): the Backoffice setup for hosted verification.
- [Identity verification events and webhooks](https://noxtica.com/docs/identity-verification-webhooks/): the `kyc.erasure.completed` event.
- [Business and merchant verification (KYB and KYM)](https://noxtica.com/docs/identity-verification-business/): the business and merchant flows.
- [Privacy Policy](https://noxtica.com/privacy/) and [Security page](https://noxtica.com/docs/security/): how Noxtica handles personal data.
---
Source: https://noxtica.com/docs/identity-verification-faq/
Markdown: https://noxtica.com/docs/identity-verification-faq/index.md
Last updated: 2026-10-27
# Identity verification FAQ and troubleshooting
This page answers the questions that backend engineers and Backoffice operators ask most about hosted identity verification. Start with the concept answers, use the five-step triage when something looks wrong, and use the troubleshooting tables to match a symptom to a fix.
## What it is
Availability: Controlled availability. Identity verification is provisioned by your account team, and optional steps apply when they are enabled for your organisation. Every answer below follows the behaviour of the hosted flow described in [Identity verification integration](https://noxtica.com/docs/identity-verification-integration/).
### Sessions and results
**What do I get back when I create a session?** A `sessionId` and a single-use `url`. Store the `sessionId`, send the customer to the `url`, then read the outcome by status read or by a signed event. See [Identity verification integration](https://noxtica.com/docs/identity-verification-integration/).
**What is the difference between `completed`, `unverified`, `error` and `review_pending`?** `completed` means a decision approved the session. `unverified` is a negative outcome. `error` means processing could not finish. `review_pending` means a person in your Backoffice must decide. It is neither an approval nor a rejection. Only `completed` is an approval.
**Why does my session wait in `review_pending`?** A finished capture currently waits for a decision in Backoffice → Identity Verification → KYC Review Queue. A session in `review_pending` does not expire while it waits. An administrator selects "Approve" or "Override", and either completes the session. "Record escalation" leaves the session as it is. There is no separate reject decision today.
**Is a result a decision about my customer?** No. A result is an automated signal. You decide what it means, and a person in your organisation should review any adverse decision before it affects a customer. Results can be wrong in either direction and are not legal proof of identity.
**Can I embed the hosted page in an iframe?** No. The page refuses to load inside a frame. Open it as a full page or in a new tab. It does not post a message to your page and does not close itself, so learn the outcome by status read or event.
**Can I set the language of the hosted page?** No. The language comes from the customer's browser, and the link accepts no parameters beyond its own path.
**How long does a link stay valid?** An unopened link stays valid for 86400 seconds by default. You can set `expiresInSeconds` from 300 to 604800. After the customer opens the link, the customer has 30 minutes to finish, or until the original expiry if that is sooner. See [KYC Hosted Sessions](https://noxtica.com/docs/kyc-hosted-sessions/).
**Can I resend, revoke or cancel a hosted link in Backoffice?** No. Backoffice has no such control for hosted links. If a link is lost or no longer wanted, create a new session and let the old one expire. Retrying with the same `Idempotency-Key` returns the same `sessionId` without the `url`.
**Do I need a return link?** No. `returnUrl` is optional. It must be an `https` address whose host you approved in Backoffice → Identity Verification → KYC Invitations → Settings. After a completed outcome the page shows a plain link to it. There is no automatic redirect, and the address carries no session id or status. Never treat a visit to your return page as proof of completion.
### Keys and events
**Which key do I use?** Create a key with the "Verify identity documents (KYC)" permission in Backoffice → API & SDK → Server API Keys. Server keys start with `sk_prod_`. Never put the key in a browser or an app.
**Should I poll the status or use events?** Use both. Events save you from polling, and the status read is the authority. When you poll, increase the delay between reads and stop at a final status.
**Which events can I receive, and do they carry my customer reference?** `kyc.session.completed`, `kyc.session.cancelled`, `kyc.verification.completed`, `kyc.erasure.completed`, `kyc.document.expiry_warning` and `kyc.reverification.due`. Some depend on settings for your organisation. Events never carry your `subjectRef`: match an event to your customer by `sessionId`. The status read returns your reference as `subjectId`. See [Identity verification events and webhooks](https://noxtica.com/docs/identity-verification-webhooks/).
**Why do I see the same event twice, or in a different order?** Delivery is at least once and order is not fixed. Deduplicate on `X-Noxtica-Delivery`, then read the status before you act.
### Data and identifiers
**What is a Noxtica Verification ID?** A short reference that a hosted session receives when it completes or waits for review. It is not a credential. See [Noxtica Verification ID](https://noxtica.com/docs/identity-verification-id/).
**What data does Noxtica keep, and can I delete it?** Noxtica does not delete verification details or evidence automatically, and it sets no retention date for them. They stay until a tenant administrator deletes them, so verification data is never deleted automatically. An administrator deletes verifications in Backoffice → Identity Verification → KYC Verifications: select **Delete verification** on a case, or tick several rows and select **Delete selected** (up to 25), give a reason, type the confirmation phrase and complete the step-up check. The delete removes the verification and its evidence files and keeps the billing usage records, the legal-basis receipts and the audit trail. Right-to-erasure requests are handled in KYC Erasure, where a request is approved by an administrator other than the requester. See [Identity verification data](https://noxtica.com/docs/identity-verification-data/), [Requests and deletion](https://noxtica.com/docs/compliance/requests-and-deletion/) and the [Privacy Policy](https://noxtica.com/privacy/).
**Are business and merchant verification available?** KYB and KYM are in development. Availability depends on your organisation; ask your account team. See [Business and merchant verification](https://noxtica.com/docs/identity-verification-business/).
## Prerequisites
- A server key with the identity permission, and access to the Backoffice KYC pages. Reading cases needs a user who can open KYC Verifications. Recording a decision needs the administrator role and fresh step-up verification (MFA).
- The `sessionId` and, when you have it, the `requestId` from the response or the error body.
- An endpoint registered under Backoffice → Integrations & API → Webhooks, if you use events.
## Steps
Triage in five steps.
### 1. Read the session status
```http
GET https://collect.noxtica.com/v1/kyc/sessions/{sessionId}
Authorization: Bearer sk_prod_your_server_key
```
A session you created always returns `200`, including an expired one. A `404` means the id is unknown, belongs to another organisation, or the module is not provisioned.
### 2. Match the status to an action
| `status` | What it means | What to do |
| -------- | ------------- | ---------- |
| `pending` | Created. The customer has not opened the link. | Wait. The link expires at `expiresAt`. |
| `opened` | The customer is working through the steps. | Wait. The session expires within 30 minutes of the customer opening the link. |
| `verifying` | The customer submitted and processing is running. | Wait and read again. If it stays longer than you expect, go to step 5. |
| `review_pending` | A decision is needed in your Backoffice. | Open KYC Review Queue and record a decision. |
| `completed` | A decision approved the session. | Continue your journey. |
| `unverified` | Processing finished with a negative outcome. | Have a person review before you act on it. |
| `error` | Processing could not finish. | Create a new session. If it repeats, go to step 5. |
| `expired` | The link or the capture window lapsed. | Create a new session. |
| `cancelled_by_user` | The customer cancelled. | Create a new session if you still need one. |
### 3. Open the case in Backoffice
Open Backoffice → Identity Verification → KYC Verifications and find the case by the `verificationId` from the status read. The case shows the checks, the decision and the timeline. For session and verification events, Backoffice → Identity Verification → KYC → KYC Processes → "View" lists the webhook deliveries for that process.
### 4. Check delivery
If you expected an event, confirm that the endpoint is enabled and subscribed to it under Integrations & API → Webhooks, that your receiver answers `2xx` within the wait per attempt (5 seconds by default), and that the signature check uses the raw body and the current secret. Read the status instead of waiting for an event that does not apply: neither `review_pending` nor `expired` sends one.
### 5. Collect the details and contact support
Quote the `requestId` from the response or error body, the `sessionId` and the time. Do not send the one-shot link, the server key or the signing secret.
## Verify it works
- Creating a session returns `200` with `sessionId`, `url`, `expiresAt` and `requestId`.
- The status read returns the status you expect, and a Backoffice case exists for a submitted session.
- Your receiver verifies each signature, drops repeated `X-Noxtica-Delivery` values and reads the status before it acts.
- Backoffice → Identity Verification → KYC → KYC Processes shows `delivered` for the events your endpoint acknowledged.
## Troubleshooting
### Creating sessions
| Symptom | Cause | Fix |
| ------- | ----- | --- |
| `404` with `V1 endpoint not found` | The module is not provisioned for your organisation, or the path is wrong. | Check the path. If it is right, ask your account team. Do not retry in a loop. |
| `401` with `invalid_api_key` | The key is missing, malformed, unknown or revoked. | Check the `Authorization` header and that the key is a current `sk_prod_` key. |
| `403` with `API key does not have write:identity scope` | The key lacks the identity permission. | Create a key with "Verify identity documents (KYC)" ticked. |
| `403` with `kyc_legal_basis_receipt_required` | Your organisation has not recorded the legal basis for hosted identity verification. | An authorised person records it in Backoffice → Identity Verification → KYC Invitations → Settings. |
| `400` with `invalid_request` or `invalid_hosted_options` | Malformed JSON, a missing or over-long `subjectRef`, an `expiresInSeconds` outside 300 to 604800, an `Idempotency-Key` outside 8 to 128 characters, or a `hostedOptions` object that is not complete. | Fix the request, and send the complete `hostedOptions` object or leave it out. An unknown field is ignored without an error, so check the spelling of each name. |
| `400` with `return_url_not_allowed` | `returnUrl` is not `https`, or its host is not approved. | Add the host in the hosted page settings, or leave `returnUrl` out. |
| A retry returned `"replayed": true` and no `url` | The `Idempotency-Key` matched an existing session. The link is shown once, in the initial response. | Create a new session with a new key and let the old one expire. |
| `429` with `Rate limit exceeded` | Too many requests. | Back off and honour `retryAfter` or `Retry-After`. Bounds can change. |
| `503` with `hosted_verify_not_configured` | The hosted service is not set up for this environment. | Ask your account team. |
### What your customer sees
| Symptom | Cause | Fix |
| ------- | ----- | --- |
| "Verification isn't ready yet" | Your hosted verification page is not fully set up. | Complete the settings and check the readiness checklist in the Backoffice KYC pages. |
| "This link has expired" | The link or the 30-minute capture window ran out. | Create a new session and send the new link. |
| The page says the browser cannot run verification | The customer opened the link in an in-app browser. | Ask the customer to open the link in their regular browser. |
| The customer cancelled and the link no longer works | A cancel ends the link. The status is `cancelled_by_user`. | Create a new session. The reason comes in the `kyc.session.cancelled` event when that event is enabled for your organisation. |
### Results and events
| Symptom | Cause | Fix |
| ------- | ----- | --- |
| A session stays in `review_pending` | Nobody has recorded a decision. | Open Backoffice → Identity Verification → KYC Review Queue and select "Approve", "Override" or "Record escalation". |
| No event arrives for `review_pending` or `expired` | Neither state sends an event. | Read the session status. |
| An event arrives minutes after the decision | Review decisions are sent on a periodic schedule. | Wait a few minutes. The status read is current. |
| The signature check fails | The body was parsed before it was hashed, the secret was rotated, or `created_at` was used instead of the timestamp header. | Hash the raw body with the current secret and the `X-Noxtica-Timestamp` header. |
| The endpoint shows "No deliveries yet" while events work | Identity event outcomes are recorded under KYC Processes, not on the endpoint row. | Open KYC Processes → "View" → "Webhook deliveries". |
| `nvid` is missing from the status read or an event | Verification IDs are not enabled for your organisation, or the session has none. | See [Noxtica Verification ID](https://noxtica.com/docs/identity-verification-id/). |
## Related
- [Identity verification integration](https://noxtica.com/docs/identity-verification-integration/) — create a session and read the outcome.
- [Identity verification events and webhooks](https://noxtica.com/docs/identity-verification-webhooks/) — register an endpoint and verify signatures.
- [Noxtica Verification ID](https://noxtica.com/docs/identity-verification-id/) — format, validity and revocation.
- [Business and merchant verification](https://noxtica.com/docs/identity-verification-business/) — KYB and KYM.
- [Identity verification data](https://noxtica.com/docs/identity-verification-data/) — what is kept and who deletes it.
- [KYC Hosted Sessions](https://noxtica.com/docs/kyc-hosted-sessions/) — expiry and the `410` responses.
- [Errors](https://noxtica.com/docs/api/errors/) — the generic error reference.
---
Source: https://noxtica.com/docs/identity-verification-operations/
Markdown: https://noxtica.com/docs/identity-verification-operations/index.md
Last updated: 2026-10-27
# Identity verification operations in Backoffice
After verifications start arriving, people in your organisation work them in the **Identity Verification** group of Backoffice. This guide covers every KYC page beyond [invitations and hosted settings](https://noxtica.com/docs/identity-verification-invitations/) and the [integration](https://noxtica.com/docs/identity-verification-integration/): what each page is for, who may use it, and what to check before you act. Reviewers and administrators do the work; a verification result is a signal, and the decision on an adverse result is yours.
## What it is
Availability: Controlled availability (identity verification). Each page below also depends on your plan, your role and the modules enabled for your organisation; a page that is not enabled says so instead of showing data.
The sidebar lists the pages under **Identity Verification**. The landing page `/kyc` is the **KYC** item; every other page is a sub-item of it. This guide describes pages and permissions. It does not list what a verification captures; see the [Privacy Policy](https://noxtica.com/privacy/) and the [Security page](https://noxtica.com/docs/security/).
| Nav label | Route | Read it | Change things | What it is for |
| --- | --- | --- | --- | --- |
| KYC | `/kyc` | Analyst | n/a | Setup status, verification steps guide, directory of KYC pages |
| KYC Verifications | `/kyc/verifications` | Analyst | Administrator + step-up | Case list, case detail, Integration tab, delete verifications |
| KYC Invitations | `/kyc/invitations` | Analyst | Administrator + step-up | Hosted links and settings: [Invitations](https://noxtica.com/docs/identity-verification-invitations/) |
| KYC Review Queue | `/kyc/review-queue` | Analyst | Administrator + step-up | Decide cases that wait for a person |
| KYC Processes (no sidebar item) | `/kyc/processes` | Analyst | Read-only | Follow one process end to end |
| KYC Erasure | `/kyc/erasure-requests` | Analyst | Administrator + step-up | Erasure requests: [Verification data](https://noxtica.com/docs/identity-verification-data/) |
| KYC Policies | `/kyc/policies` | Analyst | Administrator + step-up | Review policies, advisory screening hits, corpus versions |
| KYC Screening Cases | `/kyc/screening-cases` | Analyst | Administrator + step-up | Casework on advisory screening hits |
| KYC Rescreening | `/kyc/rescreening` | Analyst | Read-only | Rescreening coverage and hit volume |
| Assisted Recovery | `/kyc/recovery` | Administrator | Administrator + step-up | Recovery cases and appeals queue |
| Agent Delegations | `/kyc/agent-delegations` | Analyst | Revoke: Analyst + step-up. New Delegation: Administrator + step-up | Delegated agent activity (KYA × KYC) |
| Evidence Access | `/kyc/evidence` | Administrator | View, export, audit trail: Administrator + step-up | Sensitive evidence, every view audited |
| Passkeys | `/kyc/passkey-credentials` | Analyst | Administrator + step-up | Registered passkeys and authenticator trust rules |
| Step-Up Verification | `/kyc/step-up` | Analyst | Read-only | Posture of your customers' biometric step-up |
| Device Registry | `/kyc/device-registry` | Analyst | Administrator + step-up | Trusted-device links |
| Device Topology Policy | `/kyc/device-topology` | Analyst | Administrator + step-up | Active-device limits and step-up rules |
Older addresses such as `/kyc-review-queue` and `/kyc-evidence-access` redirect to these routes. The page heading can differ from the nav label: Evidence Access opens as **Sensitive Evidence Access**, Assisted Recovery as **Assisted Recovery Operations**, Passkeys as **Passkey Credentials**, Step-Up Verification as **Passkey Step-Up**.
**Step-up** is a fresh check of the signed-in person with their MFA method. Backoffice asks for it when an action needs it and then repeats the action. A completed check stays fresh for 360 minutes. It is not the same thing as the **Step-Up Verification** page, which describes your customers' step-up.
## Prerequisites
- **The identity verification module is provisioned** for your organisation. Without it the pages show "KYC verification is not enabled", or a strip reading "KYC is not included in your plan". Ask your account team.
- **Roles.** Analysts read. Administrators record decisions and change settings. See [Roles and permissions](https://noxtica.com/docs/security/roles-and-permissions/).
- **MFA enrolled** for every person who will decide or change settings, so the step-up check can complete: [Sign-in, SSO, SCIM, MFA and IP allowlist](https://noxtica.com/docs/security/sign-in-and-access/).
- **Hosted settings and a legal basis recorded** ([Invitations](https://noxtica.com/docs/identity-verification-invitations/)). Without an active legal basis for the capture surface, Backoffice refuses to approve or override.
- **Webhook endpoint (optional)** to learn about decisions: [Identity verification events and webhooks](https://noxtica.com/docs/identity-verification-webhooks/).
- **Data lifecycle.** Noxtica does not delete verification details or evidence automatically and sets no retention date. Nothing on these pages schedules a deletion. An administrator can delete verifications on purpose in KYC Verifications. See [Verification data](https://noxtica.com/docs/identity-verification-data/).
## Steps
### 1. Decide who can review and see evidence
1. Give analysts the role for reading cases, the queue, processes, screening and device pages.
2. Give administrators the role for recording decisions, running recovery and changing policies. Keep the group small: every decision is audited with the person who made it.
3. Treat **Evidence Access** as a separate, higher permission. Administrators hold the permission to open original images, video or audio, and every open asks for step-up. Review the list at Backoffice → Administration → Users.
4. Check who did what in the [audit log](https://noxtica.com/docs/security/audit-log-and-exports/).
### 2. Check setup status on the KYC overview
Open Backoffice → Identity Verification → KYC (`/kyc`).
- A confirmation line, "KYC verification is set up — invitation links will open a working verification page.", means customers can complete a link.
- A block titled "KYC verification isn't ready for this organisation" lists each missing step with a link to the page that fixes it: activate the module, configure the hosted verification page, or register the legal basis. Two steps belong to Noxtica (the module is switched off on the deployment, or hosted links cannot be issued); the list says "Contact a platform operator" for those.
- The **Verification steps** guide below it shows which capture steps are on for your organisation.
- The directory links to every KYC page and to the **Integration guide** (`/kyc/verifications?tab=integration`).
### 3. Read cases in KYC Verifications
Open Backoffice → Identity Verification → KYC Verifications (`/kyc/verifications`). The **Verifications** tab is the default; **Integration** holds the in-app integration guide.
- Search by case id, session id or subject reference. Filter by Status, Verdict, Review, Source (**Hosted** or **API**), Document type, Issuing country, Reason code and a Created date range. Switch between the List and Cards layouts and choose columns.
- Case status reads Not started, In progress, Awaiting review, Completed, Abandoned, Expired, Cancelled or Error. The count shows "1000+" when the list is capped.
- **Export** downloads the loaded rows as CSV or JSON. Names stay masked and no face images are included.
- Select a case to open `/kyc/cases/`. The tabs follow the steps that ran: Overview, Document, Face & liveness, Voice, Evidence, Checks & scores, Timeline & audit, Consent. Link to a tab with `?tab=`, for example `?tab=timeline`.
- Original media is sealed. **Unlock evidence** asks for step-up once, then loads items on demand and audits each one. A role without evidence access sees findings and measurements, not the originals.
- **Timeline & audit** ends with the evidence access audit: who opened which evidence object, and when.
- Showing personal details on a case is audited before it is returned. If the audit entry cannot be written, Backoffice withholds the details instead.
- **Delete verification** (on a case) and the row checkboxes with **Delete selected** (on the list, up to 25 at a time) are visible to administrators only. The dialog asks for a reason of 3 to 500 characters and a typed confirmation phrase, and the action asks for step-up. A delete removes the verification and its evidence files, keeps the billing usage records, the legal-basis receipts and the audit trail, and cannot be undone. A legal hold or an open erasure request blocks it. Steps and refusals: [Verification data](https://noxtica.com/docs/identity-verification-data/).
### 4. Work the review queue
Open Backoffice → Identity Verification → KYC Review Queue (`/kyc/review-queue`). It lists verifications that need attention: a verdict of Unverified or Failed, or the reason code **Manual review requested** (`provider_manual_review`). A finished hosted capture currently waits here. The queue filters the pages already loaded; select **Load more** to reach older rows.
1. Read the row: Subject, Verdict, Review state (Open, In review, Approved, Overridden, Closed), Reason codes and Created. Select **Open case** and read the evidence before you decide.
2. Select **Reason codes, note & history** to attach reason codes (up to 10 from the closed list) and an optional note of up to 2000 characters, and to see the timeline of the automated checks and the linked hosted session.
3. Choose one decision and confirm the dialog. **Approve** and **Override** record that you affirm or overrule the result. **Record escalation** routes the case to deeper review without affirming or overriding the result.
4. Complete the step-up check when asked. The row shows the new review state.
The same three decisions (Approve, Override, Escalate) are on the **Overview** tab of a case, with one reason code and a note.
What a decision does:
- It needs an administrator and step-up. In the queue an analyst can select the buttons but the server refuses the decision. The case page hides them and says "Recording a review requires KYC management permission and fresh MFA."
- It writes a versioned review record and an audit entry. It never changes the stored verdict of the verification.
- For a hosted session in `review_pending`, Approve or Override moves the session to `completed` and sends `kyc.session.completed` to subscribed endpoints. Escalate does not touch the session. The page has no Reject decision.
- Two people deciding at once: the second gets "This verification was reviewed in another session — reload and retry".
### 5. Follow a process end to end
Open Backoffice → Identity Verification → KYC, then **KYC Processes** in the directory (`/kyc/processes`). Each row is one customer attempt, either a **Hosted session** or an **S2S verification** (started by your server).
- Filter by status, document type, or search by session or subject id. Statuses include Awaiting review, Submitted, Verified, Unverified, Error, Expired and Cancelled by user. A recorded review decision (Approved, Overridden, In review) replaces the session status.
- Select **View** for the detail: the hosted-session timeline, the verification and decision, failures and retakes, evidence objects (kind, state and quality, never the content), the stage results and **Webhook deliveries**.
- Webhook deliveries lists each event with Event, State, Attempts and Created. It shows no signing secret and no endpoint address. Use it after a decision to confirm the event was queued and delivered, then compare with your endpoint logs.
- A process with no hosted link reads "Not hosted-originated — a tenant S2S verification." A hosted session that has not reached submit reads "Not yet admitted".
### 6. Author policies and work screening cases
Availability depends on the review-policy and advisory screening modules enabled for your organisation.
**KYC Policies** (`/kyc/policies`) has three panels.
- **Review policies.** Select **New policy** and set Priority, Action (Allow, Challenge or Block), Enabled, Shadow and a Condition as a JSON object. A new rule starts disabled and in shadow, which means it is logged and does not act. Take a rule out of shadow with **Graduate**, which asks for step-up; editing cannot do it. Graduating does not by itself make a rule challenge or block anything.
- **Response-side enforcement.** An administrator arms or disarms it for your organisation. A rule acts on a live verification when enforcement is armed, the rule is graduated and the rule resolves an acting decision; all three must hold. Disarm stops every rule at once. Ask your account team before you rely on enforcement.
- **Screening hits** and **Corpus versions.** Hits are advisory: subject, best score, matches and outcome (Clear, Potential match, Not evaluated, Evaluation error). Corpus versions show provenance of the shared screening corpus; changing the serving pin is a platform operator action.
**KYC Screening Cases** (`/kyc/screening-cases`) is casework on advisory hits. The page says it makes no enforcement decisions.
1. Open a case from the list (State, Owner, Priority, Corpus version, Updated).
2. Move it through the states: Potential match → Triaged → Investigating. From Investigating choose a disposition: **Clear as false positive**, **Confirm match**, **Mark insufficient data** or **Escalate for enhanced review**.
3. After Confirm match you can **Mark action pending** and then **Record action taken**. A case with a final disposition can be reopened.
4. Every change needs a rationale (up to 2000 characters) and step-up. **Save assignment and priority** sets the Owner ID and Low, Normal or High priority.
5. Reopening needs a different evidence reference or a newer complete corpus version.
**KYC Rescreening** (`/kyc/rescreening`) is read-only. It shows coverage by corpus version, corpus deltas and tenant hit volume. It states that per-run history is not recorded.
### 7. Run assisted recovery
Availability depends on the trusted-device registry module enabled for your organisation.
Open Backoffice → Identity Verification → Assisted Recovery (`/kyc/recovery`). Two tabs: **Recovery cases** and **Recovery appeals**. Every action asks for step-up and is audited.
1. In **Recovery cases** read Tier, Status, Readiness and the SLA badges (On track, Overdue, Escalated).
2. Use the action the case needs: **Vouch** (trusted referee), **Approve** (one of two required approvers), **Record fraud verdict**, **Block** (when the required operations lane is unavailable) or **Resolve**.
3. Resolution needs a referee vouch, or two distinct approvers plus a cleared fraud review. A different operator than the approvers must resolve.
4. In **Recovery appeals** select **Resolve** and choose Upheld, Overturned or Expired.
### 8. Manage agent delegations (KYA × KYC)
Availability depends on the agent-delegation module enabled for your organisation.
Open Backoffice → Identity Verification → Agent Delegations (`/kyc/agent-delegations`). The table shows an opaque delegation id, principal type, scope, audience, activity (Minted, Presented, Verified, Refused, Revoked), expiry and revocation state. It shows no subject identity.
- **Revoke** ends a delegation. An analyst can do it with step-up. It cannot be undone.
- **New Delegation** needs an administrator and step-up. Enter Audience and Scope as lowercase letters, digits and `:._-` (1 to 64 characters), choose the Principal type, and optionally a TTL in minutes. The server clamps the maximum.
### 9. Open sensitive evidence when a decision needs it
Availability depends on raw-evidence storage being enabled for your organisation.
Open Backoffice → Identity Verification → Evidence Access (`/kyc/evidence`), or **Unlock evidence** on a case. The list is by session and shows metadata without step-up.
1. Select a session, then **View evidence**.
2. Pick the **Access purpose** from the closed list: Identity verification, Document authenticity, Liveness check, Address verification, Manual review or Regulatory audit.
3. Complete step-up. The evidence opens in memory in the viewer; closing it clears the decrypted bytes. No public address exists for it.
4. **Download metadata manifest (CSV)** exports metadata and **Audit trail** lists the access claims and audit events for one object. Both ask for step-up.
If the audit entry for a view cannot be committed, the view is blocked. Reading evidence does not delete it: see [Verification data](https://noxtica.com/docs/identity-verification-data/).
### 10. Review passkeys, customer step-up and device trust
Availability depends on the passkey and trusted-device registry modules enabled for your organisation.
- **Passkeys** (`/kyc/passkey-credentials`) lists registered credentials with Status Active or Revoked. **Revoke** is permanent. The **AAGUID trust policy** section sets a rule per authenticator model: Decision Allow, Require attestation or Block, and Enforcement Shadow (rules are logged and do not act; the default) or Enforce. Revoking and editing rules need an administrator and step-up.
- **Step-Up Verification** (`/kyc/step-up`) is read-only: the declared step-up configuration (not the live runtime value), the count of successful step-ups and the reason-code catalog. It says no health probe exists and failed attempts leave no row.
- **Device Registry** (`/kyc/device-registry`) lists trusted-device links with Verification level and Status (Proofed (unbound), Bound, Active, Suspended, Revoked, Migrated, Tenant terminated). **Suspend** is reversible, **Revoke** is permanent. The page has no reinstate control.
- **Device Topology Policy** (`/kyc/device-topology`) sets **Maximum active devices** (1 to 100, or blank for no cap), **Shared and delegated device handling** and **Unmanaged-device handling** (Allow or Step up). Select **Save policy**. Analysts see it read-only.
## Verify it works
- The KYC overview shows the setup confirmation line, and a test invitation ([Invitations](https://noxtica.com/docs/identity-verification-invitations/)) appears in KYC Verifications and the Review Queue.
- After Approve or Override, the row shows Approved or Overridden, the case Overview shows the new version, and a hosted session leaves Awaiting review.
- Your endpoint receives `kyc.session.completed`, and the process detail lists it under **Webhook deliveries**.
- A viewed evidence object appears in the Evidence access audit of the case and in the object's **Audit trail**.
- A saved policy, topology setting or trust rule reads back after you reload the page.
## Troubleshooting
| Symptom | Cause | Fix |
| --- | --- | --- |
| "KYC verification is not enabled", or "KYC is not included in your plan" | The module is not enabled for your organisation. | Ask your account team. |
| "Passkey module is not enabled", "Device registry is not enabled", "Agent delegation is not enabled", "Recovery operations are not enabled", "Screening cases are not enabled", "KYC rescreening is not enabled" | That page's module is not enabled. | Ask your account team. |
| The step-up dialog appears again | The completed check is older than 360 minutes. | Complete it again. Enrol MFA first if you have none. |
| Approve or Override fails with a message about the legal basis | No active legal basis covers the capture surface. | Record it under KYC Invitations → Settings. |
| "This verification was reviewed in another session — reload and retry" | Someone else recorded a decision. | Reload, read the new state and decide again if needed. |
| "This verification's review is closed and cannot be changed" | The review state is Closed. | No further decision can be recorded; read the recorded decision. |
| The queue shows "Nothing to review" | No loaded row has an Unverified or Failed verdict or a manual review reason. | Select **Load more** or check KYC Verifications. |
| "Original media is sealed" or "Evidence access required" | Step-up not done, or your role lacks evidence access. | Select **Unlock evidence**, or ask an administrator. |
| "The view was blocked because its audit event could not be committed" | Evidence views fail closed when the audit entry fails. | Try again later. |
| "A different operator must approve or resolve this recovery case." | Recovery needs separate operators. | Ask another administrator. |
| "Use Graduate to take a rule out of shadow." | A policy edit tried to switch Shadow off. | Use **Graduate**. |
| "Provide a newer indexed corpus version or a new usable evidence reference." | A screening case reopen lacks new input. | Add one of the two. |
| "Policy changed in another session. Reloaded the current policy." | Two people edited the topology policy. | Review the reloaded values and save again. |
| "Scheduled rescreening is disabled" | The scheduler that runs rescreening is switched off for this deployment. | Ask your account team. |
## Related
- [Invitations and hosted verification settings](https://noxtica.com/docs/identity-verification-invitations/): create links, set up the hosted page and the legal basis.
- [Identity verification integration](https://noxtica.com/docs/identity-verification-integration/): create sessions from your server.
- [Identity verification events and webhooks](https://noxtica.com/docs/identity-verification-webhooks/): the events a decision sends.
- [Noxtica Verification ID (NVID)](https://noxtica.com/docs/identity-verification-id/): revoke or resend an ID from a case.
- [Verification data: storage, access and deletion](https://noxtica.com/docs/identity-verification-data/): who sees evidence and how an administrator deletes data.
- [Identity verification FAQ and troubleshooting](https://noxtica.com/docs/identity-verification-faq/): session statuses and common questions.
- [Backoffice guide](https://noxtica.com/docs/backoffice/overview/): navigation, roles and shortcuts.
- [Privacy Policy](https://noxtica.com/privacy/) and [Security page](https://noxtica.com/docs/security/): how Noxtica handles personal data.
---
Source: https://noxtica.com/docs/api/webhooks/
Markdown: https://noxtica.com/docs/api/webhooks/index.md
Last updated: 2026-10-27
# API webhooks
Noxtica sends signed HTTPS requests, called deliveries, to the endpoints you register in the Backoffice under Integrations & API, Webhooks. A delivery tells your system that something happened. Treat it as a notification and read the current state from the API before you act on it.
The signing secret of an endpoint is shown once when the endpoint is created or rotated. Store it like an API key.
## Delivery request
Each delivery is a `POST` with a JSON body. These headers accompany it:
| Header | Required | Description |
| --- | --- | --- |
| `X-Noxtica-Signature` | Yes | `sha256=` followed by the lowercase hex HMAC-SHA256 of the string `.`, keyed with the endpoint's signing secret (the secret string's UTF-8 bytes). Verify against the raw body bytes before parsing, with a constant-time comparison. |
| `X-Noxtica-Timestamp` | Yes | Unix time in milliseconds at which this attempt was signed. Every retry is re-signed with a fresh timestamp, so compare it with your own clock (a 300 second tolerance is recommended; Noxtica itself enforces none), not with the body's `created_at`. |
| `X-Noxtica-Event` | Yes | The event type; equals `type` in the body. |
| `X-Noxtica-Delivery` | Yes | The delivery id; equals `id` in the body and `data.deliveryId`. It is identical on every retry of the same delivery: use it as the deduplication key. |
Every delivery body is a JSON object with the top-level fields `id`, `type`, `created_at`, `tenant_id`, `data`. The content of `data` depends on the event and is described with each event below.
## Verify the signature
The signature header holds `sha256=` followed by the lowercase hexadecimal HMAC-SHA256 of the string `.`, keyed with the signing secret of the endpoint. Compute it over the raw body bytes before you parse the JSON, compare it in constant time, and reject a delivery whose timestamp is outside a tolerance you choose. The samples use five minutes. The timestamp is in milliseconds since the Unix epoch.
**Node.js**
```js
import { createHmac, timingSafeEqual } from 'node:crypto';
const TOLERANCE_MS = 5 * 60 * 1000;
export function verifyWebhook({ secret, rawBody, signature, timestamp }) {
const age = Math.abs(Date.now() - Number(timestamp));
if (!Number.isFinite(age) || age > TOLERANCE_MS) return false;
const expected = createHmac('sha256', secret).update(`${timestamp}.`).update(rawBody).digest('hex');
const received = String(signature).replace(/^sha256=/, '').toLowerCase();
const a = Buffer.from(expected);
const b = Buffer.from(received);
return a.length === b.length && timingSafeEqual(a, b);
}
```
**Python**
```python
import hashlib
import hmac
import time
TOLERANCE_MS = 5 * 60 * 1000
def verify_webhook(secret: str, raw_body: bytes, signature: str, timestamp: str) -> bool:
try:
sent = int(timestamp)
except ValueError:
return False
if abs(time.time() * 1000 - sent) > TOLERANCE_MS:
return False
signed = timestamp.encode() + b"." + raw_body
expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
received = signature.removeprefix("sha256=").lower()
return hmac.compare_digest(expected, received)
```
**Shell (openssl)**
```bash
printf '%s.%s' "$TIMESTAMP" "$RAW_BODY" \
| openssl dgst -sha256 -hmac "$WEBHOOK_SECRET"
```
Compare the printed hexadecimal digest with the part of the signature header after `sha256=`.
## Delivery, retries and deduplication
Answer every delivery with a `2xx` status as soon as you have stored it, and process it afterwards. The delivery header is the same on every retry of one delivery, so use it as the deduplication key.
Noxtica sends events to the HTTPS endpoints your organisation registers in the Backoffice
(Integrations & API, Webhooks); an endpoint receives only the event types ticked on it. An
endpoint URL must be HTTPS without embedded credentials and must not point at a private,
loopback or internal address, and an organisation can register at most 25 endpoints. The
signing secret is shown once when the endpoint is created or rotated; a rotation invalidates
the old secret at once.
**Request.** Each delivery is `POST` with `Content-Type: application/json` and the headers
`X-Noxtica-Signature`, `X-Noxtica-Timestamp` (Unix **milliseconds**), `X-Noxtica-Event` and
`X-Noxtica-Delivery`. The body is the envelope `{"id","type","created_at","tenant_id","data"}`:
`id` equals `X-Noxtica-Delivery`, `created_at` is Unix milliseconds and `tenant_id` is your
organisation. Verdict payloads carry no raw IP address and no personal data.
**Signature.** `X-Noxtica-Signature` is `sha256=` plus the lowercase hex HMAC-SHA256, keyed with
the endpoint's secret (its UTF-8 bytes), of the string `.`.
Recompute it over the raw body bytes before parsing the JSON, compare in constant time, and
reject a stale timestamp (Noxtica enforces no tolerance of its own; 300 seconds is
recommended). Every retry is re-signed with a fresh timestamp.
```js
import { createHmac, timingSafeEqual } from 'node:crypto';
function verify(secret, timestamp, rawBody, signatureHeader) {
const expected = createHmac('sha256', secret).update(`${timestamp}.${rawBody}`).digest('hex');
const given = signatureHeader.replace(/^sha256=/, '').toLowerCase();
return given.length === expected.length && timingSafeEqual(Buffer.from(given), Buffer.from(expected));
}
```
**Delivery and retries.** Delivery is at-least-once, never exactly-once: deduplicate on
`X-Noxtica-Delivery`, which is identical on every retry of the same delivery. Answer within
5 seconds; redirects are never followed. Any `2xx` marks the delivery delivered. **Any `4xx`
(including `408` and `429`) is final: it is never retried.** A `3xx`, a `5xx`, a timeout or a
network error is retried, up to 5 retries after the first attempt, after which the delivery is
recorded as dead and is not retried again. The spacing between retries is not published.
Respond `2xx` first and process asynchronously. Events can arrive out of order. A webhook is a
notification, not authority: read the resource it refers to before taking an irreversible
action. The Backoffice "Send test" button sends only a sample `submission.scored` event.
## Event catalog
| Event | Sent when | API |
| --- | --- | --- |
| [`kyc.session.completed`](https://noxtica.com/docs/api/webhooks/#kycWebhookSessionCompleted) | A hosted verification session reached a business outcome | Identity verification API |
| [`kyc.session.cancelled`](https://noxtica.com/docs/api/webhooks/#kycWebhookSessionCancelled) | The end customer cancelled a hosted verification session | Identity verification API |
| [`kyc.verification.completed`](https://noxtica.com/docs/api/webhooks/#kycWebhookVerificationCompleted) | A KYC verification request reached a terminal state | Identity verification API |
| [`kyc.erasure.completed`](https://noxtica.com/docs/api/webhooks/#kycWebhookErasureCompleted) | A KYC erasure request finished successfully | Identity verification API |
| [`kyc.document.expiry_warning`](https://noxtica.com/docs/api/webhooks/#kycWebhookDocumentExpiryWarning) | A verified identity document is approaching or past its expiry | Identity verification API |
| [`kyc.reverification.due`](https://noxtica.com/docs/api/webhooks/#kycWebhookReverificationDue) | A previously verified identity is due for re-verification | Identity verification API |
| [`submission.scored`](https://noxtica.com/docs/api/webhooks/#webhookSubmissionScored) | A submission was scored | Device intelligence API |
| [`risk.high`](https://noxtica.com/docs/api/webhooks/#webhookRiskHigh) | A submission was scored high or critical | Device intelligence API |
| [`risk.flagged`](https://noxtica.com/docs/api/webhooks/#webhookRiskFlagged) | A risk flag fired | Device intelligence API |
| [`risk.cluster_flagged`](https://noxtica.com/docs/api/webhooks/#webhookRiskClusterFlagged) | A device cluster was flagged as bad | Device intelligence API |
| [`account.agent_linked`](https://noxtica.com/docs/api/webhooks/#webhookAccountAgentLinked) | A verified agent was linked to an account for the first time | Device intelligence API |
## kyc.session.completed {#kycWebhookSessionCompleted}
A hosted verification session reached a business outcome
Sent by Noxtica to every endpoint you registered for `kyc.session.completed`
(Backoffice, Integrations & API, Webhooks). See "Webhooks (KYC)" in the API description
for the headers, the signature, retries and deduplication; they are common to all six
KYC events.
**When it fires.** A hosted session reached `completed`, `unverified` or `error`.
**It does not fire when a session lands in `review_pending`.** With the identity provider
configured today, a successful hosted capture ends in `review_pending` (the provider
routes every success to manual review, reason code `provider_manual_review`); the event
is sent later, when a Backoffice reviewer approves or overrides the case and the session
moves `review_pending` to `completed`. Allow up to about 5 minutes between the reviewer's
decision and the delivery (the relay runs on the platform's 5-minute tick). A
`review_pending` session never expires, so your system must keep waiting for the
decision (or poll `GET /v1/kyc/sessions/{sessionId}`). It never fires for `expired`
or `cancelled_by_user` sessions.
This is a notification, not authority: before you act on it, read
`GET /v1/kyc/sessions/{sessionId}`. The payload carries no subject reference; correlate
by `data.sessionId`, the id you stored when you minted the session.
### Payload
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | The delivery id, `:`. Identical on every retry; equals `X-Noxtica-Delivery` and `data.deliveryId`. |
| `type` | string | Yes | Allowed values: `kyc.session.completed`. |
| `created_at` | integer (int64) | Yes | Unix ms the event occurred. |
| `tenant_id` | string | Yes | |
| `data` | object (KycSessionCompletedWebhookData) | Yes | The `data` member of `kyc.session.completed` (`schemaVersion` `"1"`). Delivery is at-least-once: deduplicate by `deliveryId`. A webhook is a notification, not authority; read `GET /v1/kyc/sessions/{sessionId}` for the outcome. There is no subject reference, digest, evidence id or scorecard. The event does not fire when a session lands in `review_pending`; it fires when a reviewer's decision moves it to `completed`. `email` and `emailVerified` (added 2026-10-01, additive) are present only when hosted email verification is enabled for the platform AND the session has a stored address; otherwise both keys are absent. |
| `data.schemaVersion` | string | Yes | Allowed values: `1`. |
| `data.sessionId` | string (uuid) | Yes | The id the mint call returned. |
| `data.status` | string | Yes | The terminal session status. `expired` and `cancelled_by_user` sessions never emit this event. Allowed values: `completed`, `unverified`, `error`. |
| `data.verificationId` | string, nullable | Yes | |
| `data.reasonCodes` | array of string | Yes | |
| `data.occurredAt` | integer (int64) | Yes | Unix ms the session reached this status (its `completedAt`). |
| `data.deliveryId` | string | Yes | |
| `data.nvid` | string | No | The session's Noxtica Verification ID (`NVID-XXXX-XXXX-XXXX-XXXX`). Present only when the session has one (the feature is enabled for your organisation and the outcome was positive); otherwise absent. Never accompanied by the address the person may have given to receive it. |
| `data.email` | string | No | Present only when the session has a stored address (and hosted email verification is enabled for the platform). The normalised address the end customer entered in the hosted flow. Unverified unless `emailVerified` is `true`. |
| `data.emailVerified` | boolean | No | Present together with `email`. `true` only if the customer clicked the confirmation link for `email`. |
### Example payload
```json
{
"id": "6d3c3a8e-6b4b-4a8f-8f4e-0a0e6b3d9d21:wh_7f3a2c",
"type": "kyc.session.completed",
"created_at": 1790762445000,
"tenant_id": "tenant_42",
"data": {
"schemaVersion": "1",
"sessionId": "6d3c3a8e-6b4b-4a8f-8f4e-0a0e6b3d9d21",
"status": "completed",
"verificationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"reasonCodes": [],
"occurredAt": 1790762445000,
"deliveryId": "6d3c3a8e-6b4b-4a8f-8f4e-0a0e6b3d9d21:wh_7f3a2c"
}
}
```
## kyc.session.cancelled {#kycWebhookSessionCancelled}
The end customer cancelled a hosted verification session
Sent when the customer confirms on the hosted page that they do not want to continue and
the session actually moves to `cancelled_by_user`. Available only when session
cancellation is enabled for your organisation. Subscriptions are opt-in per event: an
endpoint registered before this event existed does not receive it until you add it to the
endpoint's event list.
`data.cancelReason` and `data.cancelledAt` are delivered only in this event.
`GET /v1/kyc/sessions/{sessionId}` reports the terminal status `cancelled_by_user` but does
not return the cancel reason or the cancel time. An expiry emits no event; observe it by
reading the session status.
See "Webhooks (KYC)" in the API description for headers, signature, retries and
deduplication.
### Payload
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | The delivery id, `:`. |
| `type` | string | Yes | Allowed values: `kyc.session.cancelled`. |
| `created_at` | integer (int64) | Yes | Unix ms the event occurred. |
| `tenant_id` | string | Yes | |
| `data` | object (KycSessionCancelledWebhookData) | Yes | The `data` member of `kyc.session.cancelled` (`schemaVersion` `"1"`). Same delivery semantics as `KycSessionCompletedWebhookData`. `email` and `emailVerified` (added 2026-10-01, additive) are present only when hosted email verification is enabled for the platform AND the session has a stored address; otherwise both keys are absent. |
| `data.schemaVersion` | string | Yes | Allowed values: `1`. |
| `data.sessionId` | string (uuid) | Yes | |
| `data.status` | string | Yes | Allowed values: `cancelled_by_user`. |
| `data.cancelReason` | one of KycSessionCancelReason or any, nullable | Yes | |
| `data.cancelledAt` | integer (int64) | Yes | Unix ms. |
| `data.occurredAt` | integer (int64) | Yes | Unix ms; equal to `cancelledAt`. |
| `data.deliveryId` | string | Yes | |
| `data.email` | string | No | Present only when the session has a stored address (and hosted email verification is enabled for the platform). The normalised address the end customer entered before cancelling. Unverified unless `emailVerified` is `true`. |
| `data.emailVerified` | boolean | No | Present together with `email`. `true` only if the customer clicked the confirmation link for `email`. |
### Example payload
```json
{
"id": "6d3c3a8e-6b4b-4a8f-8f4e-0a0e6b3d9d21:wh_7f3a2c",
"type": "kyc.session.cancelled",
"created_at": 1790762300000,
"tenant_id": "tenant_42",
"data": {
"schemaVersion": "1",
"sessionId": "6d3c3a8e-6b4b-4a8f-8f4e-0a0e6b3d9d21",
"status": "cancelled_by_user",
"cancelReason": "not_now",
"cancelledAt": 1790762300000,
"occurredAt": 1790762300000,
"deliveryId": "6d3c3a8e-6b4b-4a8f-8f4e-0a0e6b3d9d21:wh_7f3a2c"
}
}
```
## kyc.verification.completed {#kycWebhookVerificationCompleted}
A KYC verification request reached a terminal state
Sent when a verification request (`POST /v1/kyc/verify`, or the verification a hosted
session runs when the customer submits) reaches a terminal state: `completed`,
`terminal_error`, `expired` or `cancelled`. The non-terminal states `retryable_error`
and `provider_unknown` emit nothing. `data.verdict` is the stored canonical verdict
(`verified`, `unverified` or `error`; `error` for an infrastructure-faulted terminal
request that has no verdict).
A hosted session's submit runs the same pipeline, so an endpoint subscribed to both events
can receive `kyc.verification.completed` for the same attempt as
`kyc.session.*`; with the identity provider configured today the verdict of a successful
hosted capture is `unverified` with the reason code `provider_manual_review`. Delivery
order between the two events is not guaranteed. `data.verificationId` equals
`session.verificationId` on the session status read.
See "Webhooks (KYC)" in the API description for headers, signature, retries and
deduplication.
### Payload
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | The delivery id, `:`. |
| `type` | string | Yes | Allowed values: `kyc.verification.completed`. |
| `created_at` | integer (int64) | Yes | Unix ms the event occurred. |
| `tenant_id` | string | Yes | |
| `data` | object (KycVerificationCompletedWebhookData) | Yes | The `data` member of `kyc.verification.completed` (`schemaVersion` `"1"`). A closed, non-personal field set: no subject id, digest or document value. Deduplicate by `deliveryId`; read the verification through the API before acting. |
| `data.schemaVersion` | string | Yes | Allowed values: `1`. |
| `data.verificationId` | string | Yes | |
| `data.verdict` | string | Yes | Allowed values: `verified`, `unverified`, `error`. |
| `data.reasonCodes` | array of string | Yes | Closed reason-code catalog; may be empty. |
| `data.idType` | string | Yes | The document type asserted on the request, e.g. `passport`. |
| `data.occurredAt` | integer (int64) | Yes | Unix ms the verification reached its terminal state. |
| `data.deliveryId` | string | Yes | |
### Example payload
```json
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6:wh_7f3a2c",
"type": "kyc.verification.completed",
"created_at": 1790762440000,
"tenant_id": "tenant_42",
"data": {
"schemaVersion": "1",
"verificationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"verdict": "unverified",
"reasonCodes": [
"provider_manual_review"
],
"idType": "passport",
"occurredAt": 1790762440000,
"deliveryId": "3fa85f64-5717-4562-b3fc-2c963f66afa6:wh_7f3a2c"
}
}
```
## kyc.erasure.completed {#kycWebhookErasureCompleted}
A KYC erasure request finished successfully
Sent when an erasure request reaches `completed`. A `partial` erasure never emits this
event. The payload deliberately carries no subject identifier or subject digest: an erasure
notification must not re-establish a link to the person whose linkage was just erased.
`data.requestId` is the erasure request's own id.
See "Webhooks (KYC)" in the API description for headers, signature, retries and
deduplication.
### Payload
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | The delivery id; equals `data.deliveryId`. |
| `type` | string | Yes | Allowed values: `kyc.erasure.completed`. |
| `created_at` | integer (int64) | Yes | Unix ms the event occurred. |
| `tenant_id` | string | Yes | |
| `data` | object (KycErasureCompletedWebhookData) | Yes | The `data` member of `kyc.erasure.completed` (`schemaVersion` `"1"`). Emitted only when the erasure request reaches `completed`; a `partial` erasure emits nothing. No subject identifier is carried. |
| `data.schemaVersion` | string | Yes | Allowed values: `1`. |
| `data.requestId` | string | Yes | The erasure request's own id; not a subject id. |
| `data.outcome` | string | Yes | Allowed values: `completed`. |
| `data.occurredAt` | integer (int64) | Yes | Unix ms the erasure request reached its terminal state. |
| `data.deliveryId` | string | Yes | |
### Example payload
```json
{
"id": "er_4b81d2:wh_7f3a2c",
"type": "kyc.erasure.completed",
"created_at": 1790900000000,
"tenant_id": "tenant_42",
"data": {
"schemaVersion": "1",
"requestId": "er_4b81d2",
"outcome": "completed",
"occurredAt": 1790900000000,
"deliveryId": "er_4b81d2:wh_7f3a2c"
}
}
```
## kyc.document.expiry_warning {#kycWebhookDocumentExpiryWarning}
A verified identity document is approaching or past its expiry
Sent by the scheduled document-expiry monitoring pass when a monitored verification's
document crosses the 90, 60 or 30 day threshold or has expired (`data.alertType`). Only
available when document-expiry monitoring is enabled for your organisation. Each
threshold fires once per monitored verification.
Unlike the other KYC events, this event is not read from the delivery ledger: the
scheduled pass makes a single signed delivery attempt to each subscribed endpoint and
does not retry a failed attempt. Deduplicate on the delivery id anyway, and use
`data.verificationId` to correlate with the original `kyc.verification.completed`.
See "Webhooks (KYC)" for headers and signature.
### Payload
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | The delivery id; equals `data.deliveryId`. |
| `type` | string | Yes | Allowed values: `kyc.document.expiry_warning`. |
| `created_at` | integer (int64) | Yes | Unix ms the event occurred. |
| `tenant_id` | string | Yes | |
| `data` | object (KycDocumentExpiryWarningWebhookData) | Yes | The `data` member of `kyc.document.expiry_warning` (`schemaVersion` `"1"`). No subject id and no document number: correlate by `verificationId`. |
| `data.schemaVersion` | string | Yes | Allowed values: `1`. |
| `data.verificationId` | string | Yes | |
| `data.alertType` | string | Yes | Allowed values: `expiry_90d`, `expiry_60d`, `expiry_30d`, `expiry_expired`. |
| `data.documentExpiresAt` | integer (int64) | Yes | Unix ms the monitored document expires (or expired). |
| `data.occurredAt` | integer (int64) | Yes | Unix ms the threshold crossing was detected. |
| `data.deliveryId` | string | Yes | |
### Example payload
```json
{
"id": "sched_91c0:wh_7f3a2c",
"type": "kyc.document.expiry_warning",
"created_at": 1798538000000,
"tenant_id": "tenant_42",
"data": {
"schemaVersion": "1",
"verificationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"alertType": "expiry_30d",
"documentExpiresAt": 1801130000000,
"occurredAt": 1798538000000,
"deliveryId": "sched_91c0:wh_7f3a2c"
}
}
```
## kyc.reverification.due {#kycWebhookReverificationDue}
A previously verified identity is due for re-verification
Sent by the same scheduled monitoring pass as `kyc.document.expiry_warning` when a
re-verification schedule entry reaches its due time. Only available when document-expiry
monitoring is enabled for your organisation, and only for a verification that has a
re-verification schedule entry. Single signed delivery attempt, no retry, as for
`kyc.document.expiry_warning`.
See "Webhooks (KYC)" in the API description for headers and signature.
### Payload
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | The delivery id; equals `data.deliveryId`. |
| `type` | string | Yes | Allowed values: `kyc.reverification.due`. |
| `created_at` | integer (int64) | Yes | Unix ms the event occurred. |
| `tenant_id` | string | Yes | |
| `data` | object (KycReverificationDueWebhookData) | Yes | The `data` member of `kyc.reverification.due` (`schemaVersion` `"1"`). No subject id. |
| `data.schemaVersion` | string | Yes | Allowed values: `1`. |
| `data.verificationId` | string | Yes | |
| `data.dueAt` | integer (int64) | Yes | Unix ms the re-verification became due. |
| `data.occurredAt` | integer (int64) | Yes | |
| `data.deliveryId` | string | Yes | |
### Example payload
```json
{
"id": "sched_92d1:wh_7f3a2c",
"type": "kyc.reverification.due",
"created_at": 1801130000000,
"tenant_id": "tenant_42",
"data": {
"schemaVersion": "1",
"verificationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"dueAt": 1801130000000,
"occurredAt": 1801130000000,
"deliveryId": "sched_92d1:wh_7f3a2c"
}
}
```
## submission.scored {#webhookSubmissionScored}
A submission was scored
Sent for every scored browser or app submission of your organisation (the broadest
subscription: use `risk.high` or `risk.flagged` if you only need the notable ones). The
Backoffice "Send test" button sends a sample of this event type, with placeholder verdict
data and a valid signature.
`data.event_id` is the request id of the submission: correlate it with the `X-Request-Id`
your browser integration received. `data.device_id` is the opaque device id
(`fingerprintId`). This is a notification, not authority; read the device
(`GET /v1/device/{deviceId}`) before taking an irreversible action.
See "Webhook delivery and retries" in the API description for the headers, the signature,
retries and deduplication.
### Payload
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | The delivery id; equals `X-Noxtica-Delivery`. |
| `type` | string | Yes | Allowed values: `submission.scored`, `risk.high`, `risk.flagged`, `risk.cluster_flagged`. |
| `created_at` | integer (int64) | Yes | Unix ms the event was produced. |
| `tenant_id` | string | Yes | |
| `data` | object (VerdictWebhookData) | Yes | The verdict of one scored submission. Never carries a raw IP address or personal data. |
| `data.score` | number | No | The numeric risk score. |
| `data.risk_level` | string | No | The verdict band, for example `low`, `medium`, `high` or `critical`. |
| `data.confidence` | number | No | Model confidence from 0 to 1. |
| `data.flags` | array of string | No | The risk flags that fired. |
| `data.reason_codes` | array of string | No | The published reason-code projection of `flags`; empty unless reason-code output is enabled for your organisation. |
| `data.device_id` | string | Yes | The opaque device id. An empty string means that no stable per-device identity is available for this event. |
| `data.domain_id` | string | Yes | Your domain id. |
| `data.event_id` | string | Yes | The request id of the submission or attestation; always present. |
### Example payload
```json
{
"id": "6d3c3a8e-6b4b-4a8f-8f4e-0a0e6b3d9d21",
"type": "submission.scored",
"created_at": 1790762445000,
"tenant_id": "YOUR_TENANT_ID",
"data": {
"score": 12,
"risk_level": "low",
"confidence": 0.91,
"flags": [],
"reason_codes": [],
"device_id": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
"domain_id": "dom_42",
"event_id": "8f1c2a52-6a6e-4b0e-9d52-2a7c1d9e4b10"
}
}
```
## risk.high {#webhookRiskHigh}
A submission was scored high or critical
Sent when a scored submission lands in the `high` or `critical` risk band. The payload is
the same verdict shape as `submission.scored`. A submission in that band also produces
`submission.scored` (and `risk.flagged` when a flag fired) for endpoints subscribed to
those types.
See "Webhook delivery and retries" in the API description for the headers, the signature,
retries and deduplication.
### Payload
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | The delivery id; equals `X-Noxtica-Delivery`. |
| `type` | string | Yes | Allowed values: `submission.scored`, `risk.high`, `risk.flagged`, `risk.cluster_flagged`. |
| `created_at` | integer (int64) | Yes | Unix ms the event was produced. |
| `tenant_id` | string | Yes | |
| `data` | object (VerdictWebhookData) | Yes | The verdict of one scored submission. Never carries a raw IP address or personal data. |
| `data.score` | number | No | The numeric risk score. |
| `data.risk_level` | string | No | The verdict band, for example `low`, `medium`, `high` or `critical`. |
| `data.confidence` | number | No | Model confidence from 0 to 1. |
| `data.flags` | array of string | No | The risk flags that fired. |
| `data.reason_codes` | array of string | No | The published reason-code projection of `flags`; empty unless reason-code output is enabled for your organisation. |
| `data.device_id` | string | Yes | The opaque device id. An empty string means that no stable per-device identity is available for this event. |
| `data.domain_id` | string | Yes | Your domain id. |
| `data.event_id` | string | Yes | The request id of the submission or attestation; always present. |
### Example payload
```json
{
"id": "0b9d7b1c-2f0e-4c8b-9a52-7c1b3a1f9e11",
"type": "risk.high",
"created_at": 1790762446000,
"tenant_id": "YOUR_TENANT_ID",
"data": {
"score": 87,
"risk_level": "high",
"confidence": 0.88,
"flags": [
"example_flag"
],
"reason_codes": [],
"device_id": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
"domain_id": "dom_42",
"event_id": "3a7d1e52-6a6e-4b0e-9d52-2a7c1d9e4b11"
}
}
```
## risk.flagged {#webhookRiskFlagged}
A risk flag fired
Sent when at least one risk flag fired on a scored submission, whatever its risk band.
The same event type is also sent after each mobile attestation `verify` (see
`POST /v1/attest/android` and `POST /v1/attest/ios`), with `flags` of the form
`mobile_attest:`, `mobile_attest_level:` and `mobile_attest_verdict:`.
There `data.device_id` can be an empty string, which means that no stable per-device
identity is available for the event: do not group events on an empty `device_id`, and use
`data.event_id`, which is always present, as the per-event key.
See "Webhook delivery and retries" in the API description for the headers, the signature,
retries and deduplication.
### Payload
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | The delivery id; equals `X-Noxtica-Delivery`. |
| `type` | string | Yes | Allowed values: `submission.scored`, `risk.high`, `risk.flagged`, `risk.cluster_flagged`. |
| `created_at` | integer (int64) | Yes | Unix ms the event was produced. |
| `tenant_id` | string | Yes | |
| `data` | object (VerdictWebhookData) | Yes | The verdict of one scored submission. Never carries a raw IP address or personal data. |
| `data.score` | number | No | The numeric risk score. |
| `data.risk_level` | string | No | The verdict band, for example `low`, `medium`, `high` or `critical`. |
| `data.confidence` | number | No | Model confidence from 0 to 1. |
| `data.flags` | array of string | No | The risk flags that fired. |
| `data.reason_codes` | array of string | No | The published reason-code projection of `flags`; empty unless reason-code output is enabled for your organisation. |
| `data.device_id` | string | Yes | The opaque device id. An empty string means that no stable per-device identity is available for this event. |
| `data.domain_id` | string | Yes | Your domain id. |
| `data.event_id` | string | Yes | The request id of the submission or attestation; always present. |
### Example payload
```json
{
"id": "9c1e5d2a-3b4f-4a6c-8d7e-1f2a3b4c5d6e",
"type": "risk.flagged",
"created_at": 1790762447000,
"tenant_id": "YOUR_TENANT_ID",
"data": {
"score": 40,
"risk_level": "medium",
"confidence": 0.7,
"flags": [
"example_flag"
],
"reason_codes": [],
"device_id": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
"domain_id": "dom_42",
"event_id": "5e8f2a52-6a6e-4b0e-9d52-2a7c1d9e4b12"
}
}
```
## risk.cluster_flagged {#webhookRiskClusterFlagged}
A device cluster was flagged as bad
Sent once, on the first escalation, when a cluster of devices (devices sharing an
observational sub-fingerprint) is flagged bad in real time because a high or critical
submission came with strong cluster evidence. It lets you react to an emerging cluster
before slower offline feeds catch up. A cluster that is already flagged does not produce
a new delivery for every further submission.
The payload has the same verdict shape as `submission.scored`; `data.risk_level` is the
cluster's band. It carries no raw IP address and no personal data. Available only when
real-time cluster propagation is enabled for the deployment.
See "Webhook delivery and retries" in the API description for the headers, the signature,
retries and deduplication.
### Payload
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | The delivery id; equals `X-Noxtica-Delivery`. |
| `type` | string | Yes | Allowed values: `submission.scored`, `risk.high`, `risk.flagged`, `risk.cluster_flagged`. |
| `created_at` | integer (int64) | Yes | Unix ms the event was produced. |
| `tenant_id` | string | Yes | |
| `data` | object (VerdictWebhookData) | Yes | The verdict of one scored submission. Never carries a raw IP address or personal data. |
| `data.score` | number | No | The numeric risk score. |
| `data.risk_level` | string | No | The verdict band, for example `low`, `medium`, `high` or `critical`. |
| `data.confidence` | number | No | Model confidence from 0 to 1. |
| `data.flags` | array of string | No | The risk flags that fired. |
| `data.reason_codes` | array of string | No | The published reason-code projection of `flags`; empty unless reason-code output is enabled for your organisation. |
| `data.device_id` | string | Yes | The opaque device id. An empty string means that no stable per-device identity is available for this event. |
| `data.domain_id` | string | Yes | Your domain id. |
| `data.event_id` | string | Yes | The request id of the submission or attestation; always present. |
### Example payload
```json
{
"id": "2a4c6e8f-1b3d-4f5a-9c7e-0d2b4f6a8c1e",
"type": "risk.cluster_flagged",
"created_at": 1790762448000,
"tenant_id": "YOUR_TENANT_ID",
"data": {
"score": 91,
"risk_level": "critical",
"confidence": 0.93,
"flags": [
"example_flag"
],
"reason_codes": [],
"device_id": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
"domain_id": "dom_42",
"event_id": "7a9b1c52-6a6e-4b0e-9d52-2a7c1d9e4b13"
}
}
```
## account.agent_linked {#webhookAccountAgentLinked}
A verified agent was linked to an account for the first time
Sent once, when a cryptographically verified signed agent (Web Bot Auth, RFC 9421) is linked
to one of your end-user accounts for the first time, that is when the (agent, account)
pair had no earlier link. It lets you react when a new agent starts acting on an account.
The payload carries the keyed `account_hash` (a 16-character lowercase-hex pseudonym; the
raw account id is never stored or sent), the verified agent's `agent_keyid` and
`agent_host`, and the usual `device_id`, `domain_id` and `event_id`. It carries no raw IP
address and no personal data. Use `GET /v1/accounts/{accountHash}/devices` to list the
devices and agents linked to the account.
See "Webhook delivery and retries" in the API description for the headers, the signature,
retries and deduplication.
### Payload
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes | The delivery id; equals `X-Noxtica-Delivery`. |
| `type` | string | Yes | Allowed values: `account.agent_linked`. |
| `created_at` | integer (int64) | Yes | Unix ms the event was produced. |
| `tenant_id` | string | Yes | |
| `data` | object (AgentLinkedWebhookData) | Yes | The first link between a verified agent and one of your accounts. Never carries a raw account id, IP address or personal data. |
| `data.account_hash` | string | Yes | The keyed 16-character lowercase-hex account pseudonym. |
| `data.agent_keyid` | string | Yes | The verified agent's `Signature-Input` key id. |
| `data.agent_host` | string, nullable | Yes | The verified agent's directory host |
| `data.device_id` | string | Yes | |
| `data.domain_id` | string | Yes | |
| `data.event_id` | string | Yes | |
### Example payload
```json
{
"id": "4d6f8a1c-5e7b-4d9f-8a2c-3b5d7f9a1c2e",
"type": "account.agent_linked",
"created_at": 1790762449000,
"tenant_id": "YOUR_TENANT_ID",
"data": {
"account_hash": "0a1b2c3d4e5f6071",
"agent_keyid": "agent-key-1",
"agent_host": "agent.example.com",
"device_id": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
"domain_id": "dom_42",
"event_id": "9b1d3f52-6a6e-4b0e-9d52-2a7c1d9e4b14"
}
}
```
_This page is generated from the Noxtica OpenAPI specification release `v0.4.0`: `kyc.yaml` version `1.2.0-2026-10-27` (SHA-256 `c91a695cfde0`), `mcp.yaml` version `0.1.0-2026-10-27` (SHA-256 `1a4875efa736`), `pulse.yaml` version `0.9.0-2026-10-27` (SHA-256 `95196a58bb5b`), `v1.yaml` version `1.3.0-2026-10-27` (SHA-256 `3fd15257a022`). Do not edit it by hand._
---
Source: https://noxtica.com/docs/identity-verification-webhooks/
Markdown: https://noxtica.com/docs/identity-verification-webhooks/index.md
Last updated: 2026-10-27
# Identity verification events and webhooks
Identity verification sends signed HTTPS events to endpoints you register in Backoffice, so your server does not have to poll for outcomes. A Backoffice administrator registers the endpoint. A backend engineer verifies each delivery, removes duplicates and reads the session status before acting.
## What it is
Availability: Controlled availability. Events belong to identity verification, which your account team provisions for your organisation. Events marked "when enabled for your organisation" depend on settings your account team controls.
An event is a notification, not a decision. Each delivery is a `POST` with a JSON envelope and four headers, signed with the signing secret of the endpoint that receives it. The six identity events are:
| Event | Fires when | Delivery |
| ----- | ---------- | -------- |
| `kyc.session.completed` | A hosted session reaches `completed`, `unverified` or `error`. A session in `review_pending` fires it later, when a reviewer approves or overrides the case. | Retried |
| `kyc.session.cancelled` | The customer cancels on the hosted page. Subscribe to it explicitly. When enabled for your organisation. | Retried |
| `kyc.verification.completed` | A verification reaches a final state, whether it came from a hosted session or from a direct API call. | Retried |
| `kyc.erasure.completed` | An erasure request reaches `completed`. A `partial` erasure sends nothing. When erasure is enabled for your organisation. | Retried |
| `kyc.document.expiry_warning` | A verified document is 90, 60 or 30 days from expiry, or has expired. When enabled for your organisation. | Single attempt |
| `kyc.reverification.due` | A scheduled re-verification becomes due. When enabled for your organisation. | Single attempt |
"Retried" means up to 5 more attempts (step 5). "Single attempt" means one try with no retry. A session that expires sends no event. Read its status to see `expired`. Events for business and merchant verification (`kyb.entity.*`, `kym.*`) are on [Business and merchant verification](https://noxtica.com/docs/identity-verification-business/). The generic envelope and header reference is on [Webhooks](https://noxtica.com/docs/api/webhooks/).
## Prerequisites
- Identity verification provisioned for your organisation. See [Identity verification integration](https://noxtica.com/docs/identity-verification-integration/).
- A Backoffice user with the administrator role. The Webhooks page is restricted to administrators, and every change asks for fresh step-up verification (MFA).
- A public HTTPS endpoint. Localhost, private addresses, internal names and URLs that carry a user name or password are refused. A custom HTTPS port is allowed.
- Room for the endpoint: an organisation can register up to 25 endpoints, and each URL can be registered once.
- A server-side secret store for the signing secret. The secret is shown once.
- An endpoint that answers within 5 seconds. That is the default wait for each attempt; bounds can change.
## Steps
### 1. Register the endpoint
1. Open Backoffice → Integrations & API → Webhooks (`/integrations/webhooks`). Stay on the "Manage" tab. The "Integration" tab holds the in-product guide.
2. Under "Add endpoint", enter the "Endpoint URL". Add a "Description (optional)" of up to 200 characters if you want one.
3. Under "Events to deliver", tick the identity events you need. Select at least one event.
4. Select "Add endpoint" and complete the step-up prompt.
5. Copy the secret from "Copy your signing secret now" into your server secret store, then select "I've copied it". Backoffice never shows it again.
The Backoffice label for each identity event:
| Event | Label in "Events to deliver" |
| ----- | ---------------------------- |
| `kyc.session.completed` | Hosted KYC session completed |
| `kyc.session.cancelled` | Hosted KYC session cancelled by the end user |
| `kyc.verification.completed` | KYC verification completed |
| `kyc.erasure.completed` | KYC erasure completed |
| `kyc.document.expiry_warning` | KYC document expiry warning |
| `kyc.reverification.due` | KYC re-verification due |
Subscriptions are per event. An endpoint receives the events you ticked, and an event type added to the platform later is not added to an existing endpoint.
### 2. Receive and acknowledge deliveries
Every delivery is an HTTPS `POST` with `Content-Type: application/json` and these headers:
| Header | Value |
| ------ | ----- |
| `X-Noxtica-Signature` | `sha256=` followed by the lowercase hex HMAC-SHA256 signature |
| `X-Noxtica-Timestamp` | The time of this attempt in epoch milliseconds. It changes on every retry. |
| `X-Noxtica-Event` | The event type, equal to `type` in the body |
| `X-Noxtica-Delivery` | The delivery id, equal to `id` in the body and to `data.deliveryId`. It stays the same across retries. |
The body is one envelope:
| Field | Meaning |
| ----- | ------- |
| `id` | The delivery id. Treat it as an opaque string. |
| `type` | The event type. |
| `created_at` | When the event occurred, in epoch milliseconds. It equals `data.occurredAt`. |
| `tenant_id` | Your organisation id. |
| `data` | The event fields in step 4. `schemaVersion` (`"1"`) sits inside `data`, not on the envelope. |
Answer with a `2xx` status and do the work afterwards. Noxtica does not follow redirect responses.
### 3. Verify the signature
The signature is an HMAC-SHA256 over `.`, keyed with the endpoint's signing secret as UTF-8 text. Verify it before you parse or trust anything in the body.
- Use the body exactly as received. Do not parse and re-serialise it.
- Compare in constant time.
- Check the timestamp header, not `created_at`. Every retry is signed again with a fresh timestamp.
- Noxtica enforces no timestamp window. Enforce your own; five minutes is a sensible tolerance.
```js
import { createHmac, timingSafeEqual } from 'node:crypto';
const TOLERANCE_MS = 5 * 60 * 1000;
export function verifyNoxticaWebhook({ secret, timestamp, signature, rawBody, now = Date.now() }) {
const sentAt = Number(timestamp);
if (!Number.isSafeInteger(sentAt) || Math.abs(now - sentAt) > TOLERANCE_MS) return false;
const expected = createHmac('sha256', secret).update(`${timestamp}.${rawBody}`).digest('hex');
const provided = String(signature).replace(/^sha256=/, '').toLowerCase();
const expectedBytes = Buffer.from(expected);
const providedBytes = Buffer.from(provided);
return expectedBytes.length === providedBytes.length && timingSafeEqual(expectedBytes, providedBytes);
}
```
Save the verifier above as `verify-noxtica-webhook.mjs`. This receiver keeps the raw body, deduplicates and acknowledges quickly:
```js
import { createServer } from 'node:http';
import { verifyNoxticaWebhook } from './verify-noxtica-webhook.mjs';
const seen = new Set(); // replace with a durable store shared by all your instances
createServer(async (req, res) => {
const chunks = [];
for await (const chunk of req) chunks.push(chunk);
const rawBody = Buffer.concat(chunks).toString('utf8');
const valid = verifyNoxticaWebhook({
secret: process.env.NOXTICA_WEBHOOK_SECRET,
timestamp: req.headers['x-noxtica-timestamp'],
signature: req.headers['x-noxtica-signature'],
rawBody,
});
if (!valid) return res.writeHead(401).end();
const deliveryId = req.headers['x-noxtica-delivery'];
if (!seen.has(deliveryId)) {
seen.add(deliveryId);
void handleEvent(JSON.parse(rawBody)); // step 5
}
res.writeHead(204).end();
}).listen(3000);
```
The same check in Python:
```python
import hashlib
import hmac
import time
TOLERANCE_MS = 5 * 60 * 1000
def verify_noxtica_webhook(secret: str, timestamp: str, signature: str, raw_body: bytes) -> bool:
if not (timestamp.isascii() and timestamp.isdigit()):
return False
if abs(time.time() * 1000 - int(timestamp)) > TOLERANCE_MS:
return False
signed = timestamp.encode() + b"." + raw_body
expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
provided = signature.removeprefix("sha256=").lower()
return hmac.compare_digest(expected, provided)
```
### 4. Handle each event
Every identity `data` object carries `schemaVersion` (`"1"`), `occurredAt` (epoch milliseconds) and `deliveryId`. No identity event carries your `subjectRef`, a name or a document value. `reasonCodes` come from a closed catalog; see [Server API reference](https://noxtica.com/docs/api/reference/kyc/). Ignore fields you do not recognise.
#### `kyc.session.completed`
The delivery id is `:`.
| Field | Meaning |
| ----- | ------- |
| `sessionId` | The `sessionId` you stored when you created the session. |
| `status` | `completed`, `unverified` or `error`. |
| `verificationId` | The verification case id, or `null` when no verification ran. |
| `reasonCodes` | An array of closed reason codes. It can be empty. |
| `nvid` | Optional. The Noxtica Verification ID, when one was issued. See [Noxtica Verification ID](https://noxtica.com/docs/identity-verification-id/). |
| `email`, `emailVerified` | Optional. The address the customer entered and whether they confirmed it. Present when email verification is enabled for your organisation and an address was entered. It is personal data. |
```json
{
"id": ":",
"type": "kyc.session.completed",
"created_at": 1790762445000,
"tenant_id": "",
"data": {
"schemaVersion": "1",
"sessionId": "",
"status": "completed",
"verificationId": "",
"reasonCodes": [],
"occurredAt": 1790762445000,
"deliveryId": ":"
}
}
```
A finished capture currently waits in `review_pending`. This event follows when a reviewer approves or overrides the case in Backoffice, normally within a few minutes of the decision.
#### `kyc.session.cancelled`
The delivery id is `:`. It fires once, when the customer's cancel moves the session to `cancelled_by_user`. A repeated cancel, a refused cancel and an expiry send nothing. Persist the reason from the event: the status read does not return it.
| Field | Meaning |
| ----- | ------- |
| `sessionId` | The session id. |
| `status` | Always `cancelled_by_user`. |
| `cancelReason` | `not_now`, `privacy_concern`, `no_document`, `technical_problem`, `other`, or `null`. |
| `cancelledAt` | When the customer cancelled, in epoch milliseconds. |
| `email`, `emailVerified` | Optional, as above. |
```json
{
"id": ":",
"type": "kyc.session.cancelled",
"created_at": 1790762300000,
"tenant_id": "",
"data": {
"schemaVersion": "1",
"sessionId": "",
"status": "cancelled_by_user",
"cancelReason": "not_now",
"cancelledAt": 1790762300000,
"occurredAt": 1790762300000,
"deliveryId": ":"
}
}
```
#### `kyc.verification.completed`
The delivery id is `:`. A hosted session runs a verification too, so an endpoint subscribed to both events can receive this one and `kyc.session.completed` for the same session. Correlate by `verificationId`. The order between the two is not fixed.
| Field | Meaning |
| ----- | ------- |
| `verificationId` | The verification id. It equals `session.verificationId` on the status read. |
| `verdict` | `verified`, `unverified` or `error`. |
| `reasonCodes` | An array of closed reason codes. It can be empty. |
| `idType` | The document type asserted on the request. |
```json
{
"id": ":",
"type": "kyc.verification.completed",
"created_at": 1790762440000,
"tenant_id": "",
"data": {
"schemaVersion": "1",
"verificationId": "",
"verdict": "unverified",
"reasonCodes": [""],
"idType": "passport",
"occurredAt": 1790762440000,
"deliveryId": ":"
}
}
```
#### `kyc.erasure.completed`
It fires when an erasure request reaches `completed`. It deliberately carries no subject identifier, so the notice cannot re-link to the person. Noxtica does not delete verification details or evidence automatically. An administrator deletes verifications in Backoffice → Identity Verification → KYC Verifications, which does not send this event, or works an erasure request in KYC Erasure, where a request is approved by an administrator other than the requester. See [Identity verification data](https://noxtica.com/docs/identity-verification-data/).
| Field | Meaning |
| ----- | ------- |
| `requestId` | The id of the erasure request. It is not a subject id. |
| `outcome` | Always `completed`. |
```json
{
"id": "",
"type": "kyc.erasure.completed",
"created_at": 1790900000000,
"tenant_id": "",
"data": {
"schemaVersion": "1",
"requestId": "",
"outcome": "completed",
"occurredAt": 1790900000000,
"deliveryId": ""
}
}
```
#### `kyc.document.expiry_warning` and `kyc.reverification.due`
A scheduled job sends both, when enabled for your organisation. The delivery id is `:`. Match `verificationId` to the original verification. Each threshold fires once and is attempted once, so a failed attempt is not retried. Reconcile from your own records if you miss one.
| Field | Event | Meaning |
| ----- | ----- | ------- |
| `verificationId` | both | The verification whose document is expiring, or that is due again. |
| `alertType` | expiry | `expiry_90d`, `expiry_60d`, `expiry_30d` or `expiry_expired`. |
| `documentExpiresAt` | expiry | When the document expires or expired, in epoch milliseconds. |
| `dueAt` | re-verification | When the re-verification became due, in epoch milliseconds. |
```json
{
"id": ":",
"type": "kyc.document.expiry_warning",
"created_at": 1798538000000,
"tenant_id": "",
"data": {
"schemaVersion": "1",
"verificationId": "",
"alertType": "expiry_30d",
"documentExpiresAt": 1801130000000,
"occurredAt": 1798538000000,
"deliveryId": ":"
}
}
```
### 5. Deduplicate, tolerate order and read the status
Delivery is at least once. Noxtica answers each outcome as follows:
| Your response | What happens |
| ------------- | ------------ |
| `2xx` | Delivered. |
| `4xx`, including `408` and `429` | Final. Not retried. Return a `4xx` when you mean it. |
| `3xx`, `5xx`, a timeout or a network error | Retried, up to 5 more attempts. The spacing is not published. |
| All retries fail | Marked `dead`. The endpoint stays enabled and Noxtica does not send the delivery again. |
| The URL is no longer a public HTTPS target | Refused and not retried. |
- Deduplicate on `X-Noxtica-Delivery`. Record it before you act.
- Do not rely on order. Two events for the same session can arrive in either order.
- There is no redelivery button and no replay API. To catch up, read the state: for hosted sessions, call the status read, and for a verification, open it in Backoffice → Identity Verification → KYC Verifications.
- Treat the event as a prompt, and the status read as the authority:
```js
async function handleEvent(event) {
if (event.type !== 'kyc.session.completed') return;
const response = await fetch(`https://collect.noxtica.com/v1/kyc/sessions/${event.data.sessionId}`, {
headers: { Authorization: `Bearer ${process.env.NOXTICA_SERVER_KEY}` },
});
const { session } = await response.json();
// Act on session.status. The "completed" status is the sole approval.
}
```
### 6. Rotate, disable or delete an endpoint
On the "Manage" tab of Backoffice → Integrations & API → Webhooks, each endpoint has these buttons:
- "Rotate secret" asks you to confirm "Rotate signing secret?". The current secret stops working immediately, with no overlap, and the new one is shown once. Update your receiver straight away. Retries still waiting are signed with the new secret.
- "Disable" stops deliveries to the endpoint and keeps it listed. "Enable" turns it back on.
- "Delete" removes the endpoint; deliveries to it stop immediately.
The tab has no editor for the event list of an existing endpoint. To change the events, delete the endpoint and add it again; the new endpoint has a new secret.
## Verify it works
1. On the endpoint row, select "Send test". Backoffice posts one signed sample, once, and shows "Test delivery succeeded" with the status and time. The row then shows the last status, for example `ok`.
2. Confirm that your receiver passed the signature check. The sample has the type `submission.scored`. It cannot produce an identity event, so it proves reachability and your signature code, not your identity handler.
3. Test the handler with a signed sample of your own for each identity event, or finish a hosted session from your server or from Backoffice → Identity Verification → KYC Invitations ("Create test session").
4. For a session or verification event, open Backoffice → Identity Verification → KYC → KYC Processes, select "View" on the process, and read the "Webhook deliveries" table. Its columns are Event, State, Attempts and Created. `delivered` means your endpoint answered `2xx`, `dead` means every retry failed, and `terminal` means a `4xx` or a refused URL ended it. The endpoint row's last status reflects "Send test" and non-identity events, not these deliveries.
## Troubleshooting
| Symptom | Cause | Fix |
| ------- | ----- | --- |
| "Send test" succeeds but no identity event arrives | The test sends `submission.scored`. The endpoint may not be subscribed to the identity event, may be disabled, or the event is not enabled for your organisation. | Check "Events to deliver", select "Enable" if needed, and ask your account team about gated events. |
| Signature check fails | The body was parsed and re-serialised, the secret is old after a rotation, the timestamp is read in seconds, or `created_at` was used instead of the header. | Hash the raw body, use the current secret, and use `X-Noxtica-Timestamp` in milliseconds. |
| Identity events never arrive for an endpoint that was created long ago | The endpoint was created before encrypted secret storage. Identity events are not delivered to it, and the delivery ends as `terminal`. | Select "Rotate secret" once, then update your receiver. |
| Events stop after you return `429` | Any `4xx` is final and is never retried. | Return `2xx` and queue the work. |
| An event arrives minutes after the reviewer's decision | Review decisions are sent on a periodic schedule. | Wait a few minutes. Read the status for the current state. |
| No event for `review_pending` or `expired` | Neither state sends an event. | Read the session status. |
| The same event arrives twice | Delivery is at least once, and an unconfirmed delivery can be sent again. | Deduplicate on `X-Noxtica-Delivery`. |
| A delivery shows `dead` | Every retry failed. | Fix the endpoint, then read the state from the status read. |
| "Send test" shows `blocked` or `http_0` | The URL is not a public HTTPS target. | Use a public HTTPS URL without credentials in it. |
| "That URL is already registered as a webhook endpoint" | The organisation has the URL already. | Use the existing endpoint, or delete it before you add it again. |
| "Webhook endpoints are limited to 25 per tenant" | The endpoint limit is reached. | Delete an endpoint you no longer use. |
## Related
- [Identity verification integration](https://noxtica.com/docs/identity-verification-integration/) — create sessions and read the status.
- [Noxtica Verification ID](https://noxtica.com/docs/identity-verification-id/) — the `nvid` field on events and the status read.
- [Business and merchant verification](https://noxtica.com/docs/identity-verification-business/) — `kyb.entity.*` and `kym.*` events.
- [Identity verification FAQ and troubleshooting](https://noxtica.com/docs/identity-verification-faq/) — duplicates, ordering and missing events.
- [Webhooks](https://noxtica.com/docs/api/webhooks/) — the generic envelope, headers and signature reference.
- [Errors](https://noxtica.com/docs/api/errors/) — error codes and the `requestId` to quote.
---
Source: https://noxtica.com/docs/backoffice/event-sinks/
Markdown: https://noxtica.com/docs/backoffice/event-sinks/index.md
Last updated: 2026-10-27
# Event sinks (SIEM export)
An event sink pushes Noxtica events to an HTTPS endpoint that you run, such as a SIEM collector. A workspace Admin creates the sink in Backoffice, arms it and checks delivery with a real test request. Use a sink when you want events in your own tooling without polling an API.
## What it is
Availability: Availability depends on your plan, role and the modules enabled for your organisation.
- **Where**: `Backoffice → Integrations & API → Event Sinks` (`/event-sinks`). The page title is **Event Sinks (SIEM)**. The sidebar item and the route need the Admin role.
- **What a sink holds**: a name (optional), an HTTPS endpoint, a format, a list of events, optional payload enrichments and a PII acknowledgement.
- **Events**: the sink subscribes to the same verdict event types as webhooks (see [Webhooks](https://noxtica.com/docs/api/webhooks/)), plus `audit.log` for the Backoffice audit stream and `compliance.evidence` for signed compliance evidence. A sink needs at least one event.
- **Payload enrichment**: the optional `incident.summary` token adds extra fields to every delivered record. It does not change which events are delivered.
- **Signing**: each sink has its own signing secret. Every delivery is an HMAC-signed HTTP POST, so your receiver can check it came from Noxtica.
- **Two keys for delivery**: creating a sink arms nothing. Delivery also needs your sink to be enabled and the platform event stream to be on for your workspace. If the page works but nothing arrives, the platform key is the usual reason; ask your account team.
- **Limit**: a workspace can hold up to 25 sinks.
Formats you can choose:
| Format label in Backoffice | Use for |
| --- | --- |
| Generic JSON webhook | Any HTTPS receiver that accepts JSON |
| Splunk HEC | Splunk HTTP Event Collector |
| Elasticsearch bulk (NDJSON) | Elasticsearch bulk endpoint |
| Google Chronicle (UDM) | Google Chronicle |
| CEF (ArcSight) | CEF receivers such as ArcSight |
| OCSF | OCSF-aware pipelines |
| Microsoft Sentinel | Azure Monitor ingestion with an Azure AD client-credentials flow |
## Prerequisites
- The Admin role and an authenticator app. Every change to a sink asks for a fresh MFA check. See [Backoffice guide](https://noxtica.com/docs/backoffice/overview/).
- A public `https://` endpoint that is ready to receive live traffic. Loopback, private, link-local and metadata addresses are refused, and a URL with embedded credentials is refused.
- A receiver that can verify an HMAC signature and answer with a 2xx status.
- For Microsoft Sentinel: the Azure tenant ID, the application (client) ID and a secure secret reference. Do not paste a client secret into the form.
- A decision on raw IP addresses. Raw IP is included in a sink's records only when your workspace stores raw IPs and you tick the PII acknowledgement on that sink. See [Data retention, raw IP storage and data locations](https://noxtica.com/docs/compliance/retention-and-locations/).
## Steps
### 1. Create the sink
1. Open `Event Sinks` and complete the form.
2. **Name (optional)**: for example "Splunk prod".
3. **HTTPS endpoint**: for example `https://siem.example.com/hec`.
4. **Format**: choose from the table above.
5. **Events**: tick the events this sink receives. Add **Payload enrichments** if you want them.
6. Leave **Acknowledge PII** unticked unless you need raw IP addresses.
7. Select **Create sink** and enter your MFA code.
The toast reads: "Event sink created (disabled). Copy the signing secret now — it is shown only once." A second sink with the same URL is refused with a 409 duplicate message.
### 2. Save the signing secret
The **Signing secret** box says it is "shown ONCE". Copy it into your receiver's configuration, then select **Dismiss**. Configure the receiver to verify the HMAC with it.
### 3. Verify each delivery in your receiver
Each request carries these headers:
| Header | Value |
| --- | --- |
| `X-Noxtica-Signature` | `sha256=` followed by the hex HMAC-SHA256 of `.` with your signing secret |
| `X-Noxtica-Timestamp` | The Unix timestamp used in the signature |
| `X-Noxtica-Event` | The event type |
| `X-Noxtica-Delivery` | A delivery ID, useful for de-duplication |
Compute the HMAC over the timestamp, a dot and the raw request body. Answer quickly with a 2xx status and process the event afterwards. Each attempt has a 5 second timeout.
```js
// Node.js receiver sketch
import { createHmac, timingSafeEqual } from 'node:crypto';
export function verify(rawBody, headers, secret) {
const ts = headers['x-noxtica-timestamp'];
const expected = 'sha256=' + createHmac('sha256', secret).update(`${ts}.${rawBody}`).digest('hex');
const got = headers['x-noxtica-signature'] ?? '';
return got.length === expected.length && timingSafeEqual(Buffer.from(got), Buffer.from(expected));
}
```
Reject a request whose timestamp is far from your clock. Treat a repeated `X-Noxtica-Delivery` as a duplicate.
### 4. Arm the sink
The new sink has the status **disabled**. In the table, select **Enable** for the sink. The toast reads "Sink armed". Select **Disable** to stop delivery without deleting the sink.
### 5. Send a real test request
Select **Send real test request**. The dialog warns that this sends a real signed HTTPS request from Noxtica to your endpoint right now and records it as a delivery attempt. Select **Send real request**. On success the toast reads "Test delivery accepted by the endpoint (HTTP )." The test uses the same SSRF guard and 5 second timeout as live delivery. Marked test probes are excluded from the delivery objective figures.
### 6. Inspect deliveries
Select **Deliveries** for a sink. The list shows the newest deliveries with **Status**, **Attempts**, **Last error** and **Created**, and a **Failed only** filter. Summary figures show success rate, last success and last failure. A delivery counts as a success when your endpoint answers 2xx. A 4xx answer is final. A 5xx answer, a network error or a timeout is retried.
The page also shows a **Seven-day delivery SLO** card. It counts recorded terminal HTTP acceptance only. It is not proof of ingestion in your SIEM and not proof that no events were lost, and an empty or unavailable observation is not healthy.
When recovery is available for a retained failure, **Redrive once** queues a single real delivery to the sink's current endpoint. The receiver may already have accepted the original event, so de-duplicate on `X-Noxtica-Delivery`. Redrive is single-use and depends on the feature being enabled for your organisation.
### 7. Rotate or delete
- **Rotate secret**: mints a new signing secret, shown once. The old secret stops working at once, so update your receiver first or accept failed verification until you do.
- **Delete sink**: removes the sink and stops all delivery to its URL. Deletion cannot be undone.
### 8. Microsoft Sentinel
Choosing **Microsoft Sentinel** adds fields for the Azure tenant ID, the application ID and a secret reference. Delivery uses an OAuth2 client-credentials flow instead of the HMAC signature. Noxtica refuses a form that carries an inline client secret.
## Verify it works
- The sink row shows **enabled** and a **Last delivery** time after the test.
- The test toast shows an HTTP 2xx status.
- **Deliveries** lists the test request as delivered.
- Your receiver logged the request and the signature check passed.
## Troubleshooting
| Symptom | Cause | Fix |
| --- | --- | --- |
| "A https URL and at least one event type are required" | The endpoint is not `https`, or no event is ticked | Fix the URL and tick an event |
| Create fails with a duplicate message | A sink for this URL already exists | Edit the existing sink |
| Create fails with a limit message | The workspace has 25 sinks | Delete an unused sink |
| The test succeeds but live events never arrive | Sink is disabled, or the platform event stream is off for your workspace | Enable the sink; ask your account team |
| Signature check fails | Wrong secret, parsed body used instead of raw body, or timestamp not included | Recompute over `.` with the current secret |
| Deliveries show repeated failures | Endpoint returns 5xx, times out or is blocked | Fix the receiver and check the 5 second timeout |
| Sentinel form is refused | A client secret was pasted inline | Use a secure secret reference |
| Every change asks for a code | Sink changes need a fresh MFA check | Enter the authenticator code |
## Related
- [Integrations and API pages](https://noxtica.com/docs/backoffice/integrations/): the map of this group.
- [Webhooks](https://noxtica.com/docs/api/webhooks/): event types and the shared signing scheme.
- [Audit log and data export](https://noxtica.com/docs/security/audit-log-and-exports/): what the `audit.log` stream carries.
- [Data retention, raw IP storage and data locations](https://noxtica.com/docs/compliance/retention-and-locations/): raw IP storage.
- [Roles and permissions](https://noxtica.com/docs/security/roles-and-permissions/): who can manage sinks.
---
Source: https://noxtica.com/docs/api/
Markdown: https://noxtica.com/docs/api/index.md
Last updated: 2026-10-27
# API overview
The Noxtica server APIs are HTTPS JSON APIs that your own back end calls. These pages are generated from the OpenAPI specifications that Noxtica publishes, so every route, parameter, field and status code listed here comes from the same source as the specification files.
The specifications themselves are published as files: [`/docs/api/openapi.json`](https://noxtica.com/docs/api/openapi.json) holds every public operation of the four APIs, and `/docs/api/openapi/.json` holds one API each (`v1`, `kyc`, `pulse`, `mcp`); every file is also served as YAML, at the same address with the YAML extension. Import them into a client generator, an API workspace, or an AI agent. See [Integrate with an AI agent](https://noxtica.com/docs/ai-agents/).
Call these APIs from a server you control. A server API key is a secret and must never reach a browser or a mobile app. Availability is account-specific: the modules enabled for your account and the scopes on your key decide which operations you can call.
## Base URLs
Send each request to the base URL listed for the API you call.
| Environment | Base URL | Key prefix | APIs |
| --- | --- | --- | --- |
| Production | `https://collect.noxtica.com` | `sk_prod_` | [Identity verification API](https://noxtica.com/docs/api/reference/kyc/), [Risk scoring and agent trust API](https://noxtica.com/docs/api/reference/score/), [Protected actions API](https://noxtica.com/docs/api/reference/protected-actions/), [Device intelligence API](https://noxtica.com/docs/api/reference/device/), [Mobile and device identity API](https://noxtica.com/docs/api/reference/mobile/), [Telemetry ingestion API](https://noxtica.com/docs/api/reference/ingest/), [Observability query API](https://noxtica.com/docs/api/reference/observability/), [Health and public key endpoints](https://noxtica.com/docs/api/reference/status/) |
| Production ingest host | `https://ingest.noxtica.com` | | [Telemetry ingestion API](https://noxtica.com/docs/api/reference/ingest/), [Observability query API](https://noxtica.com/docs/api/reference/observability/) |
| Production | `https://backoffice.noxtica.com` | | [MCP server](https://noxtica.com/docs/api/reference/mcp/) |
| Production (not yet deployed) | `https://pulse.noxtica.com` | | [Pulse tenant API](https://noxtica.com/docs/api/reference/pulse/) |
## Authentication
Operations authenticate with the credential named in their section. The credential formats are:
| Credential | Header | Used by |
| --- | --- | --- |
| `ApiKeyAuth` | `Authorization: Bearer sk_` | [Identity verification API](https://noxtica.com/docs/api/reference/kyc/), [Risk scoring and agent trust API](https://noxtica.com/docs/api/reference/score/), [Protected actions API](https://noxtica.com/docs/api/reference/protected-actions/), [Device intelligence API](https://noxtica.com/docs/api/reference/device/), [Mobile and device identity API](https://noxtica.com/docs/api/reference/mobile/), [Observability query API](https://noxtica.com/docs/api/reference/observability/) |
| `SessionTokenAuth` | `Authorization: Bearer kycs..` | [Identity verification API](https://noxtica.com/docs/api/reference/kyc/) |
| `ApmIngestKeyAuth` | `Authorization: Bearer sk_apm_` | [Telemetry ingestion API](https://noxtica.com/docs/api/reference/ingest/) |
| `CodingAgentKeyAuth` | `Authorization: Bearer cak_` | [Observability query API](https://noxtica.com/docs/api/reference/observability/) |
| `McpTokenAuth` | `Authorization: Bearer mcp_` | [MCP server](https://noxtica.com/docs/api/reference/mcp/) |
| `tenantKey` | `Authorization: Bearer sk_prod_<32 hex>` | [Pulse tenant API](https://noxtica.com/docs/api/reference/pulse/) |
See [Authentication](https://noxtica.com/docs/api/authentication/) for key handling and the scope each operation requires.
## Scopes
A key can call an operation only if it carries the scope the operation requires. The reference names 22 scopes; the [Authentication](https://noxtica.com/docs/api/authentication/) page lists the operations that need each one.
## Errors
Error responses use the HTTP status code and a JSON body that carries a machine-readable code and a request id. See [Errors](https://noxtica.com/docs/api/errors/) for the body, the codes each API returns and how to report a failed request.
## Rate limits
A request that exceeds a limit receives status `429` with a `Retry-After` header. See [Rate limits](https://noxtica.com/docs/api/rate-limits/) for how to back off and retry.
## Idempotency
These operations accept an `Idempotency-Key` header. Send a new, unique value for each logical operation and the same value when you retry it, so a retry cannot repeat the operation.
| Operation | Header | Length |
| --- | --- | --- |
| [`kycVerify`](https://noxtica.com/docs/api/reference/kyc/#kycVerify) | Required | 8 to 128 characters |
| [`kycVerifyBatchSubmit`](https://noxtica.com/docs/api/reference/kyc/#kycVerifyBatchSubmit) | Required | 8 to 128 characters |
| [`kycSessionMint`](https://noxtica.com/docs/api/reference/kyc/#kycSessionMint) | Optional | 8 to 128 characters |
| [`offlineCaptureBundleAdmit`](https://noxtica.com/docs/api/reference/mobile/#offlineCaptureBundleAdmit) | Required | 8 to 128 characters |
## Pagination
These operations return results in pages. Pass the cursor from one response, unchanged, in the `cursor` query parameter of the next request.
| Operation | Page size | Cursor in the response |
| --- | --- | --- |
| [`v1ListDevices`](https://noxtica.com/docs/api/reference/device/#v1ListDevices) | default 50, maximum 200 | `nextCursor` |
| [`v1ListAccountDevices`](https://noxtica.com/docs/api/reference/device/#v1ListAccountDevices) | default 50, maximum 200 | `nextCursor` |
| [`v1ListEvents`](https://noxtica.com/docs/api/reference/device/#v1ListEvents) | default 50, maximum 200 | `nextCursor` |
| [`v1ListVisits`](https://noxtica.com/docs/api/reference/device/#v1ListVisits) | default 50, maximum 200 | `nextCursor` |
| [`v1ExportFingerprints`](https://noxtica.com/docs/api/reference/device/#v1ExportFingerprints) | | `X-Noxtica-Export-Next-Cursor`, `next_cursor` |
| [`v1ExportEvents`](https://noxtica.com/docs/api/reference/device/#v1ExportEvents) | | `X-Noxtica-Export-Next-Cursor`, `next_cursor` |
| [`v1ExportVisits`](https://noxtica.com/docs/api/reference/device/#v1ExportVisits) | | `X-Noxtica-Export-Next-Cursor`, `next_cursor` |
| [`v1ExportScoredEvents`](https://noxtica.com/docs/api/reference/device/#v1ExportScoredEvents) | | `X-Noxtica-Export-Next-Cursor` |
| [`v1ListLabels`](https://noxtica.com/docs/api/reference/device/#v1ListLabels) | default 50, maximum 200 | `nextCursor` |
| [`v1ApmListProjects`](https://noxtica.com/docs/api/reference/observability/#v1ApmListProjects) | default 50, maximum 200 | `next_cursor` |
| [`v1ApmListProjectEnvironments`](https://noxtica.com/docs/api/reference/observability/#v1ApmListProjectEnvironments) | default 50, maximum 200 | `next_cursor` |
| [`v1ApmSearchTraces`](https://noxtica.com/docs/api/reference/observability/#v1ApmSearchTraces) | default 50, maximum 200 | `next_cursor` |
| [`pulseTenantListDecisions`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantListDecisions) | default 50, maximum 200 | `nextCursor` |
## Webhooks
Noxtica sends signed webhook deliveries for 11 event types: `kyc.session.completed`, `kyc.session.cancelled`, `kyc.verification.completed`, `kyc.erasure.completed`, `kyc.document.expiry_warning`, `kyc.reverification.due`, `submission.scored`, `risk.high`, `risk.flagged`, `risk.cluster_flagged`, `account.agent_linked`. See [Webhooks](https://noxtica.com/docs/api/webhooks/) for the headers, the signature and the event catalog.
## API reference
| API | What it covers | Operations | Credential |
| --- | --- | --- | --- |
| [Identity verification API](https://noxtica.com/docs/api/reference/kyc/) | Verify identities, run hosted verification sessions, batch and re-verify, store evidence, and receive signed KYC, KYB and KYM webhooks. | 25 | `ApiKeyAuth`, `SessionTokenAuth` |
| [Risk scoring and agent trust API](https://noxtica.com/docs/api/reference/score/) | Score a request, look up IP and device reputation, verify AI agents, and mint signed crawler vouchers from your server. | 7 | `ApiKeyAuth` |
| [Protected actions API](https://noxtica.com/docs/api/reference/protected-actions/) | Redeem the request id a browser obtains for a protected action (login, signup, checkout) before your server lets the action proceed. | 1 | `ApiKeyAuth` |
| [Device intelligence API](https://noxtica.com/docs/api/reference/device/) | Read devices, events and visits, export data, fetch the sealed-results key, write labels, and manage behavioral baselines. | 18 | `ApiKeyAuth` |
| [Mobile and device identity API](https://noxtica.com/docs/api/reference/mobile/) | Verify mobile attestation and integrity, deliver app configuration, and manage passkeys, handoff, delegation, recovery, wallet state and offline capture. | 22 | `ApiKeyAuth` |
| [Telemetry ingestion API](https://noxtica.com/docs/api/reference/ingest/) | Send OpenTelemetry traces, metrics, logs, profiles and deployment markers with an ingestion key. | 5 | `ApmIngestKeyAuth` |
| [Observability query API](https://noxtica.com/docs/api/reference/observability/) | Query projects, traces, services and releases, manage environment policy, run exports and privacy-request lookups, and read recent signals from a coding agent. | 17 | `ApiKeyAuth`, `CodingAgentKeyAuth` |
| [MCP server](https://noxtica.com/docs/api/reference/mcp/) | Connect an AI assistant or your own code to your workspace through the Model Context Protocol with a scoped token. | 1 | `McpTokenAuth` |
| [Pulse tenant API](https://noxtica.com/docs/api/reference/pulse/) | Read player status and decisions, create link codes, and manage links from your own back end with a tenant API key. | 7 | `tenantKey` |
| [Health and public key endpoints](https://noxtica.com/docs/api/reference/status/) | The unauthenticated collector health probe and the public signing-key documents for verifying signed envelopes and Agent Passports offline. | 3 | None |
_This page is generated from the Noxtica OpenAPI specification release `v0.4.0`: `kyc.yaml` version `1.2.0-2026-10-27` (SHA-256 `c91a695cfde0`), `mcp.yaml` version `0.1.0-2026-10-27` (SHA-256 `1a4875efa736`), `pulse.yaml` version `0.9.0-2026-10-27` (SHA-256 `95196a58bb5b`), `v1.yaml` version `1.3.0-2026-10-27` (SHA-256 `3fd15257a022`). Do not edit it by hand._
---
Source: https://noxtica.com/docs/api/errors/
Markdown: https://noxtica.com/docs/api/errors/index.md
Last updated: 2026-10-27
# API errors
A request that cannot be completed returns an HTTP status of `400` or higher and a JSON body. Branch on the status code first, then on the `error` or `code` value when the response carries one, and treat any value you do not recognise as a failure of that status class.
Every error body carries a request id. Log it with the failed call and quote it when you contact support.
## Error body
### Noxtica KYC / KYB / KYM API
| Field | Type | Always returned | Description |
| --- | --- | --- | --- |
| `error` | string | Yes | |
| `requestId` | string | Yes | |
### Noxtica Pulse customer, sign-in and device API
| Field | Type | Always returned | Description |
| --- | --- | --- | --- |
| `code` | string | Yes | Stable machine-readable identifier. |
| `error` | string | Yes | |
| `message` | string | No | |
| `requestId` | string | No | |
### Noxtica Server API (/v1)
| Field | Type | Always returned | Description |
| --- | --- | --- | --- |
| `error` | string | Yes | Machine-readable error string; route-specific values are listed on each operation. |
| `requestId` | string | Yes | Correlation id for this call; quote it when you contact support. |
## Identity verification API: errors
Codes named in the responses of the Identity verification API operations.
| Status | Code | Returned by |
| --- | --- | --- |
| `400` | `consent_required` | [`kycSessionVerificationIdEmail`](https://noxtica.com/docs/api/reference/kyc/#kycSessionVerificationIdEmail) |
| `400` | `email_verification_unavailable` | [`kycSessionMint`](https://noxtica.com/docs/api/reference/kyc/#kycSessionMint) |
| `400` | `idempotency_key_invalid` | [`kycSessionSubmit`](https://noxtica.com/docs/api/reference/kyc/#kycSessionSubmit) |
| `400` | `Invalid sessionId` | [`kycSessionStatus`](https://noxtica.com/docs/api/reference/kyc/#kycSessionStatus) |
| `400` | `invalid_case_id` | [`kymTransactionsReport`](https://noxtica.com/docs/api/reference/kyc/#kymTransactionsReport) |
| `400` | `invalid_email` | [`kycSessionVerificationIdEmail`](https://noxtica.com/docs/api/reference/kyc/#kycSessionVerificationIdEmail), [`kycSessionEmailSend`](https://noxtica.com/docs/api/reference/kyc/#kycSessionEmailSend) |
| `400` | `invalid_hosted_options` | [`kycSessionMint`](https://noxtica.com/docs/api/reference/kyc/#kycSessionMint) |
| `400` | `invalid_id_type` | [`kycSessionMint`](https://noxtica.com/docs/api/reference/kyc/#kycSessionMint) |
| `400` | `invalid_or_expired` | [`kycEmailVerificationConfirm`](https://noxtica.com/docs/api/reference/kyc/#kycEmailVerificationConfirm) |
| `400` | `invalid_request` | [`kycVerify`](https://noxtica.com/docs/api/reference/kyc/#kycVerify), [`kycAddressDocumentCrossMatch`](https://noxtica.com/docs/api/reference/kyc/#kycAddressDocumentCrossMatch), [`kycVerifyBatchSubmit`](https://noxtica.com/docs/api/reference/kyc/#kycVerifyBatchSubmit), [`kycEvidenceHandleMint`](https://noxtica.com/docs/api/reference/kyc/#kycEvidenceHandleMint), and 10 more |
| `400` | `payload_invalid` | [`kycSessionSubmit`](https://noxtica.com/docs/api/reference/kyc/#kycSessionSubmit) |
| `400` | `return_url_not_allowed` | [`kycSessionMint`](https://noxtica.com/docs/api/reference/kyc/#kycSessionMint) |
| `401` | `invalid_api_key` | [`kycVerify`](https://noxtica.com/docs/api/reference/kyc/#kycVerify), [`kycAddressDocumentCrossMatch`](https://noxtica.com/docs/api/reference/kyc/#kycAddressDocumentCrossMatch), [`kycVerifyBatchSubmit`](https://noxtica.com/docs/api/reference/kyc/#kycVerifyBatchSubmit), [`kycVerifyBatchStatus`](https://noxtica.com/docs/api/reference/kyc/#kycVerifyBatchStatus), and 10 more |
| `401` | `invalid_session` | [`kycSessionCancel`](https://noxtica.com/docs/api/reference/kyc/#kycSessionCancel), [`kycSessionEmailSend`](https://noxtica.com/docs/api/reference/kyc/#kycSessionEmailSend), [`kycSessionEmailStatus`](https://noxtica.com/docs/api/reference/kyc/#kycSessionEmailStatus) |
| `402` | `spend_cap_reached` | [`kycVerify`](https://noxtica.com/docs/api/reference/kyc/#kycVerify) |
| `403` | `age_gender_estimation_not_enabled` | [`kycSessionMint`](https://noxtica.com/docs/api/reference/kyc/#kycSessionMint) |
| `403` | `API key does not have write:identity scope` | [`kycVerify`](https://noxtica.com/docs/api/reference/kyc/#kycVerify), [`kycAddressDocumentCrossMatch`](https://noxtica.com/docs/api/reference/kyc/#kycAddressDocumentCrossMatch), [`kycVerifyBatchSubmit`](https://noxtica.com/docs/api/reference/kyc/#kycVerifyBatchSubmit), [`kycVerifyBatchStatus`](https://noxtica.com/docs/api/reference/kyc/#kycVerifyBatchStatus), and 8 more |
| `403` | `invalid_request` | [`kycEvidenceFinalize`](https://noxtica.com/docs/api/reference/kyc/#kycEvidenceFinalize), [`kycSessionView`](https://noxtica.com/docs/api/reference/kyc/#kycSessionView), [`kycSessionProgress`](https://noxtica.com/docs/api/reference/kyc/#kycSessionProgress), [`kycSessionSubmit`](https://noxtica.com/docs/api/reference/kyc/#kycSessionSubmit), and 2 more |
| `403` | `kyc_legal_basis_receipt_required` | [`kycSessionMint`](https://noxtica.com/docs/api/reference/kyc/#kycSessionMint) |
| `403` | `origin_not_allowed` | [`kycSessionCancel`](https://noxtica.com/docs/api/reference/kyc/#kycSessionCancel), [`kycSessionVerificationIdEmail`](https://noxtica.com/docs/api/reference/kyc/#kycSessionVerificationIdEmail), [`kycSessionEmailSend`](https://noxtica.com/docs/api/reference/kyc/#kycSessionEmailSend), [`kycSessionEmailStatus`](https://noxtica.com/docs/api/reference/kyc/#kycSessionEmailStatus), and 2 more |
| `404` | `invalid_request` | [`kymTransactionsReport`](https://noxtica.com/docs/api/reference/kyc/#kymTransactionsReport) |
| `404` | `not_found` | [`kycVerificationIdStatus`](https://noxtica.com/docs/api/reference/kyc/#kycVerificationIdStatus) |
| `404` | `V1 endpoint not found` | [`kycVerify`](https://noxtica.com/docs/api/reference/kyc/#kycVerify), [`kycAddressDocumentCrossMatch`](https://noxtica.com/docs/api/reference/kyc/#kycAddressDocumentCrossMatch), [`kycVerifyBatchSubmit`](https://noxtica.com/docs/api/reference/kyc/#kycVerifyBatchSubmit), [`kycVerifyBatchStatus`](https://noxtica.com/docs/api/reference/kyc/#kycVerifyBatchStatus), and 19 more |
| `409` | `already_verified` | [`kycSessionEmailSend`](https://noxtica.com/docs/api/reference/kyc/#kycSessionEmailSend) |
| `409` | `email_verification_not_enabled` | [`kycSessionEmailSend`](https://noxtica.com/docs/api/reference/kyc/#kycSessionEmailSend), [`kycSessionEmailStatus`](https://noxtica.com/docs/api/reference/kyc/#kycSessionEmailStatus) |
| `409` | `email_verification_required` | [`kycSessionSubmit`](https://noxtica.com/docs/api/reference/kyc/#kycSessionSubmit) |
| `409` | `example-code` | [`kycVerify`](https://noxtica.com/docs/api/reference/kyc/#kycVerify) |
| `409` | `idempotency_conflict` | [`kycVerify`](https://noxtica.com/docs/api/reference/kyc/#kycVerify) |
| `409` | `invalid_request` | [`kycAddressDocumentCrossMatch`](https://noxtica.com/docs/api/reference/kyc/#kycAddressDocumentCrossMatch), [`kycSessionProgress`](https://noxtica.com/docs/api/reference/kyc/#kycSessionProgress), [`kycSessionSubmit`](https://noxtica.com/docs/api/reference/kyc/#kycSessionSubmit) |
| `409` | `session_expiring` | [`kycSessionEmailSend`](https://noxtica.com/docs/api/reference/kyc/#kycSessionEmailSend) |
| `409` | `session_not_cancellable` | [`kycSessionCancel`](https://noxtica.com/docs/api/reference/kyc/#kycSessionCancel) |
| `409` | `session_not_editable` | [`kycSessionEmailSend`](https://noxtica.com/docs/api/reference/kyc/#kycSessionEmailSend) |
| `409` | `session_not_submittable` | [`kycSessionSubmit`](https://noxtica.com/docs/api/reference/kyc/#kycSessionSubmit) |
| `409` | `verification_id_unavailable` | [`kycSessionVerificationIdEmail`](https://noxtica.com/docs/api/reference/kyc/#kycSessionVerificationIdEmail) |
| `409` | `verify_gate_consumed` | [`kycSessionSubmit`](https://noxtica.com/docs/api/reference/kyc/#kycSessionSubmit) |
| `410` | `kyc_session_cancelled` | [`kycSessionView`](https://noxtica.com/docs/api/reference/kyc/#kycSessionView), [`kycSessionProgress`](https://noxtica.com/docs/api/reference/kyc/#kycSessionProgress), [`kycSessionSubmit`](https://noxtica.com/docs/api/reference/kyc/#kycSessionSubmit), [`kycSessionVerificationIdEmail`](https://noxtica.com/docs/api/reference/kyc/#kycSessionVerificationIdEmail), and 4 more |
| `410` | `kyc_session_expired` | [`kycSessionCancel`](https://noxtica.com/docs/api/reference/kyc/#kycSessionCancel) |
| `410` | `session_cancelled` | [`kycSessionView`](https://noxtica.com/docs/api/reference/kyc/#kycSessionView), [`kycSessionProgress`](https://noxtica.com/docs/api/reference/kyc/#kycSessionProgress), [`kycSessionCancel`](https://noxtica.com/docs/api/reference/kyc/#kycSessionCancel), [`kycSessionSubmit`](https://noxtica.com/docs/api/reference/kyc/#kycSessionSubmit), and 5 more |
| `410` | `session_expired` | [`kycSessionCancel`](https://noxtica.com/docs/api/reference/kyc/#kycSessionCancel) |
| `413` | `body_too_large` | [`kycVerify`](https://noxtica.com/docs/api/reference/kyc/#kycVerify), [`kycAddressDocumentCrossMatch`](https://noxtica.com/docs/api/reference/kyc/#kycAddressDocumentCrossMatch), [`kycVerifyBatchSubmit`](https://noxtica.com/docs/api/reference/kyc/#kycVerifyBatchSubmit), [`kycEvidenceHandleMint`](https://noxtica.com/docs/api/reference/kyc/#kycEvidenceHandleMint), and 4 more |
| `415` | `invalid_request` | [`kycVerifyBatchSubmit`](https://noxtica.com/docs/api/reference/kyc/#kycVerifyBatchSubmit), [`kycSessionMint`](https://noxtica.com/docs/api/reference/kyc/#kycSessionMint) |
| `429` | `cooldown` | [`kycSessionEmailSend`](https://noxtica.com/docs/api/reference/kyc/#kycSessionEmailSend) |
| `429` | `invalid_request` | [`kycSessionSubmit`](https://noxtica.com/docs/api/reference/kyc/#kycSessionSubmit) |
| `429` | `Rate limit exceeded` | [`kycVerify`](https://noxtica.com/docs/api/reference/kyc/#kycVerify), [`kycAddressDocumentCrossMatch`](https://noxtica.com/docs/api/reference/kyc/#kycAddressDocumentCrossMatch), [`kycVerifyBatchSubmit`](https://noxtica.com/docs/api/reference/kyc/#kycVerifyBatchSubmit), [`kycEvidenceHandleMint`](https://noxtica.com/docs/api/reference/kyc/#kycEvidenceHandleMint), and 14 more |
| `429` | `rate_limited` | [`kycSessionVerificationIdEmail`](https://noxtica.com/docs/api/reference/kyc/#kycSessionVerificationIdEmail), [`kycVerificationIdStatus`](https://noxtica.com/docs/api/reference/kyc/#kycVerificationIdStatus) |
| `429` | `send_limit_reached` | [`kycSessionEmailSend`](https://noxtica.com/docs/api/reference/kyc/#kycSessionEmailSend) |
| `429` | `session_rate_limited` | [`kycSessionSubmit`](https://noxtica.com/docs/api/reference/kyc/#kycSessionSubmit) |
| `500` | `server_misconfigured` | [`kycSessionMint`](https://noxtica.com/docs/api/reference/kyc/#kycSessionMint), [`kycSessionStatus`](https://noxtica.com/docs/api/reference/kyc/#kycSessionStatus) |
| `502` | `email_send_failed` | [`kycSessionVerificationIdEmail`](https://noxtica.com/docs/api/reference/kyc/#kycSessionVerificationIdEmail), [`kycSessionEmailSend`](https://noxtica.com/docs/api/reference/kyc/#kycSessionEmailSend) |
| `503` | `email_unavailable` | [`kycSessionVerificationIdEmail`](https://noxtica.com/docs/api/reference/kyc/#kycSessionVerificationIdEmail) |
| `503` | `hosted_verify_not_configured` | [`kycSessionSubmit`](https://noxtica.com/docs/api/reference/kyc/#kycSessionSubmit), [`kycSessionEmailSend`](https://noxtica.com/docs/api/reference/kyc/#kycSessionEmailSend) |
| `503` | `invalid_request` | [`kycVerify`](https://noxtica.com/docs/api/reference/kyc/#kycVerify), [`kycAddressDocumentCrossMatch`](https://noxtica.com/docs/api/reference/kyc/#kycAddressDocumentCrossMatch), [`kycVerifyBatchSubmit`](https://noxtica.com/docs/api/reference/kyc/#kycVerifyBatchSubmit), [`kycEvidenceHandleMint`](https://noxtica.com/docs/api/reference/kyc/#kycEvidenceHandleMint), and 8 more |
| `503` | `kyc_legal_basis_receipt_unavailable` | [`kycSessionSubmit`](https://noxtica.com/docs/api/reference/kyc/#kycSessionSubmit) |
| `503` | `nonce_mint_unavailable` | [`kycSessionSubmit`](https://noxtica.com/docs/api/reference/kyc/#kycSessionSubmit) |
| `503` | `session_backend_unavailable` | [`kycSessionEmailSend`](https://noxtica.com/docs/api/reference/kyc/#kycSessionEmailSend), [`kycSessionEmailStatus`](https://noxtica.com/docs/api/reference/kyc/#kycSessionEmailStatus) |
| `503` | `submit_internal_error` | [`kycSessionSubmit`](https://noxtica.com/docs/api/reference/kyc/#kycSessionSubmit) |
| `503` | `temporarily_unavailable` | [`kycEmailVerificationConfirm`](https://noxtica.com/docs/api/reference/kyc/#kycEmailVerificationConfirm), [`kycVerificationIdStatus`](https://noxtica.com/docs/api/reference/kyc/#kycVerificationIdStatus) |
| `503` | `write_failed` | [`kymTransactionsReport`](https://noxtica.com/docs/api/reference/kyc/#kymTransactionsReport) |
## Risk scoring and agent trust API: errors
Codes named in the responses of the Risk scoring and agent trust API operations.
| Status | Code | Returned by |
| --- | --- | --- |
| `400` | `Invalid body` | [`v1VerifyReputation`](https://noxtica.com/docs/api/reference/score/#v1VerifyReputation), [`postAgentVerify`](https://noxtica.com/docs/api/reference/score/#postAgentVerify), [`postIpReputation`](https://noxtica.com/docs/api/reference/score/#postIpReputation), [`postScore`](https://noxtica.com/docs/api/reference/score/#postScore) |
| `400` | `invalid_request` | [`v1MintCrawlVoucher`](https://noxtica.com/docs/api/reference/score/#v1MintCrawlVoucher) |
| `401` | `invalid_api_key` | [`v1VerifyReputation`](https://noxtica.com/docs/api/reference/score/#v1VerifyReputation), [`v1MintCrawlVoucher`](https://noxtica.com/docs/api/reference/score/#v1MintCrawlVoucher), [`getAgentPassport`](https://noxtica.com/docs/api/reference/score/#getAgentPassport), [`postAgentPassport`](https://noxtica.com/docs/api/reference/score/#postAgentPassport), and 3 more |
| `402` | `invalid_request` | [`v1MintCrawlVoucher`](https://noxtica.com/docs/api/reference/score/#v1MintCrawlVoucher) |
| `403` | `API key does not have read:device scope` | [`v1VerifyReputation`](https://noxtica.com/docs/api/reference/score/#v1VerifyReputation), [`v1MintCrawlVoucher`](https://noxtica.com/docs/api/reference/score/#v1MintCrawlVoucher), [`postAgentVerify`](https://noxtica.com/docs/api/reference/score/#postAgentVerify), [`postIpReputation`](https://noxtica.com/docs/api/reference/score/#postIpReputation), and 1 more |
| `403` | `feature disabled` | [`getAgentPassport`](https://noxtica.com/docs/api/reference/score/#getAgentPassport), [`postAgentPassport`](https://noxtica.com/docs/api/reference/score/#postAgentPassport) |
| `404` | `Not found` | [`getAgentPassport`](https://noxtica.com/docs/api/reference/score/#getAgentPassport), [`postAgentPassport`](https://noxtica.com/docs/api/reference/score/#postAgentPassport) |
| `404` | `V1 endpoint not found` | [`v1VerifyReputation`](https://noxtica.com/docs/api/reference/score/#v1VerifyReputation) |
| `413` | `body_too_large` | [`v1MintCrawlVoucher`](https://noxtica.com/docs/api/reference/score/#v1MintCrawlVoucher), [`postAgentVerify`](https://noxtica.com/docs/api/reference/score/#postAgentVerify) |
| `413` | `invalid_request` | [`postAgentPassport`](https://noxtica.com/docs/api/reference/score/#postAgentPassport) |
| `415` | `invalid_request` | [`v1MintCrawlVoucher`](https://noxtica.com/docs/api/reference/score/#v1MintCrawlVoucher), [`postAgentVerify`](https://noxtica.com/docs/api/reference/score/#postAgentVerify) |
| `429` | `Rate limit exceeded` | [`v1VerifyReputation`](https://noxtica.com/docs/api/reference/score/#v1VerifyReputation), [`v1MintCrawlVoucher`](https://noxtica.com/docs/api/reference/score/#v1MintCrawlVoucher), [`getAgentPassport`](https://noxtica.com/docs/api/reference/score/#getAgentPassport), [`postAgentPassport`](https://noxtica.com/docs/api/reference/score/#postAgentPassport), and 3 more |
| `500` | `Internal server error` | [`v1VerifyReputation`](https://noxtica.com/docs/api/reference/score/#v1VerifyReputation), [`v1MintCrawlVoucher`](https://noxtica.com/docs/api/reference/score/#v1MintCrawlVoucher), [`postAgentVerify`](https://noxtica.com/docs/api/reference/score/#postAgentVerify), [`postIpReputation`](https://noxtica.com/docs/api/reference/score/#postIpReputation), and 1 more |
| `500` | `invalid_request` | [`getAgentPassport`](https://noxtica.com/docs/api/reference/score/#getAgentPassport), [`postAgentPassport`](https://noxtica.com/docs/api/reference/score/#postAgentPassport) |
| `503` | `invalid_request` | [`v1MintCrawlVoucher`](https://noxtica.com/docs/api/reference/score/#v1MintCrawlVoucher), [`getAgentPassport`](https://noxtica.com/docs/api/reference/score/#getAgentPassport), [`postAgentPassport`](https://noxtica.com/docs/api/reference/score/#postAgentPassport) |
## Protected actions API: errors
Codes named in the responses of the Protected actions API operations.
| Status | Code | Returned by |
| --- | --- | --- |
| `400` | `invalid_action` | [`postProtectedActionsVerify`](https://noxtica.com/docs/api/reference/protected-actions/#postProtectedActionsVerify) |
| `400` | `invalid_body` | [`postProtectedActionsVerify`](https://noxtica.com/docs/api/reference/protected-actions/#postProtectedActionsVerify) |
| `400` | `invalid_expected_domain` | [`postProtectedActionsVerify`](https://noxtica.com/docs/api/reference/protected-actions/#postProtectedActionsVerify) |
| `400` | `invalid_request_id` | [`postProtectedActionsVerify`](https://noxtica.com/docs/api/reference/protected-actions/#postProtectedActionsVerify) |
| `401` | `invalid_api_key` | [`postProtectedActionsVerify`](https://noxtica.com/docs/api/reference/protected-actions/#postProtectedActionsVerify) |
| `403` | `API key does not have read:device scope` | [`postProtectedActionsVerify`](https://noxtica.com/docs/api/reference/protected-actions/#postProtectedActionsVerify) |
| `404` | `request_not_found` | [`postProtectedActionsVerify`](https://noxtica.com/docs/api/reference/protected-actions/#postProtectedActionsVerify) |
| `409` | `already_consumed` | [`postProtectedActionsVerify`](https://noxtica.com/docs/api/reference/protected-actions/#postProtectedActionsVerify) |
| `413` | `payload_too_large` | [`postProtectedActionsVerify`](https://noxtica.com/docs/api/reference/protected-actions/#postProtectedActionsVerify) |
| `422` | `action_mismatch` | [`postProtectedActionsVerify`](https://noxtica.com/docs/api/reference/protected-actions/#postProtectedActionsVerify) |
| `422` | `domain_mismatch` | [`postProtectedActionsVerify`](https://noxtica.com/docs/api/reference/protected-actions/#postProtectedActionsVerify) |
| `429` | `Rate limit exceeded` | [`postProtectedActionsVerify`](https://noxtica.com/docs/api/reference/protected-actions/#postProtectedActionsVerify) |
| `500` | `Internal server error` | [`postProtectedActionsVerify`](https://noxtica.com/docs/api/reference/protected-actions/#postProtectedActionsVerify) |
## Device intelligence API: errors
Codes named in the responses of the Device intelligence API operations.
| Status | Code | Returned by |
| --- | --- | --- |
| `400` | `invalid_request` | [`v1GetDevice`](https://noxtica.com/docs/api/reference/device/#v1GetDevice), [`v1ListDevices`](https://noxtica.com/docs/api/reference/device/#v1ListDevices), [`v1ListAccountDevices`](https://noxtica.com/docs/api/reference/device/#v1ListAccountDevices), [`v1ListEvents`](https://noxtica.com/docs/api/reference/device/#v1ListEvents), and 11 more |
| `401` | `invalid_api_key` | [`v1GetDevice`](https://noxtica.com/docs/api/reference/device/#v1GetDevice), [`v1ListDevices`](https://noxtica.com/docs/api/reference/device/#v1ListDevices), [`v1ListAccountDevices`](https://noxtica.com/docs/api/reference/device/#v1ListAccountDevices), [`v1ListEvents`](https://noxtica.com/docs/api/reference/device/#v1ListEvents), and 14 more |
| `403` | `API key does not have read:device scope` | [`v1GetDevice`](https://noxtica.com/docs/api/reference/device/#v1GetDevice), [`v1ListDevices`](https://noxtica.com/docs/api/reference/device/#v1ListDevices), [`v1ListAccountDevices`](https://noxtica.com/docs/api/reference/device/#v1ListAccountDevices), [`v1ListEvents`](https://noxtica.com/docs/api/reference/device/#v1ListEvents), and 13 more |
| `403` | `invalid_request` | [`v1GetSealedResultsKey`](https://noxtica.com/docs/api/reference/device/#v1GetSealedResultsKey) |
| `404` | `Device not found` | [`v1GetDevice`](https://noxtica.com/docs/api/reference/device/#v1GetDevice) |
| `404` | `invalid_request` | [`v1GenerateFingerprintBatch`](https://noxtica.com/docs/api/reference/device/#v1GenerateFingerprintBatch), [`v1GenerateSingleFingerprint`](https://noxtica.com/docs/api/reference/device/#v1GenerateSingleFingerprint), [`v1GetBehavioralSubject`](https://noxtica.com/docs/api/reference/device/#v1GetBehavioralSubject), [`v1EraseBehavioralSubject`](https://noxtica.com/docs/api/reference/device/#v1EraseBehavioralSubject), and 1 more |
| `404` | `sealed_key_version_unavailable` | [`v1GetSealedResultsKey`](https://noxtica.com/docs/api/reference/device/#v1GetSealedResultsKey) |
| `404` | `sealed-results key version unavailable` | [`v1GetSealedResultsKey`](https://noxtica.com/docs/api/reference/device/#v1GetSealedResultsKey) |
| `413` | `body_too_large` | [`v1WriteLabel`](https://noxtica.com/docs/api/reference/device/#v1WriteLabel), [`v1GenerateFingerprintBatch`](https://noxtica.com/docs/api/reference/device/#v1GenerateFingerprintBatch), [`v1GenerateSingleFingerprint`](https://noxtica.com/docs/api/reference/device/#v1GenerateSingleFingerprint) |
| `415` | `invalid_request` | [`v1WriteLabel`](https://noxtica.com/docs/api/reference/device/#v1WriteLabel), [`v1GenerateFingerprintBatch`](https://noxtica.com/docs/api/reference/device/#v1GenerateFingerprintBatch), [`v1GenerateSingleFingerprint`](https://noxtica.com/docs/api/reference/device/#v1GenerateSingleFingerprint) |
| `429` | `Rate limit exceeded` | [`v1GetDevice`](https://noxtica.com/docs/api/reference/device/#v1GetDevice), [`v1ListDevices`](https://noxtica.com/docs/api/reference/device/#v1ListDevices), [`v1ListAccountDevices`](https://noxtica.com/docs/api/reference/device/#v1ListAccountDevices), [`v1ListEvents`](https://noxtica.com/docs/api/reference/device/#v1ListEvents), and 12 more |
| `500` | `Internal server error` | [`v1GetDevice`](https://noxtica.com/docs/api/reference/device/#v1GetDevice), [`v1ListEvents`](https://noxtica.com/docs/api/reference/device/#v1ListEvents), [`v1ListVisits`](https://noxtica.com/docs/api/reference/device/#v1ListVisits), [`v1ExportFingerprints`](https://noxtica.com/docs/api/reference/device/#v1ExportFingerprints), and 12 more |
| `500` | `invalid_request` | [`v1ListDevices`](https://noxtica.com/docs/api/reference/device/#v1ListDevices), [`v1ListAccountDevices`](https://noxtica.com/docs/api/reference/device/#v1ListAccountDevices) |
| `500` | `server_misconfigured` | [`v1GetSealedResultsKey`](https://noxtica.com/docs/api/reference/device/#v1GetSealedResultsKey) |
| `502` | `invalid_request` | [`v1EraseBehavioralSubject`](https://noxtica.com/docs/api/reference/device/#v1EraseBehavioralSubject) |
## Mobile and device identity API: errors
Codes named in the responses of the Mobile and device identity API operations.
| Status | Code | Returned by |
| --- | --- | --- |
| `400` | `device_delegation_invalid_subject_id` | [`deviceDelegationCreate`](https://noxtica.com/docs/api/reference/mobile/#deviceDelegationCreate) |
| `400` | `invalid_request` | [`postAttestAndroid`](https://noxtica.com/docs/api/reference/mobile/#postAttestAndroid), [`postAttestIos`](https://noxtica.com/docs/api/reference/mobile/#postAttestIos), [`postAttestVerify`](https://noxtica.com/docs/api/reference/mobile/#postAttestVerify), [`postAttestChallenge`](https://noxtica.com/docs/api/reference/mobile/#postAttestChallenge), and 14 more |
| `400` | `offline_capture_nonce_invalid` | [`offlineCaptureBundleAdmit`](https://noxtica.com/docs/api/reference/mobile/#offlineCaptureBundleAdmit) |
| `400` | `offline_capture_verdict_claim_rejected` | [`offlineCaptureBundleAdmit`](https://noxtica.com/docs/api/reference/mobile/#offlineCaptureBundleAdmit) |
| `401` | `invalid_api_key` | [`postAttestAndroid`](https://noxtica.com/docs/api/reference/mobile/#postAttestAndroid), [`postAttestIos`](https://noxtica.com/docs/api/reference/mobile/#postAttestIos), [`postAttestVerify`](https://noxtica.com/docs/api/reference/mobile/#postAttestVerify), [`postAttestChallenge`](https://noxtica.com/docs/api/reference/mobile/#postAttestChallenge), and 18 more |
| `403` | `API key does not have read:device scope` | [`postAttestAndroid`](https://noxtica.com/docs/api/reference/mobile/#postAttestAndroid), [`postAttestIos`](https://noxtica.com/docs/api/reference/mobile/#postAttestIos), [`postAttestVerify`](https://noxtica.com/docs/api/reference/mobile/#postAttestVerify), [`postAttestChallenge`](https://noxtica.com/docs/api/reference/mobile/#postAttestChallenge), and 15 more |
| `403` | `API key does not have write:identity:trusted-subject scope` | [`walletSuspend`](https://noxtica.com/docs/api/reference/mobile/#walletSuspend) |
| `403` | `invalid_request` | [`offlineNoncePoolMint`](https://noxtica.com/docs/api/reference/mobile/#offlineNoncePoolMint), [`offlineCaptureBundleAdmit`](https://noxtica.com/docs/api/reference/mobile/#offlineCaptureBundleAdmit) |
| `403` | `kyc_legal_basis_receipt_required` | [`offlineNoncePoolMint`](https://noxtica.com/docs/api/reference/mobile/#offlineNoncePoolMint), [`offlineCaptureBundleAdmit`](https://noxtica.com/docs/api/reference/mobile/#offlineCaptureBundleAdmit) |
| `404` | `invalid_request` | [`deviceDelegationRevoke`](https://noxtica.com/docs/api/reference/mobile/#deviceDelegationRevoke) |
| `404` | `V1 endpoint not found` | [`postAttestAndroid`](https://noxtica.com/docs/api/reference/mobile/#postAttestAndroid), [`postAttestIos`](https://noxtica.com/docs/api/reference/mobile/#postAttestIos), [`postPasskeyChallenge`](https://noxtica.com/docs/api/reference/mobile/#postPasskeyChallenge), [`postPasskeyRegister`](https://noxtica.com/docs/api/reference/mobile/#postPasskeyRegister), and 13 more |
| `409` | `invalid_request` | [`offlineCaptureBundleAdmit`](https://noxtica.com/docs/api/reference/mobile/#offlineCaptureBundleAdmit) |
| `409` | `offline_capture_idempotency_conflict` | [`offlineCaptureBundleAdmit`](https://noxtica.com/docs/api/reference/mobile/#offlineCaptureBundleAdmit) |
| `409` | `offline_capture_nonce_replayed` | [`offlineCaptureBundleAdmit`](https://noxtica.com/docs/api/reference/mobile/#offlineCaptureBundleAdmit) |
| `410` | `invalid_request` | [`offlineCaptureBundleAdmit`](https://noxtica.com/docs/api/reference/mobile/#offlineCaptureBundleAdmit) |
| `410` | `offline_capture_bundle_expired` | [`offlineCaptureBundleAdmit`](https://noxtica.com/docs/api/reference/mobile/#offlineCaptureBundleAdmit) |
| `413` | `body_too_large` | [`postAttestAndroid`](https://noxtica.com/docs/api/reference/mobile/#postAttestAndroid), [`postAttestIos`](https://noxtica.com/docs/api/reference/mobile/#postAttestIos), [`postAttestVerify`](https://noxtica.com/docs/api/reference/mobile/#postAttestVerify), [`postAttestChallenge`](https://noxtica.com/docs/api/reference/mobile/#postAttestChallenge), and 8 more |
| `413` | `invalid_request` | [`postAppConfig`](https://noxtica.com/docs/api/reference/mobile/#postAppConfig), [`postHandoffMint`](https://noxtica.com/docs/api/reference/mobile/#postHandoffMint), [`postHandoffConsume`](https://noxtica.com/docs/api/reference/mobile/#postHandoffConsume), [`offlineCaptureBundleAdmit`](https://noxtica.com/docs/api/reference/mobile/#offlineCaptureBundleAdmit) |
| `415` | `invalid_request` | [`postAttestAndroid`](https://noxtica.com/docs/api/reference/mobile/#postAttestAndroid), [`postAttestIos`](https://noxtica.com/docs/api/reference/mobile/#postAttestIos), [`postAttestVerify`](https://noxtica.com/docs/api/reference/mobile/#postAttestVerify), [`postAttestChallenge`](https://noxtica.com/docs/api/reference/mobile/#postAttestChallenge), and 7 more |
| `429` | `Rate limit exceeded` | [`postAttestAndroid`](https://noxtica.com/docs/api/reference/mobile/#postAttestAndroid), [`postAttestIos`](https://noxtica.com/docs/api/reference/mobile/#postAttestIos), [`postAttestVerify`](https://noxtica.com/docs/api/reference/mobile/#postAttestVerify), [`postAttestChallenge`](https://noxtica.com/docs/api/reference/mobile/#postAttestChallenge), and 18 more |
| `500` | `Internal server error` | [`postAttestAndroid`](https://noxtica.com/docs/api/reference/mobile/#postAttestAndroid), [`postAttestIos`](https://noxtica.com/docs/api/reference/mobile/#postAttestIos), [`postAppConfig`](https://noxtica.com/docs/api/reference/mobile/#postAppConfig), [`postPasskeyChallenge`](https://noxtica.com/docs/api/reference/mobile/#postPasskeyChallenge), and 4 more |
| `503` | `device_delegation_storage_unavailable` | [`deviceDelegationCreate`](https://noxtica.com/docs/api/reference/mobile/#deviceDelegationCreate), [`deviceDelegationList`](https://noxtica.com/docs/api/reference/mobile/#deviceDelegationList), [`deviceDelegationRevoke`](https://noxtica.com/docs/api/reference/mobile/#deviceDelegationRevoke) |
| `503` | `invalid_request` | [`postAttestAndroid`](https://noxtica.com/docs/api/reference/mobile/#postAttestAndroid), [`postAttestIos`](https://noxtica.com/docs/api/reference/mobile/#postAttestIos), [`deviceDelegationCreate`](https://noxtica.com/docs/api/reference/mobile/#deviceDelegationCreate), [`deviceDelegationList`](https://noxtica.com/docs/api/reference/mobile/#deviceDelegationList), and 3 more |
| `503` | `kyc_first_party_provenance_unavailable` | [`offlineNoncePoolMint`](https://noxtica.com/docs/api/reference/mobile/#offlineNoncePoolMint), [`offlineCaptureBundleAdmit`](https://noxtica.com/docs/api/reference/mobile/#offlineCaptureBundleAdmit) |
| `503` | `offline_capture_storage_unavailable` | [`offlineNoncePoolMint`](https://noxtica.com/docs/api/reference/mobile/#offlineNoncePoolMint), [`offlineCaptureBundleAdmit`](https://noxtica.com/docs/api/reference/mobile/#offlineCaptureBundleAdmit) |
| `503` | `registry_write_failed` | [`recoveryOpenCase`](https://noxtica.com/docs/api/reference/mobile/#recoveryOpenCase), [`recoveryGetCase`](https://noxtica.com/docs/api/reference/mobile/#recoveryGetCase), [`recoveryOpenAppeal`](https://noxtica.com/docs/api/reference/mobile/#recoveryOpenAppeal), [`recoveryGetAppeal`](https://noxtica.com/docs/api/reference/mobile/#recoveryGetAppeal) |
## Telemetry ingestion API: errors
Codes named in the responses of the Telemetry ingestion API operations.
| Status | Code | Returned by |
| --- | --- | --- |
| `400` | `apm_invalid_payload` | [`v1ApmIngestDeploymentMarker`](https://noxtica.com/docs/api/reference/ingest/#v1ApmIngestDeploymentMarker) |
| `400` | `apm_malformed_json` | [`v1ApmIngestDeploymentMarker`](https://noxtica.com/docs/api/reference/ingest/#v1ApmIngestDeploymentMarker) |
| `400` | `apm_malformed_logs_payload` | [`v1ApmIngestLogs`](https://noxtica.com/docs/api/reference/ingest/#v1ApmIngestLogs) |
| `400` | `apm_malformed_metrics_payload` | [`v1ApmIngestMetrics`](https://noxtica.com/docs/api/reference/ingest/#v1ApmIngestMetrics) |
| `400` | `apm_malformed_otlp_json` | [`v1ApmIngestTraces`](https://noxtica.com/docs/api/reference/ingest/#v1ApmIngestTraces) |
| `400` | `apm_malformed_profile_json` | [`v1ApmIngestProfiles`](https://noxtica.com/docs/api/reference/ingest/#v1ApmIngestProfiles) |
| `401` | `apm_auth_expired` | [`v1ApmIngestDeploymentMarker`](https://noxtica.com/docs/api/reference/ingest/#v1ApmIngestDeploymentMarker) |
| `403` | `apm_environment_mismatch` | [`v1ApmIngestDeploymentMarker`](https://noxtica.com/docs/api/reference/ingest/#v1ApmIngestDeploymentMarker) |
| `413` | `apm_body_too_large` | [`v1ApmIngestDeploymentMarker`](https://noxtica.com/docs/api/reference/ingest/#v1ApmIngestDeploymentMarker) |
| `415` | `apm_unsupported_media_type` | [`v1ApmIngestDeploymentMarker`](https://noxtica.com/docs/api/reference/ingest/#v1ApmIngestDeploymentMarker) |
| `429` | `apm_rate_limited` | [`v1ApmIngestDeploymentMarker`](https://noxtica.com/docs/api/reference/ingest/#v1ApmIngestDeploymentMarker) |
| `503` | `apm_authority_unavailable` | [`v1ApmIngestDeploymentMarker`](https://noxtica.com/docs/api/reference/ingest/#v1ApmIngestDeploymentMarker) |
| `503` | `apm_profile_storage_unavailable` | [`v1ApmIngestProfiles`](https://noxtica.com/docs/api/reference/ingest/#v1ApmIngestProfiles) |
## Observability query API: errors
Codes named in the responses of the Observability query API operations.
| Status | Code | Returned by |
| --- | --- | --- |
| `400` | `invalid_request` | [`v1ApmListProjects`](https://noxtica.com/docs/api/reference/observability/#v1ApmListProjects), [`v1ApmListProjectEnvironments`](https://noxtica.com/docs/api/reference/observability/#v1ApmListProjectEnvironments), [`v1ApmGetEnvironmentPolicy`](https://noxtica.com/docs/api/reference/observability/#v1ApmGetEnvironmentPolicy), [`v1ApmUpdateEnvironmentPolicy`](https://noxtica.com/docs/api/reference/observability/#v1ApmUpdateEnvironmentPolicy), and 10 more |
| `400` | `schema_invalid` | [`codingAgentListFindings`](https://noxtica.com/docs/api/reference/observability/#codingAgentListFindings) |
| `401` | `coding_agent_auth_invalid` | [`codingAgentListFindings`](https://noxtica.com/docs/api/reference/observability/#codingAgentListFindings), [`codingAgentGetTrace`](https://noxtica.com/docs/api/reference/observability/#codingAgentGetTrace), [`codingAgentGetErrorGroup`](https://noxtica.com/docs/api/reference/observability/#codingAgentGetErrorGroup) |
| `401` | `coding_agent_auth_missing` | [`codingAgentListFindings`](https://noxtica.com/docs/api/reference/observability/#codingAgentListFindings), [`codingAgentGetTrace`](https://noxtica.com/docs/api/reference/observability/#codingAgentGetTrace), [`codingAgentGetErrorGroup`](https://noxtica.com/docs/api/reference/observability/#codingAgentGetErrorGroup) |
| `401` | `Unauthorized` | [`v1ApmListProjects`](https://noxtica.com/docs/api/reference/observability/#v1ApmListProjects), [`v1ApmListProjectEnvironments`](https://noxtica.com/docs/api/reference/observability/#v1ApmListProjectEnvironments), [`v1ApmGetEnvironmentPolicy`](https://noxtica.com/docs/api/reference/observability/#v1ApmGetEnvironmentPolicy), [`v1ApmUpdateEnvironmentPolicy`](https://noxtica.com/docs/api/reference/observability/#v1ApmUpdateEnvironmentPolicy), and 10 more |
| `403` | `API key does not have read:apm scope` | [`v1ApmListProjects`](https://noxtica.com/docs/api/reference/observability/#v1ApmListProjects), [`v1ApmListProjectEnvironments`](https://noxtica.com/docs/api/reference/observability/#v1ApmListProjectEnvironments), [`v1ApmGetEnvironmentPolicy`](https://noxtica.com/docs/api/reference/observability/#v1ApmGetEnvironmentPolicy), [`v1ApmUpdateEnvironmentPolicy`](https://noxtica.com/docs/api/reference/observability/#v1ApmUpdateEnvironmentPolicy), and 10 more |
| `403` | `coding_agent_scope_denied` | [`codingAgentGetTrace`](https://noxtica.com/docs/api/reference/observability/#codingAgentGetTrace), [`codingAgentGetErrorGroup`](https://noxtica.com/docs/api/reference/observability/#codingAgentGetErrorGroup) |
| `404` | `coding_agent_error_group_not_found` | [`codingAgentGetErrorGroup`](https://noxtica.com/docs/api/reference/observability/#codingAgentGetErrorGroup) |
| `404` | `resource_not_found` | [`v1ApmListProjectEnvironments`](https://noxtica.com/docs/api/reference/observability/#v1ApmListProjectEnvironments), [`v1ApmGetEnvironmentPolicy`](https://noxtica.com/docs/api/reference/observability/#v1ApmGetEnvironmentPolicy), [`v1ApmUpdateEnvironmentPolicy`](https://noxtica.com/docs/api/reference/observability/#v1ApmUpdateEnvironmentPolicy), [`v1ApmSearchTraces`](https://noxtica.com/docs/api/reference/observability/#v1ApmSearchTraces), and 9 more |
| `409` | `capture_unavailable` | [`v1ApmUpdateEnvironmentPolicy`](https://noxtica.com/docs/api/reference/observability/#v1ApmUpdateEnvironmentPolicy) |
| `429` | `coding_agent_rate_limited` | [`codingAgentListFindings`](https://noxtica.com/docs/api/reference/observability/#codingAgentListFindings), [`codingAgentGetTrace`](https://noxtica.com/docs/api/reference/observability/#codingAgentGetTrace), [`codingAgentGetErrorGroup`](https://noxtica.com/docs/api/reference/observability/#codingAgentGetErrorGroup) |
| `429` | `Rate limit exceeded` | [`v1ApmListProjects`](https://noxtica.com/docs/api/reference/observability/#v1ApmListProjects), [`v1ApmListProjectEnvironments`](https://noxtica.com/docs/api/reference/observability/#v1ApmListProjectEnvironments), [`v1ApmGetEnvironmentPolicy`](https://noxtica.com/docs/api/reference/observability/#v1ApmGetEnvironmentPolicy), [`v1ApmSearchTraces`](https://noxtica.com/docs/api/reference/observability/#v1ApmSearchTraces), and 8 more |
| `500` | `internal_error` | [`v1ApmSearchTraces`](https://noxtica.com/docs/api/reference/observability/#v1ApmSearchTraces), [`v1ApmGetTrace`](https://noxtica.com/docs/api/reference/observability/#v1ApmGetTrace) |
| `502` | `coding_agent_query_failed` | [`codingAgentListFindings`](https://noxtica.com/docs/api/reference/observability/#codingAgentListFindings), [`codingAgentGetTrace`](https://noxtica.com/docs/api/reference/observability/#codingAgentGetTrace), [`codingAgentGetErrorGroup`](https://noxtica.com/docs/api/reference/observability/#codingAgentGetErrorGroup) |
| `503` | `coding_agent_authority_unavailable` | [`codingAgentListFindings`](https://noxtica.com/docs/api/reference/observability/#codingAgentListFindings), [`codingAgentGetTrace`](https://noxtica.com/docs/api/reference/observability/#codingAgentGetTrace), [`codingAgentGetErrorGroup`](https://noxtica.com/docs/api/reference/observability/#codingAgentGetErrorGroup) |
| `503` | `coding_agent_bq_unavailable` | [`codingAgentListFindings`](https://noxtica.com/docs/api/reference/observability/#codingAgentListFindings), [`codingAgentGetTrace`](https://noxtica.com/docs/api/reference/observability/#codingAgentGetTrace), [`codingAgentGetErrorGroup`](https://noxtica.com/docs/api/reference/observability/#codingAgentGetErrorGroup) |
## MCP server: errors
Codes named in the responses of the MCP server operations.
| Status | Code | Returned by |
| --- | --- | --- |
| `401` | `unauthorized` | [`mcpJsonRpc`](https://noxtica.com/docs/api/reference/mcp/#mcpJsonRpc) |
| `404` | `not_found` | [`mcpJsonRpc`](https://noxtica.com/docs/api/reference/mcp/#mcpJsonRpc) |
| `429` | `rate_limited` | [`mcpJsonRpc`](https://noxtica.com/docs/api/reference/mcp/#mcpJsonRpc) |
| `500` | `internal_error` | [`mcpJsonRpc`](https://noxtica.com/docs/api/reference/mcp/#mcpJsonRpc) |
## Pulse tenant API: errors
Codes named in the responses of the Pulse tenant API operations.
| Status | Code | Returned by |
| --- | --- | --- |
| `400` | `invalid_cursor` | [`pulseTenantListDecisions`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantListDecisions) |
| `400` | `invalid_parameter` | [`pulseTenantCreateLinkCode`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantCreateLinkCode), [`pulseTenantGetLink`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantGetLink), [`pulseTenantUnlink`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantUnlink) |
| `400` | `invalid_request` | [`pulseTenantListDecisions`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantListDecisions), [`pulseTenantReverseDecision`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantReverseDecision) |
| `400` | `invalid_subject` | [`pulseTenantSubjectStatus`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantSubjectStatus), [`pulseTenantGetLink`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantGetLink), [`pulseTenantUnlink`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantUnlink) |
| `401` | `invalid_api_key` | [`pulseTenantSubjectStatus`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantSubjectStatus), [`pulseTenantListDecisions`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantListDecisions), [`pulseTenantGetDecision`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantGetDecision), [`pulseTenantReverseDecision`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantReverseDecision), and 3 more |
| `401` | `missing_api_key` | [`pulseTenantSubjectStatus`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantSubjectStatus), [`pulseTenantListDecisions`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantListDecisions), [`pulseTenantGetDecision`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantGetDecision), [`pulseTenantReverseDecision`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantReverseDecision), and 3 more |
| `403` | `insufficient_scope` | [`pulseTenantSubjectStatus`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantSubjectStatus), [`pulseTenantListDecisions`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantListDecisions), [`pulseTenantGetDecision`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantGetDecision), [`pulseTenantReverseDecision`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantReverseDecision), and 3 more |
| `403` | `scope_not_granted` | [`pulseTenantListDecisions`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantListDecisions) |
| `403` | `tenant_not_armed` | [`pulseTenantSubjectStatus`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantSubjectStatus), [`pulseTenantListDecisions`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantListDecisions), [`pulseTenantGetDecision`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantGetDecision), [`pulseTenantReverseDecision`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantReverseDecision), and 3 more |
| `404` | `application_not_found` | [`pulseTenantCreateLinkCode`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantCreateLinkCode) |
| `404` | `decision_not_found` | [`pulseTenantGetDecision`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantGetDecision), [`pulseTenantReverseDecision`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantReverseDecision) |
| `404` | `subject_not_found` | [`pulseTenantSubjectStatus`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantSubjectStatus), [`pulseTenantListDecisions`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantListDecisions), [`pulseTenantGetLink`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantGetLink), [`pulseTenantUnlink`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantUnlink) |
| `409` | `ambiguous_subject` | [`pulseTenantSubjectStatus`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantSubjectStatus), [`pulseTenantGetLink`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantGetLink), [`pulseTenantUnlink`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantUnlink) |
| `409` | `external_user_already_linked` | [`pulseTenantCreateLinkCode`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantCreateLinkCode) |
| `409` | `hint_not_active` | [`pulseTenantReverseDecision`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantReverseDecision) |
| `429` | `rate_limited` | [`pulseTenantCreateLinkCode`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantCreateLinkCode) |
| `429` | `too_many_outstanding_codes` | [`pulseTenantCreateLinkCode`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantCreateLinkCode) |
| `503` | `rate_limiter_unavailable` | [`pulseTenantSubjectStatus`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantSubjectStatus), [`pulseTenantCreateLinkCode`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantCreateLinkCode), [`pulseTenantGetLink`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantGetLink), [`pulseTenantUnlink`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantUnlink) |
| `503` | `tenant_auth_unavailable` | [`pulseTenantSubjectStatus`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantSubjectStatus), [`pulseTenantCreateLinkCode`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantCreateLinkCode), [`pulseTenantGetLink`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantGetLink), [`pulseTenantUnlink`](https://noxtica.com/docs/api/reference/pulse/#pulseTenantUnlink) |
## Health and public key endpoints: errors
Codes named in the responses of the Health and public key endpoints operations.
| Status | Code | Returned by |
| --- | --- | --- |
| `404` | `Not found` | [`getCollectorJwks`](https://noxtica.com/docs/api/reference/status/#getCollectorJwks), [`getAgentPassportJwks`](https://noxtica.com/docs/api/reference/status/#getAgentPassportJwks) |
| `429` | `Rate limit exceeded` | [`getHealth`](https://noxtica.com/docs/api/reference/status/#getHealth) |
_This page is generated from the Noxtica OpenAPI specification release `v0.4.0`: `kyc.yaml` version `1.2.0-2026-10-27` (SHA-256 `c91a695cfde0`), `mcp.yaml` version `0.1.0-2026-10-27` (SHA-256 `1a4875efa736`), `pulse.yaml` version `0.9.0-2026-10-27` (SHA-256 `95196a58bb5b`), `v1.yaml` version `1.3.0-2026-10-27` (SHA-256 `3fd15257a022`). Do not edit it by hand._
---
Source: https://noxtica.com/docs/api/rate-limits/
Markdown: https://noxtica.com/docs/api/rate-limits/index.md
Last updated: 2026-10-27
# API rate limits
Noxtica limits how often a caller can use an operation. Limits depend on the operation and on your account, so this page describes the mechanism and does not list figures. Do not hard-code a limit: the response tells you when to try again.
## What a limited request returns
A request over its limit is rejected with HTTP status `429` and a JSON body. The `Retry-After` header holds the number of seconds to wait before the next request.
| Header | Meaning |
| --- | --- |
| `Retry-After` | Seconds until the bucket allows another request. |
| Field | Type | Always returned | Description |
| --- | --- | --- | --- |
| `error` | string | No | Allowed values: `Rate limit exceeded`. |
| `retryAfter` | integer | No | |
| `requestId` | string | No | |
Example body:
```json
{
"error": "Rate limit exceeded",
"retryAfter": 1,
"requestId": "req-test"
}
```
| Header | Meaning |
| --- | --- |
| `Retry-After` | Seconds until the window resets. |
| Field | Type | Always returned | Description |
| --- | --- | --- | --- |
| `code` | string | Yes | Stable machine-readable identifier. |
| `error` | string | Yes | |
| `message` | string | No | |
| `requestId` | string | No | |
| Header | Meaning |
| --- | --- |
| `Retry-After` | Seconds until the bucket allows another request. |
| Field | Type | Always returned | Description |
| --- | --- | --- | --- |
| `error` | string | Yes | Allowed values: `Rate limit exceeded`. |
| `retryAfter` | integer | Yes | Seconds to wait; equals the `Retry-After` header. |
| `requestId` | string | No | |
Example body:
```json
{
"error": "Rate limit exceeded",
"retryAfter": 12,
"requestId": "req-test"
}
```
## How to retry
1. Stop sending requests for the operation until the `Retry-After` period has passed.
2. Retry the request once, then increase the wait on each further `429`, with random jitter, up to a maximum you choose.
3. Retry only requests that are safe to repeat. For an operation that creates something, send an `Idempotency-Key` where the operation accepts one so a retry cannot create a second copy.
4. Spread bulk work over time instead of sending it in one burst.
_This page is generated from the Noxtica OpenAPI specification release `v0.4.0`: `kyc.yaml` version `1.2.0-2026-10-27` (SHA-256 `c91a695cfde0`), `mcp.yaml` version `0.1.0-2026-10-27` (SHA-256 `1a4875efa736`), `pulse.yaml` version `0.9.0-2026-10-27` (SHA-256 `95196a58bb5b`), `v1.yaml` version `1.3.0-2026-10-27` (SHA-256 `3fd15257a022`). Do not edit it by hand._
---
Source: https://noxtica.com/docs/api/reference/
Markdown: https://noxtica.com/docs/api/reference/index.md
Last updated: 2026-10-27
# API reference
The reference has one page for each API area. Every operation on a page has its own anchor, which is the `operationId` of the operation in the OpenAPI specification, so a link such as `/docs/api/reference//#` always points at one operation.
## API areas
| API | What it covers | Operations | Credential |
| --- | --- | --- | --- |
| [Identity verification API](https://noxtica.com/docs/api/reference/kyc/) | Verify identities, run hosted verification sessions, batch and re-verify, store evidence, and receive signed KYC, KYB and KYM webhooks. | 25 | `ApiKeyAuth`, `SessionTokenAuth` |
| [Risk scoring and agent trust API](https://noxtica.com/docs/api/reference/score/) | Score a request, look up IP and device reputation, verify AI agents, and mint signed crawler vouchers from your server. | 7 | `ApiKeyAuth` |
| [Protected actions API](https://noxtica.com/docs/api/reference/protected-actions/) | Redeem the request id a browser obtains for a protected action (login, signup, checkout) before your server lets the action proceed. | 1 | `ApiKeyAuth` |
| [Device intelligence API](https://noxtica.com/docs/api/reference/device/) | Read devices, events and visits, export data, fetch the sealed-results key, write labels, and manage behavioral baselines. | 18 | `ApiKeyAuth` |
| [Mobile and device identity API](https://noxtica.com/docs/api/reference/mobile/) | Verify mobile attestation and integrity, deliver app configuration, and manage passkeys, handoff, delegation, recovery, wallet state and offline capture. | 22 | `ApiKeyAuth` |
| [Telemetry ingestion API](https://noxtica.com/docs/api/reference/ingest/) | Send OpenTelemetry traces, metrics, logs, profiles and deployment markers with an ingestion key. | 5 | `ApmIngestKeyAuth` |
| [Observability query API](https://noxtica.com/docs/api/reference/observability/) | Query projects, traces, services and releases, manage environment policy, run exports and privacy-request lookups, and read recent signals from a coding agent. | 17 | `ApiKeyAuth`, `CodingAgentKeyAuth` |
| [MCP server](https://noxtica.com/docs/api/reference/mcp/) | Connect an AI assistant or your own code to your workspace through the Model Context Protocol with a scoped token. | 1 | `McpTokenAuth` |
| [Pulse tenant API](https://noxtica.com/docs/api/reference/pulse/) | Read player status and decisions, create link codes, and manage links from your own back end with a tenant API key. | 7 | `tenantKey` |
| [Health and public key endpoints](https://noxtica.com/docs/api/reference/status/) | The unauthenticated collector health probe and the public signing-key documents for verifying signed envelopes and Agent Passports offline. | 3 | None |
## Shared conventions
The credentials, errors, rate limits and webhooks that apply to every area are described once: start with the [API overview](https://noxtica.com/docs/api/), then read [Authentication](https://noxtica.com/docs/api/authentication/), [Errors](https://noxtica.com/docs/api/errors/), [Rate limits](https://noxtica.com/docs/api/rate-limits/) and [Webhooks](https://noxtica.com/docs/api/webhooks/).
_This page is generated from the Noxtica OpenAPI specification release `v0.4.0`: `kyc.yaml` version `1.2.0-2026-10-27` (SHA-256 `c91a695cfde0`), `mcp.yaml` version `0.1.0-2026-10-27` (SHA-256 `1a4875efa736`), `pulse.yaml` version `0.9.0-2026-10-27` (SHA-256 `95196a58bb5b`), `v1.yaml` version `1.3.0-2026-10-27` (SHA-256 `3fd15257a022`). Do not edit it by hand._
---
Source: https://noxtica.com/docs/api/mcp/
Markdown: https://noxtica.com/docs/api/mcp/index.md
Last updated: 2026-10-27
# Connect an MCP client
Connect an AI assistant or your own code to your workspace through the Model Context Protocol with a scoped token.
## Endpoint
| Environment | Base URL |
| --- | --- |
| Production | `https://backoffice.noxtica.com` |
### Scope
The MCP server is one HTTPS endpoint, `POST /api/mcp`, on the Backoffice host:
`https://backoffice.noxtica.com` (production). It speaks JSON-RPC 2.0 over a synchronous HTTP POST. It is not part of the
collector API and is not consumed by the SDK family; this file describes the HTTP envelope
and the JSON-RPC methods. The catalogue of tools is **not** listed here: it depends on the
token, so call `tools/list` for the tools your token may use.
### Authentication
Send `Authorization: Bearer mcp_...`, where the token is an MCP token created in the
Backoffice under Integrations & API, MCP tokens (the secret is shown once). The server uses a
static opaque bearer token, **not** OAuth: it sends no `WWW-Authenticate` challenge and
exposes no OAuth metadata, so configure your MCP client with a custom `Authorization`
header. A token lives at most 90 days and also expires after 90 days without use. A revoked,
expired or unknown token gets HTTP `401`.
A token is either a *read* token or a *write* token and carries scopes. Scopes are the
ceiling of what a token can do: `tools/list` shows only the tools a token's scopes and tool
allowlist permit, and a tool outside them answers JSON-RPC error `-32001` (a tool that does
not exist for the token answers `-32002`). A write token can only *plan* a management
change; it can never apply one: a person approves every plan in the Backoffice.
### Methods
| Method | Purpose |
|---|---|
| `initialize` | Server information and capabilities. |
| `tools/list` | The tools this token may call, with their input schemas. |
| `tools/call` | Call one tool: `params: {"name": "...", "arguments": {...}}`. The result is one text content item holding JSON. |
| `resources/list`, `resources/templates/list`, `resources/read` | Public-content resources, available only for tokens that are allowed to read them; otherwise `-32601`. |
The protocol version answered by `initialize` is `2024-11-05`. A client that asks for
`2025-03-26` in `initialize.params.protocolVersion` gets that version when streamable
transport is enabled for the deployment; the server then also answers the same JSON-RPC
response as a single `text/event-stream` message when the request carries
`Accept: text/event-stream`. Otherwise the answer is always a plain JSON body.
### Errors
Transport-level failures use the HTTP status and a small JSON body:
`401 {"error":"unauthorized"}`, `404 {"error":"not_found"}` (MCP is not enabled for the
deployment), `429 {"error":"rate_limited"}` and `500 {"error":"internal_error"}`. Everything
else is a JSON-RPC error carried in an HTTP `200` body, including an unparseable body
(`-32700`). Branch on the numeric `error.code`; see `JsonRpcError`.
### Rate limits and limits
Each token has a request limit; a request over it answers `429` with `Retry-After` and the
headers `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset` (Unix seconds)
and `X-RateLimit-Bucket`, which are also sent on successful responses of this endpoint.
`tools/call` and resource reads are additionally limited to 60 calls per 60 seconds per
token; going over answers `-32004` with `error.data.retryAfterSeconds`. A monthly query
allowance applies to tool calls and resource reads (`-32003` when used up, `-32005` when the
plan does not include MCP). A serialized tool result may be at most 200 KB; a larger one
answers `-32602`, so lower the `limit` argument of the tool. The request body may be at most
1 MB.
## Operations
The full request and response description of each operation is in the [MCP server](https://noxtica.com/docs/api/reference/mcp/) reference.
| Operation | Request | Summary |
| --- | --- | --- |
| [`mcpJsonRpc`](https://noxtica.com/docs/api/reference/mcp/#mcpJsonRpc) | `POST /api/mcp` | Send one MCP JSON-RPC request |
_This page is generated from the Noxtica OpenAPI specification release `v0.4.0`: `kyc.yaml` version `1.2.0-2026-10-27` (SHA-256 `c91a695cfde0`), `mcp.yaml` version `0.1.0-2026-10-27` (SHA-256 `1a4875efa736`), `pulse.yaml` version `0.9.0-2026-10-27` (SHA-256 `95196a58bb5b`), `v1.yaml` version `1.3.0-2026-10-27` (SHA-256 `3fd15257a022`). Do not edit it by hand._
---
Source: https://noxtica.com/docs/concepts/mcp-integration/
Markdown: https://noxtica.com/docs/concepts/mcp-integration/index.md
Last updated: 2026-10-27
# MCP Integration
**Definition.** Noxtica's Model Context Protocol (MCP) integration gives an eligible tenant's external AI workflow structured, **read-only** access to supported Noxtica context. The surface uses MCP over JSON-RPC and requires a scoped bearer token.
It solves a context problem: an internal assistant or investigation workflow may need current policy, alert, or risk-distribution information without a person copying it from the console. MCP makes approved reads machine-consumable while leaving action and authorization in customer-owned systems.
Two boundaries define the integration:
- **Read-only.** An MCP client cannot change Noxtica configuration, create a policy, or act on traffic.
- **Opt-in and tenant-scoped.** MCP is off by default, enabled only for eligible tenants, and restricted to the tenant and scopes associated with the issued token.
## When it applies
MCP is useful when a security, fraud, support, or reporting workflow already uses an MCP-compatible client and needs Noxtica context for:
- summarizing a tenant's current policies or rules;
- adding recent alerts to an investigation brief;
- describing risk distribution for an operational review; or
- answering a bounded question before a human opens the source record.
If a workflow needs to update Noxtica, enforce a traffic decision, or combine data across tenants, this integration does not provide that capability.
## How customers use it
1. Confirm MCP eligibility and request tenant enablement.
2. Have an authorized operator create a token with only the required read scopes.
3. Configure the MCP-compatible client with the provisioned server details and token.
4. Request a supported read and inspect the structured response.
5. Route the result to a human review, report, or customer-owned automation with its own permissions.
6. Review call history, and mint or revoke tokens under your normal access process.
Connection details and available tools are provided during tenant provisioning; do not infer undocumented endpoints or scopes from examples.
## How Noxtica does it
MCP is the open protocol boundary. Noxtica applies product access controls before returning tenant information and records calls for review.
### Authentication
Bearer tokens have three customer-facing controls:
- **Scoped** — a token can read only the enabled surfaces represented by its scopes.
- **Rate-limited** — requests are subject to the tenant's provisioned limits.
- **Audited** — calls are recorded, including denied calls, so operators can review what was requested and when.
Treat the token as a secret. Give each integration the narrowest useful scope, keep it out of browser code and prompts, and revoke it and mint a new one when ownership changes.
### The read-only tool set
Subject to tenant enablement and token scope, the current read surface can include:
- **Policies** — configured policy context.
- **Rules** — rules used by supported decision workflows.
- **Alerts** — recent tenant alerts.
- **Risk distribution** — aggregate risk context for the tenant's traffic.
Every tool is a read. Responses are data for the client to interpret, not instructions and not permission to take an action. The connected agent cannot use MCP to change Noxtica or customer infrastructure.
## Outputs and decisions
| MCP output | How it can inform a decision |
| ----------------------- | -------------------------------------------------------------------- |
| Policy and rule context | Check whether an observed result matches the intended tenant posture |
| Recent alerts | Prioritize which event or period a human should investigate |
| Risk distribution | Compare current traffic mix with the team's expected operating range |
| Call audit record | Review which integration requested which Noxtica context |
An MCP response can become stale after configuration or traffic changes. For customer-impacting decisions, retrieve current source records and apply the customer's normal authorization and review controls.
## Eligibility and limitations
- MCP requires explicit tenant enablement and provisioned connection details; there is no anonymous or self-serve connection.
- The integration is read-only even if the connected client supports write-capable tools elsewhere.
- Tokens do not bypass operator roles, tenant boundaries, scopes, or rate limits.
- Supported tools can differ by tenant provisioning. An absent tool is not an invitation to call an undocumented API.
- MCP does not verify the identity or trustworthiness of agents arriving at your site; that is the separate [KYA](https://noxtica.com/docs/concepts/know-your-agent/) concern.
## Where it fits
MCP is the "you integrate agentically" part of [Agentic Security](https://noxtica.com/docs/concepts/agentic-security/). It is distinct from the [AI Assistant](https://noxtica.com/docs/concepts/ai-assistant/) inside the console and from [Know Your Agent](https://noxtica.com/docs/concepts/know-your-agent/), which evaluates supported incoming-agent identities.
## Who it fits
MCP fits a security, fraud, support or reporting workflow that already uses an MCP-compatible client. The uses are listed under [When it applies](https://noxtica.com/docs/concepts/mcp-integration/#when-it-applies): investigation briefs, policy summaries and operations reporting.
## How teams connect
Connection details come from your tenant provisioning; the steps are under [How customers use it](https://noxtica.com/docs/concepts/mcp-integration/#how-customers-use-it). Tokens are created in Backoffice: a workspace Admin mints and revokes tokens after a fresh multi-factor check, and tokens expire. See [AI assistant, MCP tokens and coding-agent keys](https://noxtica.com/docs/backoffice/ai-assistant-and-mcp/). The endpoint, protocol and tool list are in [MCP server](https://noxtica.com/docs/api/mcp/).
## Limits
MCP is a read path into tenant telemetry, not a control path.
- **Controlled availability.** MCP access follows the tenant's plan tier and operator gates. Connections are set up with Noxtica.
- Scores and risk levels in responses are probabilistic and can be wrong. Your team decides what to do, and is responsible for the client and model it connects. See [Calibration](https://noxtica.com/docs/concepts/calibration/).
What the tools can and cannot do is under [The read-only tool set](https://noxtica.com/docs/concepts/mcp-integration/#the-read-only-tool-set). Enablement rules and stale responses are under [Eligibility and limitations](https://noxtica.com/docs/concepts/mcp-integration/#eligibility-and-limitations) and [Outputs and decisions](https://noxtica.com/docs/concepts/mcp-integration/#outputs-and-decisions).
## Common questions
### Can an AI client change my Noxtica settings?
No. The tools are read-only. See [The read-only tool set](https://noxtica.com/docs/concepts/mcp-integration/#the-read-only-tool-set).
### Can anyone connect an AI client?
No. Every connection needs a token issued by an authorized operator, and access is gated as described under [Limits](https://noxtica.com/docs/concepts/mcp-integration/#limits).
### How is MCP different from the AI assistant?
The [AI Assistant](https://noxtica.com/docs/concepts/ai-assistant/) serves a signed-in operator inside the console. MCP serves an approved external client that reads scoped data with a token. They are provisioned separately.
## Read deeper
- [Agentic Security](https://noxtica.com/docs/concepts/agentic-security/) — how external reads, operator investigation, and incoming-agent governance differ.
- [AI Assistant](https://noxtica.com/docs/concepts/ai-assistant/) — the operator-side read experience.
- [Features: AI-assisted operations](https://noxtica.com/docs/features/#ai-assisted-operations) — the assistant and MCP customer surfaces.
- [Backend integration](https://noxtica.com/docs/backend-integration/) — supported Server API device reads for application code.
- [Contact](https://noxtica.com/contact/) — confirm MCP eligibility and enablement.
---
Source: https://noxtica.com/docs/backoffice/ai-assistant-and-mcp/
Markdown: https://noxtica.com/docs/backoffice/ai-assistant-and-mcp/index.md
Last updated: 2026-10-27
# AI assistant, MCP tokens and coding-agent keys
Backoffice has three AI-related surfaces. The **assistant** is a chat panel for operators. **MCP Tokens** let an outside AI client read workspace data through the Model Context Protocol. **Coding Agent Keys** let a coding agent read your errors, traces and logs. A workspace Admin sets all three up and keeps each one to the narrowest access it needs.
## What it is
Availability: Availability depends on your plan, role and the modules enabled for your organisation.
| Surface | Where | Who uses it | What it reads or does |
| --- | --- | --- | --- |
| Assistant | Floating **Assistant** button on every page | Admin and above | Answers questions about your workspace inside your own role and workspace |
| LLM Routing, Speech, LLM Provider Keys | `/ai/llm-routing`, `/ai/speech`, `/ai/provider-keys` | Admin | Where model calls go, voice features, your own provider keys |
| MCP Tokens | `/integrations/mcp-tokens` | Admin | Bearer tokens for an MCP client |
| Coding Agent Keys | `/integrations/coding-agent-keys` | Admin | Read-only keys for a coding agent |
How they differ from the concept pages: [AI Assistant](https://noxtica.com/docs/concepts/ai-assistant/) describes the operator copilot and [MCP Integration](https://noxtica.com/docs/concepts/mcp-integration/) describes the external read surface. The wire protocol, endpoint and tool list for MCP are in [MCP server](https://noxtica.com/docs/api/mcp/). This page covers the Backoffice side.
Treat every answer as a signal. The assistant says "AI-generated — may be inaccurate or incomplete. Not advice. Verify independently before acting." An MCP or coding-agent response is data for your own tooling to interpret.
## Prerequisites
- The Admin role. Lower roles do not see the assistant button or these pages. See [Backoffice guide](https://noxtica.com/docs/backoffice/overview/).
- An authenticator app. Minting a token or key, and changing assistant configuration, ask for a fresh MFA check.
- The assistant enabled for your organisation. When it is not, opening it shows "Assistant not enabled". When it is enabled but no provider is configured, it shows "Configuration pending". A tenant-level switch can also turn AI off for a workspace.
- For MCP Tokens: MCP enabled for your organisation. The page says the MCP server stays disabled until an operator turns it on.
- A secret store. Tokens and keys are shown once.
## Steps
### 1. Use the assistant
1. Select the **Assistant** button (bottom-right by default). Drag it to another corner, or focus it and press an arrow key to move it.
2. Ask a bounded question about your workspace, for example about policies, domains, fingerprints or the audit log.
3. Use the toolbar for **New chat**, **Save**, **Sessions**, the **Assistant model** picker, **Dock to the right** or **Dock to the bottom**, **Minimize** and **Maximize**. The panel is a helper: it does not block the page behind it.
What to expect:
- The assistant answers within your role and the active workspace.
- Answers show the data they were based on under **Sources**, or "No tenant data was read for this answer."
- Credits: the panel shows your monthly AI credits remaining. When they run out it says so and they reset at the start of the next month (UTC).
- Sessions: **Usage & export** lists your sessions with model, token cost and status, never their contents. When available, conversation text is kept for 30 days in a size-capped record that only you can see; you can export or erase it. If retention is off for your workspace, text is never stored on the server.
- Voice: when speech is enabled, dictation inserts a transcript for review and sends nothing until you press **Send**. Read-aloud plays an answer.
- Changes: write actions are off by default. Where they are enabled, the assistant only proposes a change. A **plan** shows the diff, and a person approves it with a fresh MFA check. The assistant cannot apply a change itself.
### 2. Choose model routing (LLM Routing)
`AI & Agents → LLM Routing` offers three modes: **Platform default**, **Prefer local** (use a locally running model when one is available, otherwise fall back silently) and **Require local (data residency)** (never send the workspace's data to a cloud model; a task with no matching local model fails). The section describes the setting as the model choice for the workstation Backoffice Agent's tasks for this workspace. Pick **Save**.
### 3. Set speech and your own provider keys
- `Speech`: shows which voice features are available and why any are off. Add your own speech provider key if you do not want to use the platform pool. Usage appears on **Usage & Quotas**.
- `LLM Provider Keys`: add a key for a provider you have an account with. Keys are stored encrypted and never shown again. Choose a **Data policy** for each key: **Tier-safe** (eligible to serve assistant turns once it has a model) or **Dev only** (can be tested, cannot serve assistant turns; OpenRouter is always dev only). Use **Discover models**, pick a **Default model**, and **Test** the credential. If you remove a key while using your own keys only, assistant turns stop when no other eligible key can serve them; the platform does not take over.
### 4. Mint an MCP token
1. Open `Integrations & API → MCP Tokens`. Tabs: **Manage** and **Integration** (an in-app guide).
2. Enter a **Name** of 2 to 200 characters that identifies the client that will hold it.
3. Choose read scopes. Scopes are grouped by area: Workspace & usage, Detection analytics, Devices, Noxtica Pulse, Rules & disputes, Alerts, Session replay, Governance, Agent Worker, Published content, RUM, APM & runtime tracker, KYC, KYB & KYM, SEO, Billing & wallet, Workspace settings & integrations, Infrastructure, Team & credential inventory. Each read scope names what it exposes, for example **Device scores & related devices** or **Audit log**.
4. Optionally restrict the tools the token can call, and set an expiry.
5. Select the create button, enter your MFA code, and copy the token. It is shown once.
Rules Backoffice enforces:
- The token is bound to your workspace, and it can never carry a permission that you do not hold.
- Expiry is mandatory and bounded. If you give none, the token expires 90 days after creation. A longer date is reduced to 90 days, and a date in the past is refused. A token that sits idle can also expire.
- A token has a summary or detail tier that changes how fine-grained the read results are. The tier never widens the token's column allowlist.
- Revoke a token to cut off any client at once. The row shows **Last used**.
- Write tokens exist only when write tokens are enabled for your organisation; otherwise minting one is refused. An agent that holds a write token can only plan a change. The plan appears under **Pending AI-agent plans** for 24 hours. You approve it with a fresh MFA check within 10 minutes, or reject it. If the token is revoked, the plan is cancelled.
Connect your client with the endpoint, headers and rate limits in [MCP server](https://noxtica.com/docs/api/mcp/). **Agentic Security → MCP token usage** shows queries used against the period limit. See [Risk actions, investigations and entity lookup](https://noxtica.com/docs/backoffice/risk-actions-and-investigations/).
### 5. Create a coding-agent key
1. Open `AI & Agents → Coding Agent Keys`.
2. Enter a **Label** (for example `ci-agent`; up to 200 characters) and choose scopes. The available scopes are **RUM errors**, **APM traces**, **APM errors**, **APM metrics**, **Logs**, **Profiles**, **Fingerprint / bot signals** and **KYC risk summaries**. Choose only the data the agent needs. The KYC scope covers risk summaries, not identity documents.
3. Select **Mint key** and enter your MFA code. Copy the `cak_` key; it is shown once.
4. Use **Rotate key** to replace the secret with the same scopes and label, or **Revoke key** to end access at once.
A coding-agent key is tenant-wide and read-only. The page says it never grants write access.
## Verify it works
- The assistant answers a question and lists its sources.
- The MCP token appears under **Manage** with scopes and an expiry, and **Last used** changes after your client's first call.
- Your MCP client lists tools and a call returns data inside its scopes. A call outside the scopes is refused.
- The coding-agent key row shows **Created** and, after use, **Last used**.
## Troubleshooting
| Symptom | Cause | Fix |
| --- | --- | --- |
| No **Assistant** button | Role below Admin | Ask a workspace Admin |
| "Assistant not enabled" | Not enabled for your environment | Ask your account team |
| "Configuration pending" | No AI provider key is configured | Ask your account team, or add a provider key if you use your own |
| "You've reached the assistant's usage limit" | A usage or credit limit was reached | Wait for the reset, or ask your account team |
| "Speech input is not available for your account yet" | Speech is off or not granted | See `AI & Agents → Speech` |
| Token creation says to enter a name or choose a scope | Name under 2 characters or no scope selected | Complete the form |
| Token creation is refused for a scope | You do not hold that permission | Ask for the role that includes it |
| A plan expired | Not approved within 10 minutes | Ask the agent to plan again |
| MCP client is refused | The token is revoked, expired or out of scope | Mint a new token with the scopes the client needs |
## Related
- [AI Assistant](https://noxtica.com/docs/concepts/ai-assistant/): what the operator copilot is for.
- [MCP Integration](https://noxtica.com/docs/concepts/mcp-integration/): the external read surface.
- [MCP server](https://noxtica.com/docs/api/mcp/): endpoint, protocol and limits.
- [Integrations and API pages](https://noxtica.com/docs/backoffice/integrations/): the other credential pages.
- [Roles and permissions](https://noxtica.com/docs/security/roles-and-permissions/): the capability list.
- [Know Your Agent](https://noxtica.com/docs/concepts/know-your-agent/): incoming agents, a separate topic.
---
Source: https://noxtica.com/docs/architecture/
Markdown: https://noxtica.com/docs/architecture/index.md
Last updated: 2026-09-27
# Architecture: From Evidence to Decision
Every device tells a story. Noxtica reads the available evidence, checks whether that story holds together, and hands your application a clear, explainable risk read — not a black-box verdict. This page is the guided tour of that engine: how the browser is read, how it becomes a calibrated risk read, and where the outcome is handed back to your code. It connects the deeper implementation guides so you can follow the whole path end to end or jump straight to the stage you need.
Noxtica frames this as **Agentic Security & Risk Intelligence**, now extended for the agentic web: you can operate your own console with a built-in AI assistant, let your agents read Noxtica over a read-only MCP server, and verify and observe the agents that reach your application. See [Agentic Security & Risk Intelligence](https://noxtica.com/docs/risk-intelligence/) for that product framing; this page stays focused on the mechanics.
## The engine in four stages
| Stage | What happens | Detail |
| --- | --- | --- |
| **01. Browser** | A lightweight collector reads the visitor's browser the moment they land, without slowing the page down. | [Integration Flow → Customer client](https://noxtica.com/docs/integration-flow/#1-customer-client) |
| **02. Hand-off** | What it sees is handed safely to your backend — it cannot be faked, copied, or replayed on the way. | [Integration Flow → Noxtica processing](https://noxtica.com/docs/integration-flow/#2-noxtica-processing) |
| **03. Risk read** | Your server checks the available evidence and returns a reasoned assessment: score, five-level risk tier, confidence, and named reasons. | [Detection Signals](https://noxtica.com/docs/detection-signals/) |
| **04. Decision** | Your code makes the call — block, challenge, observe, or allow. Your policy, your context, your decision. | [Integration Flow → Customer policy](https://noxtica.com/docs/integration-flow/#4-customer-policy) |
This is a summary, not a substitute for the implementation guide: follow [Integration Flow](https://noxtica.com/docs/integration-flow/) for the full five-step evaluation checkpoint list, error handling, and rollout sequence.
## What we measure
Noxtica reads four things about every visitor — the browser, the network, the device, and how the person behaves. Together they tell a real customer apart from a clever fake; no single layer proves "human," "bot," or "safe" on its own.
- **Browser intelligence** — is this browser context internally consistent?
- **Network signals** — does the connection add risk context?
- **Device verification** — does the environment and history support the claimed context?
- **Behavioral patterns** — does eligible timing or journey context corroborate the rest?
See [Detection Signals](https://noxtica.com/docs/detection-signals/) for what each layer can contribute, its common limitations, and how to configure the evidence you need.
## What we catch
The threats that cost you — automation, fraud, and abuse — caught without false-positively challenging real customers: bots and automated traffic, sessions that hide what they are, suspicious origins, privacy users treated fairly, fake or throwaway devices, and activity that doesn't behave human. Each one gives you a risk read and a confidence level, not a blunt yes/no — your team owns the final call.
See [Threat Categories](https://noxtica.com/docs/threat-categories/) for the public reason families, their appropriate uses, and their common false-positive boundaries.
## Why a read, not a verdict
Most tools tell you what you want to hear: bot or human. Clean, simple, and often wrong, with no way to see how they got there. Noxtica separates what can be observed, what the evidence suggests, and what your business chooses to do — the useful question isn't "is this a bot," it's "how unusual is this visitor, and how hard would the suspicious parts be to fake?"
See [Why Calibration, Not Verdicts](https://noxtica.com/docs/why-calibration/) for how to turn risk and confidence into route-specific policy.
## Governing the agentic web
Three bounded, customer-controlled workflows extend this engine to AI agents, with no autonomous changes to your systems:
- **Noxtica operates the console.** A built-in AI assistant reads policies, rules, domains, and risk distribution for you under the operator session, with per-tenant budget caps and full audit logging. See [AI Assistant](https://noxtica.com/docs/concepts/ai-assistant/).
- **Your agents read Noxtica.** An opt-in, read-only Model Context Protocol (MCP) server lets your own AI agents read policies, rules, alerts, and risk distribution over JSON-RPC — read access only, never write. See [MCP Integration](https://noxtica.com/docs/concepts/mcp-integration/).
- **Noxtica governs incoming agents.** Know Your Agent (KYA) verifies and observes AI agents and bots per tenant by JWK thumbprint or Signature-Agent host, integrated with Web Bot Auth verification. Policy enforcement is on the roadmap. See [Know Your Agent](https://noxtica.com/docs/concepts/know-your-agent/).
See [Agentic Security](https://noxtica.com/docs/concepts/agentic-security/) for how these three workflows relate, and [Agentic Security & Risk Intelligence](https://noxtica.com/docs/risk-intelligence/) for the product framing that connects them to the risk read above.
## Example risk reads
Illustrative patterns derived from the threat categories above — not customer data. Scores sit on the same 0–100 scale your policy acts on.
| Pattern | Score | Verdict | Read in |
| --- | --- | --- | --- |
| Headless automation flood — a wave of headless, scripted sessions hitting login in lockstep | 94 / 100 | Blocked | 410 ms |
| Spoofed-fingerprint session — a browser lying about its own canvas output and runtime APIs | 78 / 100 | Step-up | 470 ms |
| Datacenter proxy origin — a request routed through an anonymizing datacenter range | 86 / 100 | Blocked | 350 ms |
| Privacy-browser visitor — a real person on a hardened privacy browser, waved through | 24 / 100 | Allow | 340 ms |
| Throwaway virtual machine — an emulated device posing as real consumer hardware | 90 / 100 | Blocked | 520 ms |
| Non-human interaction pattern — a form filled with tell-tale precision no person types with | 71 / 100 | Step-up | 430 ms |
## Related reading
- [Integration Flow](https://noxtica.com/docs/integration-flow/) — the full browser-to-policy evaluation, step by step.
- [Detection Signals](https://noxtica.com/docs/detection-signals/) — what each evidence layer contributes and how missing evidence affects confidence.
- [Threat Categories](https://noxtica.com/docs/threat-categories/) — public reason families and their interpretation limits.
- [Why Calibration, Not Verdicts](https://noxtica.com/docs/why-calibration/) — map risk and confidence to route-specific policy.
- [Agentic Security & Risk Intelligence](https://noxtica.com/docs/risk-intelligence/) — the product framing this engine supports.
- [Concepts & Glossary](https://noxtica.com/docs/concepts/) — agentic security, know-your-agent, MCP, and the assistant, explained.
- [Customer Capability Reference](https://noxtica.com/docs/features/) — every customer-facing capability, configuration, and limitation.
---
Source: https://noxtica.com/docs/backoffice/overview/
Markdown: https://noxtica.com/docs/backoffice/overview/index.md
Last updated: 2026-10-27
# Backoffice guide: navigation, roles and shortcuts
Backoffice is the Noxtica console at `backoffice.noxtica.com`. Use this page to learn how the sidebar is organised, which role opens which page, and which keyboard shortcuts and chrome controls save time. Operators, analysts and workspace administrators all use the same console; what you see depends on your role and on what is enabled for your organisation.
## What it is
Availability: Availability depends on your plan, role and the modules enabled for your organisation.
The left sidebar groups pages into 15 workspace groups. Each group has a heading that you can fold shut; the sidebar remembers folded groups in your browser. The top bar holds the workspace switcher (when your account belongs to more than one workspace), the command palette, notifications, page help and the UI tweaks panel. Most pages end with a **Related pages** bar, and a **Settings** menu at the top right of a page lists the settings pages that control it.
Every page is scoped to the active workspace. A role is per workspace: one account can be an Admin in one workspace and a Viewer in another.
### Roles and what they reach
| Role | What the sidebar shows |
| --- | --- |
| Viewer | Home, analytics, fingerprints and their sub-pages, Issues, RUM & APM, Behavior Analytics, Infrastructure, Pulse (when enabled), SEO pages, Usage & Quotas, Settings |
| Analyst | Everything a Viewer sees, plus Session Replay, Live Assist, Spot Captures, Hunter Reports (when enabled), Feature Flags, KYC review pages and the Audit Log |
| Admin | Everything an Analyst sees, plus every configuration page: Detection & Collection, Web Analytics & Privacy, Privacy & Legal, Integrations & API, AI & Agents, Billing & Plan, Domains, Users, Sign-in & Access, Workspace Gates, Exports and Data Operations |
| Billing | Only when enabled for your organisation: a branch role for Billing & Plan pages, not a step above Viewer |
The role you hold in the active workspace is printed in the sidebar footer. For the full capability list per role, see [Roles and permissions](https://noxtica.com/docs/security/roles-and-permissions/).
Two rules explain most "why can't I open it" questions:
- The sidebar hides a page below its minimum role. Most configuration pages are hidden below Admin. A deep link to a hidden page can still open for a lower role, but the server checks every read and every change against your role.
- A page can also be hidden or inert because a module or feature is not enabled for your organisation. Pulse, Hunter Reports and Investigations stay out of the sidebar until they are enabled. Related Devices opens with a "disabled" state when it is not enabled.
### Sidebar groups, routes and floors
Routes are paths under `backoffice.noxtica.com`. "Minimum role" is the sidebar floor.
**Overview**
| Nav label | Route | Minimum role | What you do there |
| --- | --- | --- | --- |
| Home | `/home` | Any signed-in role | See plan and usage, every product module, platform status and next steps |
**Device Intelligence.** See [Fingerprints, analytics and live monitoring](https://noxtica.com/docs/backoffice/fingerprints-and-analytics/).
| Nav label | Route | Minimum role | What you do there |
| --- | --- | --- | --- |
| Risk Analytics | `/analytics` | Viewer | Trends, distribution, signals and geography per domain |
| Traffic Intelligence | `/insights` | Admin | Read-only traffic summaries; empty until the underlying rollups are on |
| Dashboards | `/dashboards` | Viewer to read, Admin to change | Build dashboards, reusable cards and cohorts |
| Fingerprints | `/fingerprints` | Viewer | Search and open device fingerprints |
| Live Fingerprints | `/fingerprints/live-monitoring` | Viewer | Watch devices as they arrive |
| Compare Fingerprints | `/fingerprints/compare` | Viewer | Diff devices side by side |
| Fingerprint Population | `/fingerprints/population` | Viewer | Fleet-wide hardware and attestation distributions |
| Related Devices | `/fingerprints/linkage` | Viewer, when enabled | Advisory device-relation candidates |
| Geo-risk | `/geo-risk` | Admin | Risk bands per country, network and IP block |
| Hardware Attestation | `/hardware-attestation` | Admin | GPU and CPU attestation views; see [Device and app attestation](https://noxtica.com/docs/security/attestation/) |
**Session Insights.** See [Observability overview](https://noxtica.com/docs/observability/overview/).
| Nav label | Route | Minimum role | What you do there |
| --- | --- | --- | --- |
| Issues | `/issues` | Viewer | Triage grouped errors and behavior signals |
| RUM & APM (Client RUM, APM Traces, Profiles, Services, Releases, Metrics, Logs) | `/rum-apm` and `/rum-apm/` | Viewer | Real-user monitoring and application performance |
| Session Replay, Live Assist | `/replay`, `/replay/live` | Analyst | Play recorded sessions and watch live ones |
| Spot Captures | `/spot` | Analyst | Review operator-started captures; see [Spot captures](https://noxtica.com/docs/hunter/spot/) |
| Hunter Reports | `/hunter-reports` | Analyst, when enabled | Review page audits; see [Hunter reports](https://noxtica.com/docs/hunter/reports/) |
| Behavior Analytics, Heatmaps, Journeys, Funnels | `/runtime-tracker` and `/runtime-tracker/` | Viewer | Tracker health and behavior analytics |
**Infrastructure and Noxtica Pulse**
| Nav label | Route | Minimum role | What you do there |
| --- | --- | --- | --- |
| Infrastructure | `/infrastructure` | Viewer | Enrolled observability hosts |
| Pulse, Applications, Profiles, Bundles, Rollouts, Detections, Response, Devices, Privacy, Usage | `/pulse` and `/pulse/` | Viewer to read, when enabled | Endpoint telemetry; see [Pulse overview](https://noxtica.com/docs/pulse/overview/) |
**Protection & Investigations.** See [Risk actions, investigations and entity lookup](https://noxtica.com/docs/backoffice/risk-actions-and-investigations/).
| Nav label | Route | Minimum role | What you do there |
| --- | --- | --- | --- |
| Risk Actions | `/risk-actions` | Admin | Check shadow evidence before you enforce |
| Agentic Security | `/agentic-security` | Admin | Agent verification, attestation chain and MCP usage |
| Bot Intelligence | `/bot-intel` | Admin | Named-bot catalog and operators that reached you |
| Behavioral Corroboration, Behavioral Subjects | `/behavioral`, `/behavioral/subjects` | Admin | Advisory behavioral baselines |
| Investigations | `/investigations` | Viewer, when enabled | Journey and device-location investigations |
| Entity Lookup | `/investigation` | Viewer | Look up an IP address, domain or ASN |
| Quality & Calibration | `/quality-calibration` | Admin | Calibration proposals, disputes, corpus, shadow reports |
**Identity Verification.** See [Identity verification integration](https://noxtica.com/docs/identity-verification-integration/) and [Invitations and hosted verification settings](https://noxtica.com/docs/identity-verification-invitations/).
| Nav label | Route | Minimum role | What you do there |
| --- | --- | --- | --- |
| KYC, KYC Verifications, KYC Invitations, KYC Review Queue, KYC Erasure, KYC Policies, KYC Screening Cases, KYC Rescreening, Passkeys, Step-Up Verification, Device Registry, Device Topology Policy | `/kyc` and `/kyc/` | Analyst | Review verification cases and run the review workflow; administrators delete verifications in KYC Verifications and work erasure requests in KYC Erasure |
| Assisted Recovery | `/kyc/recovery` | Admin | Recovery operations queue |
| Agent Delegations | `/kyc/agent-delegations` | Analyst | See delegated agent activity |
| Evidence Access | `/kyc/evidence` | Admin | View sensitive evidence; every view is audited |
| KYB, KYM and their sub-pages | `/kyb`, `/kym` | Admin | Business and merchant verification; see [Business and merchant verification](https://noxtica.com/docs/identity-verification-business/) |
Each KYC page depends on the modules enabled for your organisation; a page whose module is off says so on the page. KYC Processes (`/kyc/processes`) has no sidebar item: open it from the KYC directory page or from a case. See [Identity verification operations](https://noxtica.com/docs/identity-verification-operations/) for the full page list.
**Detection & Collection.** See [Detection and collection settings](https://noxtica.com/docs/backoffice/detection-settings/). All pages need Admin.
| Nav label | Route | What you do there |
| --- | --- | --- |
| Rules & Risk Scoring | `/detection/rules` | Rules, simulation, risk scoring, shadow candidates |
| Client Cost Levels | `/detection/client-cost-levels` | Visitor-browser cost per domain |
| Verdict Bands | `/detection/verdict-bands` | Stage replay protection; sealed results |
| Honeypots & Shared Intel | `/detection/honeypots` | Tripwires and shared-intelligence opt-in |
| Collector | `/detection/collector` | Token refresh interval |
| Probes | `/detection/probes` | Extra collector probes |
| Behavioral Signals | `/detection/behavioral-signals` | Behavioral capture options |
**Web Analytics & Privacy and Privacy & Legal.** All pages need Admin. See [Privacy and compliance controls in Backoffice](https://noxtica.com/docs/compliance/overview/) and [Real user monitoring and Web Vitals](https://noxtica.com/docs/observability/rum/).
| Nav label | Route | What you do there |
| --- | --- | --- |
| Consent & Privacy, RUM Collection, Tracking Allowlists, Capture Policies, RUM Data Lifecycle, Uptime Checks | `/web-analytics/` | Per-domain RUM consent, sampling, allowlists, capture and uptime checks |
| Data Retention, Data Locations, KYC Training Data, Compliance, Legal Basis Register, Data Subject Scope, Sub-processors, Platform Assurances | `/privacy/` | Retention, legal basis and assurance pages |
**Integrations & API.** See [Integrations and API pages](https://noxtica.com/docs/backoffice/integrations/). All pages need Admin.
| Nav label | Route | What you do there |
| --- | --- | --- |
| Event Sinks | `/event-sinks` | Push events to a SIEM; see [Event sinks](https://noxtica.com/docs/backoffice/event-sinks/) |
| API & SDK | `/api-config` | Server API keys and integration links |
| MCP Tokens, Score API Keys, Ingestion API Keys, Webhooks | `/integrations/` | Credentials and event delivery |
| Script & Consent | `/integrations/script-consent` | Collector snippets and consent mode |
| Alerts, Status Reports, Relay Hostnames, Attestation Apps, Connectors | `/integrations/` | Notifications, reports, first-party hostnames, mobile apps, connections |
**SEO & Marketing.** Viewer reads; running checks and connecting Search Console need Admin. See [SEO tools](https://noxtica.com/docs/observability/seo-tools/).
| Nav label | Route | What you do there |
| --- | --- | --- |
| SEO Check, Site Crawls, Search Console, Search Score | `/seo/` | Technical checks, crawls and search visibility for an owned domain |
**AI & Agents.** See [AI assistant, MCP tokens and coding-agent keys](https://noxtica.com/docs/backoffice/ai-assistant-and-mcp/). All pages need Admin.
| Nav label | Route | What you do there |
| --- | --- | --- |
| Agent Registry | `/ai/agent-registry` | Decide how verified AI crawlers are treated |
| LLM Routing, Speech, LLM Provider Keys | `/ai/llm-routing`, `/ai/speech`, `/ai/provider-keys` | Model routing, voice features, your own provider keys |
| Coding Agent Keys | `/integrations/coding-agent-keys` | Read-only keys for a coding agent |
| Agent Monitor | `/agent/monitor` | Watch agent runs; when enabled for your organisation |
**Billing & Plan.** See [Plans, packages and add-ons](https://noxtica.com/docs/billing/plans-and-packages/).
| Nav label | Route | Minimum role | What you do there |
| --- | --- | --- | --- |
| Usage & Quotas | `/usage` | Viewer | Meters, AI usage and spend |
| Plan | `/billing/plan` | Admin | See limits and request a change |
| Packages & Add-ons, Wallet, Invoices, Monthly Reports | `/billing/` | Admin (Billing role when enabled) | Subscriptions, balance, statements and reports |
**Administration.** See [Domains, site keys and the install card](https://noxtica.com/docs/backoffice/domains/) and [Workspace gates, feature flags, data operations and mobile operations](https://noxtica.com/docs/backoffice/workspace-settings/).
| Nav label | Route | Minimum role | What you do there |
| --- | --- | --- | --- |
| Domains | `/domains` | Admin | Register origins, site keys, per-domain settings |
| Users | `/users` | Admin | Invite and manage team members; see [Roles and permissions](https://noxtica.com/docs/security/roles-and-permissions/) |
| Settings | `/settings` | Any signed-in role | Your own sign-in security, appearance, notifications |
| Sign-in & Access | `/administration/sign-in-access` | Admin | SSO, IP allowlist, enforced MFA; see [Sign-in, SSO, SCIM, MFA and IP allowlist](https://noxtica.com/docs/security/sign-in-and-access/) |
| Workspace Gates | `/administration/workspace-gates` | Admin | Optional workspace behaviours |
| Feature Flags | `/feature-flags` | Analyst to read, Admin to change | Visitor experiments |
| Mobile Operations | `/mobile-operations` | Admin | Mobile posture and the tenant kill-switch key |
| Audit Log | `/audit` | Analyst | Who changed what; see [Audit log and data export](https://noxtica.com/docs/security/audit-log-and-exports/) |
| Exports | `/exports` | Admin | Download data exports |
| Data Operations | `/data-operations` | Admin | Delete end-user browser data, retention runs |
## Prerequisites
- A Backoffice account in at least one workspace. Sign-in, SSO and MFA are covered in [Sign-in, SSO, SCIM, MFA and IP allowlist](https://noxtica.com/docs/security/sign-in-and-access/).
- An authenticator app, if you will change settings. Sensitive changes ask for a fresh MFA code (see step 5).
- For Pulse, Hunter Reports, Investigations and Related Devices: the feature enabled for your organisation. Ask your account team.
## Steps
### 1. Check your workspace and role
Look at the sidebar footer: it shows your email and role. If your account belongs to more than one workspace, the top bar also shows the workspace switcher with the active workspace name.
### 2. Switch workspace
1. Open the workspace switcher in the top bar: **Switch workspace (current: )**.
2. Pick a workspace. Workspaces marked **Suspended** or **Unavailable** cannot be opened.
3. Backoffice reloads on **Home**. Nothing from the previous workspace stays on screen.
If the switch fails, the switcher shows one of three messages: you are no longer an active member, the workspace could not be verified (retry in a moment), or your network is not allowed to reach that workspace (ask its administrator to add your IP address).
### 3. Jump to a page with the command palette
Press `Ctrl+K` (`⌘K` on macOS), or use the search box at the top of the sidebar. Type at least 2 characters.
- **Navigation** lists pages you can open. Items also match aliases, for example `siem` finds Event Sinks and `mfa` finds Settings.
- **Results** lists matching entities. Everyone with device access gets device results. Users and domains need Admin. Replay sessions need the replay permission, error groups and funnels need analytics, and KYC verifications need the KYC review permission.
- **Recent pages** lists the pages you opened last while the search box is empty.
### 4. Use G shortcuts and the shortcuts list
Press `G`, then a letter within about a second.
| Keys | Opens |
| --- | --- |
| `G` `D` | Home |
| `G` `A` | Risk Analytics |
| `G` `F` | Fingerprints |
| `G` `L` | Live Fingerprints |
| `G` `C` | Compare Fingerprints |
| `G` `I` | Issues |
| `G` `R` | Session Replay |
| `G` `H` | Heatmaps |
| `G` `J` | Journeys |
| `G` `N` | Funnels |
| `G` `S` | Settings |
Press `?` to open the **Keyboard shortcuts** list. It shows only the chords your role can use. `Ctrl+\` (`⌘\` on macOS) collapses or expands the sidebar. `Esc` closes the open dialog or panel. Shortcuts stay quiet while you type in a field, while a modifier key is held and while a dialog is open.
### 5. Confirm sensitive changes with step-up MFA
Creating or rotating keys, changing domains, minting tokens, changing detection settings and similar actions ask for a code from your authenticator app, even though you are signed in. A successful check stays fresh for 6 hours by default; Backoffice asks again after that. If you cancel, nothing changes.
### 6. Set your own preferences
Open the tweaks button in the top bar (**UI tweaks**) for:
- **Theme**: Dark, Light, High contrast.
- **Density**: Compact, Comfortable, Spacious.
- **Font**: Sans, Mono, Humanist, Mixed.
- **Language**: pick a language from the list.
The same theme, density and font defaults are on **Settings → Appearance**.
### 7. Read page help and the in-console legal pages
- The help button in the top bar opens **Page help** for the page you are on, with a link to the full documentation.
- The bell opens **Notifications**: recent audit activity and destructive actions.
- The console carries read-only copies of the legal documents under `/legal/`: Terms of Service, Privacy Policy, Cookie Policy, Acceptable Use, Legal Notice, Subprocessors, Disclaimer and Data Processing Addendum. The public versions are at [Terms](https://noxtica.com/terms/), [Privacy](https://noxtica.com/privacy/), [Cookies](https://noxtica.com/cookies/), [Acceptable use](https://noxtica.com/acceptable-use/), [Legal notice](https://noxtica.com/legal-notice/), [Subprocessors](https://noxtica.com/subprocessors/), [Disclaimer](https://noxtica.com/disclaimer/) and [DPA](https://noxtica.com/dpa/).
### 8. Find a page you cannot see
| If the page is missing because | You see | Do this |
| --- | --- | --- |
| Your role is below the floor | No sidebar item; a deep link shows **Access denied** and names the required role | Ask a workspace admin for the role, or an admin to do the task |
| The module is not in your plan | A strip reading " is not included in your plan" (KYC, Behavioral Corroboration, Hardware Attestation) | Ask your account team |
| The feature is not enabled for your organisation | No sidebar item (Pulse, Hunter Reports, Investigations), or a "not enabled" state on the page | Ask your account team |
| Billing needs attention | Every page except Billing & Plan and Settings is paused | See [Billing status, grace period and reminders](https://noxtica.com/docs/billing/status-grace-reminders/) |
| Your workspace requires MFA enrolment | Backoffice sends you to `/mfa/enroll` | Enrol an authenticator app |
| You are in a different workspace | The item exists in another workspace | Switch workspace (step 2) |
## Verify it works
- Press `?`: the **Keyboard shortcuts** dialog opens with an **Anywhere** section and a **Go to (press G, then the letter)** section.
- Press `Ctrl+K` or `⌘K`, type `fing`: **Fingerprints** appears under **Navigation**.
- Press `G` then `D`: Backoffice opens **Home**.
- Open the workspace switcher (if shown) and pick another workspace: the console reloads on **Home** under the new workspace name, and the role in the sidebar footer matches that workspace.
## Troubleshooting
| Symptom | Cause | Fix |
| --- | --- | --- |
| A page in these docs is not in your sidebar | Your role is below its floor, or the feature is not enabled for your organisation | Check the role in the sidebar footer against the tables above |
| **Access denied** with "Required role: admin or higher" | The deep link needs a higher role | Ask a workspace admin |
| The palette shows no users or domains | User and domain results need Admin | Ask for the Admin role, or open the page itself |
| A `G` shortcut does nothing | Focus is in a field, a modifier key is held, a dialog is open, or the page is not available to your role | Click outside the field, close the dialog, press `G` then the letter within about a second |
| No workspace switcher | The account belongs to one workspace | None needed |
| Backoffice keeps asking for an MFA code | The fresh-verification window has passed | Enter the code; the check stays fresh for 6 hours by default |
| Every page except Billing & Plan and Settings is paused | No package is active after the grace period | Choose a package under Billing & Plan |
## Related
- [Domains, site keys and the install card](https://noxtica.com/docs/backoffice/domains/): register a domain and copy its site key.
- [Fingerprints, analytics and live monitoring](https://noxtica.com/docs/backoffice/fingerprints-and-analytics/): the Device Intelligence pages.
- [Integrations and API pages](https://noxtica.com/docs/backoffice/integrations/): map of every credential and delivery page.
- [Roles and permissions](https://noxtica.com/docs/security/roles-and-permissions/): the capability list behind each role.
- [Sign-in, SSO, SCIM, MFA and IP allowlist](https://noxtica.com/docs/security/sign-in-and-access/): MFA and SSO setup.
- [Customer Capability Reference](https://noxtica.com/docs/features/): what each capability family returns and its limits.
- [Getting started](https://noxtica.com/docs/getting-started/): install the collector and verify the evaluation.
---
Source: https://noxtica.com/docs/backoffice/fingerprints-and-analytics/
Markdown: https://noxtica.com/docs/backoffice/fingerprints-and-analytics/index.md
Last updated: 2026-10-27
# Fingerprints, analytics and live monitoring
The **Device Intelligence** group of the sidebar holds the pages for reading what the collector scored. Analysts and operators use them to find a device, understand its score, compare it with another device and see where risk concentrates. This page covers each page, what it shows and what you can do on it.
## What it is
Availability: Availability depends on your plan, role and the modules enabled for your organisation.
Every page here reads the active workspace. Results are signals for your own policy, not verdicts about a person: a fingerprint is a scored device observation, and a relation between two devices is a lead for review. See [Why calibration, not verdicts](https://noxtica.com/docs/why-calibration/).
| Page | Route | Minimum role | Use it to |
| --- | --- | --- | --- |
| Risk Analytics | `/analytics` | Viewer | Read key metrics, trends, risk distribution, signals and geography for a time range and domain |
| Traffic Intelligence | `/insights` | Admin | Read summaries of bot-versus-human share, AI-crawler traffic, geography against risk and anomalies; observe-only |
| Dashboards | `/dashboards` | Viewer to read, Admin to change | Build dashboards, reusable cards and cohort analyses |
| Fingerprints | `/fingerprints` | Viewer | Search, filter and open real device records |
| Live Fingerprints | `/fingerprints/live-monitoring` | Viewer | Watch devices arrive in near real time |
| Compare Fingerprints | `/fingerprints/compare` | Viewer | Diff up to four devices |
| Fingerprint Population | `/fingerprints/population` | Viewer | Read fleet-wide hardware and attestation distributions |
| Related Devices | `/fingerprints/linkage` | Viewer, when enabled | Review advisory candidate relations between devices |
| Geo-risk | `/geo-risk` | Admin | See risk bands per country, network (ASN) and IP block |
| Hardware Attestation | `/hardware-attestation` | Admin | Read GPU and CPU attestation distributions, GPU detail and mobile attestations |
| Issues | `/issues` | Viewer | Triage grouped errors and behavior signals |
Some pages show an empty or "not enabled" state until the underlying rollup or module is turned on for your organisation. An empty state is not evidence of no traffic.
## Prerequisites
- A workspace with at least one registered domain that sends traffic. See [Domains, site keys and the install card](https://noxtica.com/docs/backoffice/domains/).
- The minimum role in the table. Roles are explained in [Backoffice guide](https://noxtica.com/docs/backoffice/overview/).
- For Hardware Attestation: the attestation module in your plan and attestation enabled for the domain. See [Device and app attestation](https://noxtica.com/docs/security/attestation/).
- For Related Devices: the feature enabled for your organisation and a recorded legal basis for investigations. Without them the page opens with a disabled state.
## Steps
### 1. Find a device in Fingerprints
Open `Backoffice → Device Intelligence → Fingerprints`.
- **Search** accepts a device ID, IP address, ASN or user-agent text.
- Filters cover **Risk** (Critical, High, Medium, Low, Minimal, Unknown), **Country**, the collection **Method** (native, sealed, sealed with encryption) and **Hardware Attestation** (attested or not attested).
- The **Devices** tab lists devices. The **User Agents** tab lists each distinct user-agent string with counts and a copy action.
- The list refreshes itself every 5, 15 or 30 seconds. Use **Pause** and **Resume**, or **Refresh**.
- Pick the page size from 25, 50 or 100 rows. Selections persist across pages and filter changes.
- Tick 2 to 4 rows and choose **Compare**, or choose **Export** to open `Exports` with your current filters filled in. Exports are described in [Audit log and data export](https://noxtica.com/docs/security/audit-log-and-exports/).
### 2. Read a device record
Select a row. The record opens at `/fingerprints/` with tabs:
| Tab | What it shows |
| --- | --- |
| Overview | Score, risk band, confidence, flags, and a ranked "Why this score" breakdown with no personal data |
| Sessions timeline | Replay sessions captured for this device in the last 90 days that are still within replay retention (7 days by default), newest first; plus a 7-day activity strip of visits, submissions and risk signals (dates in UTC) |
| Browser, Network, Hardware | Collected browser, network and hardware signals |
| Behavioral | Behavioral subscore and signals, when collected |
| Techniques | Which collection techniques were switched on for this submission |
| Population | Where this device sits in your fleet distributions |
| Events | Event timeline for the device |
| History | Prior scores |
| Raw | The raw submission; visible to platform superadmins only |
Header actions include **Copy ID**, **Compare**, **View journeys**, **View heatmap**, **View in Investigations** (when enabled) and **Open in…**. When disputes are enabled for your workspace, the Overview tab offers **Dispute Verdict** to open a false-positive dispute; the dispute goes to the review workflow described in [Risk actions, investigations and entity lookup](https://noxtica.com/docs/backoffice/risk-actions-and-investigations/). The sessions timeline says "One device only": it does not merge identities.
### 3. Watch live traffic
Open `Device Intelligence → Live Fingerprints`. The page streams recent visits and submissions with a location map.
- KPI tiles: **Active devices**, **Active now**, **Devices seen (history)**, **Visits**, **Submissions**, **High / Critical**.
- **Filter the stream by risk level**, pause and resume it, and choose a polling interval of 5, 15 or 30 seconds.
- Select a row to open the device record.
- The history panels can lag. The page states the lag: history up to the shown window, which "may lag up to ~15 min". If the real-time read fails, the page says so and shows delayed history instead.
### 4. Compare devices
Select 2 to 4 rows on Fingerprints and choose **Compare**, or open `/fingerprints/compare?ids=,`. Tabs: **Overview**, **Signals**, **Signal data**, **Environment**, **Raw**. Differences are highlighted; flags are split into common and only-in-one-device. If a device ID exists in more than one workspace you can reach, pick the tenant for each slot.
### 5. Read population statistics
Open `Fingerprint Population` for fleet-wide distributions over a window of 24 hours, 7 days or 30 days, filtered by signal family. Buckets with too few devices are hidden before they reach the page, and hidden buckets are excluded from every total. The page never identifies an individual device and changes no detection behavior. Use a device's **Population** tab to see where one device sits.
### 6. Review Related Devices (when enabled)
`Related Devices` lists candidate relations: two device IDs that share signals, with a confidence (High, Medium, Low), an ordinal score from 0 to 100 for ranking, the link types and the itemised evidence and counter-evidence. A relation expires. It never merges devices and never feeds a score or verdict. The page states that edge precision and 7-day re-link recall have not been evaluated, so treat each relation as a lead, not as proof that one operator controls both devices.
### 7. Use Risk Analytics and Dashboards
`Risk Analytics` has the tabs **Trends**, **Distribution**, **Signals** and **Geography**, a **Time range**, a **Breakdown dimension** (Country, City, Platform, ASN) and key figures: **Total submissions**, **Critical rate**, **High risk** and a device count. Use **CSV** buttons to download a chart's data. **Views → Save current view…** stores the time range, filters and toggles as a preset that only you can see.
`Dashboards` has the tabs **Dashboards**, **Cards** and **Cohorts**. Build operator views from funnels, journeys, heat maps, web vitals, dimensions, retention and feature adoption. Viewers and Analysts read them. Creating or changing a dashboard, card or cohort needs the Admin role and a fresh MFA check.
### 8. Read Geo-risk and Hardware Attestation
- `Geo-risk` (Admin) has the tabs **Country**, **ASN** and **IP block** over 7, 30 or 90 days, with a map. Cells below the privacy floor are suppressed. Without the underlying rollup the page says "Not enabled yet".
- `Hardware Attestation` (Admin) has **Distribution**, **GPU detail** and **Mobile attestations**. The mobile tab is a read-only ledger of Android and iOS attestation results for the workspace, with Play Integrity and App Attest verdicts shown as recorded. If too few records exist, the ledger hides individual rows. Register your apps under `Integrations & API → Attestation Apps`; see [Device and app attestation](https://noxtica.com/docs/security/attestation/).
### 9. Triage Issues
`Issues` groups runtime errors and deterministic behavior signals. The **Errors** and **Behavior** tabs take filters for severity, type, route, release and device. Severity is a deterministic impact rule: occurrences multiplied by affected users (1,000 or more is Critical, 100 or more High, 10 or more Medium, otherwise Low), with a High floor on checkout, payment and billing routes. It is not AI grading. Error capture is covered in [Browser errors, console logs and source maps](https://noxtica.com/docs/observability/errors-and-source-maps/).
## Verify it works
- A device you know sent traffic appears on **Fingerprints** after a search by its device ID, and its record opens with a score, a band and the **Why this score** breakdown.
- **Live Fingerprints** shows **Streaming** and your visit appears within one polling interval.
- On a comparison, selected devices show a difference count and highlighted rows.
- **Risk Analytics → Trends** shows non-zero **Total submissions** for the chosen range.
- If a page shows "not enabled", "Rollup disabled" or an empty table, widen the range and confirm traffic exists before you conclude anything.
## Troubleshooting
| Symptom | Cause | Fix |
| --- | --- | --- |
| Fingerprints is empty | No traffic yet, a filter is narrowing the list, or the domain's collector is not installed | Select **Clear filters**; check **Last seen** on Domains |
| Live Fingerprints shows "Real-time read unavailable" | The real-time read failed; delayed history is shown instead | Retry; history panels are unaffected |
| **Raw** tab is missing | The raw submission is visible to superadmins only | Use the other tabs |
| Compare asks you to pick a tenant | The device ID exists in more than one workspace | Choose the tenant for that slot |
| Population or Geo-risk hide a bucket | The bucket is below the privacy floor | Widen the window; a hidden bucket is not a zero |
| Geo-risk shows "Not enabled yet" | The rollup is not enabled for your organisation | Ask your account team |
| Related Devices shows a disabled state | Feature or investigation legal basis is not in place | Ask your account team; see [Legal basis register and receipts](https://noxtica.com/docs/compliance/legal-basis/) |
| Hardware Attestation tabs are empty | Attestation is not enabled for the domain, or no attested traffic has arrived yet | See [Device and app attestation](https://noxtica.com/docs/security/attestation/) |
| A dashboard or card will not save | Changes need the Admin role and an MFA check | Enter the authenticator code |
## Related
- [Backoffice guide: navigation, roles and shortcuts](https://noxtica.com/docs/backoffice/overview/): roles and shortcuts, including `G F`, `G L` and `G C`.
- [Risk actions, investigations and entity lookup](https://noxtica.com/docs/backoffice/risk-actions-and-investigations/): act on what you find.
- [Detection signals](https://noxtica.com/docs/detection-signals/): what each evidence layer contributes.
- [Threat categories](https://noxtica.com/docs/threat-categories/): public reason families and false-positive boundaries.
- [Behavior analytics: heatmaps, journeys and funnels](https://noxtica.com/docs/observability/behavior-analytics/): the tracker pages.
- [Audit log and data export](https://noxtica.com/docs/security/audit-log-and-exports/): export fingerprints and events.
---
Source: https://noxtica.com/docs/backoffice/risk-actions-and-investigations/
Markdown: https://noxtica.com/docs/backoffice/risk-actions-and-investigations/index.md
Last updated: 2026-10-27
# Risk actions, investigations and entity lookup
The **Protection & Investigations** group of the sidebar is where you check what your policy would do, review agent and bot traffic, and investigate a lead. Admins validate risk actions here before they move enforcement from shadow to active. Analysts use the lookup and investigation pages to follow a lead across devices and networks.
## What it is
Availability: Availability depends on your plan, role and the modules enabled for your organisation.
Most pages in this group show evidence. They do not act on traffic. The table says which pages are observe-only and which carry a change you can make.
| Page | Route | Minimum role | Observe-only or actionable |
| --- | --- | --- | --- |
| Risk Actions | `/risk-actions` | Admin | Observe-only: shows what the pipeline would have done |
| Agentic Security | `/agentic-security` | Admin | Observe-only: agent verdicts, attestation chain and MCP usage |
| Bot Intelligence | `/bot-intel` | Admin | Observe-only: catalog and activity |
| Behavioral Corroboration, Behavioral Subjects | `/behavioral`, `/behavioral/subjects` | Admin | Advisory; one action: reset a subject baseline (MFA and confirmation) |
| Investigations | `/investigations` | Viewer, when enabled | Read-only views and saved views; no case actions |
| Entity Lookup | `/investigation` | Viewer | Lookups; sanctions screening is advisory |
| Quality & Calibration | `/quality-calibration` | Admin | Actionable: accept or reject calibration proposals, open and resolve disputes, import labels |
Results are signals for your own decision. A sanctions-screening match, a behavioral deviation or a bot-operator match is a lead for human review, never an automatic block. See [Why calibration, not verdicts](https://noxtica.com/docs/why-calibration/).
Enforcement itself is configured under **Detection & Collection → Rules & Risk Scoring**. See [Detection and collection settings](https://noxtica.com/docs/backoffice/detection-settings/).
## Prerequisites
- The minimum role from the table. Roles are explained in [Backoffice guide](https://noxtica.com/docs/backoffice/overview/).
- For Investigations: the feature enabled for your organisation and an active legal-basis receipt. Without them the page opens with an "Investigations not enabled" state, and the sidebar item stays hidden. See [Legal basis register and receipts](https://noxtica.com/docs/compliance/legal-basis/).
- For Entity Lookup enrichment: OSINT enrichment enabled for your organisation. Without it a lookup shows "Enrichment not enabled".
- For Behavioral Corroboration: the behavioral module in your plan. Without it a strip reads "Behavioral Corroboration is not included in your plan".
- An authenticator app. Accepting a calibration proposal and resetting a behavioral baseline ask for a fresh MFA code.
## Steps
### 1. Validate risk actions before you enforce
Open `Backoffice → Protection & Investigations → Risk Actions`. The page states: "Everything here is what the pipeline WOULD have done. No policy is enforced from this page."
- **Shadow decisions** count would-be policy actions. **Submit shadow hits** are per-submission decisions. **Enforcement shadow hits** are in-path allow, challenge or block decisions made while enforcement runs in shadow. Counts are approximate volumes.
- **Challenge outcomes by method** break down **Invisible PoW** and **Turnstile** step-up challenges into **Issued**, **Solved**, **Failed** and **Abandoned**. **Challenge solve rate** is solved divided by solved plus failed.
- Submit and enforcement counts cover the last 24 rolling hours. Challenge outcomes cover the current UTC day. The two windows rarely align, so a later stage can show a higher count than an earlier one.
- **Live updates** polls for new data. Use **Refresh** to reload.
A tenant admin sees only the own workspace. If the page says "Risk Actions not provisioned", the shadow pipeline has no data yet; it is off until it is enabled for your workspace.
### 2. Review agent traffic in Agentic Security
Open `Agentic Security`. It is read-only and has three sections:
- **Agent verification verdicts**: **Verified**, **Unsigned**, **Invalid signature**, **Expired** and **Replay** over 24 hours, 7 days or 30 days.
- **Attestation-chain forensics**: per-agent observations recorded in shadow. Detail is hidden below a small-count threshold and only a summary shows.
- **MCP token usage**: queries used, period limit and remaining for the current period.
A **Cloudflare Verified AI Agents** panel can seed the agent registry when your deployment exposes it. Each section shows its own "not enabled" note until its rollup is on. Concepts are in [Know Your Agent](https://noxtica.com/docs/concepts/know-your-agent/) and [Agentic Security](https://noxtica.com/docs/concepts/agentic-security/).
### 3. Browse bot operators in Bot Intelligence
`Bot Intelligence` shows a **Verified bot catalog** of named operators, with source and license attribution, and **Per-operator activity** for your workspace over 1, 7 or 30 days. Filter the catalog by operator, slug, category or kind. The catalog is platform data; the activity is yours. Empty states distinguish "not enabled", "waiting for upstream collection" and "no recognized bot activity in this window".
### 4. Read behavioral corroboration
`Behavioral Corroboration` shows the enrolment funnel (learning to active), the session-deviation histogram, drift by capture channel and concordance against labeled ground truth. `Behavioral Subjects` lists pseudonymous subjects with status, sample count, last deviation band (low through severe) and drift time. A deviation says how consistent a session is with the subject's own history. It is advisory evidence, never identity and never a verdict. Small groups are suppressed. On a subject page you can reset the baseline, which returns it to learning and clears learned statistics; that needs a fresh MFA check and a confirmation.
### 5. Investigate (when enabled)
`Investigations` has five tabs: **Journeys (Sankey)**, **Device Locations**, **Journeys (Chord)**, **Events** and **Incident Triage**.
- **Events** takes filters for risk, attestation, automation, network and account. Select **Apply**, then page with **Load more**; **Download CSV** exports the loaded rows.
- **Journeys (Chord)** shows how devices, accounts, agents and networks co-occur. Pairs below a privacy floor of 5 are not shown.
- **Incident Triage** is read-only: status counts and grouping of existing signals, with no case queue and no close actions.
- Save a view with the saved-views menu. Superadmins must pick a workspace first.
Reads are tenant-scoped. When the feature or the legal-basis receipt is missing, each tab shows a disabled state.
### 6. Look up an entity
Open `Entity Lookup`, enter an IP address, domain or ASN (for example `8.8.8.8`, `example.com`, `AS13335`) and select **Investigate**. Enrichment tabs include **IP**, **WHOIS / RDAP**, **BGP / ASN**, **DNS**, **Certificates**, **Threat intel**, **CVE (NVD)** and **GitHub**. An **Entity graph** expands related entities. A separate sanctions search screens a name against the US OFAC Specially Designated Nationals list. The page says it is advisory, does not claim to be complete, and a match is "a lead for human review — never an automated block or decision". Source attribution is listed under the results.
### 7. Work the calibration queue
`Quality & Calibration` has five tabs: **Calibration inbox** (default), **Calibration concordance**, **FP disputes**, **Corpus** and **Shadow reports**.
| Tab | What you do | Notes |
| --- | --- | --- |
| Calibration inbox | Review proposals (Proposed, Accepted, Rejected); inspect the threshold change and its evidence; accept or reject | Propose-only. Nothing applies until you accept, and accepting needs a fresh MFA check. Each proposal shows its origin and whether AI drafted it |
| Calibration concordance | Read how each shadow candidate would change bands over a window | Read-only; never applies a change |
| FP disputes | Open, track and resolve false-positive disputes; export the list to CSV | A dispute moves from open through reviewing to upheld or overturned. Resolving is an admin action |
| Corpus | Read the labeled bot or human base rate; import labels from resolved disputes or add a manual label | A label is annotation only and never moves a scoring weight. Import and annotate need MFA |
| Shadow reports | Read a per-flag report card for each shadow signal over 24 hours, 7 days or 30 days | Recommendations are annotations. Weight changes stay a separate, explicit step |
You can also open a dispute from the **Dispute Verdict** button on a device record. See [Fingerprints, analytics and live monitoring](https://noxtica.com/docs/backoffice/fingerprints-and-analytics/).
## Verify it works
- **Risk Actions** shows non-zero shadow counts after traffic has been evaluated, or a clear "no risk-action evidence in this window" state.
- **Agentic Security** shows a verdict total for the window you pick, or a note naming the rollup that is off.
- **Entity Lookup** returns tabs of results for a valid IP, domain or ASN, or "Enrichment not enabled".
- A calibration proposal you accept appears under **Accepted** after the MFA check.
## Troubleshooting
| Symptom | Cause | Fix |
| --- | --- | --- |
| Risk Actions says "not provisioned" | The shadow pipeline and challenge ladder are off by default | Ask your account team; collect traffic after enablement |
| Counts at a later stage exceed an earlier one | Submit counts use 24 rolling hours, challenge outcomes the UTC day | Compare within one window only |
| Investigations is not in the sidebar | Feature or legal-basis receipt is not enabled | Ask your account team |
| Entity Lookup says "Enrichment not enabled" | OSINT enrichment is off for your organisation | Ask your account team |
| Bot Intelligence is empty | Named-operator collection is not enabled, or no recognized bots arrived in the window | Widen the window; ask your account team |
| Behavioral pages are empty | No subjects have enrolled | Review the behavioral settings in [Detection and collection settings](https://noxtica.com/docs/backoffice/detection-settings/) |
| Sanctions screening is rate limited | Too many screenings in a short time | Wait a moment and retry |
| Accepting a proposal fails | The MFA check lapsed | Enter a new authenticator code |
## Related
- [Detection and collection settings](https://noxtica.com/docs/backoffice/detection-settings/): enforcement mode, risk scoring and shadow candidates.
- [Fingerprints, analytics and live monitoring](https://noxtica.com/docs/backoffice/fingerprints-and-analytics/): devices and population context.
- [Know Your Agent](https://noxtica.com/docs/concepts/know-your-agent/): how incoming agents are evaluated.
- [Calibration](https://noxtica.com/docs/concepts/calibration/): how to read risk and confidence.
- [Threat categories](https://noxtica.com/docs/threat-categories/): public reason families.
- [Roles and permissions](https://noxtica.com/docs/security/roles-and-permissions/): the capabilities behind each page.
---
Source: https://noxtica.com/docs/backoffice/detection-settings/
Markdown: https://noxtica.com/docs/backoffice/detection-settings/index.md
Last updated: 2026-10-27
# Detection and collection settings
The **Detection & Collection** group holds seven pages that change how Noxtica scores traffic and what the collector asks of a visitor's browser. A workspace Admin changes them. This page says what each setting changes and gives an order for rolling a change out so that live traffic is never surprised.
## What it is
Availability: Availability depends on your plan, role and the modules enabled for your organisation.
All seven pages are Admin pages in the sidebar. Every change is audited and asks for a fresh MFA check. Several settings have two keys: your switch, and a platform switch that Noxtica operations controls. Turning on your key does nothing visible until the platform key is also on, and a page says so next to the switch.
| Page | Route | What it changes |
| --- | --- | --- |
| Rules & Risk Scoring | `/detection/rules` | Ordered enforcement rules, the stage of enforcement, signal weights, risk-level cutoffs, shadow candidates |
| Client Cost Levels | `/detection/client-cost-levels` | How much work a visitor's browser does, per domain |
| Verdict Bands | `/detection/verdict-bands` | Staging of replay protection and binding; sealed results |
| Honeypots & Shared Intel | `/detection/honeypots` | Decoy tripwires; contribution to and use of shared intelligence |
| Collector | `/detection/collector` | Session-token refresh interval |
| Probes | `/detection/probes` | DNS-leak, extension, location and device-recognition probes |
| Behavioral Signals | `/detection/behavioral-signals` | Behavioral capture, movement tracks and behavior flags |
Several of these settings read personal data from visitors' browsers. Noxtica provides the mechanism; the legal basis is yours. Link your decisions to [Legal basis register and receipts](https://noxtica.com/docs/compliance/legal-basis/) and [Cookies, storage and consent categories for your site](https://noxtica.com/docs/compliance/cookies-and-storage/).
## Prerequisites
- The Admin role in the workspace. See [Backoffice guide](https://noxtica.com/docs/backoffice/overview/).
- An authenticator app for the step-up check.
- At least one domain with traffic, so shadow evidence can accumulate. See [Domains, site keys and the install card](https://noxtica.com/docs/backoffice/domains/).
- For behavioral capture, movement tracks, the extension probe, the location probe and persistent device recognition: counsel review and end-user consent where the law requires it. The page shows a warning next to each switch.
## Steps
### 1. Plan the rollout order
Change one thing at a time and watch the evidence before the next change.
1. Collection cost first: **Client Cost Levels** and **Collector** change load, not decisions.
2. Collection additions next: **Probes** and **Behavioral Signals**, each with a recorded legal basis.
3. Scoring: **Risk scoring** weights and cutoffs, tested with **Shadow candidates** and **Simulate & evidence** before you save.
4. Enforcement: write **Rules**, set **Enforcement mode** to **Shadow**, read [Risk actions, investigations and entity lookup](https://noxtica.com/docs/backoffice/risk-actions-and-investigations/), and only then consider **Active**.
5. Protection bands: move **Verdict Bands** from off to shadow, observe, then active.
### 2. Write rules and set the enforcement stage
Open `Detection & Collection → Rules & Risk Scoring`. The page has four tabs: **Rules**, **Simulate & evidence**, **Risk scoring** and **Shadow candidates**.
- **Rules** is an ordered list. Rules run by ascending priority, and the earliest matching rule picks the action. Actions are **Allow**, **Challenge**, **Block** and **Tarpit**. A rule can match on risk band, fired flags, agent verdict, URL path, device score, device properties, IP reputation or a flag prefix, and a per-rule challenge method (**Invisible proof-of-work** or **Turnstile**). A workspace can hold up to 100 rules.
- **Enforcement mode** has three stages. **Off** forwards every request. **Shadow** evaluates your rules and logs the would-be action without acting; this is the recommended first stage. **Active** acts on matches: block, challenge or tarpit. Changing the mode needs MFA, and switching to Active asks you to confirm.
- A rule acts only when the mode is Active and the rule's own **Shadow** switch is off. Otherwise it observes. Each rule shows "Observing" or "Enforcing" with the reason.
- Selecting Active also depends on a platform enforcement switch that Noxtica operations controls. You can stage Active in advance, and it takes effect when that switch is on.
- **Simulate & evidence** dry-runs a rule against recent events and shows the daily fire mix, so you can size a rule before you arm it.
- **Revisions & rollback** publishes the live rule set as a numbered revision and can roll back to an older one. History is never rewritten.
- Domain-scoped rules are also available on a domain's **Risk rules** tab and apply alongside tenant-wide rules.
### 3. Tune risk scoring
On the **Risk scoring** tab you can change the weight of each signal and the four cutoffs that map a score to a risk band. Cutoffs must stay strictly ordered: Critical above High above Medium above Low. A signal you turn off is ignored. High-confidence bot signals are marked **Critical signal** and only a platform superadmin can change or disable them. **Estimate impact** previews how a change would shift the band mix over recent traffic without applying it. **Reset to defaults** clears your overrides.
On the **Shadow candidates** tab, author alternative weightings. A candidate runs in a shadow pass, records a delta against the production verdict for the concordance view, and never changes a live verdict. Use **Traffic impact** to estimate flips. Accepting a change into production is a separate, deliberate step in [Risk actions, investigations and entity lookup](https://noxtica.com/docs/backoffice/risk-actions-and-investigations/).
### 4. Set Client Cost Levels
Open `Client Cost Levels`, pick a domain, and choose **Off**, **Light**, **Standard** or **High** for each of three costs:
| Cost | What it controls |
| --- | --- |
| Proof-of-work & challenge cost | How deep the CPU and GPU proof-of-work ladder runs, and whether the challenge prefers proof-of-work over Turnstile. Off skips proof-of-work |
| Detection probes cost | Which client-side probes run. Off disables every probe on the domain |
| Session-replay capture cost | Replay sampling, throttling and network-body capture. Saving any level needs an active session-replay legal-basis receipt |
Standard is the default behavior. Higher levels detect more and ask more of every visitor's device. The page suggests Light for checkout flows. The cost lands on the visitor's device, so no level needs extra sign-off. Any effective replay rate below 100 percent records no anonymous web visitors.
### 5. Stage Verdict Bands and sealed results
`Verdict Bands` has two sections.
- **Sealed Runtime security bands**: **Replay protection mode** and **Binding mode**. Each moves **Off → Shadow → Active**. Off and shadow do not enforce. Active becomes selectable once a band is in shadow. In Active the replay band can block live submissions, subject to the platform enforcement switch. The binding band is signal-only in this iteration: Active does not block.
- **Sealed results**: turn on **Emit sealed results** and the submit response carries an encrypted envelope that only your backend can open. It restores the detailed flags withheld from the browser response. Your server fetches the key with a secret API key that carries the `read:sealed_results` scope, then opens the envelope. The console never shows the key. See the [Server API overview](https://noxtica.com/docs/api/).
### 6. Honeypots and shared intelligence
On `Honeypots & Shared Intel`, **Enable honeypot tripwires** arms decoy routes, decoy form fields and per-session canary tripwires. A tripped wire raises a risk signal for your rules and never blocks a visitor on its own. The page shows anonymous daily counts per tripwire (**Hits (7d)**). **Rotate canary** invalidates current per-session canaries and needs MFA. Detection stays inactive until the platform also arms honeypots for your workspace.
**Federated intelligence** has two independent switches: **Contribute** reports an anonymized, tenant-blinded marker when a cluster escalates; **Consume** lets scoring read a shared signal that exists only after several workspaces flagged the same cluster. Both default to off.
### 7. Set the Collector refresh interval
On `Collector`, **Token refresh interval** controls how often the script refreshes its session token. Options: 30 seconds, 1 minute, **5 minutes (default)**, 15 minutes, 1 hour, 6 hours, 24 hours, or **Use plan default**. Your plan sets a floor; a value below it is refused. Lower values are more responsive and cost more infrastructure. **Effective** shows the value in force. A single domain can override the interval on its detail page. New sessions use the new interval.
### 8. Toggle probes and behavioral signals
`Probes` has four sections. Each is a switch with a warning.
| Probe | What it does | Notes |
| --- | --- | --- |
| DNS-leak probe | Compares the observed DNS resolver with the client network | Default off. Needs the platform switch as a second key |
| Extension probe | Probes a short list of high-signal browser extensions; stores a one-way hash and a count, not the list | On Chromium browsers it causes one expected console error line per page view. Never used to auto-block |
| Geo probe | Reads precise location only when the browser has already granted permission; never prompts | Only a coarse bucket is emitted |
| Persistent device recognition | Recognizes a returning device with a daily-rotating token keyed to a clearable first-party ID | Off by default. The page calls it the most legally sensitive setting. Recognition only; never used to auto-block |
`Behavioral Signals` has three sections: **Behavioral biometrics** (mouse, click and scroll patterns for a per-domain behavioral subscore; disabled by default and classified as biometric data under the GDPR), **Behavioral path tracks** (a higher-risk category: pointer and touch path geometry; turning it off permanently deletes stored path records), and **Behavioral flags** (server-derived flags from session aggregates such as no interaction; default off, with a platform switch as the second key).
## Verify it works
- After saving, the page shows a success message and the **Last changed** time.
- After you set a rule to shadow, the rule card reads "Observing (shadow)" and **Would have fired** counts grow with traffic.
- **Effective** on the Collector page shows the interval you chose.
- A verdict band set to Shadow shows no blocking; check Risk Actions for would-be decisions.
- Every change appears in the [audit log](https://noxtica.com/docs/security/audit-log-and-exports/).
## Troubleshooting
| Symptom | Cause | Fix |
| --- | --- | --- |
| Switch is on but nothing changes | The platform key for that feature is off | Ask your account team to confirm the platform switch |
| **Active** is greyed out for a band | The band is Off | Move it to Shadow first and observe |
| Rules log matches but do not act | Mode is Off or Shadow, or the rule's Shadow switch is on | Set mode to Active and turn off the rule's Shadow switch when evidence supports it |
| Thresholds will not save | Cutoffs are not strictly ordered | Keep Critical above High above Medium above Low |
| A signal cannot be changed | It is a critical signal | Only a platform superadmin can change it |
| Cost level will not save for replay | No active session-replay legal-basis receipt | Record one under Web Analytics & Privacy → Capture Policies |
| Interval below plan floor | The plan sets a minimum | Choose a larger value or **Use plan default** |
| Adding a rule fails with "Rules are limited to 100 per tenant" | The workspace holds 100 rules | Delete or merge rules |
## Related
- [Risk actions, investigations and entity lookup](https://noxtica.com/docs/backoffice/risk-actions-and-investigations/): read shadow evidence before you go Active.
- [Domains, site keys and the install card](https://noxtica.com/docs/backoffice/domains/): per-domain tracker policy and token refresh.
- [Consent modes, GPC and Google Consent Mode](https://noxtica.com/docs/sdk/consent/): what the browser does without consent.
- [Protected actions: client trigger and server check](https://noxtica.com/docs/sdk/protected-actions/): protect login and checkout.
- [Why calibration, not verdicts](https://noxtica.com/docs/why-calibration/): map risk and confidence to your policy.
- [Legal basis register and receipts](https://noxtica.com/docs/compliance/legal-basis/): record the basis for optional collection.
---
Source: https://noxtica.com/docs/backoffice/integrations/
Markdown: https://noxtica.com/docs/backoffice/integrations/index.md
Last updated: 2026-10-27
# Integrations and API pages
The **Integrations & API** group of the Backoffice sidebar holds every page that connects Noxtica to your code and your tools: credentials, install snippets, event delivery, notifications and connections. A workspace Admin uses these pages. This page maps each one, so you know where to go and which guide covers the detail.
## What it is
Availability: Availability depends on your plan, role and the modules enabled for your organisation.
The group has 11 sidebar pages, all Admin in the sidebar. A twelfth credential page, **Coding Agent Keys**, sits in **AI & Agents** and is covered in [AI assistant, MCP tokens and coding-agent keys](https://noxtica.com/docs/backoffice/ai-assistant-and-mcp/).
| Nav label | Route | What it does | Covered in |
| --- | --- | --- | --- |
| Event Sinks | `/event-sinks` | Push verdict and audit events to a SIEM | [Event sinks](https://noxtica.com/docs/backoffice/event-sinks/) |
| API & SDK | `/api-config` | Server API keys and integration links | [Server API](https://noxtica.com/docs/api/), [Authentication](https://noxtica.com/docs/api/authentication/) |
| MCP Tokens | `/integrations/mcp-tokens` | Read-only tokens for an MCP client | [AI assistant, MCP tokens and coding-agent keys](https://noxtica.com/docs/backoffice/ai-assistant-and-mcp/), [MCP server](https://noxtica.com/docs/api/mcp/) |
| Score API Keys | `/integrations/score-api-keys` | Keys for server-side score calls | [Backend Integration](https://noxtica.com/docs/backend-integration/) |
| Script & Consent | `/integrations/script-consent` | Collector snippets, consent mode, protected actions | [Install & Browser Runtime](https://noxtica.com/docs/browser-runtime/) |
| Ingestion API Keys | `/integrations/ingestion-api-keys` | Keys for traces, metrics and logs | [APM and the ingestion service](https://noxtica.com/docs/observability/apm-and-ingest/) |
| Webhooks | `/integrations/webhooks` | Signed event delivery to your HTTPS endpoints | [Webhooks](https://noxtica.com/docs/api/webhooks/) |
| Alerts | `/integrations/alerts` | Email, Slack or webhook alerts | [Uptime checks, alerts, status reports](https://noxtica.com/docs/observability/uptime-alerts-status/) |
| Status Reports | `/integrations/status-reports` | Periodic email reports | [Uptime checks, alerts, status reports](https://noxtica.com/docs/observability/uptime-alerts-status/) |
| Relay Hostnames | `/integrations/relay` | Serve the collector from your own hostname | [Content Security Policy, hosts and first-party relay](https://noxtica.com/docs/sdk/csp-and-relay/) |
| Attestation Apps | `/integrations/attestation-apps` | Register Android and iOS apps | [Device and app attestation](https://noxtica.com/docs/security/attestation/) |
| Connectors | `/integrations/connectors` | Connect log providers, issue trackers, help desks and warehouses | This page |
The sidebar label for the server key page is **API & SDK**. Some older pages call it "API Config"; its page heading reads **API Configuration**.
## Prerequisites
- The Admin role. Lower roles do not see these pages, and the server checks the role on every read and every change. See [Backoffice guide](https://noxtica.com/docs/backoffice/overview/).
- An authenticator app. Creating, rotating and revoking a credential asks for a fresh MFA check.
- A place to store a secret. Every credential is shown once, when you create it. Backoffice cannot show it again.
- Some pages exist but depend on your plan or on a feature being enabled for your organisation, for example Score API Keys and Alerts. A page that is not available shows an empty or "not enabled" state, or a 404 on its API.
## Steps
### 1. Create a server API key (API & SDK)
1. Open `Backoffice → Integrations & API → API & SDK`. The tabs are **Client Integration**, **Backend Integration** and **Server API Keys**.
2. On **Server API Keys** select **Create API Key**.
3. Enter a **Key Name** (required), choose the narrowest **Scopes**, and select **Create Key**. The picker groups scopes as **Read access**, **Write access** and **Erase (destructive)**. A new key starts with `read:device` selected.
4. Copy the **Secret Key**. The page says "Save this secret key now — it will not be shown again."
5. To replace a key, select **Rotate** and type `ROTATE`. To retire it, select **Revoke** and type `REVOKE`. Revoking is permanent and requests that use the key fail at once.
Server keys start `sk_prod_`. Never put a secret key in browser code. Scope meanings, errors and limits are in [Server API](https://noxtica.com/docs/api/), [Authentication](https://noxtica.com/docs/api/authentication/) and [Errors](https://noxtica.com/docs/api/errors/).
### 2. Install the collector (Script & Consent)
Open `Script & Consent`. Tabs: **How it works**, **Snippets**, **Consent & extensions**, **Protected actions**, **CSP & storage**, **Check it works**. Pick a domain (the page keeps it in the URL as `?domain_id=`), copy its core script, choose how the domain receives consent, and name protected actions such as login or checkout. The public walkthrough is [Install & Browser Runtime](https://noxtica.com/docs/browser-runtime/). See also [Domains, site keys and the install card](https://noxtica.com/docs/backoffice/domains/).
### 3. Add a webhook
1. Open `Webhooks`. Tabs: **Manage** and **Integration** (an in-app developer guide).
2. Select **Add endpoint**, enter a public `https://` URL, choose the events and select **Add endpoint**. Localhost and private addresses are refused.
3. Copy the **Signing secret** when it is shown; it is shown once.
4. Select **Send test** to confirm your endpoint answers. Use **Enable**, **Disable**, **Rotate secret** and **Delete** as needed.
A workspace can hold up to 25 endpoints. Each attempt has a 5 second response timeout, and delivery is at least once, so a delivery can arrive more than once. Verify the `X-Noxtica-Signature` header on every delivery. The envelope, events and retry rules are in [Webhooks](https://noxtica.com/docs/api/webhooks/). Identity events are in [Identity verification events and webhooks](https://noxtica.com/docs/identity-verification-webhooks/).
### 4. Create MCP, Score and ingestion credentials
- **MCP Tokens** and **Coding Agent Keys**: see [AI assistant, MCP tokens and coding-agent keys](https://noxtica.com/docs/backoffice/ai-assistant-and-mcp/).
- **Score API Keys**: create a key for server-side score calls. Store it on your server, never in browser or app code. Calls made with any key count toward the workspace. Revoke keys you no longer use.
- **Ingestion API Keys**: create a key for one project and environment, add it to your telemetry exporter, and revoke it when the service is retired.
Each of these pages has a **Manage** tab and an **Integration** tab with an in-app guide.
### 5. Send events to your SIEM
Open `Event Sinks`. A new sink is created disabled. Arm it, then send a real test request. The steps are in [Event sinks](https://noxtica.com/docs/backoffice/event-sinks/).
### 6. Set up alerts and reports
- `Alerts` has the tabs **Channels**, **Rules**, **History** and **Escalations**. Add a channel (email, Slack or webhook), create rules that decide when an alert fires, and review the delivery history. A workspace can hold up to 10 channels and 20 rules. Alert evaluation depends on the feature being enabled for your organisation.
- `Status Reports` sends periodic emails about traffic, detection activity, usage and quota. Reports are on by default. Choose the frequency, the time zone and an extra contact, and preview the next report.
### 7. Serve the collector from your hostname (Relay Hostnames)
Choose the domain and a hostname on your own domain, add the DNS record the page shows (a CNAME and, for verification, a TXT record), then wait until it verifies. When it does, the collector loads from your hostname. Creating, verifying and revoking need MFA. A domain's **Relay** tab shows the same status read-only. See [Content Security Policy, hosts and first-party relay](https://noxtica.com/docs/sdk/csp-and-relay/).
### 8. Register mobile apps (Attestation Apps)
Add the app identifier for each Android and iOS app. Noxtica then accepts attestation results from that app. Remove an app to stop trusting its results. Registering needs MFA. See [Device and app attestation](https://noxtica.com/docs/security/attestation/).
### 9. Connect other services (Connectors)
Pick the service (log provider, issue tracker, help desk or data warehouse), enter its credentials, and save. Credentials are stored encrypted and never shown again. Remove or update a connection at any time.
## Verify it works
- A new credential appears in its page's list with a created time, and **Last Used** updates after its first call.
- A test webhook shows a success message with the response status and time.
- On Script & Consent, **Check it works** confirms the script reaches Noxtica.
- On Relay Hostnames, the status badge changes to `active` once DNS verifies.
## Troubleshooting
| Symptom | Cause | Fix |
| --- | --- | --- |
| The page is missing from the sidebar | The role is below Admin | Ask a workspace Admin |
| A create or revoke action prompts for a code | Sensitive change needs a fresh MFA check | Enter the authenticator code |
| Lost a secret | Secrets are shown once | Rotate or recreate the credential |
| Webhook URL is refused | It is not public `https`, or points to localhost or a private address | Use a public `https` URL |
| A key returns 403 from the API | The scope does not cover the call | Create a key with the needed scope; see [Authentication](https://noxtica.com/docs/api/authentication/) |
| Score API Keys page is empty or its API returns 404 | Self-serve score keys are not enabled for your organisation | Ask your account team |
| Relay hostname stays unverified | The DNS record is missing or wrong | Check the CNAME and TXT values shown on the page |
## Related
- [Backoffice guide: navigation, roles and shortcuts](https://noxtica.com/docs/backoffice/overview/): where each page sits in the sidebar.
- [Event sinks](https://noxtica.com/docs/backoffice/event-sinks/): SIEM export.
- [AI assistant, MCP tokens and coding-agent keys](https://noxtica.com/docs/backoffice/ai-assistant-and-mcp/): MCP and coding-agent credentials.
- [Server API](https://noxtica.com/docs/api/): endpoints, scopes and errors.
- [Roles and permissions](https://noxtica.com/docs/security/roles-and-permissions/): who can manage credentials.
---
Source: https://noxtica.com/docs/backoffice/workspace-settings/
Markdown: https://noxtica.com/docs/backoffice/workspace-settings/index.md
Last updated: 2026-10-27
# Workspace gates, feature flags, data operations and mobile operations
The **Administration** group of the sidebar holds the workspace controls that are not about detection: optional product behaviours, visitor experiments, deleting browser data and mobile posture. This page also covers your own **Settings** page and the notifications panel. A workspace Admin uses most of these pages; Analysts can read Feature Flags.
## What it is
Availability: Availability depends on your plan, role and the modules enabled for your organisation.
| Page | Route | Minimum role | Purpose |
| --- | --- | --- | --- |
| Workspace Gates | `/administration/workspace-gates` | Admin | Turn optional product behaviours on or off for this workspace |
| Feature Flags | `/feature-flags` | Analyst to read, Admin to change | Per-domain visitor experiences, experiment splits, conditional-recording keys |
| Data Operations | `/data-operations` | Admin | Soft-delete end-user browser data, run retention, remove admin accounts |
| Mobile Operations | `/mobile-operations` | Admin | Read mobile posture; arm or disarm the workspace's mobile kill-switch key |
| Settings | `/settings` | Any signed-in role | Your own sign-in security, appearance, notifications and privacy choices |
Sign-in, SSO and MFA enforcement are on **Sign-in & Access**, covered in [Sign-in, SSO, SCIM, MFA and IP allowlist](https://noxtica.com/docs/security/sign-in-and-access/). Users and roles are in [Roles and permissions](https://noxtica.com/docs/security/roles-and-permissions/). The audit log and exports are in [Audit log and data export](https://noxtica.com/docs/security/audit-log-and-exports/).
## Prerequisites
- The role in the table. See [Backoffice guide](https://noxtica.com/docs/backoffice/overview/).
- An authenticator app. Gates, flags, data operations and the mobile key each ask for a fresh MFA check.
- For Feature Flags: at least one registered domain. See [Domains, site keys and the install card](https://noxtica.com/docs/backoffice/domains/).
- For Data Operations: a clear reason for each deletion and the identifiers to match (device IDs, user ID, domain or dates).
## Steps
### 1. Review Workspace Gates
Open `Administration → Workspace Gates`. The page lists the gates your workspace can govern. These are product preferences, not legal assertions; assertions live in the [Legal basis register](https://noxtica.com/docs/compliance/legal-basis/).
For each gate you see its state (**On** or **Off**), whether this workspace overrides the platform default, and a note headed **What this switch does not stop**. Read that note: some gates change the Backoffice side of a feature while collection stays on the platform side.
- **Turn on**: some gates need an acknowledgement, and some also need you to type the gate key. Backoffice re-checks both on the server.
- **Turn off** and **Use platform default**: one click, no extra confirmation. Both still need a fresh MFA check and are audited.
- Every change is recorded in the audit log.
If no gate is controllable, the page says so.
### 2. Create a Feature Flag
Open `Administration → Feature Flags`. A flag controls a visitor experience on one domain, splits traffic for an experiment, or provides a key for conditional session recording.
1. Pick a domain, then select **New flag**.
2. **Flag key**: lowercase letters, numbers, dots, underscores or dashes. The key cannot change later.
3. **Description**: up to 500 characters.
4. **Rollout percentage**: the share of identified visitors admitted, from 0 to 100 with up to four decimals. Anonymous visitors always receive the default variant.
5. **Experiment variants** (optional): up to eight, each with a key and an allocation. Allocations must total 100 percent. Leave variants empty for a **Boolean flag**.
6. **Default variant**: what anonymous visitors and out-of-rollout visitors receive.
7. **Enabled**: allows assignment only when platform delivery is armed. Select **Create flag**.
On a flag's page you see **State**, **Identified rollout**, **30-day exposures** and **Reaching anyone**, the configured and observed split, and **Pinned subjects**. To pin a subject to a variant, enter the same email or user ID your integration sends; only a one-way hash is stored. Use the exact flag key in a conditional-recording trigger.
If the page says "Flag delivery is not armed", definitions are saved but visitors receive no assignments until Noxtica arms delivery for your workspace. Creating and changing flags needs the Admin role and an MFA check. Deleting a flag removes its variants and pins.
### 3. Run a Data Operation
Open `Administration → Data Operations`. Tabs: **End-User Data**, **Retention**, **Admin Accounts**, **History**. Every operation follows three steps: **Preview**, **Review impact**, **Confirm**.
- **End-User Data** soft-deletes browser intelligence data for chosen devices or users. Match by device IDs (one per line, up to 500), an external user ID, a domain or a date range. Add a reason, which goes to the audit log. Select **Preview Impact** and read the counts of fingerprints, events and visits.
- **Retention** triggers a manual retention cleanup of data older than your configured retention period. The page notes that an automatic retention run also happens daily at 03:00 UTC.
- **Admin Accounts** soft-deletes an operator, who can then no longer sign in. A reason is required.
- Type `DELETE` in capitals to unlock **Confirm Soft Delete**. Data is hidden from views and exports, and a platform superadmin can hard-delete it later. The **History** tab lists every run with its type, status and counts. A run that reaches the per-run row cap is marked **Partial**; run it again with tighter filters.
Data Operations applies to browser intelligence data. It does not apply to identity verification details or evidence. Noxtica does not remove those on a schedule; a tenant administrator removes them in `Backoffice → Identity Verification → KYC Verifications` (**Delete verification** and **Delete selected**) or through `KYC Erasure`. See [Verification data: storage, access and deletion](https://noxtica.com/docs/identity-verification-data/).
### 4. Read Mobile Operations
Open `Administration → Mobile Operations`. It shows **Fleet posture** and **Tenant posture** for these capabilities: **Mobile kill switch**, **Secure app handoff**, **Transactional activation**, **Account deletion**, **Android minimum version** and **iOS minimum version**. The page is read-only except for one control.
The kill switch has two keys: a fleet key that Noxtica operators control and a tenant key you control. Mobile access is killed only when both are on. Under **Tenant kill-switch control**, enter a **Change reason** (1 to 500 characters), then select **Arm tenant kill-switch key** or **Disarm tenant kill-switch key**, and confirm with MFA. If your key is armed, the page cannot observe the fleet key, so the effective posture shows as unknown rather than killed. Registered mobile apps and attestation results are covered in [Device and app attestation](https://noxtica.com/docs/security/attestation/).
### 5. Set your own account preferences
Open `Settings` (shortcut `G` then `S`). The page follows your account, not the workspace.
- **Security**: turn on two-step sign-in with an authenticator app, manage backup codes and review where you are signed in.
- **Appearance**: theme (Dark, Light, High contrast), density (Compact, Comfortable, Spacious) and interface font (Sans, Mono, Humanist, Mixed).
- **Notifications**: **Critical device email** (email when a device exceeds the configured risk threshold), **Weekly digest** (summary every Monday at 09:00 workspace time) and **In-app alerts**.
- **Privacy & cookies**: Noxtica's own security script always runs on the console to protect sign-in. Analytics, session replay and device recognition for your own console use are your choice and are off until you allow them.
The bell in the top bar opens **Notifications**: recent audit activity and destructive actions. Workspace-level alerts and reports are on [Integrations and API pages](https://noxtica.com/docs/backoffice/integrations/).
## Verify it works
- A changed gate shows its new state and "Turned on for this workspace." or "Turned off for this workspace.", and an audit entry appears.
- A new flag appears in the list with its **State**; after delivery is armed and traffic arrives, **30-day exposures** grow.
- After a data operation, **History** shows the run as **Completed**.
- After arming or disarming the tenant kill-switch key, the page shows its confirmation message and the tenant key state changes.
- Your notification choices stay after you reload **Settings**.
## Troubleshooting
| Symptom | Cause | Fix |
| --- | --- | --- |
| No gates are listed | No gate is currently controllable per workspace | None; check back after a product update |
| A gate will not turn on | It needs an acknowledgement or the typed key | Complete the dialog |
| Flag assignments never reach visitors | Platform delivery is not armed, the flag is disabled, or rollout is 0 | Check the notices on the page; ask your account team |
| "Variant allocations must total 100%" | Allocations do not add up | Adjust them to total 100 |
| Preview Impact is disabled | No filter is set | Add device IDs, a user ID, a domain or dates |
| Too many device IDs | More than 500 IDs in one run | Split the run |
| Confirm button stays locked | `DELETE` was not typed exactly in capitals | Retype it |
| A run is marked Partial | It reached the per-run row cap | Run again with tighter filters |
| The kill-switch buttons are greyed out | No change reason entered | Enter a reason of 1 to 500 characters |
| Mobile page asks you to switch tenant scope | A platform operator has no workspace selected | Select a workspace |
## Related
- [Backoffice guide: navigation, roles and shortcuts](https://noxtica.com/docs/backoffice/overview/): where these pages sit.
- [Audit log and data export](https://noxtica.com/docs/security/audit-log-and-exports/): every change here is audited.
- [Data retention, raw IP storage and data locations](https://noxtica.com/docs/compliance/retention-and-locations/): retention settings.
- [Data subject scope, erasure requests and account deletion](https://noxtica.com/docs/compliance/requests-and-deletion/): erasure workflows.
- [Verification data: storage, access and deletion](https://noxtica.com/docs/identity-verification-data/): identity data lifecycle.
- [Sign-in, SSO, SCIM, MFA and IP allowlist](https://noxtica.com/docs/security/sign-in-and-access/): MFA and SSO.
---
Source: https://noxtica.com/docs/billing/plans-and-packages/
Markdown: https://noxtica.com/docs/billing/plans-and-packages/index.md
Last updated: 2026-10-27
# Plans, packages and add-ons
This page covers the Backoffice pages that show your plan, the packages and add-ons you can have, and how to ask for changes. It describes pages and behaviour. It states no prices, rates or quota values. For those, see the [pricing page](https://noxtica.com/pricing/) and your agreement.
## What it is
Availability: Availability depends on your plan, role and the modules enabled for your organisation.
Self-serve purchase of packages and add-ons is available when it is enabled for your organisation. Otherwise your account team provisions them. Backoffice tells you which case applies on the page itself.
| Term | What it means in Backoffice |
| --- | --- |
| Plan | Your base tier. It sets your monthly allowances and your domain limit. |
| Plan change request | A request to move to another plan. A platform administrator reviews it. |
| Add-on request | A request for extra events or extra collector requests on top of your plan. A platform administrator reviews it. |
| Package | A bundle that turns on the core modules of one or more product areas for a monthly fee. |
| Module add-on | A single optional module you can turn on or off for your workspace. |
Where the pages are, under Backoffice → Billing & Plan:
| Page | Route | Who can open it |
| --- | --- | --- |
| Plan | `/billing/plan` | Admin sees it in the menu. |
| Packages & Add-ons | `/billing/packages` | Admin role, or billing role when enabled for your organisation. |
Packages & Add-ons has four tabs: **Packages**, **Add-ons**, **Included usage** and **Billing status**. The Add-ons tab is shown only to roles that may manage it, which means the admin role.
Prices, if shown, are the values in force for your workspace. This page does not repeat them.
## Prerequisites
- The admin role to request a plan change, request an add-on, or turn a module add-on on or off. See [Roles and permissions](https://noxtica.com/docs/security/roles-and-permissions/).
- The admin role or the billing role to subscribe to or cancel a package. The billing role is available when enabled for your organisation.
- MFA enrolled on your account. Subscribing, cancelling and module toggles ask for a step-up check from the last 6 hours. Plan and add-on requests do not.
- Wallet funds to subscribe to a priced package. Subscribing charges your wallet. See [Wallet, invoices and reports](https://noxtica.com/docs/billing/wallet-invoices-reports/).
- Self-serve purchase enabled for your organisation, if you want to subscribe yourself. Otherwise ask your account team.
## Steps
### 1. Review your current plan
Go to Backoffice → Billing & Plan → **Plan**. The **Plan & Quotas** card shows your plan name, the monthly event limit and the maximum domains.
The **Request plan change** card below it shows **Your current plan** with its allowances: events, API requests, ingestion requests, Score API calls, AI credits, domains and data retention. It also shows the monthly price and where that price comes from: **Plan price**, **Your negotiated price** or **Custom plan default**.
### 2. Request a plan change or extra capacity
On the same page, choose a tab.
**Change plan**
1. Choose **Select new plan**. Each option is marked as an upgrade or a downgrade.
2. Read **What changes**. It compares your current plan with the new plan, allowance by allowance.
3. Add an optional **Reason**.
4. Click **Submit request**.
**Add-ons**
1. Choose a resource: **Additional API requests** (collector requests) or **Additional events**.
2. Choose a quantity. Backoffice shows an estimated monthly price.
3. Enter a **Reason**. It is required on this tab.
4. Click **Request add-on**.
After you submit, a **Pending** badge shows and the page reads **Your plan change request is awaiting review**, or the same for an add-on request. You can have one pending request for each type. You cannot withdraw a request from Backoffice. Contact your account team to cancel it before review.
What happens next:
- A platform administrator reviews the request. Nothing changes until it is approved.
- Plan pricing and billing are confirmed by your account team after approval.
- No card is charged in the product for a plan or add-on request. Approved add-ons recur monthly until cancelled.
- Add-ons stack on top of your plan and are used after your plan allowance runs out.
- A plan change does not retroactively shrink the limit of a month that has already started.
### 3. Compare packages
Go to Backoffice → Billing & Plan → **Packages & Add-ons**. The **Packages** tab shows one card for each package:
- The package name and description.
- A badge: **Current plan**, **Cancelling** or **Not subscribed**.
- The monthly price, **Free**, **Coming soon** or **Price unavailable**.
- **Covers:** the product areas the package turns on.
- **Next charge:** the date of the next charge, for an active package.
A note under the cards reads **Subscribing charges your wallet balance** and links to **Top up your wallet**.
### 4. Read why an item is unavailable
When you cannot subscribe or turn something on, the card or row shows a badge and a plain reason before you click. The control is disabled and points at that reason.
| Badge | Reason shown | What you can do |
| --- | --- | --- |
| **Requires plan** | The item needs a higher plan. | Click **request a plan change**. Backoffice shows your workspace ID so you can quote it. |
| **Core module needed** | Turn on the core module of this product first. | Turn on the core module, or subscribe to a package that includes it. |
| **Embargoed** | A sale embargo applies. For attestation the text is **Embargoed until hardware verification is proven.** | Contact Noxtica support and name the item. Quote your workspace ID. |
| **Pending legal review** | The item waits for legal sign-off, for example behavioral data or the EU AI Act active tier. | Contact Noxtica support and name the item. |
| **Not available yet** | The item is on hold or still being built. | Contact Noxtica support and name the item. |
| **No price set yet** | A package has no price while self-serve billing is on. | Contact Noxtica support and name the package. |
Backoffice has no waitlist. For a held item, contact support and quote the workspace ID. Use the copy button next to it.
### 5. Subscribe to a package
1. On the **Packages** tab, click **Subscribe** on a card. The button reads **Activate** when the package is free or when self-serve billing is not enabled.
2. Complete the step-up prompt.
3. Read the result: **Subscribed.**
Subscribing charges your wallet. If the balance is too low you see **Your wallet balance is too low** with a **Top up your wallet** button. Nothing is charged and nothing changes.
### 6. Cancel a package
On an active package card, click **Cancel package** and complete the step-up prompt. The card changes to **Cancelling** and shows **Package cancelled.** A cancelled package cannot be subscribed again from Backoffice. Ask your account team if you need it back. Cancelling does not delete your data or your audit history.
### 7. Turn module add-ons on or off
Open the **Add-ons** tab. It lists the module add-ons published for your workspace. Each row shows **Subscribed** or **Not subscribed**, its monthly fee or **No monthly fee**, and whether it turns on for your whole workspace or per domain.
1. Switch the toggle for the module.
2. Complete the step-up prompt.
3. Read **Add-on subscribed.** or **Add-on unsubscribed.**
Items that cannot be turned on are listed under **Not available yet**, each with its reason and the next step, as in step 4. If module add-ons are not enabled for your organisation, Backoffice shows a banner and the controls are read-only. Subscribing records the add-on and its monthly fee. The charge is not taken at the click.
The **Included usage** tab and the **Billing status** tab are covered in [Usage, quotas and metering](https://noxtica.com/docs/billing/usage-and-quotas/) and [Billing status, grace period and reminders](https://noxtica.com/docs/billing/status-grace-reminders/).
## Verify it works
- A submitted request shows **Pending** and the submission date on the Plan page.
- The request appears in the audit log as Plan Requested or Extra Quota Requested. See [Audit log and data export](https://noxtica.com/docs/security/audit-log-and-exports/).
- A subscribed package card shows **Current plan** and a **Next charge** date. Your wallet activity shows the package charge.
- A module row shows **Subscribed**.
- A cancelled package shows **Cancelling**.
## Troubleshooting
| Symptom | Cause | Fix |
| --- | --- | --- |
| The Plan page is missing from the menu | Your role is below admin. | Ask an admin. |
| **A pending plan change request already exists. Please wait for it to be reviewed.** | One request of that type is already pending. | Wait for the review, or contact your account team to cancel it. |
| **A pending extra-quota request already exists. Please wait for it to be reviewed.** | One add-on request is already pending. | Same as above. |
| **You are already on this plan** | The chosen plan is your current plan. | Choose another plan. |
| The Subscribe button is disabled with a badge | A reason applies, for example plan tier or a hold. | Read the reason and follow the action in step 4. |
| **Your wallet balance is too low** | The wallet cannot cover the package fee. | Click **Top up your wallet**, then subscribe again. |
| **No packages available** | No package is published for your workspace. | Ask your account team. |
| **No package can be subscribed to yet** | Every package is on hold or has no price. | Contact Noxtica support and quote your workspace ID. A platform administrator can assign a package or extend a grace period. |
| **This change could not be applied** | The change was refused and nothing was changed. | Retry. Contact support with the time of the attempt if it repeats. |
| A cancelled package cannot be subscribed again | Packages in Cancelling or off state cannot be activated again. | Ask your account team. |
| The Add-ons tab is missing | Your role is below admin. | Ask an admin. |
| A banner says module add-ons are disabled | Module add-ons are not enabled for your organisation. | Ask your account team. |
| **Package billing is not enforced for this workspace yet** | Self-serve billing is not enabled for your workspace. | Nothing is charged and no page is paused. Ask your account team to provision the package. |
| **Verification cancelled** | You closed the step-up prompt. | Repeat the action and verify. |
## Related
- [Usage, quotas and metering](https://noxtica.com/docs/billing/usage-and-quotas/): meters, quota rules and the Included usage tab.
- [Wallet, invoices and reports](https://noxtica.com/docs/billing/wallet-invoices-reports/): add funds, invoices and reports.
- [Billing status, grace period and reminders](https://noxtica.com/docs/billing/status-grace-reminders/): the Billing status tab and the grace window.
- [Roles and permissions](https://noxtica.com/docs/security/roles-and-permissions/): who can see and change billing pages.
- [Pricing](https://noxtica.com/pricing/): plan and rate information. [Pricing reference](https://noxtica.com/docs/pricing/) has the definitions behind it.
---
Source: https://noxtica.com/docs/billing/usage-and-quotas/
Markdown: https://noxtica.com/docs/billing/usage-and-quotas/index.md
Last updated: 2026-10-27
# Usage, quotas and metering
Usage & Quotas shows what your workspace has used this month against what your plan includes. This page explains the tabs, how each meter counts, and what happens when you reach a limit. It states no quota values and no prices. Backoffice shows the values in force for your workspace. See [pricing](https://noxtica.com/pricing/) and your agreement for commercial terms.
## What it is
Availability: Availability depends on your plan, role and the modules enabled for your organisation.
Usage & Quotas is under Backoffice → Billing & Plan → **Usage & Quotas** (`/usage`). Viewers, analysts, admins and billing users can open it. Some sections need more than view access.
| Tab | Content | Needs |
| --- | --- | --- |
| **Overview** | Usage against quota for events, collector requests, ingestion requests, Score API calls, AI credits, MCP queries and domains. Burn-down chart. Usage by domain. Plan limits. | View access |
| **Meters & quotas** | One row for each meter, with usage, quota, projection and status. Usage by store. Usage by functionality and endpoint. | The capability to view billing: admin or billing role |
| **AI & agents** | AI Assistant usage. Agent and MCP usage. LLM sourcing usage. | View access. Agent and MCP usage needs the admin role. LLM sourcing usage needs the admin role. |
| **KYC & identity** | Verifications this period and an estimated spend. | The capability to view KYC usage: any role |
| **PAYG & wallet** | Module add-ons, pay-as-you-go accrual and wallet balances. | View access |
| **History** | Recent wallet activity and pay-as-you-go close-outs. | View access |
Old links still work. `/billing/usage` opens the **Meters & quotas** tab and `/ai-usage` opens **AI & agents**.
### Quota rules in plain words
All counters run on the UTC calendar month. They reset at the start of each month.
| Meter | What counts | At the limit |
| --- | --- | --- |
| Collector requests | Each token issuance request to the collector. | When quota enforcement is enabled for your organisation, a further token request is refused with `429`, code `COLLECTOR_REQUESTS_QUOTA_EXCEEDED`, and a `Retry-After` header with the seconds until next month. Without enforcement the counter fills and nothing is refused. |
| Events | Each event submission. | The same enforcement setting applies. |
| Ingestion requests | Each authenticated request served by the ingestion service in native mode. Proxied and unauthenticated requests are excluded. The quota is 10 times your collector request quota. | Counted and shown. Never blocked. |
| Score API calls | Each authenticated, valid `POST /v1/score` call. | Calls above the included amount are billed as metered usage and are never rejected. |
| AI credits | AI Assistant use. The plan gives a monthly allotment. Purchased extra credits stay until used. | Backoffice shows Remaining. |
| MCP queries | MCP tool use against a monthly cap for the token scope tier. | Backoffice labels it **Enforced — counts toward your monthly cap** or **Shadow only — not yet enforced**. |
| Domains | Active domains against the plan maximum. | Creating another domain is refused with **Maximum domains limit reached for this tenant**. |
Two further points:
- A meter with no enforced quota shows **Count only — no enforced quota**.
- Each plan includes a share of the listed monthly allowances for module meters, rounded down to a whole unit. Whether an overage price applies depends on your plan. Where a plan sells no overage the table shows **Hard cap**.
Some figures are estimates. The page labels them. **Billable units** and pay-as-you-go accrual are estimated and display-only. What you are charged appears on your [invoices](https://noxtica.com/docs/billing/wallet-invoices-reports/).
## Prerequisites
- A Backoffice user with at least view access for the Overview. The admin role or the billing role for **Meters & quotas**.
- A workspace with traffic. A new workspace shows **No usage recorded yet**.
- For KYC usage: the identity verification module activated for your workspace. Otherwise the tab says **Not activated**.
- For quota alerts: the admin role, and alert delivery set up. See [Uptime checks, alerts, status reports and the status page](https://noxtica.com/docs/observability/uptime-alerts-status/).
## Steps
### 1. Open Usage & Quotas
Go to Backoffice → Billing & Plan → **Usage & Quotas**. The subtitle shows the period. The tab you open is kept in the `?tab=` part of the address, so you can bookmark it.
### 2. Read the Overview
Each quota card shows the used amount, the limit and **N% used**. The footer reads:
- **Healthy** below 75 percent.
- **Approaching limit** from 75 percent.
- **Over 90% — upgrade recommended** from 90 percent.
The **Quota burn-down** chart draws cumulative usage and a straight-line projection to month end. It says **Within quota**, **Projected to exhaust on ~** or **Quota exhausted on **. A plan without a monthly event quota shows no limit line.
**Usage by domain** lists Domain, Status, Submissions and Visits for the period. **Plan limits** lists the static limits of your plan.
Backoffice labels figures by what they are:
- **Usage vs quota**: the metered counters your plan is measured against.
- **Analytics & trend**: raw event volume. These are trend metrics, not billing counters, and can exceed the quota count.
- **Observed (not billed)**: read-only meters shown for visibility.
- **Billable units (post free-tier)**: an estimate, display only.
### 3. Read the meters
Open **Meters & quotas**. Use **Filter by group** for All groups, Plan-included, Pay-as-you-go or Observability. Each row shows:
| Column | Meaning |
| --- | --- |
| Meter | The feature axis, with a link to its page. |
| Used / quota | Usage and the ceiling, with a percent bar. |
| Projected month-end | A straight-line projection. Monthly meters only. |
| Last 14 days | A trend line for meters with daily data. |
| Rate | The pay-as-you-go rate code and unit price, when the meter is billed. |
| Status | **Within quota**, **Over quota**, **Tier-included** or **No ceiling**. |
Below the table:
- **Usage by store** lists rows and estimated size this calendar month for each data class: Event data, Event payloads, Metrics, Warehouse analytics and KYC evidence, by storage location.
- **Usage by functionality and endpoint** shows what the Collect and Ingest endpoints served in a UTC month, per meter, against the included quantity, with % used and any overage. Choose the period with the selector.
- For KYC usage the section can show a **Shadow invoice — not billed**: what the period would cost under the rate card. The page states the rate card version and status. When a rate card is a proposal, the figures are informational and nothing is enforced or billed against them.
### 4. Compare plans
Open Backoffice → Billing & Plan → Packages & Add-ons → **Included usage**. The table has one row for each meter and one column for each plan. A cell shows the monthly included quantity and the overage price per unit, or **Hard cap**. Your plan column is marked **Your plan**. A badge says whether the rate card is active or **Proposed — not billed**.
### 5. Read KYC usage
Open **KYC & identity**. It shows **Verifications this period** and **Estimated KYC spend (this period)**. The spend is a display-only estimate. Use the pricing page for the rate card.
### 6. Check pay-as-you-go and wallet
Open **PAYG & wallet** for module add-on state, estimated pay-as-you-go accrual and wallet balances. Open **History** for the latest wallet entries and pay-as-you-go close-outs. Full wallet detail is under Billing & Plan → Wallet.
### 7. Set a quota alert
Go to Backoffice → Integrations & API → **Alerts** → rules.
1. Add a rule from the **Quota usage** template. It alerts when this workspace's monthly quota usage reaches the threshold percentage.
2. Set the threshold between 50 and 100 percent. The default is 90. The rule evaluates over one day.
3. Choose one or more alert channels and save. The save needs a step-up check.
Rules can be written even when the evaluator is paused for your organisation. Backoffice shows a banner when it is. Status-report e-mails also summarise usage and quota. See [Wallet, invoices and reports](https://noxtica.com/docs/billing/wallet-invoices-reports/).
## Verify it works
- The Overview shows a period in the subtitle and your quota cards with percentages.
- The burn-down chart shows a cumulative line that grows through the month.
- **Meters & quotas** lists meters with a **Status** for each.
- A quota alert rule shows in the Alerts list with its condition and state.
- After the month changes, the counters start again from zero.
## Troubleshooting
| Symptom | Cause | Fix |
| --- | --- | --- |
| **Failed to load usage data** | The overview read failed. | Click **Retry**. Other tabs load their own data. |
| **This report is temporarily unavailable.** | A section read failed. | Click **Retry**. |
| **Unavailable** on a card | That metric could not be read. | Retry later. |
| **No usage recorded yet** | No billable events in the current period. | Send traffic, or check the domain install. |
| Analytics events are higher than the Events quota count | Analytics volume includes rejected and removed events. It is a trend metric. | Use **Usage vs quota** for the billing counter. |
| **This plan has no monthly event quota, so no limit line is shown.** | Your plan has no event quota. | None needed. |
| No ingestion quota line | No collector request quota is set, and the ingestion quota is 10 times it. | None needed. |
| **No quota** or **No allowance** on a meter | The plan has no rate-card row for that meter. | Ask your account team. |
| Meters & quotas tab is missing | Your role has no view-billing capability. | Ask an admin or use the billing role. |
| Token requests return `429` with `COLLECTOR_REQUESTS_QUOTA_EXCEEDED` | Quota enforcement is enabled and the collector request quota is used up. | Wait for the next UTC month or request more capacity. See [Plans, packages and add-ons](https://noxtica.com/docs/billing/plans-and-packages/). |
| **Maximum domains limit reached for this tenant** | You reached the plan domain limit. | Remove a domain, or request a plan change. |
| **Not activated** on KYC & identity | The identity verification module is not activated. | Ask your account team. |
| **Per-store usage appears here once the daily store-usage rollup has run** | The daily rollup has not run for this workspace. | Check again later. |
| A rate card badge says **Proposed — not billed** | The rate card is not active. The figures are informational. | Use invoices for amounts charged. |
## Related
- [Plans, packages and add-ons](https://noxtica.com/docs/billing/plans-and-packages/): request more capacity.
- [Wallet, invoices and reports](https://noxtica.com/docs/billing/wallet-invoices-reports/): wallet, invoices and status reports.
- [Billing status, grace period and reminders](https://noxtica.com/docs/billing/status-grace-reminders/): banners and reminders.
- [Uptime checks, alerts, status reports and the status page](https://noxtica.com/docs/observability/uptime-alerts-status/): alert channels and rules.
- [Pricing reference](https://noxtica.com/docs/pricing/): the definitions of collector request, event, ingestion request and Score API call.
---
Source: https://noxtica.com/docs/billing/wallet-invoices-reports/
Markdown: https://noxtica.com/docs/billing/wallet-invoices-reports/index.md
Last updated: 2026-10-27
# Wallet, invoices and reports
The wallet is your prepaid balance. Package fees and other charges draw on it. Invoices are the monthly statements. Reports are the periodic usage and status e-mails. This page covers the Backoffice pages for all three. It states no amounts. See [pricing](https://noxtica.com/pricing/) and your agreement for commercial terms.
## What it is
Availability: Availability depends on your plan, role and the modules enabled for your organisation.
| Page | Route | Who can open it |
| --- | --- | --- |
| Wallet | `/billing/wallet` | Admin role, or billing role when enabled for your organisation |
| Invoices | `/billing/invoices` | Same |
| Monthly Reports | `/billing/reports` | Same |
| Status Reports | `/integrations/status-reports` | Admin role |
All are under Backoffice → Billing & Plan, except Status Reports, which is under Integrations & API. Adding funds needs the capability to manage billing and a step-up MFA check from the last 6 hours. Reading needs only the capability to view billing.
When the wallet is not enabled for your workspace, the Wallet page says **Wallet not enabled**. Your account team can turn it on.
Self-serve credit packs for AI Assistant credits are available when self-serve purchase is enabled for your organisation. Otherwise your account team provisions them.
## Prerequisites
- The admin role or the billing role. See [Roles and permissions](https://noxtica.com/docs/security/roles-and-permissions/).
- MFA enrolled on your account.
- The wallet enabled for your workspace, and a payment set up for it. If it is not, Backoffice says **This workspace isn't set up for payments yet. Contact your administrator to enable billing.**
- For the low-balance warning e-mail: the warning sweep enabled for your organisation. The preference is saved either way.
## Steps
### 1. Read your balances
Go to Backoffice → Billing & Plan → **Wallet**. Each currency has a card with:
| Field | Meaning |
| --- | --- |
| Balance | What the wallet holds. |
| Available | The balance minus holds. It turns red when negative. |
| Negative-balance allowance | How far below zero charges may go. A platform administrator sets it. |
| Platform floor | The lowest balance the platform allows for that currency. |
A **Low balance** badge shows when the balance is under your warning threshold. A new wallet shows **No balances yet** until a credit lands.
### 2. Add funds
In the **Add funds** card:
1. Choose a **Currency**. The rail follows the currency. A card currency opens a secure checkout page. A crypto currency gives you a deposit address. The baseline set is USD, USDT and USDC. EUR, GBP, TRY and EUROC appear when multi-currency is enabled for your organisation.
2. For crypto, choose a **Network**: default, TRC20 or ERC20.
3. Enter the **Amount**.
4. Click **Add funds** and complete the step-up prompt.
For a card, Backoffice redirects you to the hosted checkout. For crypto, the address, the amount and an expiry countdown appear inline. Send the deposit before it expires. If it expires, start a new top-up.
Funds are credited after the payment is confirmed. They are not credited when you return from checkout, and a crypto deposit is credited after on-chain confirmation. A top-up still waiting to settle shows under **Pending top-ups** as Card or Crypto, with its start date. Your balance updates after confirmation.
### 3. Set a low-balance warning
In the **Low-balance warning** card, enter an **Amount** and click **Save**. Leave it blank to use the default, which is a percentage of your last invoice with a minimum. The card shows **Currently warns below **. The card applies to the USD wallet. It is shown only to roles that manage billing. Saving needs no step-up check.
You get one e-mail when the balance crosses below the threshold. You do not get another while it stays below. Recovery sends no e-mail. See [Billing status, grace period and reminders](https://noxtica.com/docs/billing/status-grace-reminders/).
### 4. Check AI credits
The **AI credits** card shows **Monthly allotment**, **Used this period**, **Extra credits** and **Remaining**. A custom plan can read **Unlimited (custom plan)**. The monthly allotment resets each month in UTC. Purchased extra credits stay until used and are consumed after the monthly allotment.
When self-serve purchase is enabled for your organisation, **Buy AI credits** lists the available packs. One credit is 1,000 assistant tokens.
1. Click **Buy credit pack** on a pack and complete the step-up prompt.
2. Pay on the hosted checkout page.
3. Credits appear after payment is confirmed, on your next visit.
The buy button needs the admin role. If purchase is not enabled you see **Buying AI credits isn't available yet for this environment.** Ask your account team.
### 5. Read and export the ledger
**Recent activity** lists every wallet entry. Filter by currency, entry type (Top-up, Charge, Refund, Conversion, Adjustment), direction (Credit, Debit) and a From and To date. Choose 25, 50 or 100 rows to a page. The default is 50. Columns include date, type, direction, amount, currency, provider, payment reference and memo. Click **Download CSV** to export the filtered view.
### 6. Open an invoice
Go to Backoffice → Billing & Plan → **Invoices**. The list shows Period, Status, Total, Issued and Due. Click **Open**.
| Status | Meaning |
| --- | --- |
| Draft | Not yet issued. |
| Issued | Issued and open. |
| Paid | Settled. |
| Unpaid | Not settled. It counts toward the **Unpaid invoices** banner and reminder e-mails. |
| Void | Cancelled. |
An invoice for a month is created after the month ends. It combines plan, package, module, pay-as-you-go, AI-credit and speech lines in one statement. AI-credit and speech lines show consumption and carry no amount. Click **Download** on the detail page. It opens a print-ready page in a new tab. Use your browser's print function to save a PDF.
Only a platform administrator, with a second administrator approving, can void or reissue an invoice.
Wallet settlement of an invoice depends on your organisation. When it is enabled, a successful debit marks the invoice **Paid** and a failure for insufficient funds marks it **Unpaid**.
### 7. Review reports
Go to Backoffice → Billing & Plan → **Monthly Reports**. The page lists past reports, up to the 50 most recent. Each row shows Period, Cadence (Monthly, Weekly or Daily), Sent, and Status:
| Status | Meaning |
| --- | --- |
| Sent | At least one recipient was sent the report. |
| Suppressed | No recipient was sent it and at least one was suppressed. |
| Failed | No recipient was sent it. |
Click **Open** to see the exact report that was sent. It is a stored copy, not a new calculation. **Snapshot unavailable** means no copy was stored for that send. A Daily Report panel lets a workspace admin opt in to a short AI-written summary that uses AI credits. It does not turn on e-mail delivery.
### 8. Choose who gets status reports
Go to Backoffice → Integrations & API → **Status Reports**.
1. Leave **Send periodic status reports to workspace admins** on, or switch it off. It is on by default. An opt-out always wins.
2. Optionally enter a **Nominated external contact**. It is an extra recipient outside your admin list.
3. Optionally enter a **Display timezone**, an IANA name such as `Europe/Paris`. It changes only how dates are shown. Blank means UTC.
4. Save and complete the step-up prompt.
5. Click **Preview** to render your next report with live data. Nothing is sent.
Recipients of reports and billing notices are every active workspace admin plus the nominated contact. The billing role is not a recipient by role. Nominate a finance address as the contact if finance staff need the e-mails.
A note reads **Report delivery is not active yet** while delivery is not enabled for your organisation. Your choice is recorded now.
## Verify it works
- After a card top-up is confirmed, the wallet **Balance** rises and the ledger shows a **Top-up** credit. The pending top-up leaves the **Pending top-ups** card.
- A saved threshold shows **Currently warns below **.
- Invoices lists a row for each closed month with a status.
- **Open** on a report row shows the stored report.
- Status Reports shows **Enabled (default)** or **Turned off for this workspace**.
## Troubleshooting
| Symptom | Cause | Fix |
| --- | --- | --- |
| **Wallet not enabled** | The wallet is not enabled for the workspace. | Ask your account team. |
| **The wallet isn't available yet for this workspace.** | The wallet or payment rail is not enabled. | Ask your account team. |
| **Top-up is temporarily unavailable. Please try again later.** | The checkout service is not available. | Retry later. |
| **This workspace isn't set up for payments yet.** | No payment account is linked to the workspace. | Contact your account team. |
| **You're starting top-ups too frequently.** | Rate limit. | Wait a moment and retry. |
| **That currency isn't available on this workspace yet.** | A multi-currency option is not enabled. | Choose a baseline currency. |
| A top-up is not credited | Payment is not confirmed yet. | Check **Pending top-ups**. For crypto, wait for on-chain confirmation. |
| This deposit address has expired | A crypto address has a time limit. | Start a new top-up. |
| The Low-balance warning card is missing | Your role does not manage billing. | Use an admin account. |
| **No invoices yet** | No month has been closed for the workspace. | Check after the initial month ends. |
| **No reports yet** or **Reports have not run yet** | No periodic report was composed yet. | Check after the next scheduled send. |
| **Snapshot unavailable** | No copy was stored for that send. | None. Older sends can lack a copy. |
| Nobody receives reports | Status reports are switched off, or delivery is not enabled. | Check the Status Reports page and ask your account team. |
## Related
- [Billing status, grace period and reminders](https://noxtica.com/docs/billing/status-grace-reminders/): banners, grace window and reminder schedule.
- [Plans, packages and add-ons](https://noxtica.com/docs/billing/plans-and-packages/): what charges your wallet.
- [Usage, quotas and metering](https://noxtica.com/docs/billing/usage-and-quotas/): usage against quota.
- [Roles and permissions](https://noxtica.com/docs/security/roles-and-permissions/): the billing role.
- [Terms of Service](https://noxtica.com/terms/): fees, billing and payment.
---
Source: https://noxtica.com/docs/billing/status-grace-reminders/
Markdown: https://noxtica.com/docs/billing/status-grace-reminders/index.md
Last updated: 2026-10-27
# Billing status, grace period and reminders
Backoffice tells you about billing problems in three ways: a banner at the top of every page, a grace-period notice when a package is required, and reminder e-mails. This page explains each one, what it does and does not affect, and what to do. It states no amounts. See [pricing](https://noxtica.com/pricing/) and your agreement for commercial terms.
## What it is
Availability: Availability depends on your plan, role and the modules enabled for your organisation.
| Signal | Where | Blocks anything? |
| --- | --- | --- |
| Billing status banner | Top of every Backoffice page | No |
| Package grace notice | Banner, and the **Billing status** tab of Packages & Add-ons | No, until the window ends |
| Package grace gate | Replaces most Backoffice pages after the window ends | Backoffice pages only |
| Reminder e-mails | Your admins' inboxes | No |
Billing signals reach roles that can view billing: the admin role and, when enabled for your organisation, the billing role. Other roles see no banner.
### Billing status banner
Backoffice shows at most one banner. It picks the most severe:
| Order | Banner | Button | Can you hide it? |
| --- | --- | --- | --- |
| 1 | **Wallet balance is negative** | **Add funds** | No |
| 2 | **Unpaid invoices** with the count | **View invoices** | No |
| 3 | **Wallet balance is running low** | **Top up** | Yes, for 1 day |
A banner only informs. It never blocks a page. The negative-balance and low-balance banners show only when the wallet is enabled for your workspace.
### Package grace window
When package billing is enforced for your workspace, the workspace needs one active package. A grace window gives you time to choose one. Package billing is enforced when self-serve purchase is enabled for your organisation. Otherwise the Billing status tab says **Package billing is not enforced for this workspace yet: nothing is charged and no page is paused.**
The window is a date. Workspaces created through the platform console start with a 30-day window. A platform administrator can extend it. Yours can differ, and the Billing status tab shows the date.
The notice changes as the date nears:
| Days left | Notice | Can you hide it? |
| --- | --- | --- |
| More than 14 | Information | Yes, for 7 days |
| 4 to 14 | Warning | Yes, for 1 day |
| 3 or fewer | Warning | No |
| Ended, no active package | Critical, and the gate applies | No |
A workspace with an active package is never gated. A Noxtica platform administrator is never gated. If no deadline is recorded for your workspace, the notice says **No grace deadline is set for this workspace.** and nothing pauses.
### What the gate pauses
When the window has ended and no package is active, Backoffice replaces the page you opened with **Choose a package to continue**, or **This workspace needs an active package** when you cannot choose one.
- It pauses Backoffice pages. The text says every console page except Billing & Plan and Settings.
- In the code, the pages that stay open are Packages & Add-ons (`/billing/packages`) and Settings (`/settings`). Other Billing & Plan pages such as Wallet and Invoices are paused too. Treat the page text as the intent and the list in this paragraph as what the console does.
- Data collection is not affected. The gate lives in the Backoffice console. Collection and the Server API do not read it, so tokens, events, scoring and your API keys keep working.
- Nothing is deleted.
### Reminder e-mails
Three reminders run in a daily scheduled job. Each one is enabled separately for your organisation, so you may receive some and not others.
| Reminder | Sent when | Repeats |
| --- | --- | --- |
| Low balance | The USD wallet balance moves from above (or unknown) to below your threshold | Not while it stays below. Recovery sends nothing. |
| Unpaid invoice | An invoice is unpaid 3, 7 and 14 days after its due date | One e-mail at each of the three stages for that invoice. A new invoice restarts the count. |
| Subscription payment | An active module subscription is not yet charged for the current month, on day 3, 7 and 14 of the UTC calendar month | One e-mail at each stage. The text says reminder 1, 2 or 3 of 3. |
A separate one-time e-mail is sent when an invoice is issued. No reminder cancels a subscription.
Reminders go to every active workspace admin and to the nominated report contact, in English, up to 26 recipients. Each e-mail links to your wallet or invoice. A recipient who is suppressed is skipped. Each reminder is written to the audit log with the user **System**.
## Prerequisites
- The admin role, or the billing role when enabled for your organisation. See [Roles and permissions](https://noxtica.com/docs/security/roles-and-permissions/).
- To clear a negative balance: MFA enrolled, so you can pass the step-up check when you add funds.
- To end a gate: wallet funds for a priced package, and the capability to manage billing. If no package can be chosen, you need a platform administrator.
## Steps
### 1. Clear a banner
- **Wallet balance is negative** or **running low**: click the button, go to Wallet and add funds. See [Wallet, invoices and reports](https://noxtica.com/docs/billing/wallet-invoices-reports/).
- **Unpaid invoices**: click **View invoices**, open each invoice with status Unpaid and add funds. A wallet charge for an open invoice depends on your organisation. If you are unsure, ask your account team.
- Hide a low-balance banner for a day with its hide button if you have already planned the top-up.
### 2. Read the grace state
Go to Backoffice → Billing & Plan → **Packages & Add-ons** → **Billing status**. The **Package access** card gives one of these statements:
- **A package is active, so console access is not restricted.**
- **The grace period ends on ** with the days left.
- **The grace period ended on .** Pages are paused.
- **No grace deadline is set for this workspace.**
- **Package billing is not enforced for this workspace yet.**
**Active packages** lists each active package with its **Next charge** date.
### 3. Choose a package before the window ends
1. Open the **Packages** tab.
2. Click **Subscribe** on a package you can subscribe to. Complete the step-up prompt.
3. Check that **Billing status** now says a package is active.
Reasons a package may be unavailable are in [Plans, packages and add-ons](https://noxtica.com/docs/billing/plans-and-packages/).
### 4. When no package can be chosen
If every package is on hold or has no price, Backoffice says **No package can be subscribed to yet**. Only a platform administrator can extend your grace period or assign a package. Contact them and quote your workspace ID. Copy it with the button next to it on the page. A platform administrator extends or sets the window with a recorded reason and cannot set it more than 366 days ahead. You cannot do this yourself.
### 5. Keep reminders reaching the right people
Nominate a finance address on Backoffice → Integrations & API → **Status Reports**. Billing reminders use the same recipient list as status reports.
## Verify it works
- After you add funds and the payment is confirmed, the negative or low-balance banner disappears on your next page load.
- After you subscribe, the Billing status tab says a package is active and the grace banner no longer shows.
- The audit log shows the reminder rows, for example `money.low_balance_warned`, with the user **System**. See [Audit log and data export](https://noxtica.com/docs/security/audit-log-and-exports/).
## Troubleshooting
| Symptom | Cause | Fix |
| --- | --- | --- |
| No billing banner at all | Your role cannot view billing, or the wallet is not enabled and no invoice is unpaid. | Use an admin account. |
| The banner stays after you added funds | The payment is not confirmed yet. | Check **Pending top-ups** on the Wallet page. Reload after it settles. |
| **Choose a package to continue** covers a page | The grace window ended with no active package. | Subscribe to a package. Packages & Add-ons and Settings stay open. |
| **This workspace needs an active package** | You cannot subscribe, or no package can be subscribed to. | Ask a workspace admin or billing admin. If none can, contact a platform administrator with your workspace ID. |
| **Your wallet balance is too low** | The package fee is more than the balance. | Top up your wallet, then subscribe again. |
| Wallet or Invoices pages are paused by the gate | The gate pauses Billing & Plan pages other than Packages & Add-ons. | Subscribe from Packages & Add-ons. If funds are needed first, contact a platform administrator. |
| Collection still works while Backoffice is paused | By design. The gate affects only the Backoffice console. | None. |
| No reminder e-mail arrived | The reminder is not enabled for your organisation, the recipient is suppressed, or the address is not an active admin or the nominated contact. | Check Status Reports for the contact. Ask your account team. |
| An unpaid-invoice reminder arrived late | Reminders are sent by a daily job at the 3, 7 and 14 day marks. | None. |
| The grace banner does not show | A package is active, package billing is not enforced, or no deadline is recorded. | Check the Billing status tab. |
## Related
- [Wallet, invoices and reports](https://noxtica.com/docs/billing/wallet-invoices-reports/): add funds, invoices and the report e-mails.
- [Plans, packages and add-ons](https://noxtica.com/docs/billing/plans-and-packages/): choose a package and read unavailability reasons.
- [Usage, quotas and metering](https://noxtica.com/docs/billing/usage-and-quotas/): quota status.
- [Audit log and data export](https://noxtica.com/docs/security/audit-log-and-exports/): reminder and billing events.
- [Terms of Service](https://noxtica.com/terms/): fees, billing and payment.
---
Source: https://noxtica.com/docs/compliance/overview/
Markdown: https://noxtica.com/docs/compliance/overview/index.md
Last updated: 2026-10-27
# Privacy and compliance controls in Backoffice
Backoffice keeps its privacy and legal controls in two sidebar groups: **Privacy & Legal** and **Web Analytics & Privacy**. Use this page as a map. It names each page, says who can open it, what it records and which docs page explains it. A security or privacy owner or a Backoffice administrator uses it to plan a review.
These pages record decisions and settings. They do not give legal advice, and a recorded setting does not make your use of Noxtica lawful. Your counsel decides that. The public legal pages are the sole source for legal terms: [Terms](https://noxtica.com/terms/), [Privacy Policy](https://noxtica.com/privacy/), [DPA](https://noxtica.com/dpa/), [Subprocessors](https://noxtica.com/subprocessors/), [Cookies](https://noxtica.com/cookies/), [Acceptable Use](https://noxtica.com/acceptable-use/), [Disclaimer](https://noxtica.com/disclaimer/) and [Legal notice](https://noxtica.com/legal-notice/).
## What it is
Availability: depends on your plan, role and the modules enabled for your organisation.
The sidebar shows both groups to administrators. A signed-in user with a lower role does not see the entries, and several pages also check a permission on the server. Changes to retention, raw IP storage, legal bases and per-domain consent ask for a fresh multi-factor check (step-up) before they save.
### Privacy & Legal
| Page | What it records or shows | Who can use it | Explained in |
| --- | --- | --- | --- |
| Data Retention | Days that browser intelligence data is kept, the check interval, a read-only retention schedule, a manual "Run retention now" action and the Raw IP storage opt-in. | Administrators. Saving needs step-up. | [Retention, raw IP and locations](https://noxtica.com/docs/compliance/retention-and-locations/) |
| Data Locations | Read-only table of where five kinds of your data are stored. | Administrators see the sidebar entry. The data is read-only. | [Retention, raw IP and locations](https://noxtica.com/docs/compliance/retention-and-locations/) |
| Compliance | Placeholder rows for compliance documents with disabled Download buttons, and an EU AI Act Article 50 transparency policy for verified AI agents when enabled for your organisation. | Administrators. | [DPA, sub-processors and assurance](https://noxtica.com/docs/compliance/assurance-and-subprocessors/) |
| Legal Basis Register | Versioned records of the legal basis your organisation asserts as controller for each gated feature, plus the per-domain Replay legal basis. | Administrators. Recording needs step-up. | [Legal basis register](https://noxtica.com/docs/compliance/legal-basis/) |
| Data Subject Scope | Read-only explanation of the decisions that belong to your visitors. Its links lead to controls that switch collection off or withdraw an assertion, never to a control that switches something on. | Administrators. | [Requests and deletion](https://noxtica.com/docs/compliance/requests-and-deletion/) |
| Sub-processors | Whether your organisation accepted the AI assistant as a sub-processor for write actions. | Administrators. | [DPA, sub-processors and assurance](https://noxtica.com/docs/compliance/assurance-and-subprocessors/) |
| Platform Assurances | Read-only statements of what Noxtica remains responsible for. Nothing to switch. | Administrators see it in the sidebar. | [DPA, sub-processors and assurance](https://noxtica.com/docs/compliance/assurance-and-subprocessors/) |
### Web Analytics & Privacy
| Page | What it records or shows | Who can use it | Explained in |
| --- | --- | --- | --- |
| Consent & Privacy | Per domain: the legal basis for real-user monitoring, whether visitors must consent, and the Do Not Track (DNT) and Global Privacy Control (GPC) policy. | Administrators. Saving needs step-up. | [Legal basis register](https://noxtica.com/docs/compliance/legal-basis/) and [Cookies and storage](https://noxtica.com/docs/compliance/cookies-and-storage/) |
| RUM Collection | Workspace switch for real-user monitoring and a sample rate per domain. | Administrators. | [Real user monitoring](https://noxtica.com/docs/observability/rum/) |
| Tracking Allowlists | Per domain: which custom events and properties are accepted and which origins may be traced. | Administrators. | [Custom events and tracing](https://noxtica.com/docs/observability/events-and-tracing/) |
| Capture Policies | Per domain: replay sampling, masking and retention, and console-log capture. | Administrators. | [Session replay](https://noxtica.com/docs/observability/session-replay/) and [Errors and console logs](https://noxtica.com/docs/observability/errors-and-source-maps/) |
| RUM Data Lifecycle | What real-user monitoring data you hold, the error-detail retention per domain, and a permanent purge per data lane. | Administrators. | [Retention, raw IP and locations](https://noxtica.com/docs/compliance/retention-and-locations/) |
| Uptime Checks | Scheduled HTTPS checks of endpoints you prove you own. | Administrators. | [Uptime checks and status](https://noxtica.com/docs/observability/uptime-alerts-status/) |
### Related pages outside these two groups
| Page | Where | What it is for | Explained in |
| --- | --- | --- | --- |
| Data Operations | Backoffice → Administration → Data Operations | Soft-delete end-user data, run retention now, remove admin accounts, read the operations history. | [Requests and deletion](https://noxtica.com/docs/compliance/requests-and-deletion/) |
| KYC Verifications and KYC Erasure Requests | Backoffice → Identity Verification → KYC Verifications and KYC Erasure | The two Backoffice routes that delete identity verification data: administrators delete verifications directly, and erasure requests are approved by a second administrator. | [Requests and deletion](https://noxtica.com/docs/compliance/requests-and-deletion/) and [Verification data](https://noxtica.com/docs/identity-verification-data/) |
| Legal basis for hosted verification | Backoffice → Identity Verification → KYC Invitations → Settings | Records the legal basis that hosted verification needs. | [Invitations and hosted settings](https://noxtica.com/docs/identity-verification-invitations/) |
| CSP & storage tab | Backoffice → Integrations & API → Script & Consent → CSP & storage | The cookie and storage table to copy into your cookie policy. | [Cookies and storage](https://noxtica.com/docs/compliance/cookies-and-storage/) |
| Privacy & cookies | Backoffice → Settings | Your own choice, as a signed-in user, whether Noxtica's consent-gated extensions run on the Backoffice console. | [Cookies and storage](https://noxtica.com/docs/compliance/cookies-and-storage/) |
Identity verification data follows a separate rule. Noxtica does not remove verification details or evidence by itself and sets no retention date for them. They stay until a tenant administrator deletes them. The Data Retention page applies to browser intelligence data and never touches verification records.
### Four separate legal-basis records
Backoffice keeps four kinds of recorded basis. A record of one kind never covers another.
| Record | Scope | Where you record it | What it gates |
| --- | --- | --- | --- |
| Register entry | Your workspace, one entry per gated feature | Privacy & Legal → Legal Basis Register | The gated feature named by the entry |
| Replay legal basis | One domain | Privacy & Legal → Legal Basis Register, section Replay legal basis | Turning on session replay for that domain |
| Consent & privacy decision | One domain | Web Analytics & Privacy → Consent & Privacy | Real-user monitoring, error-detail and console-log capture on that domain |
| Hosted verification legal basis | Your workspace | Identity Verification → KYC Invitations → Settings | Minting and submitting hosted verification sessions |
## Prerequisites
- A Backoffice account with the administrator role for your workspace. See [Roles and permissions](https://noxtica.com/docs/security/roles-and-permissions/).
- A multi-factor method enrolled on your account, because saving most of these pages asks for a fresh check. See [Sign-in and access](https://noxtica.com/docs/security/sign-in-and-access/).
- At least one domain added to the workspace for the per-domain pages. See [Domains](https://noxtica.com/docs/backoffice/domains/).
- Identity verification pages appear when the module is enabled for your organisation.
## Steps
### 1. Open the groups
Sign in at `https://backoffice.noxtica.com`. In the sidebar open **Privacy & Legal** and then **Web Analytics & Privacy**. If an entry is missing, your role is below administrator.
### 2. Set retention and raw IP storage
Open **Privacy & Legal → Data Retention**. Review the retention schedule and the Raw IP storage setting. Details are in [Retention, raw IP and locations](https://noxtica.com/docs/compliance/retention-and-locations/).
### 3. Record legal bases for the features you use
Open **Privacy & Legal → Legal Basis Register**. Record a basis for each gated feature you turn on, and record the Replay legal basis before you enable replay on a domain. Details are in [Legal basis register](https://noxtica.com/docs/compliance/legal-basis/).
### 4. Resolve per-domain consent decisions
Open **Web Analytics & Privacy → Consent & Privacy**. Decide the legal basis, the consent requirement and the DNT and GPC policy for each domain that collects real-user monitoring data.
### 5. Set capture policies
Open **Web Analytics & Privacy → Capture Policies**. Choose replay sampling, masking and retention and the console-log setting for each domain.
### 6. Publish your cookie disclosure
Open **Integrations & API → Script & Consent → CSP & storage**. Copy the storage table into your cookie policy. See [Cookies and storage](https://noxtica.com/docs/compliance/cookies-and-storage/).
### 7. Know your deletion and assurance routes
Read [Requests and deletion](https://noxtica.com/docs/compliance/requests-and-deletion/) and [DPA, sub-processors and assurance](https://noxtica.com/docs/compliance/assurance-and-subprocessors/) before a request or a procurement review arrives.
## Verify it works
- **Consent & Privacy** shows an "All resolved" badge and the line "No domain has an unresolved consent or privacy decision."
- **Legal Basis Register** shows the status "Asserted" and a receipt line for each basis you recorded.
- **Data Retention** lists the retention schedule with a Source badge for each row: "Your override", "Plan default" or "Default".
- **Raw IP storage** shows the badge "Disabled" or "Enabled" and the time of the last change.
- Every save above appears in the audit log. See [Audit log and data export](https://noxtica.com/docs/security/audit-log-and-exports/).
## Troubleshooting
| Symptom | Cause | Fix |
| --- | --- | --- |
| The Privacy & Legal group is missing from the sidebar. | The sidebar hides these entries from roles below administrator. | Ask an administrator of your workspace, or ask for the administrator role. |
| Legal Basis Register shows an error instead of the gates. | The register needs the permission to record legal bases, which is administrator level. | Sign in as an administrator. |
| A save asks you to verify again. | Retention, raw IP, legal basis and consent decisions need a fresh multi-factor check. | Complete the prompt. Cancelling changes nothing. |
| The Compliance page has Download buttons you cannot press. | The rows are placeholders. The tooltip says compliance documents will be provided through the customer success portal. | Ask your account team. Do not treat the rows as evidence that a report exists. |
| The EU AI Act card is missing from Compliance. | The card shows when the policy is enabled for your organisation. | Ask your account team whether it applies to you. |
| No identity verification retention note appears on Data Retention. | The note appears when the identity verification module is enabled for your organisation. | Enable the module through your account team. |
## Related
- [Legal basis register and receipts](https://noxtica.com/docs/compliance/legal-basis/): record, change and withdraw a legal basis.
- [Data retention, raw IP storage and data locations](https://noxtica.com/docs/compliance/retention-and-locations/): retention controls and where data lives.
- [Data subject scope, erasure requests and account deletion](https://noxtica.com/docs/compliance/requests-and-deletion/): deletion routes.
- [Cookies, storage and consent categories](https://noxtica.com/docs/compliance/cookies-and-storage/): what the SDK writes in a visitor's browser.
- [DPA, sub-processors, DPIA pointers and assurance](https://noxtica.com/docs/compliance/assurance-and-subprocessors/): public documents and assurance pointers.
- [Security and trust evidence](https://noxtica.com/docs/security/): what Noxtica publishes about its security posture.
---
Source: https://noxtica.com/docs/compliance/legal-basis/
Markdown: https://noxtica.com/docs/compliance/legal-basis/index.md
Last updated: 2026-10-27
# Legal basis register and receipts
Some Noxtica features stay off until your organisation records the legal basis it relies on. Backoffice keeps those records as receipts. A tenant administrator records, changes or withdraws a receipt. This page explains the register, the Replay legal basis, the per-domain consent decision and the errors you see when a receipt is missing.
A receipt is your organisation's statement as controller. It is not a record that any visitor consented, and it never replaces visitor consent. Noxtica does not tell you which basis to choose. Ask your counsel.
## What it is
Availability: depends on your plan, role and the modules enabled for your organisation.
The **Legal Basis Register** (Backoffice → Privacy & Legal → Legal Basis Register) lists each gated feature, called a gate. For each gate you see whether a basis is recorded ("Asserted" or "Not asserted"), the Article 6(1) basis, the Article 9(2) condition where one applies, the disclosure text you accepted, the receipt version and who recorded it.
Records are immutable and versioned:
- **Change basis** records a new version and keeps the previous one. A reason is required.
- **Withdraw** keeps the record with status "Withdrawn". A reason is required. Processing that relies on the basis stops.
- Nothing is deleted. Every action is logged with who did it, their role, the workspace and the time.
A Noxtica platform administrator can also record a basis for your workspace where that capability is enabled. The receipt then carries the actor role "superadmin", and your administrators can see it. It never substitutes for visitor consent.
Each receipt pins the exact disclosure text you read, by version, language and a digest. The register shows that text unchanged. If no disclosure is published in your current language, the register refuses to record a basis and does not fall back to another language.
### Gates in the register
Register entries use these labels. "Required" means Backoffice asks for an Article 9(2) condition. "Optional" means the dialog offers a condition for use when special-category data is in scope. Whenever you assert a condition you also type the gate key to confirm it.
| Register entry | Article 9(2) condition | Note |
| --- | --- | --- |
| Investigations module | Optional | Also covers Related Devices. |
| Assistant write actions | Optional | The sub-processor acceptance for the AI assistant. |
| Granular sub-fingerprint axes | Not accepted | Article 6(1) is limited to legitimate interests. |
| Behavioral tracks (pointer/touch) | Required | |
| JA4H HTTP fingerprinting | Required | |
| Behavioral baseline | Required | |
| Fingerprinting: CSS system colours & fonts | Required | Fixed 365-day term. |
| Fingerprinting: font enumeration | Optional | Fixed 365-day term. |
| Fingerprinting: window-key litter | Optional | Fixed 365-day term. |
| Fingerprinting: emoji geometry | Optional | Fixed 365-day term. |
| APM and host telemetry ingest | Optional | APM is In development. New Ingestion API keys are bound to the receipt. |
| KYC raw evidence storage | Optional | Identity verification. |
| KYC behavioral capture | Optional | Identity verification. |
| KYC delegation | Optional | Identity verification. |
| KYC voice profiling | Required | Identity verification. Takes effect when the platform switch is also on. |
| KYC age and gender estimation | Required | Identity verification. Takes effect when the platform switch is also on. |
The register shows the expiry date of a receipt that has a fixed 365-day term. Which entries appear depends on what is enabled for your organisation.
### Features that refuse to start without a receipt
| Feature | What you see without a receipt |
| --- | --- |
| Session replay on a domain | Enabling replay is refused with `replay_receipt_required`. |
| Looser replay masking on a domain | The change is refused with the same error, even on a disabled policy. |
| Hosted identity verification | Minting or submitting a hosted session is refused with `kyc_legal_basis_receipt_required` (HTTP 403). |
| Investigations and Related Devices | The module reads as off and the Related Devices page says it needs a recorded lawful basis. |
| Granular sub-fingerprint axes | The values are not persisted until an active legitimate-interests receipt exists. |
| APM ingestion keys (In development) | Creating a key is refused with `apm_legal_basis_required` until a receipt exists. |
| Console-log and error-detail capture | Capture stays off until the domain records a legal basis or requires visitor consent. |
Other register entries record your basis. This page does not claim that every entry blocks a feature.
### Per-domain Replay legal basis
Replay has its own receipt on the same page, in the section **Replay legal basis**. It is recorded per domain with a legal basis reference, which is your DPA or DPIA reference. A tenant administrator alone can record it. A Noxtica platform administrator cannot record it for you. Recording does not turn replay on. You turn replay on in **Web Analytics & Privacy → Capture Policies**.
### Per-domain consent decision
**Web Analytics & Privacy → Consent & Privacy** records, for each domain, the legal basis for real-user monitoring, whether visitors must consent and the DNT and GPC policy. The Legal basis list offers "— none —" and `rum_observability`. A domain appears in the list when it collects real-user monitoring data, has no legal basis recorded and either does not require consent or overrides DNT and GPC.
## Prerequisites
- The administrator role. Reading the register needs the same permission as recording a basis.
- A multi-factor method enrolled on your account. Recording, changing, withdrawing and saving a consent decision ask for a fresh check.
- The decision itself. Settle with your counsel which Article 6(1) basis and, where relevant, which Article 9(2) condition apply to the feature.
- For hosted identity verification, the basis is recorded on a different page. See [Invitations and hosted settings](https://noxtica.com/docs/identity-verification-invitations/).
- Replay legal basis is the exception to platform-administrator recording: your own tenant administrator must record it.
## Steps
### 1. Record a basis for a gate
1. Open Backoffice → Privacy & Legal → Legal Basis Register.
2. Pick the gate and select **Read the disclosure**. Read it.
3. Select **Record basis**.
4. Choose the **Article 6(1) lawful basis**. Choose an **Article 9(2) condition** when the gate shows "Art. 9 special category" or the dialog marks it required.
5. If you chose an Article 9(2) condition, type the gate key to confirm the special-category assertion.
6. Tick the acknowledgement: "I have read the disclosure above and I am recording this lawful basis on behalf of my organisation as controller."
7. Submit and complete the step-up check.
### 2. Change or withdraw a basis
1. On the gate, select **Change basis** or **Withdraw**.
2. Enter the reason. The limit is 500 characters.
3. For a change, choose the new basis and acknowledge the current disclosure. When a newer disclosure was published, processing that depends on the newer text stays off until you do.
4. Select **History** to see every version with its status, bases, actor, role, times and reasons.
### 3. Record the Replay legal basis
1. In the same page, scroll to **Replay legal basis**.
2. Select the domain.
3. Enter the real DPA or DPIA reference in **Legal basis reference (DPA / DPIA)**.
4. Read the disclosure, tick the acknowledgement and select **Record legal basis**.
5. To change it later choose **Replace the active basis**. To stop replay capture on that domain choose **Revoke the active basis**.
6. Turn replay on in Web Analytics & Privacy → Capture Policies.
A reference that is empty or contains the text "not supplied" counts as a placeholder. While the reference is a placeholder, Backoffice refuses to arm replay or loosen masking when the result uses masking looser than strict or turns off required consent.
### 4. Decide a domain's consent and DNT/GPC policy
1. Open Web Analytics & Privacy → Consent & Privacy. Domains that still need a decision are listed.
2. Choose the **Legal basis** or leave it as "— none —".
3. Turn **Requires consent** on or off. Without a legal basis, you must require consent.
4. Choose the **DNT/GPC policy**: **Honor** or **Documented override**. A documented override needs the legal basis and the acknowledgement "I acknowledge this domain overrides DNT/GPC on an approved legal basis."
5. Select **Save decision** and complete the step-up check. The domain leaves the list.
## Verify it works
- The gate shows "Asserted" with a receipt line such as "Article 6(1): … · receipt v1 · recorded by …".
- **History** lists the new version, and a withdrawn version shows "Withdrawn" with your reason.
- The audit log shows `tenant_legal_basis_asserted`, `tenant_legal_basis_superseded` or `tenant_legal_basis_revoked`. A consent decision shows `domain_rum_privacy_updated`.
- With a receipt in place, enabling replay on the domain is no longer refused for a missing receipt. Without one, Backoffice answers that no active session_replay legal-basis receipt exists for the domain and that nothing was changed.
- **Consent & Privacy** shows "No domain has an unresolved consent or privacy decision."
## Troubleshooting
| Symptom | Cause | Fix |
| --- | --- | --- |
| Enabling replay fails with `replay_receipt_required`. | No active Replay legal basis exists for the domain. | Record it in Legal Basis Register → Replay legal basis, then enable replay again. |
| Replay save fails with `legal_basis_placeholder` (HTTP 409). | The active reference is empty or says "not supplied". | Replace the active basis with the real DPA or DPIA reference. |
| Replay save fails with `replay_receipt_validation_unavailable` (HTTP 503). | The receipt check could not be completed. Nothing changed. | Retry later. |
| Record basis is blocked with a message about the disclosure. | No disclosure is published in your language, or its digest does not match. | Switch the Backoffice language to one with a published disclosure. If the digest message persists, report it. |
| Recording is refused with `asserting_role_required` (HTTP 403). | Your role is neither tenant administrator nor platform administrator. | Ask a tenant administrator of your workspace to record it. |
| Recording fails with `already_active` (HTTP 409). | A basis is already active for the gate. | Use **Change basis**. |
| Recording fails with `disclosure_mismatch` (HTTP 409). | The page you loaded is stale or the text changed. | Reload and record again. Nothing was recorded. |
| The consent decision is rejected: "Choose a legal basis, or turn on Requires consent." | Capturing without consent needs an approved basis. | Choose `rum_observability` or turn on Requires consent. |
| The consent decision is rejected for a documented override. | An override needs a legal basis and the acknowledgement. | Choose the basis, tick the acknowledgement, or set the policy back to Honor. |
| Hosted verification returns `kyc_legal_basis_receipt_required`. | No active hosted-capture basis exists for your organisation. | Record it under KYC Invitations → Settings. |
## Related
- [Privacy and compliance controls in Backoffice](https://noxtica.com/docs/compliance/overview/): map of every privacy page.
- [Cookies, storage and consent categories](https://noxtica.com/docs/compliance/cookies-and-storage/): DNT and GPC behaviour and consent categories.
- [Session replay](https://noxtica.com/docs/observability/session-replay/): arm replay after you record the basis.
- [Invitations and hosted settings](https://noxtica.com/docs/identity-verification-invitations/): the hosted verification legal basis.
- [Audit log and data export](https://noxtica.com/docs/security/audit-log-and-exports/): find who recorded what.
- [Privacy Policy](https://noxtica.com/privacy/) and [DPA](https://noxtica.com/dpa/): the public legal documents.
---
Source: https://noxtica.com/docs/compliance/retention-and-locations/
Markdown: https://noxtica.com/docs/compliance/retention-and-locations/index.md
Last updated: 2026-10-27
# Data retention, raw IP storage and data locations
An administrator uses three Backoffice pages to control and read how Noxtica stores data for the workspace: **Data Retention**, which includes the Raw IP storage opt-in, **Data Locations** and **RUM Data Lifecycle**. This page explains each control, what it changes and what to check afterwards.
The controls here apply to browser intelligence data and real-user monitoring data. Identity verification data follows a separate rule at the end of this page.
## What it is
Availability: depends on your plan, role and the modules enabled for your organisation.
### Data Retention
Open Backoffice → Privacy & Legal → Data Retention. The page has four parts.
| Part | What it does |
| --- | --- |
| Data policy | Two settings: **Data retention (days)**, "how long to keep browser intelligence data", and **Check interval (days)**, "minimum days between full re-collection per device". |
| Retention schedule | A read-only table of the effective window for each data category, with a Source badge. |
| Run retention now | An on-demand sweep that applies the saved window to your workspace. |
| Raw IP storage | An opt-in to store the full client IP address alongside the hashed one. |
The Backoffice accepts 1 to 365 days for **Data retention (days)** and 1 to 30 days for **Check interval (days)**. Every package starts at 7 days for **Data retention (days)**. The values in force and the plan defaults are shown in Backoffice and can change.
The retention schedule lists two categories:
| Category | Window comes from |
| --- | --- |
| Detection events | Your saved retention days ("Your override"), else the plan ("Plan default"), else "Default". |
| Audit log | The plan ("Plan default"). You cannot override it. |
The check interval controls how often a device is fully re-collected. It does not set how often data is removed. The purge job runs daily and you cannot configure it. Backoffice states that automated export before purge is not wired in this view. To archive data before it is removed, use the export tools. See [Audit log and data export](https://noxtica.com/docs/security/audit-log-and-exports/). Plan retention by data class is described on [Pricing](https://noxtica.com/pricing/).
For detection events, removal by retention is a soft delete. Records older than the window are hidden from views and exports. Permanent removal is a separate step that a Noxtica platform administrator performs. This page gives no timeline for it.
Some removal steps, such as audit-log removal and deletion of stored replay objects, can be paused platform-wide while Noxtica reviews its erasure safeguards. Backoffice does not show that state, and the schedule shows the window that applies, not whether a step is running now. If a window matters to your policy, ask your account team.
### Raw IP storage
By default Noxtica keeps a hashed IP and stores no raw IP. When you opt in, it also stores the raw client IP address so the operator console can search and correlate by exact IP during fraud investigations. The raw IP is purged on the same retention schedule as the rest of the submission data.
The raw IP is personal data. Backoffice warns you to enable it where your data processing agreement authorizes raw IP retention for fraud investigation and where your lawful basis and storage limitation are documented. Ask your counsel.
Turning the setting off permanently deletes every raw IP already stored for your workspace. The result message reports how many stored fingerprint records were cleared. This cannot be undone.
### Data Locations
Open Backoffice → Privacy & Legal → Data Locations. The table is read-only and shows five kinds of data. Each row has these columns.
| Column | What it shows |
| --- | --- |
| Service | Event data, Event payloads, Metrics, Warehouse analytics or KYC evidence. A "platform default" note means no location was chosen for your workspace. |
| Provider & region | The store and the location name, for example a Cloudflare or GCP store. |
| Jurisdiction | EU, US or TR jurisdiction, or "jurisdiction not assigned". |
| Retention | "retained N days" for the row. |
| Usage | A counted or estimated size with an "as of" time, "not applicable — this class has no usage meter", or a message that the figure cannot be read yet, with a reason. |
You cannot change a location from Backoffice. A Noxtica platform administrator sets placement. If you have a location requirement, ask your account team. The page shows what is configured. It is not a residency commitment, and your contract and the [DPA](https://noxtica.com/dpa/) are the source for commitments.
The Retention figure on the KYC evidence row is not a deletion date. Noxtica does not remove verification details or evidence by itself.
### RUM Data Lifecycle
Open Backoffice → Web Analytics & Privacy → RUM Data Lifecycle. It lists each real-user monitoring lane that can be purged on demand, what is stored and its current window. You can set the error-detail retention for a domain from 1 to 90 days and start a permanent purge of a lane. A purge needs a typed confirmation phrase and a fresh step-up check, and it cannot be undone. Replay retention is set per domain in Capture Policies, from 1 to 90 days.
The default window is 7 days on every package for error details, console logs, replay recordings and APM data. Error details, console log lines and APM data are held in the analytics warehouse, which removes them after 7 days: you can shorten their window but not extend it. Base RUM counters are platform-managed, kept for up to three months and not configurable.
### Identity verification data
Verification details and evidence are not part of these schedules. The Data Retention page covers browser intelligence data and never touches verification records. When the identity verification module is enabled, the page shows a note that these records are retained until a tenant administrator deletes them, with a link to KYC Erasure Requests. An administrator deletes verifications in KYC Verifications and works erasure requests in KYC Erasure. See [Requests and deletion](https://noxtica.com/docs/compliance/requests-and-deletion/).
## Prerequisites
- The administrator role. Saving retention needs the settings permission.
- A multi-factor method on your account. Saving retention, saving the raw IP setting, running retention now and purging RUM data ask for a fresh check.
- For raw IP storage, a documented decision from your privacy owner. The setting is off by default.
- For Data Locations, nothing beyond access to the page.
## Steps
### 1. Set the retention window
1. Open Backoffice → Privacy & Legal → Data Retention.
2. Enter **Data retention (days)** from 1 to 365 and **Check interval (days)** from 1 to 30.
3. Select **Save settings** and complete the step-up check.
4. If you shortened the window, confirm "Shorten data retention?". Data older than the new window becomes eligible for soft deletion at the next retention run.
### 2. Run retention now (optional)
1. Under **Run retention now**, select **Run retention now**.
2. Confirm. The run applies the saved window and cannot delete anything the schedule would keep.
3. Read the result. It lists soft-deleted fingerprints, events, visits, tracker batches and tracker metrics, and a section "What this run could NOT reach".
A workspace can start 4 runs in one hour. A run already in progress blocks a new one.
### 3. Decide raw IP storage
1. In the same page, find **Raw IP storage (opt-in)**.
2. Read the warning and the badge, which shows "Disabled" or "Enabled".
3. Move the toggle and select **Save**. Complete the step-up check.
4. When turning it off, read "Turning this off will permanently delete every raw IP already stored for this tenant." before you save.
### 4. Read your data locations
1. Open Backoffice → Privacy & Legal → Data Locations.
2. Read each row. Note any row marked "platform default".
3. Send questions about placement to your account team.
### 5. Set error-detail retention for a domain
1. Open Backoffice → Web Analytics & Privacy → RUM Data Lifecycle.
2. Select the domain.
3. Enter **Retention (days, 1–90)** and save.
## Verify it works
- The retention schedule shows your days for Detection events with the "Your override" badge.
- The audit log shows `settings_updated` with the new values.
- After a run, the history on Data Operations shows a "Retention run" with a status. See [Requests and deletion](https://noxtica.com/docs/compliance/requests-and-deletion/).
- Raw IP storage shows the new badge. The audit log shows `raw_ip_storage_enabled` or `raw_ip_storage_disabled`. When you turn it off, the audit entry records the number of scrubbed records and never the IP values.
- Data Locations lists five rows with a provider and region on each.
## Troubleshooting
| Symptom | Cause | Fix |
| --- | --- | --- |
| Save shows "Enter a value between 1 and 365." | The retention value is outside the accepted range. | Enter a whole number from 1 to 365. The check interval accepts 1 to 30. |
| Save asks you to verify again. | Saving retention needs a fresh multi-factor check. | Complete the prompt. |
| The retention schedule is missing. | The schedule is fail-soft. A failed read hides the panel without affecting the form. | Reload the page. |
| Run retention now answers "A retention run is already in progress for this workspace." | A run started in the last 30 minutes is still running. | Wait for it to finish. |
| Run retention now answers "Too many manual retention runs. Try again later." | The limit of 4 runs per hour was reached. | Try again after the hour passes. |
| The result says the run was a PARTIAL run or lists data it could not reach. | The run stopped early or could not reach some stores. | Treat the run as incomplete. Run it again later and read the unreachable list. |
| The audit log retention cannot be edited. | The audit log window comes from your plan. | Ask your account team. |
| A Data Locations row says its usage cannot be read yet. | The usage meter is not ready or the read failed. | Reload later. The location and jurisdiction columns still apply. |
| A raw IP opt-out reports zero cleared records. | No raw IP was stored for the workspace. | No action needed. |
## Related
- [Privacy and compliance controls in Backoffice](https://noxtica.com/docs/compliance/overview/): map of every privacy page.
- [Data subject scope, erasure requests and account deletion](https://noxtica.com/docs/compliance/requests-and-deletion/): delete end-user data on demand.
- [Session replay](https://noxtica.com/docs/observability/session-replay/): replay sampling, masking and retention.
- [Audit log and data export](https://noxtica.com/docs/security/audit-log-and-exports/): export data before it is removed.
- [Privacy Policy](https://noxtica.com/privacy/), [DPA](https://noxtica.com/dpa/) and [Subprocessors](https://noxtica.com/subprocessors/): the public legal documents.
---
Source: https://noxtica.com/docs/compliance/requests-and-deletion/
Markdown: https://noxtica.com/docs/compliance/requests-and-deletion/index.md
Last updated: 2026-10-27
# Data subject scope, erasure requests and account deletion
When one of your visitors or users asks for their data to be deleted, a tenant administrator works through the tools on this page. Backoffice has separate routes for browser intelligence data, identity verification data, administrator accounts and your Noxtica account. This page names each route, who runs it and what it leaves untouched.
Backoffice does not decide whether a request is valid and does not give legal advice. You verify the requester and decide the response with your counsel.
## What it is
Availability: depends on your plan, role and the modules enabled for your organisation.
| Route | What it removes | Who runs it |
| --- | --- | --- |
| Data Operations → End-user data | Soft-deletes fingerprints, events and visits for devices or an external user ID. | Tenant administrator, with step-up. |
| KYC Verifications → Delete | Identity verifications you select, with their evidence files. | Tenant administrator, with a reason, a typed confirmation phrase and step-up. |
| KYC Erasure Requests | Identity verification data for a verification subject. | A request is opened for the subject. A different tenant administrator approves it in Backoffice, with step-up. |
| Data Operations → Admin accounts | Soft-deletes a Backoffice administrator account. | Tenant administrator, with step-up. |
| Server API for behavioral baselines | Erases a subject's behavioral baseline, when the module is enabled for your organisation. | Your server, with an API key that has the erase scope. |
| Delete your Noxtica account form | Starts a reviewed account deletion request from the account email. | The account owner. |
Backoffice has no screen that assembles a per-person access report. To answer an access request, use the export tools described in [Audit log and data export](https://noxtica.com/docs/security/audit-log-and-exports/).
### Data Subject Scope
Open Backoffice → Privacy & Legal → Data Subject Scope. The page is read-only. It explains a boundary: your organisation can record its own lawful basis as controller, but it can never supply a visitor's consent. Consent belongs to the visitor.
Three cards explain what that means.
| Card | What it says | Link on the card |
| --- | --- | --- |
| Session replay | Your organisation can stop recording per domain at any time. It cannot declare that a visitor consented to being recorded. | Turn recording off in Replay policy |
| Per-domain consent and DNT/GPC | Each domain records whether consent is required and whether DNT and GPC signals are honored. Overriding a signal needs a recorded lawful basis and is never the visitor's consent. | Review per-domain decisions |
| Behavioural and biometric signals | Collection can be turned off in each signal's own section, and a recorded assertion can be withdrawn in one click. | Withdraw an assertion in the Legal basis register |
Everything reachable from the page turns collection off or withdraws an assertion. Turning something on is not offered. Recording "consent is not required" for a domain is a controller statement that another lawful basis applies. It is never a record that consent was obtained.
### End-user soft delete in Data Operations
Data Operations soft-deletes browser intelligence data. The records are hidden from views and exports. Permanent removal is a separate step that a Noxtica platform administrator performs, and this page gives no timeline for it. The operation reports fingerprints, events and visits. Every operation is audited and listed in the History tab.
Erasure can be paused platform-wide while Noxtica reviews its safeguards. While it is paused, the end-user delete is refused with HTTP 503, a one-hour `Retry-After` and the message "Customer data erasure is temporarily on hold while its safeguards are reviewed." Backoffice does not show whether the pause is on. Ask your account team.
### Identity verification data
Identity verification data is separate. Noxtica does not remove verification details or evidence by itself and sets no retention date for them. They stay until a tenant administrator deletes them. Backoffice has two routes that delete them: **Delete verification** and **Delete selected** in KYC Verifications, and KYC Erasure Requests.
Delete verification removes the verifications an administrator selects (up to 25 at a time) together with their evidence files. The administrator gives a reason of 3 to 500 characters, types a confirmation phrase such as `delete 2 verifications permanently` and completes step-up. Billing usage records, legal-basis receipts and the audit trail are kept, two audit entries record the delete, and a legal hold or an open erasure request blocks it. No server API key can delete a verification. Business (KYB) and merchant (KYM) items are erased from their own pages with a reason. The full steps are in [Verification data](https://noxtica.com/docs/identity-verification-data/).
A right-to-erasure request is opened for a verification subject, and Backoffice lists it with the name of the requester. A different administrator approves it. Approving your own request is refused. A request can be placed on legal hold, which stops it from proceeding to deletion until the hold is released. When a request completes, Noxtica sends the `kyc.erasure.completed` event to your webhooks. It is not sent for a partial result and carries no subject identifier, and deleting verifications directly does not send it. Execution depends on what is enabled for your organisation. How a request is opened, its reach and its limits are in [Verification data](https://noxtica.com/docs/identity-verification-data/).
### Admin accounts and your Noxtica account
Removing an administrator in Data Operations soft-deletes the account. The user loses access at once and disappears from lists. You cannot remove your own account, and the last active administrator cannot be removed. Backoffice has no screen that deletes a workspace. To close a workspace, contact your account team. Your contract and the [DPA](https://noxtica.com/dpa/) govern what happens to customer data after termination.
The public form at [Delete your Noxtica account](https://noxtica.com/account-deletion/) starts a reviewed deletion request for a Noxtica account. You enter the account email, receive a one-time verification code, enter it and submit. The page lists what may be retained. Read it before you submit.
## Prerequisites
- The administrator role and a multi-factor method. Data Operations asks for a fresh check before it runs an operation.
- For an end-user delete, a list of device IDs, up to 500 per operation, or an external user ID. A date range or a domain narrows the match.
- For Delete verification, the administrator role, a fresh step-up check and the identity verification module enabled for your organisation.
- For KYC Erasure Requests, the identity verification module enabled for your organisation and an administrator other than the requester to approve.
- For the behavioral baseline API, a server API key with the erase scope and the module enabled. See [API reference](https://noxtica.com/docs/api/reference/).
- For the account deletion form, access to the email address of the account.
## Steps
### 1. Review the data subject boundary
Open Privacy & Legal → Data Subject Scope. Read the three cards. Use the links to switch off collection that depends on a visitor's decision.
### 2. Soft-delete end-user data
1. Open Backoffice → Administration → Data Operations and select **End-user data**.
2. Enter **Device IDs (one per line)** or an **External user ID (optional)**. You can add a **Domain (optional)**, **From date** and **To date**.
3. Add a **Reason (optional)**, up to 280 characters. It is stored in the audit log. Use a reference such as your request number.
4. Select **Preview impact**. Read the estimated fingerprints, events and visits. The preview is a dry run.
5. Select **Proceed with soft delete**.
6. Type `DELETE` and select **Confirm soft delete**. Complete the step-up check.
7. Read the banner "Soft-deleted: … fingerprints, … events, … visits".
### 3. Delete identity verification data
To delete verifications you choose:
1. Open Backoffice → Identity Verification → KYC Verifications.
2. Open a case and select **Delete verification**, or tick the rows and select **Delete selected** (up to 25).
3. Enter a reason of 3 to 500 characters, type the confirmation phrase the dialog shows, select **Delete permanently** and complete the step-up check.
To work an erasure request:
1. Open Backoffice → Identity Verification → KYC Erasure.
2. Find the request in the list. The Requested by column names who opened it. Requests appear after a subject or an operator submits one for your workspace.
3. As an administrator other than the requester, select **Approve** and confirm. Complete the step-up check.
4. If a legal hold applies, select **Hold**. Select **Release hold** when it ends.
5. Watch the status column until the request completes. Select **View items** to see per-artifact progress.
6. Subscribe a webhook to the KYC erasure completed event to receive the completion signal. See [Identity verification events](https://noxtica.com/docs/identity-verification-webhooks/).
### 4. Remove an administrator account
1. Open Data Operations and select **Admin accounts**.
2. Select the user, add a reason and confirm with `DELETE` and the step-up check.
### 5. Request deletion of a Noxtica account
1. Open [Delete your Noxtica account](https://noxtica.com/account-deletion/).
2. Enter the account email and select **Send verification code**.
3. Enter the code from the email and select **Submit deletion request**.
## Verify it works
- The preview shows "Dry run · no data deleted yet" before you confirm anything.
- After confirmation the History tab shows an "End-user delete" row with a status of Completed. A "PARTIAL run" banner means the row limit was reached and you must run it again with tighter filters.
- The audit log records approvals and refusals of an erasure request. An end-user delete shows `data_ops_end_user_delete` with the reason. A verification delete shows `kyc_verification_delete_requested` and `kyc_verification_deleted` with the reason.
- A deleted verification no longer appears in KYC Verifications.
- A KYC erasure request moves from requested to authority verified after a different administrator approves it. It ends as completed or partial.
- The account deletion page answers "Your account deletion request has been accepted for review."
## Troubleshooting
| Symptom | Cause | Fix |
| --- | --- | --- |
| The end-user delete fails with HTTP 503 and "Customer data erasure is temporarily on hold while its safeguards are reviewed." | Erasure is paused platform-wide. | Ask your account team. Retry after the pause is lifted. |
| The delete is refused because no subject identifier was given. | A delete needs a device ID list or an external user ID. A date range or a domain alone is not enough, although the preview accepts them. | Add device IDs or an external user ID. |
| "Too many device IDs" appears. | The list exceeds 500 entries. | Split the list into several operations. |
| The external user ID matches too many devices. | The match exceeded the limit of 10,000 devices. | Narrow the date range. |
| A PARTIAL run is reported. | The operation hit the row limit for some tables. | Re-run with tighter filters, as the banner says. |
| Approve is refused with "You cannot approve your own erasure request — a different admin must approve it." | Dual control requires an approver other than the requester. | Ask another administrator to approve. |
| The KYC Erasure page says the KYC module is not enabled. | The identity verification module is not enabled for your organisation. | Ask your account team. |
| Delete verification is refused with "Blocked by a legal hold or an open erasure request." | A legal hold is in place in your tenant, or an erasure request for the same subject is still open. | Release the hold or let the request finish, then delete again. |
| "Cannot remove the last active admin." | A workspace must keep one active administrator. | Add another administrator, then remove the account. |
| The account deletion form says too many attempts. | The form limits repeated attempts. | Wait a while and try again. |
## Related
- [Privacy and compliance controls in Backoffice](https://noxtica.com/docs/compliance/overview/): map of every privacy page.
- [Data retention, raw IP storage and data locations](https://noxtica.com/docs/compliance/retention-and-locations/): scheduled removal of browser intelligence data.
- [Verification data](https://noxtica.com/docs/identity-verification-data/): identity verification data storage, access and deletion.
- [Identity verification events](https://noxtica.com/docs/identity-verification-webhooks/): the erasure completed event.
- [Audit log and data export](https://noxtica.com/docs/security/audit-log-and-exports/): export data and find who ran an operation.
- [Privacy Policy](https://noxtica.com/privacy/) and [DPA](https://noxtica.com/dpa/): the public legal documents.
---
Source: https://noxtica.com/docs/compliance/assurance-and-subprocessors/
Markdown: https://noxtica.com/docs/compliance/assurance-and-subprocessors/index.md
Last updated: 2026-10-27
# DPA, sub-processors, DPIA pointers and assurance
A procurement, security or privacy reviewer uses this page to find what Noxtica provides for a vendor review. It points to the public documents, explains the sub-processor and assurance pages inside Backoffice, and says where to ask for support material that is not public.
This page does not summarise the legal documents and does not describe the terms they contain. Read the documents themselves. It also does not restate what independent assurance exists. The [Security and trust evidence](https://noxtica.com/docs/security/) page states that.
## What it is
Availability: depends on your plan, role and the modules enabled for your organisation.
### Public documents
| Document | Where |
| --- | --- |
| Data Processing Agreement | [DPA](https://noxtica.com/dpa/) |
| Sub-processor list | [Subprocessors](https://noxtica.com/subprocessors/) |
| Privacy Policy | [Privacy Policy](https://noxtica.com/privacy/) |
| Terms | [Terms](https://noxtica.com/terms/) |
| Cookies | [Cookies](https://noxtica.com/cookies/) |
| Acceptable Use | [Acceptable Use](https://noxtica.com/acceptable-use/) |
| Disclaimer | [Disclaimer](https://noxtica.com/disclaimer/) |
| Legal notice | [Legal notice](https://noxtica.com/legal-notice/) |
Backoffice also serves a copy of each document inside the console: Terms, Privacy, Cookies, Acceptable Use, Legal notice, Subprocessors, Disclaimer and DPA. When Noxtica publishes a new edition of a document that users accept, Backoffice can ask each user to accept it again. The re-acceptance prompt covers Terms, Privacy, Acceptable Use, Disclaimer and DPA.
### Sub-processors in Backoffice
Open Backoffice → Privacy & Legal → Sub-processors. The page covers one relationship: the Noxtica AI assistant acting as a sub-processor when it makes changes inside your workspace. The page states that this follows your organisation accepting the relationship and recording a lawful basis for it. The acceptance is a signed receipt, not a toggle.
The page shows the status "Accepted" or "Not accepted". When accepted, it shows a line such as "Article 6(1): … · receipt v… · recorded by …". You record, change or revoke the acceptance in the Legal Basis Register under the entry "Assistant write actions". Revoking takes effect at once and does not ask for a basis again. The page also links to the full sub-processor list. For the public list, use [Subprocessors](https://noxtica.com/subprocessors/).
### Platform Assurances
Open Backoffice → Privacy & Legal → Platform Assurances. The page is read-only and has nothing to switch, accept or request. It names five categories that the platform keeps responsibility for:
| Category | Title on the page |
| --- | --- |
| Shared security | Security enforcement shared by every tenant |
| Infrastructure | Platform-wide infrastructure |
| Visitors | Protections owed to your visitors |
| Cross-tenant detection | Cross-tenant detection and intelligence |
| Licences | Third-party licences and contracts |
The page links to the Privacy Policy, the sub-processor list and the Terms of service for the contractual side.
### Compliance page
Open Backoffice → Privacy & Legal → Compliance. The page shows placeholder rows for compliance documents. Their Download buttons are disabled, and the tooltip says compliance documents will be available through the customer success portal. The rows are not evidence that a report exists. When the EU AI Act policy is enabled for your organisation, the page also shows the Article 50 transparency disclosure policy for verified AI agents. It is observe-only: you choose "Shadow (observe only)" or "Dry-run (preview template)", and no disclosure is injected into responses.
### DPIA support
This documentation set links no DPIA. Ask your account team for DPIA support material. When you turn on session replay, Backoffice asks you to enter the real DPA or DPIA reference for your own assessment. See [Legal basis register and receipts](https://noxtica.com/docs/compliance/legal-basis/).
### Security posture, vulnerability reports and status
- The [Security and trust evidence](https://noxtica.com/docs/security/) page lists what Noxtica publishes about controls, cryptography boundaries and module data scope.
- Vulnerability reports go to the contact named in the file `/.well-known/security.txt` on `noxtica.com`. The file has an `Expires` field. Check that the date has not passed before you rely on the file.
- Service state is at `https://status.noxtica.com`. The status page is not a contractual SLA. See [Uptime checks and status](https://noxtica.com/docs/observability/uptime-alerts-status/).
- Request procurement material for the exact service and deployment you review through [Contact](https://noxtica.com/contact/?topic=security).
### Which route answers which question
| You need | Go to |
| --- | --- |
| The processing agreement and the sub-processor list | [DPA](https://noxtica.com/dpa/) and [Subprocessors](https://noxtica.com/subprocessors/) |
| To record or revoke the AI assistant acceptance | Backoffice → Privacy & Legal → Sub-processors, then the Legal Basis Register |
| A statement of what Noxtica keeps responsibility for | Backoffice → Privacy & Legal → Platform Assurances |
| DPIA support material | Your account team |
| Security and procurement material for a named service | [Contact](https://noxtica.com/contact/?topic=security) |
| Public security evidence | [Security and trust evidence](https://noxtica.com/docs/security/) |
| To report a vulnerability | The contact in `/.well-known/security.txt` |
| Current service state | `https://status.noxtica.com` |
## Prerequisites
- For the sub-processor acceptance, the administrator role and a multi-factor method. Recording a basis asks for a fresh check.
- A decision from your counsel on whether and on which basis your organisation accepts the AI assistant for write actions. Write actions apply when the assistant is enabled for your organisation.
- For procurement material, the name of the service, the modules and the deployment you review.
## Steps
### 1. Collect the public documents
Open [DPA](https://noxtica.com/dpa/), [Subprocessors](https://noxtica.com/subprocessors/), [Privacy Policy](https://noxtica.com/privacy/) and [Terms](https://noxtica.com/terms/). Add the version you reviewed and the date to your vendor record.
### 2. Decide on the AI assistant
1. Open Backoffice → Privacy & Legal → Sub-processors.
2. Read the status, "Accepted" or "Not accepted".
3. To accept, select **Record the acceptance in the Legal basis register**. Read the disclosure, choose the Article 6(1) basis, tick the acknowledgement and submit. See [Legal basis register and receipts](https://noxtica.com/docs/compliance/legal-basis/).
### 3. Review what Noxtica keeps responsibility for
Open Backoffice → Privacy & Legal → Platform Assurances. Read the five categories. Record the page in your vendor review as a statement, not a control.
### 4. Ask for DPIA and procurement support
Send a request through [Contact](https://noxtica.com/contact/?topic=security) or to your account team. Name the service and modules you review and the questions you need answered.
### 5. Register the vulnerability contact
Open `/.well-known/security.txt` on `noxtica.com`. Copy the contact and check the `Expires` date. Add the status page to your monitoring tools.
## Verify it works
- Sub-processors shows "Accepted" with a receipt line, or "Not accepted" before you record one.
- The Legal Basis Register entry "Assistant write actions" shows "Asserted" and the same receipt version.
- The audit log shows `tenant_legal_basis_asserted` for the acceptance and `tenant_legal_basis_revoked` after a revocation.
- The public documents open at the addresses above.
- Platform Assurances lists the five categories and shows no control.
## Troubleshooting
| Symptom | Cause | Fix |
| --- | --- | --- |
| The Sub-processors page is missing from the sidebar. | The sidebar hides it from roles below administrator. | Ask an administrator. |
| The page shows an error instead of the status. | The status needs the permission to read legal-basis records, which is administrator level. | Sign in as an administrator. |
| Record the acceptance is blocked with a message about the disclosure. | No disclosure is published in your language, or its digest does not match. | Switch the Backoffice language to one with a published disclosure. |
| Revoking does not ask for a basis. | Revoking is the cheap direction by design. It asks for a reason and takes effect at once. | Enter the reason. |
| The Compliance page Download buttons do nothing. | The rows are disabled placeholders. | Ask your account team. |
| The Compliance page has no AI Act card. | The policy is not enabled for your organisation. | Ask your account team whether it applies to you. |
| The re-acceptance prompt appears after sign-in. | A new edition of an accepted document was published. | Read the documents, ask your counsel if needed, then accept. |
## Related
- [Security and trust evidence](https://noxtica.com/docs/security/): what Noxtica publishes about security and assurance.
- [Legal basis register and receipts](https://noxtica.com/docs/compliance/legal-basis/): record the sub-processor acceptance.
- [Privacy and compliance controls in Backoffice](https://noxtica.com/docs/compliance/overview/): map of every privacy page.
- [Uptime checks and status](https://noxtica.com/docs/observability/uptime-alerts-status/): the status page and incident feed.
- [DPA](https://noxtica.com/dpa/), [Subprocessors](https://noxtica.com/subprocessors/) and [Privacy Policy](https://noxtica.com/privacy/): the public legal documents.
---
Source: https://noxtica.com/docs/concepts/agentic-security/
Markdown: https://noxtica.com/docs/concepts/agentic-security/index.md
Last updated: 2026-09-11
# Agentic Security
**Definition.** At Noxtica, "agentic" covers three distinct workflows: an operator can investigate tenant information with the [AI Assistant](https://noxtica.com/docs/concepts/ai-assistant/), an external agent can read permitted tenant information through [MCP](https://noxtica.com/docs/concepts/mcp-integration/), and a tenant can govern supported incoming agent identities with [Know Your Agent](https://noxtica.com/docs/concepts/know-your-agent/).
The problem is not a lack of automation. It is unclear authority. Security teams need to know whether an automated system is assisting an operator, reading a data source, or arriving as traffic—and which person or policy remains accountable in each case.
One boundary applies to all three meanings: Noxtica does not give an assistant or MCP client autonomous write access to customer systems. Read surfaces provide context for a human or customer-owned workflow. Traffic actions occur only through policy your team configures or code your team controls.
## When it applies
Use this model when:
- operators need a faster way to summarize policies, domains, recent activity, or risk;
- an internal AI workflow needs structured, read-only access to the same tenant-scoped context;
- product or security teams need differentiated treatment for supported automated-agent identities; or
- reviewers need to show who requested information and which policy caused a traffic action.
These are separate capabilities with separate eligibility. Adopting one does not activate the others.
## The three meanings
### 1. We operate agentically
Where the AI Assistant is available, a signed-in operator asks questions inside the console. The assistant can retrieve the same supported read-only surfaces the operator is permitted to view, such as policies, rules, domains, recent fingerprints, risk distribution, and audit information.
The output is a conversational summary for investigation. An operator uses it to choose which record, trend, or policy to inspect next. It does not change configuration or act on traffic. See [AI Assistant](https://noxtica.com/docs/concepts/ai-assistant/).
### 2. You integrate agentically
For tenants with MCP enabled, an operator issues a scoped credential and configures an MCP-compatible client with the provisioned connection details. The client can request allowed policies, rules, alerts, and risk distribution over the read-only MCP surface.
The output is structured tenant context that your agent can summarize or pass into a customer-owned review workflow. MCP does not expose write tools, and data from one tenant is not a cross-tenant intelligence feed. See [MCP Integration](https://noxtica.com/docs/concepts/mcp-integration/).
### 3. We police the agentic web
Where KYA is provisioned, a tenant records which supported agent identities it recognizes and how known, unknown, or denied agents should be treated. Noxtica evaluates the identity evidence presented with traffic; your application or configured enforcement policy decides whether to allow, observe, challenge, or block.
The output is identity and policy context, not a grant of authority and not proof that an agent's requested operation is safe. Apply normal authorization and business rules after the traffic decision. See [Know Your Agent](https://noxtica.com/docs/concepts/know-your-agent/) and [Browser Security](https://noxtica.com/docs/concepts/browser-security/).
## How the pieces compose
| Meaning | Customer entry point | Output | Decision owner |
| ------------------------- | ------------------------------------------------------------------ | ------------------------------------------------ | -------------------------------------------- |
| We operate agentically | AI Assistant in an eligible operator console | Human-readable summary of permitted tenant state | Signed-in operator |
| You integrate agentically | Opt-in MCP connection with a scoped token | Structured, read-only tenant context | Your agent workflow and its human owner |
| We police the agentic web | KYA registry plus application or managed policy, where provisioned | Presented identity status and policy context | Your application or configured tenant policy |
The assistant and MCP can help investigate why traffic was assessed a certain way. KYA can add agent identity context. Device risk, confidence, flags, route sensitivity, and your policy still determine the response. This separation keeps explanation, authorization, and enforcement reviewable.
## Outputs and decisions
Common customer outcomes include:
- reducing time spent locating the policy or traffic segment relevant to an investigation;
- feeding approved Noxtica context into an internal reporting or triage workflow;
- distinguishing a supported, verified automated-agent claim from an unknown or denied claim; and
- retaining a review path from risk evidence to the customer-owned action.
None of these outputs proves human identity, business intent, or permission to perform an application operation. Treat them as inputs to your existing access-control, fraud, and incident-response processes.
## Eligibility and limits
- The assistant remains read-only. Availability, quotas, and supported read surfaces depend on the provisioned plan and operator permissions.
- MCP is read-only, off by default, and tenant-scoped. Enablement and connection details are provided for eligible tenants.
- KYA and managed risk-action controls are not implied for every tenant or every agent identity scheme. Confirm supported deployment and provisioning before launch.
- Agents that do not present supported verifiable identity remain unknown; your policy must define the fallback.
- Native mobile attestation is a separate capability and is not included by the browser or agent concepts.
## Where we're headed
Today, humans set policies and thresholds. Self-calibration and feedback-driven tuning are being explored for future releases, but they are not part of the current contract. Any future write capability would require a separately documented permission and approval model; the assistant and MCP described here remain read-only.
## Read deeper
- [AI Assistant](https://noxtica.com/docs/concepts/ai-assistant/) — console investigation, current read-only scope, and eligibility.
- [MCP Integration](https://noxtica.com/docs/concepts/mcp-integration/) — tenant-scoped external read access.
- [Know Your Agent](https://noxtica.com/docs/concepts/know-your-agent/) — defensive agent identity and policy.
- [Browser Security](https://noxtica.com/docs/concepts/browser-security/) — customer-owned decisions and managed controls.
- [Calibration](https://noxtica.com/docs/concepts/calibration/) — how to read score, confidence, and reasons together.
- [Features: AI-assisted operations](https://noxtica.com/docs/features/#ai-assisted-operations) — the assistant and MCP customer surfaces.
- [Features: agent identity and control](https://noxtica.com/docs/features/#agent-identity-and-control) — eligible incoming-agent governance.
- [Backend integration](https://noxtica.com/docs/backend-integration/) — using risk outputs in your own application policy.
---
Source: https://noxtica.com/docs/concepts/ai-assistant/
Markdown: https://noxtica.com/docs/concepts/ai-assistant/index.md
Last updated: 2026-10-27
# AI Assistant
**Definition.** The AI Assistant is a console-based **operator copilot**. It helps a signed-in operator find and summarize supported Noxtica information without turning the assistant into an autonomous administrator.
The problem it solves is investigation overhead. Policies, domains, recent assessments, risk distribution, and audit records can answer an operational question, but finding the relevant slice takes time. The assistant provides a conversational starting point; the underlying product records remain the source an operator reviews.
## When it applies
Use the assistant for questions such as:
- Which policies and rules are relevant to this domain?
- What does recent risk activity look like?
- Which recent fingerprints or audit records should I inspect?
- What context should I collect before a policy review?
Do not use an assistant response as the sole basis for blocking traffic, approving a transaction, attributing intent, or closing an investigation. Verify material conclusions against the linked console records and your normal operating procedure.
## How customers use it
1. Sign in to the operator console with an account that has the Admin role. Lower roles do not see the assistant button.
2. Open the assistant if it is enabled for your tenant.
3. Ask a bounded question about the tenant and time period you are investigating.
4. Review the returned summary and follow up in the relevant policy, domain, fingerprint, risk, or audit view.
5. Make any operational decision through the normal product control or your own application workflow.
The useful output is a concise summary and a narrower investigation path. It does not create a new source of truth, expand the operator's permissions, or perform a traffic action.
## How Noxtica does it
The public contract is defined by the controls around the assistant, not by a particular model:
- **Operator-session scope.** The assistant runs in the context of the signed-in operator.
- **Permission checks.** Supported tool calls are checked against the operator's current role-based access.
- **Tenant boundary.** Reads are limited to the active tenant and supported product surfaces.
- **Usage allowance.** Assistant availability and usage limits follow the tenant's provisioned plan.
- **Auditability.** Assistant tool activity is recorded so operators can review how tenant information was accessed.
Supported deployments can offer more than one model provider. The available provider set depends on the tenant's plan and configuration; a provider name is not a guarantee about response quality. Review assistant output before it informs a customer-impacting decision.
### Phase 1 — read-only tools
The current assistant tool boundary is **read-only**. Subject to operator permissions and tenant availability, it can retrieve and summarize:
- policies and rules;
- domains;
- recent fingerprints;
- risk distribution; and
- audit information.
It cannot change configuration, create or delete records, flip feature settings, or challenge, block, or otherwise act on traffic.
### Phase 2 — write behind a flag
This heading is retained to make the boundary explicit: write tools are not part of the current assistant contract. Prior roadmap references do not make mutation available or commit a delivery date. Plan integrations against read-only behavior unless a future product document expressly replaces this boundary for your tenant.
## Outputs and decisions
| Assistant output | Useful next decision |
| ------------------------ | ------------------------------------------------------------------------ |
| Policy or domain summary | Decide which configuration screen an operator should review |
| Recent-risk summary | Choose a time range, risk tier, or segment for deeper investigation |
| Fingerprint summary | Open the source assessment and evaluate its score, confidence, and flags |
| Audit summary | Identify the actor, time, or operation that needs normal audit review |
Assistant prose can omit context or require clarification. Treat it as navigation and synthesis, not evidence that a person is fraudulent or that a policy is correct.
## Eligibility and limitations
- The assistant is available only where included and provisioned for the tenant.
- The assistant needs the Admin role. Reads remain subject to the signed-in operator's role and the active tenant.
- Usage allowances and available read surfaces may differ by plan.
- The assistant does not browse customer systems, execute customer code, or mutate Noxtica through its current tools.
- Questions that require unsupported data, another tenant's data, or a write action remain outside scope.
## Where it fits
The assistant is the "we operate agentically" part of the [Agentic Security](https://noxtica.com/docs/concepts/agentic-security/) model. It is distinct from [MCP](https://noxtica.com/docs/concepts/mcp-integration/), which lets an eligible external agent read approved Noxtica context, and [Know Your Agent](https://noxtica.com/docs/concepts/know-your-agent/), which evaluates supported identities of agents reaching your site.
## Who it fits
The assistant fits operators who work in the console and have it enabled for their tenant. It helps them choose where to look next. The questions it suits are listed under [When it applies](https://noxtica.com/docs/concepts/ai-assistant/#when-it-applies). What each summary points to is in [Outputs and decisions](https://noxtica.com/docs/concepts/ai-assistant/#outputs-and-decisions).
## How teams connect
You write no code to use the assistant. It runs in the console. The steps are under [How customers use it](https://noxtica.com/docs/concepts/ai-assistant/#how-customers-use-it). Model routing and provider keys for the assistant are set in Backoffice; see [AI assistant, MCP tokens and coding-agent keys](https://noxtica.com/docs/backoffice/ai-assistant-and-mcp/). To let your own AI client read tenant data, see [MCP Integration](https://noxtica.com/docs/concepts/mcp-integration/).
## Limits
The assistant is a helper for operators, not an authority.
- **Controlled availability.** Access is agreed with Noxtica.
- Assistant text can be wrong. It is not a verdict.
- Risk scores and levels it summarizes are probabilistic and can be wrong. Your team decides what to do with them. See [Calibration](https://noxtica.com/docs/concepts/calibration/).
What the assistant cannot reach or change, and where it is available, is listed under [Eligibility and limitations](https://noxtica.com/docs/concepts/ai-assistant/#eligibility-and-limitations).
## Common questions
### Can the assistant change my policies?
No. Its tools are read-only. [How Noxtica does it](https://noxtica.com/docs/concepts/ai-assistant/#how-noxtica-does-it) lists what it can read and what it cannot do.
### Can it see more than I can?
No. The permission checks and the tenant boundary under [How Noxtica does it](https://noxtica.com/docs/concepts/ai-assistant/#how-noxtica-does-it) apply to every read.
### How is it different from MCP access?
Each has its own audience. The assistant serves a signed-in operator in the console. MCP serves an approved external client that holds a token. They are provisioned separately. See [Where it fits](https://noxtica.com/docs/concepts/ai-assistant/#where-it-fits).
## Read deeper
- [Agentic Security](https://noxtica.com/docs/concepts/agentic-security/) — the three agent workflows and their decision owners.
- [MCP Integration](https://noxtica.com/docs/concepts/mcp-integration/) — the read-only external-agent counterpart.
- [Features: AI-assisted operations](https://noxtica.com/docs/features/#ai-assisted-operations) — the source product views and read boundaries behind an investigation.
- [Calibration](https://noxtica.com/docs/concepts/calibration/) — how to interpret risk outputs before acting.
- [Contact](https://noxtica.com/contact/) — confirm tenant eligibility and provisioning.
---
Source: https://noxtica.com/docs/concepts/browser-intelligence/
Markdown: https://noxtica.com/docs/concepts/browser-intelligence/index.md
Last updated: 2026-09-11
# Browser Intelligence
**Definition.** Browser Intelligence is the **collection and assessment layer**. It turns characteristics available during a browser session, together with supported edge context, into a site-scoped result. It is the intelligence half of the browser workflow; [Browser Security](https://noxtica.com/docs/concepts/browser-security/) describes how a customer can act on that result.
The problem it solves is ambiguity at high-volume digital entry points. A user-agent string or IP address alone cannot explain whether a session is consistent, automated, unusual, or simply privacy-conscious. Browser Intelligence combines multiple categories of evidence and returns a result your team can review.
## When it applies
Use Browser Intelligence where a browser session affects fraud or abuse exposure, including signup, login, account recovery, promotion use, checkout, content access, and other customer-defined routes. Start in observe-only application logic where the cost of customer friction is high.
This concept covers browser traffic. Native mobile attestation has separate integration and eligibility requirements and is not implied by installing the browser collector.
## How customers use it
1. Request access and obtain the Site Key for the intended environment.
2. Add the collector using [Automatic Collection](https://noxtica.com/docs/getting-started/#automatic-collection-recommended), or call `checkOnce()` when your application needs explicit timing.
3. Listen for the collection result or read the returned object.
4. Store the `fingerprintId` with the relevant session or account only when your design requires continuity.
5. Use the [Server API](https://noxtica.com/docs/api/reference/device/) or operator console to review current device and risk context.
6. Apply route-specific policy in your code, or use separately provisioned controls where available.
The SDK also reports cache state and errors so the application can distinguish a fresh assessment, a reused result, and an unavailable assessment.
## How Noxtica does it
Collection runs in the browser runtime and considers several public categories of evidence:
- **Rendering context** — consistency in browser-exposed canvas, WebGL, audio, and related media behavior.
- **Environment context** — browser-exposed fonts, platform details, and available device characteristics.
- **Consistency context** — whether the browser's claimed properties agree with its observed behavior.
- **Network context** — supported attributes such as country, network type, and datacenter classification derived during service processing.
No single characteristic decides the outcome. The product returns a combined assessment. The protected runtime is intended to make manipulation and replay harder, but it is not a guarantee that client-side code cannot be inspected or attacked.
The browser assessment does not ask for a person's name or email as an input. A device identifier is still operational data that customers should handle under their own retention, access, consent, and legal-basis requirements.
## Outputs and decisions
| Output | What it tells you | Useful decision |
| --------------------------- | ------------------------------------------------------------ | --------------------------------------------------------------- |
| `fingerprintId` | A site-scoped handle for the assessed browser/device context | Link permitted observations across your own workflow |
| `score` and `risk_level` | The assessed level of risk | Choose allow, observe, review, or step-up policy for the route |
| `confidence` | How much weight to place on the assessment | Defer a strong action when evidence is limited |
| `flags` and summary details | Which categories contributed to the result | Explain or investigate why the score changed |
| cache and error state | Whether the result was reused or could not be refreshed | Use a documented fallback instead of treating absence as safety |
## Supported limitations
- Browser settings, privacy protections, blocked scripts, content-security policy, network failure, or unsupported capabilities can reduce available evidence.
- A fingerprint identifies an assessed browser/device context, not a legal person, account owner, or guaranteed physical device.
- Cached results trade reassessment frequency for lower client work; choose the collection interval for your risk window.
- Collection modes and available fields follow the current SDK and tenant configuration.
- Client-side output should not replace server-side authentication, authorization, or transaction controls.
## Where it fits
Browser Intelligence feeds [Know Your Device](https://noxtica.com/docs/concepts/know-your-device/), which explains identifier and risk outputs. It pairs with [Browser Security](https://noxtica.com/docs/concepts/browser-security/), which covers customer-owned actions. Together they let teams observe first, choose thresholds, and introduce friction only where policy requires it.
## Read deeper
- [Getting started](https://noxtica.com/docs/getting-started/#automatic-collection-recommended) — install the current browser scripts.
- [Browser runtime](https://noxtica.com/docs/browser-runtime/) — collection, cache behavior, events, and errors.
- [Backend integration](https://noxtica.com/docs/backend-integration/) — store the identifier and retrieve device risk.
- [Features: device and browser intelligence](https://noxtica.com/docs/features/#device-and-browser-intelligence) — the customer outcome supported by combined evidence.
- [Detection signals](https://noxtica.com/docs/detection-signals/) — the public evidence categories.
- [Know Your Device](https://noxtica.com/docs/concepts/know-your-device/) — how to use the returned identifier and risk fields.
- [Browser Security](https://noxtica.com/docs/concepts/browser-security/) — how policy can act on the assessment.
---
Source: https://noxtica.com/docs/concepts/browser-security/
Markdown: https://noxtica.com/docs/concepts/browser-security/index.md
Last updated: 2026-09-11
# Browser Security
**Definition.** Browser Security is the **decision and enforcement layer**. [Browser Intelligence](https://noxtica.com/docs/concepts/browser-intelligence/) supplies an assessment; your application or a separately provisioned policy surface decides what that assessment means for a particular route.
The problem it solves is inconsistent response. Without an explicit policy, teams either ignore useful risk evidence or apply one blunt threshold everywhere. Browser Security keeps the risk input separate from the business action so a public page, signup, account recovery, and payment flow can use different responses.
## When it applies
Use Browser Security after you can observe representative traffic and explain the fields your policy consumes. It is most useful on routes where automation, account abuse, or transaction risk has a defined response and owner.
For a first rollout:
1. collect the browser result;
2. record score, risk level, confidence, flags, route, and customer outcome;
3. review the distribution by surface;
4. define the least disruptive useful action for each band; and
5. enable enforcement only after owners agree on fallback and review procedures.
## How customers use it
A tenant can implement customer-owned policy in backend code using the documented risk output. Eligible tenants may also have managed risk-action controls in the product.
Common actions are:
- **Allow** — continue the normal path.
- **Observe** — retain the assessment for analysis without adding friction.
- **Challenge or step up** — ask the application to perform additional verification. Your application owns the actual second factor or challenge.
- **Block** — deny the requested operation and retain enough context for review.
- **Tarpit** — where provisioned, slow a class of abusive traffic under an explicit policy.
Choose an action from the combination of route sensitivity, risk level, confidence, flags, and your own account or transaction context. Do not block solely because one browser characteristic is unusual.
## How Noxtica does it
The product represents enforcement as policy-driven directives or customer-consumed API fields rather than an autonomous security decision. Two rollout controls are especially important:
- **Per-domain or per-surface policy** — apply a posture to the context it was designed for instead of assuming one global threshold.
- **Shadow mode** — where available, record what a policy would have done without applying the traffic action.
Shadow output supports threshold review, expected-impact analysis, and investigation playbooks. It does not prove that future traffic will have the same distribution, so teams should continue monitoring after activation.
### The risk-action engine
Where the risk-action engine is enabled, operators configure policies that can consider:
- **Device risk** from [Know Your Device](https://noxtica.com/docs/concepts/know-your-device/).
- **Supported agent identity or policy context** from [Know Your Agent](https://noxtica.com/docs/concepts/know-your-agent/), where provisioned.
- **URL or route patterns** that define the protected surface.
- **Network or IP reputation context** available to the tenant.
The engine's useful outputs are the matched policy, intended or applied action, and associated risk context visible through the supported product views. Those records help operators answer: _Which policy matched? What evidence was available? Was the action observed or enforced?_
## How outputs inform decisions
| Observed condition | Typical customer-owned response |
| ---------------------------------------------------------- | ------------------------------------------------------------- |
| Low risk with expected context | Allow and retain normal telemetry |
| Elevated risk with limited confidence | Observe or use a reversible step-up |
| High risk with corroborating flags on a sensitive route | Stronger verification or manual review |
| Repeated critical-risk automation under an approved policy | Block or another provisioned mitigation |
| Collection error or missing assessment | Use the application's documented fallback; do not assume safe |
These are decision patterns, not universal defaults. The right consequence depends on customer journey, loss exposure, contractual requirements, accessibility, and support capacity.
## Eligibility and limitations
- Managed enforcement, shadow mode, tarpit, and KYA inputs can require tenant-specific provisioning. Confirm them before making them a launch dependency.
- A challenge directive does not supply your application's MFA, identity verification, or authorization logic.
- Browser controls do not replace server-side validation or protect non-browser protocols unless separately integrated.
- A risk output is not proof of identity, intent, fraud, or policy compliance.
- Always define behavior for timeouts, missing results, stale cached results, and unavailable optional signals.
## Where it fits
Browser Security is the Security pillar. It consumes the outputs described by [Calibration](https://noxtica.com/docs/concepts/calibration/) and can combine device risk with separately eligible agent context. In the agentic-security model, the policy remains customer-owned even when the product carries out a configured action.
## Read deeper
- [Browser Intelligence](https://noxtica.com/docs/concepts/browser-intelligence/) — the assessment layer this policy consumes.
- [Agentic Security](https://noxtica.com/docs/concepts/agentic-security/) — the boundaries between assistant, MCP, KYA, and enforcement.
- [Backend integration](https://noxtica.com/docs/backend-integration/#customer-policy) — implement customer-owned server policy.
- [Integration flow: decision](https://noxtica.com/docs/integration-flow/#4-customer-policy) — follow the assessment into application logic.
- [Features: bot, abuse, and network defense](https://noxtica.com/docs/features/#bot-abuse-and-network-defense) — the customer-facing defense and policy surfaces.
- [Engineering principles](https://noxtica.com/docs/principles/#03-false-positives-are-not-acceptable-losses) — why rollout starts with observation.
---
Source: https://noxtica.com/docs/concepts/calibration/
Markdown: https://noxtica.com/docs/concepts/calibration/index.md
Last updated: 2026-09-11
# Calibration
**Definition.** Calibration is the practice of treating a Noxtica result as a **risk read, not a binary verdict**. The result includes a score, a risk level, a confidence value, and flags or reasons. Your team decides what combination justifies observation, review, step-up, or denial on each surface.
The problem it solves is false certainty. A single "bot" label hides uncertainty and makes it hard to explain customer friction. A multi-field result lets a reviewer see both the assessed risk and how much evidence supported it.
Calibration here describes how the current product exposes and applies risk information. It is not a guarantee that a particular score has the same business meaning for every tenant, route, geography, or time period.
## When it applies
Use calibration whenever the cost of being wrong differs by workflow:
- signups where automated account creation is costly but conversion matters;
- login or recovery where a false positive can lock out a customer;
- checkout where device evidence is one input alongside transaction context;
- public content where observation may be preferable to friction; and
- policy reviews where operators need to explain why a threshold exists.
## How Noxtica does it
- **Score and tier.** The numeric score and named risk level provide an ordered risk signal that application code and operators can consume.
- **Confidence.** Confidence indicates how much weight to place on the assessment; it is a separate dimension from severity.
- **Flags or reasons.** Named contributing conditions provide an investigation trail rather than an unexplained label.
- **Operator-owned thresholds.** Your code and enabled policy controls determine what happens at each threshold.
This is a public output contract, not a disclosure of internal weighting or detection mechanics. For the current response shape, see [Backend integration: Keep result states separate](https://noxtica.com/docs/backend-integration/#keep-result-states-separate) and the [Device API reference](https://noxtica.com/docs/api/reference/device/).
## Using the outputs
| Read | Question it answers | Decision use |
| ---------------- | ------------------------------------------------- | ------------------------------------------------------------------- |
| Score | Where does this assessment sit on the risk scale? | Sort, segment, or apply a customer-defined threshold |
| Risk level | Which named operating band contains the score? | Map the assessment to a route-specific policy |
| Confidence | How much evidence supported the assessment? | Prefer observation or reversible step-up when confidence is limited |
| Flags or reasons | What contributed to the result? | Investigate, explain, or tune the customer-owned response |
Review these fields together. A higher-risk result with limited confidence may call for more evidence rather than a hard block. A repeated pattern with corroborating flags may justify stronger treatment on a sensitive route.
## Operating a calibrated policy
1. Start with observation on representative traffic.
2. Separate results by surface and customer outcome; do not assume one threshold fits every route.
3. Review score, risk level, confidence, and flags together.
4. Choose the least disruptive action that addresses the measured risk.
5. Record false-positive and false-negative outcomes in your own review process.
6. Revisit thresholds after traffic, product, or attacker behavior changes.
The console and API provide inputs for this process. Your team owns the labels, outcome data, escalation path, and final policy.
## Supported limitations
- A score does not prove that a session is automated, fraudulent, or operated by a particular person.
- Confidence is not identity assurance and should not replace authentication or authorization.
- Missing or blocked browser capabilities can reduce available evidence.
- Scores should be evaluated against your own traffic and outcomes before enforcement.
- Changes in traffic mix can make an old threshold less useful even when the response schema is unchanged.
## Where we're headed
This section is **forward-looking** and not part of the current product contract.
> **Today, operators tune policies and thresholds. Self-calibration and feedback-driven threshold changes are being explored for future releases.**
The current workflow does not autonomously learn from customer outcomes or change policy. If your organization maintains labels or review outcomes, use them to evaluate the thresholds you control rather than assuming Noxtica will tune itself.
## Where it fits
Calibration sits beneath [Know Your Device](https://noxtica.com/docs/concepts/know-your-device/) and [Browser Intelligence](https://noxtica.com/docs/concepts/browser-intelligence/), which produce the read, and [Browser Security](https://noxtica.com/docs/concepts/browser-security/), which turns a customer-owned policy into an action.
## Read deeper
- [Why calibration, not verdicts](https://noxtica.com/docs/why-calibration/) — the full decision philosophy.
- [Features: risk and decisioning](https://noxtica.com/docs/features/#risk-and-decisioning) — where the output appears.
- [Engineering principles](https://noxtica.com/docs/principles/#01-calibration-over-verdicts) — calibration as an operating constraint.
- [Detection signals: how a signal becomes a decision](https://noxtica.com/docs/detection-signals/#how-a-signal-becomes-a-decision) — the public assessment flow.
- [Backend integration](https://noxtica.com/docs/backend-integration/#read-the-device-on-your-server) — consume the result in server-side logic.
---
Source: https://noxtica.com/docs/concepts/
Markdown: https://noxtica.com/docs/concepts/index.md
Last updated: 2026-09-11
# Concepts & Glossary
Use this section to connect Noxtica terminology to an operating decision. Each concept explains the problem it addresses, where it appears in the product or API, the output your team receives, and the boundary of what that output can establish.
Noxtica separates **intelligence** from **action**. The intelligence layer describes a browser, device, network context, or verified agent claim. Your application and configured policies decide whether to allow, observe, step up, or block. The AI Assistant and MCP integration are read-only ways to investigate that tenant-scoped information; neither is an autonomous control plane.
## The Intelligence pillar
Use the intelligence concepts when you need evidence about traffic before changing the customer journey.
- **[Know Your Device (KYD)](https://noxtica.com/docs/concepts/know-your-device/)** — turns a browser assessment into a site-scoped identifier, risk score, risk level, confidence, and flags that your application can store and review.
- **[Know Your Agent (KYA)](https://noxtica.com/docs/concepts/know-your-agent/)** — where provisioned, compares cryptographically presented agent identity with the trust policy for your tenant. It does not grant an agent authority.
- **[Browser Intelligence](https://noxtica.com/docs/concepts/browser-intelligence/)** — explains the categories of browser and edge context that contribute to an assessment, and how to consume the result through the SDK, console, or Server API.
These outputs support fraud review, account protection, signup controls, abuse investigation, and traffic analysis. They are risk evidence, not proof of a person's identity or intent.
## The Security pillar
Use the security concept after your team has decided what each level of risk should mean for a particular route or transaction.
- **[Browser Security](https://noxtica.com/docs/concepts/browser-security/)** — applies customer-owned policy to intelligence outputs. Your application can act on API results directly; eligible tenants may also use configured risk-action controls and shadow mode.
Keep collection and enforcement separate during rollout. Observe the output on representative traffic, choose thresholds for each surface, and only then introduce customer friction.
## The Agentic spine
"Agentic" describes three different customer workflows. It does not mean that Noxtica autonomously changes your systems.
- **[Agentic Security](https://noxtica.com/docs/concepts/agentic-security/)** — the umbrella for investigating with the assistant, connecting read-only external agents through MCP, and governing incoming automated agents.
- **[MCP Integration](https://noxtica.com/docs/concepts/mcp-integration/)** — an opt-in, tenant-scoped, read-only MCP surface for eligible tenants. External agents can retrieve allowed Noxtica context but cannot modify it.
- **[AI Assistant](https://noxtica.com/docs/concepts/ai-assistant/)** — a console-based operator assistant that reads only what the signed-in operator is permitted to read and returns summaries for human review.
- **[Know Your Agent (KYA)](https://noxtica.com/docs/concepts/know-your-agent/)** — a separate defensive capability for evaluating agents that reach your application; availability and supported identity paths depend on provisioning.
## Calibration
- **[Calibration](https://noxtica.com/docs/concepts/calibration/)** — explains how to use the score, risk level, confidence, and flags together instead of treating any one field as a binary verdict.
Calibration matters when the cost of a false positive differs by workflow. A medium-risk signup, a high-value payment, and a public read-only route can use the same assessment differently because your policy owns the consequence.
## Start with your task
| If you need to… | Start here | Continue with |
| ------------------------------------------------- | ------------------------------------------------------------ | -------------------------------------------------------------------------- |
| Add browser assessment to a site | [Browser Intelligence](https://noxtica.com/docs/concepts/browser-intelligence/) | [Getting started](https://noxtica.com/docs/getting-started/#automatic-collection-recommended) |
| Use an identifier or risk result in backend logic | [Know Your Device](https://noxtica.com/docs/concepts/know-your-device/) | [Backend integration](https://noxtica.com/docs/backend-integration/) |
| Choose risk thresholds and customer treatment | [Calibration](https://noxtica.com/docs/concepts/calibration/) | [Features: risk and decisioning](https://noxtica.com/docs/features/#risk-and-decisioning) |
| Observe, challenge, or block by policy | [Browser Security](https://noxtica.com/docs/concepts/browser-security/) | [Integration flow: decision](https://noxtica.com/docs/integration-flow/#4-customer-policy) |
| Investigate tenant state in the console | [AI Assistant](https://noxtica.com/docs/concepts/ai-assistant/) | [Features: AI-assisted operations](https://noxtica.com/docs/features/#ai-assisted-operations) |
| Let an external agent read approved context | [MCP Integration](https://noxtica.com/docs/concepts/mcp-integration/) | [Features: AI-assisted operations](https://noxtica.com/docs/features/#ai-assisted-operations) |
| Evaluate incoming automated agents | [Know Your Agent](https://noxtica.com/docs/concepts/know-your-agent/) | [Agentic Security](https://noxtica.com/docs/concepts/agentic-security/) |
## Availability and scope
Browser collection, its returned fields, and server-side device lookup are documented in the public integration guides. Assistant access, MCP, KYA, managed enforcement, and native mobile capabilities can depend on plan, tenant provisioning, and supported deployment context. Confirm those capabilities for your tenant before making them a launch dependency. The browser concepts do not imply that native mobile attestation is included.
## Related reading
- [Features reference](https://noxtica.com/docs/features/) — customer-visible capabilities and where they appear.
- [Getting started](https://noxtica.com/docs/getting-started/) — install the browser collector and receive a result.
- [Backend integration](https://noxtica.com/docs/backend-integration/) — look up device risk and use it in server-side policy.
- [Engineering principles](https://noxtica.com/docs/principles/) — the operating constraints behind every surface.
- [Why calibration, not verdicts](https://noxtica.com/docs/why-calibration/) — the decision model behind the platform.
- [Detection signals](https://noxtica.com/docs/detection-signals/) — the evidence categories behind browser assessment.
- [Integration flow](https://noxtica.com/docs/integration-flow/) — browser collection to customer-owned decision, end to end.
---
Source: https://noxtica.com/docs/principles/
Markdown: https://noxtica.com/docs/principles/index.md
Last updated: 2026-09-11
# Engineering Principles
These principles are customer-operating constraints, not promises that every deployment has the same configuration or outcome. Use them to review an integration before it acts on real traffic and whenever you change a policy, data source, or customer journey.
## 01. Calibration over verdicts
Your team owns the action; Noxtica provides a calibrated assessment and the context available for it.
A browser result can include a numeric score, five-level risk tier, confidence, and named flags or reason categories. Agent, network, attestation, behavioral, or identity modules can add their own status where enabled. None of those fields should be reduced to “person is a bot” or “person is safe.”
**Where you'll see this**
- Browser callbacks and server lookups expose risk separately from confidence.
- Fingerprint detail and analytics show reason categories and population context, subject to role and retention.
- Risk-action policies let you choose allow, observe, challenge, review, or block by journey.
- Shadow or observe-only modes, where available, show a proposed action without applying it.
**How to operate it**
1. Establish distributions and known outcomes for each domain and journey.
2. Define the cost and reversibility of each action.
3. Choose thresholds for that route rather than reusing one global cutoff.
4. Treat low confidence, missing evidence, and integration errors as their own paths.
5. Review outcomes and customer friction before tightening policy.
**The trade-off**
Calibration requires a policy and an owner. It is less convenient than a universal `if bot, block` rule, but it exposes uncertainty and lets checkout, login, content, and account-recovery flows make different choices.
## 02. Decisions you can defend
A consequential decision needs a reviewable receipt: what was assessed, which public reason families mattered, how confident the system was, which policy applied, and what action followed.
“Defensible” does not mean revealing hidden probes, scoring weights, anti-evasion methods, or proprietary detection logic. It means giving an authorized customer operator enough stable, customer-facing context to understand and review the outcome.
**Where you'll see this**
- The result contains documented risk fields and named reasons where applicable.
- Fingerprint, risk-action, investigation, and audit views connect an assessment to operator-visible context.
- Policy and configuration changes appear in the relevant customer surfaces and audit history when enabled.
- Exports, alerts, and event sinks can move eligible records into a customer's case workflow.
**How to operate it**
- Keep the assessment identifier, timestamp, domain, policy version or name, action, and appeal outcome needed for your review process.
- Map public reason categories to internal support language without exposing detection recipes.
- Require a second reviewer for high-impact policy changes where your governance calls for it.
- Test that support staff can find a record and route a customer to recovery without needing production secrets.
**The trade-off**
Stable public contracts and reviewable policy changes take more discipline than silently changing a black box. They also make regressions, disputed actions, and operational ownership easier to identify. Exact change-notice and version commitments come from your service agreement, not this principle.
## 03. False positives are not acceptable losses
A missed abusive request and an interrupted legitimate customer are both failures. Their costs differ by journey, so the correct response is to measure both rather than optimize only for detection.
**Where you'll see this**
- Five risk tiers preserve more decision room than a binary outcome.
- Confidence remains separate from risk so limited evidence does not masquerade as certainty.
- Public reason families distinguish privacy choices, shared infrastructure, unfamiliar devices, and suspicious contradictions.
- Reference policies prefer observation or reversible step-up for ambiguous cases and reserve blocking for reviewed conditions.
**How to operate it**
- Track challenge completion, abandonment, support contacts, reversals, confirmed abuse, and unknown/error rates.
- Segment results by route, browser population, device class, locale, and other appropriate cohorts.
- Maintain allow or bypass treatment for approved automation and operational monitoring.
- Provide an accessible fallback and an appeal or recovery path for consequential decisions.
- Re-evaluate policy after traffic shifts, browser releases, consent changes, or new integrations.
**The trade-off**
A conservative starting policy can allow some abuse while you gather evidence. An aggressive policy can suppress visible abuse while hiding customer loss. Noxtica does not promise a universal false-positive rate, catch rate, or “no CAPTCHA” experience; those are deployment outcomes to measure against your own labeled traffic.
## 04. Privacy by construction
Collect and retain only what has a defined customer purpose, scope it to the right tenant and domain, and keep optional or sensitive capture behind explicit controls.
Browser characteristics and a returning-device handle do not require a name or email, but they can still be personal data depending on law and use. Network context, session replay, interaction telemetry, behavioral biometrics, identity evidence, and external enrichment carry different obligations. “Hashed” or “pseudonymous” does not mean “not personal.”
**Where you'll see this**
- Site Keys are bound to registered origins and environments can be kept separate.
- Roles, tenant scope, API-key scopes, and module status constrain customer access.
- Domain and settings surfaces govern eligible collection mode, sampling, retention, redaction, consent/legal-basis admission, DNT/GPC treatment, exports, and deletion workflows.
- Behavioral biometrics, replay, raw-network retention, investigation, and other sensitive surfaces require specific activation or review.
- Audit and data-operations views help authorized operators review configuration and lifecycle activity.
**How to operate it**
1. Inventory the capability and data categories actually enabled for each domain.
2. Record purpose, legal basis or consent, recipient, retention, and deletion path.
3. Use the least-privilege role and API scope; keep secret keys on trusted servers.
4. Apply redaction and minimization before enabling replay, detailed interaction, or exports.
5. Review your current contract, privacy notice, subprocessor information, and jurisdiction-specific obligations.
**The trade-off**
Minimization can reduce continuity, investigation depth, or model confidence. Optional data can improve context but increases review and governance work. No universal hosting region, transfer restriction, deletion timeline, certification, air-gap option, or subprocessor commitment is created by this page; those boundaries must be stated in current legal documents and the customer's signed agreement.
**The specifics**
For a customer review, ask concrete configuration questions instead of relying on an absolute privacy label:
- Which domains and environments have active Site Keys?
- Which collection mode, cache interval, optional signals, and enforcement policies are active?
- Are replay, RUM, behavioral biometrics, network-detail retention, identity, or investigation modules enabled?
- What is the configured retention and deletion workflow for each data family?
- Which roles, API scopes, exports, sinks, and external providers can access or receive data?
- What happens when consent is denied, an API is unavailable, a result is missing, or confidence is low?
Do not publish signing keys, algorithms, rotation schedules, hidden probes, scoring weights, or internal feature controls as customer configuration. Use the supported install, settings, API, and contract surfaces.
## How the principles compose
These four principles reinforce each other:
- Calibration over verdicts only helps when the reasons, confidence, policy, and action are reviewable.
- Defensible decisions expose both abuse coverage and customer harm, making false-positive control measurable.
- False-positive control depends on privacy-aware interpretation: a missing signal or privacy choice is not proof of evasion.
- Privacy-aware design needs calibration because minimizing data can reduce confidence, and policy must respond safely to that uncertainty.
## Apply the principles to a rollout
| Phase | Customer action | Evidence to keep |
| ----------- | ----------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| **Scope** | Name the journey, owner, eligible modules, data purpose, and possible actions | Approved configuration and measurement plan |
| **Observe** | Install or enable without irreversible enforcement | Baseline distributions, unknown/error rate, labeled outcomes, support impact |
| **Review** | Inspect reason families, confidence, cohorts, and proposed actions | Policy rationale and reviewer decision |
| **Enforce** | Promote only the reviewed routes and thresholds | Action history, customer-friction and abuse metrics |
| **Revisit** | Reassess after meaningful traffic, integration, browser, provider, or legal changes | Updated comparison and rollback decision |
## Related reading
- [Why calibration, not verdicts](https://noxtica.com/docs/why-calibration/) — turn risk and confidence into a policy.
- [Threat categories](https://noxtica.com/docs/threat-categories/) — public reason families and their interpretation limits.
- [Detection signals](https://noxtica.com/docs/detection-signals/) — what evidence availability means without exposing hidden probes.
- [Use cases](https://noxtica.com/docs/use-cases/) — reference rollout patterns.
- [Customer capability reference](https://noxtica.com/docs/features/) — configuration, output, eligibility, and limitations by family.
---
Source: https://noxtica.com/docs/concepts/know-your-agent/
Markdown: https://noxtica.com/docs/concepts/know-your-agent/index.md
Last updated: 2026-10-27
# Know Your Agent (KYA)
**Definition.** Know Your Agent is a **defensive trust-policy concept** for automated traffic. Where KYA is provisioned, a tenant can compare supported cryptographic agent identity claims with its own known, allowed, or denied entries.
The problem it solves is that an agent name or user-agent string is only a claim. Organizations need a stronger input before treating an automated client as known, while still defining safe behavior for clients that cannot present supported identity evidence.
KYA governs trust treatment at the traffic boundary. It does not grant an agent authorization inside your application, prove that an agent's requested operation is safe, or enable the agent to act.
## When it applies
Use KYA when your application receives automated traffic and needs to distinguish:
- a supported identity claim that verifies and matches tenant policy;
- a supported identity claim that verifies but is not yet known to the tenant;
- a denied identity; and
- traffic with absent, invalid, or unsupported identity evidence.
Your fallback for unknown traffic matters as much as the allow list. Observe or apply existing bot-risk policy until the identity and business purpose are understood.
## How customers use it
For an eligible deployment:
1. Inventory the automated agents that are expected to reach the protected domains.
2. Record supported identity references and the tenant's desired trust treatment.
3. Define separate behavior for known, denied, and unknown claims.
4. Observe matches and non-matches before introducing enforcement.
5. Apply the result through customer-owned application logic or provisioned [Browser Security](https://noxtica.com/docs/concepts/browser-security/) controls.
6. Review entries when an agent changes keys, signing authority, ownership, or business purpose.
The useful output is identity-verification and policy-match context associated with the request. Combine it with route sensitivity, device or browser risk, and normal application authorization.
## How Noxtica does it
KYA uses public cryptographic identity references instead of trusting a display name:
- **JWK thumbprints** — stable references derived from public-key material can identify which key presented the claim.
- **Signature-Agent hosts** — the declared signing authority provides a host identity that can be checked as part of a supported verification path.
- **Web Bot Auth verification** — where supported, signed request evidence can be verified before tenant policy is evaluated.
These are public contract inputs. No single identifier establishes the agent's intent, the human or organization behind every action, or permission to access an application resource.
## Outputs and decisions
| Output state | What it means | Customer decision |
| ------------------------------- | ----------------------------------------------------------- | ----------------------------------------------------------------------- |
| Verified and allowed | Supported identity evidence matches an allowed tenant entry | Continue to normal application authorization; allow or observe by route |
| Verified and denied | Supported identity evidence matches a denied tenant entry | Apply the tenant's approved deny or challenge policy |
| Verified but unknown | The claim verifies but has no matching trust entry | Observe, review ownership and purpose, then update policy deliberately |
| Invalid, absent, or unsupported | KYA cannot establish a supported identity match | Fall back to browser, device, network, and route policy |
An "allowed" result is not a bypass. The application still checks authentication, authorization, rate limits, and business rules.
Noxtica checks the signature, key reference, and validity window. Each request resolves to a plain verification state: verified, unsigned, invalid signature, expired, or replayed. The result is recorded beside the risk read and contributes to it. A verified claim adds context. An invalid signature is a risk signal. Expired and replayed signatures are detected. Unsigned traffic stays unknown, not hostile.
## What KYA is not
- It is **not** [MCP](https://noxtica.com/docs/concepts/mcp-integration/). MCP lets your external agent read approved Noxtica context; KYA evaluates agents arriving as traffic.
- It is **not** the [AI Assistant](https://noxtica.com/docs/concepts/ai-assistant/). The assistant helps an operator investigate tenant state.
- It is **not** proof of personhood, delegated business authority, or transaction approval.
- It does **not** identify every bot. Agents without a supported identity path remain unknown and require a fallback policy.
## Eligibility and limitations
- KYA availability and supported identity standards depend on tenant provisioning and deployment context.
- Do not make KYA a launch dependency until the account team confirms eligibility and the intended agent identity path.
- Key rotation, authority changes, and malformed signatures can change verification status; maintain an operational review path.
- Browser and device scoring can complement KYA but cannot turn an unsupported identity claim into a verified one.
## Where it fits
KYA is the incoming-agent part of the Intelligence pillar and the "police the agentic web" part of [Agentic Security](https://noxtica.com/docs/concepts/agentic-security/). It supplies trust context; [Browser Security](https://noxtica.com/docs/concepts/browser-security/) or customer code supplies the action.
## Who it fits
KYA helps you answer three questions about automated traffic.
- **Which agents identify themselves?** [When it applies](https://noxtica.com/docs/concepts/know-your-agent/#when-it-applies) lists the four cases KYA separates. [Outputs and decisions](https://noxtica.com/docs/concepts/know-your-agent/#outputs-and-decisions) shows the result for each.
- **Is this claim known to us?** A verified claim that your team has not reviewed yet is the "Verified but unknown" row in [Outputs and decisions](https://noxtica.com/docs/concepts/know-your-agent/#outputs-and-decisions).
- **What should unknown traffic do?** The fallback for unknown traffic is set out in [When it applies](https://noxtica.com/docs/concepts/know-your-agent/#when-it-applies).
## How teams connect
KYA has no public sample code. Setup runs through your account team and depends on tenant provisioning. Three surfaces are involved:
- **Request path.** Supported signed requests are verified where your domains receive traffic. This needs compatible signing and an edge integration.
- **Server verification.** Your backend can ask Noxtica to verify an agent request with a server-held credential. Where provisioned, it can also carry verified agent context in an agent identity envelope. See [Backend Integration](https://noxtica.com/docs/backend-integration/) and the [Server API reference](https://noxtica.com/docs/api/reference/).
- **Operator console.** Review agent identity claims and verification results in the Agentic Security view of the console. Access follows operator role and tenant scope. See [Risk actions, investigations and entity lookup](https://noxtica.com/docs/backoffice/risk-actions-and-investigations/).
## Limits
Availability: Controlled availability. [Eligibility and limitations](https://noxtica.com/docs/concepts/know-your-agent/#eligibility-and-limitations) and [What KYA is not](https://noxtica.com/docs/concepts/know-your-agent/#what-kya-is-not) state most limits in full. This section adds the rest.
- **Verify and observe today.** Enforcement is roadmap and is not part of the offer described here. Any block or challenge based on agent identity is your own logic. Nothing here commits scope or date.
- **Results are evidence.** Your team makes the decision. Read the [disclaimer](https://noxtica.com/disclaimer/).
## Common questions
### Does Know Your Agent block unwanted agents?
Not today. It verifies and observes. [Limits](https://noxtica.com/docs/concepts/know-your-agent/#limits) states that enforcement is roadmap and that any allow, challenge, or deny decision stays in your own logic.
### Is it the same as MCP or the AI Assistant?
No. [What KYA is not](https://noxtica.com/docs/concepts/know-your-agent/#what-kya-is-not) sets out the differences.
### What happens to agents that do not sign requests?
They stay unknown. [Outputs and decisions](https://noxtica.com/docs/concepts/know-your-agent/#outputs-and-decisions) shows the fallback to apply.
## Read deeper
- [Agentic Security](https://noxtica.com/docs/concepts/agentic-security/) — the three agent workflows and their boundaries.
- [Browser Security](https://noxtica.com/docs/concepts/browser-security/) — how customer policy treats allowed, denied, and unknown traffic.
- [Browser Intelligence](https://noxtica.com/docs/concepts/browser-intelligence/) — complementary browser and device evidence.
- [Threat categories](https://noxtica.com/docs/threat-categories/) — the broader automated-traffic context.
- [Features: agent identity and control](https://noxtica.com/docs/features/#agent-identity-and-control) — the customer-facing KYA capability family.
- [Contact](https://noxtica.com/contact/) — confirm KYA eligibility and provisioning.
---
Source: https://noxtica.com/docs/concepts/know-your-device/
Markdown: https://noxtica.com/docs/concepts/know-your-device/index.md
Last updated: 2026-10-27
# Know Your Device (KYD)
**Definition.** Know Your Device is Noxtica's browser-based device-intelligence concept. It turns a browser assessment into a **site-scoped fingerprint identifier** and risk context that can be used across permitted sessions and backend workflows.
The problem it solves is continuity without pretending to know a person. Account and fraud teams often need to ask whether a browser/device context has been seen before, whether its characteristics are internally consistent, and what risk evidence accompanied the assessment. KYD provides those inputs without making the final decision.
A device identifier is not a verified person, account owner, or guaranteed physical device. It is a handle for the assessed context under the current site, browser, storage, and collection conditions.
## When it applies
KYD can inform:
- new-device and returning-device review;
- signup and promotion-abuse controls;
- login, account recovery, and step-up decisions;
- transaction review alongside account and payment context; and
- support investigations into why a session received friction.
Use KYD where your team has a defined decision and fallback. Do not collect an identifier merely because it is available.
## How customers use it
1. Add the browser collector with a provisioned Site Key.
2. Call `checkOnce()` or use automatic collection to receive the current browser result.
3. Store `fingerprintId` with the relevant session or account when your retention and access design permits it.
4. Read the current risk context in the operator console or retrieve device data from the Server API with a scoped server key.
5. Combine device history and risk fields with your own account, route, and transaction context.
6. Apply the action in your backend or through separately provisioned policy controls.
See [Getting started](https://noxtica.com/docs/getting-started/#automatic-collection-recommended) for collection and [Backend integration](https://noxtica.com/docs/backend-integration/) for the supported lookup workflow.
## How Noxtica does it
[Browser Intelligence](https://noxtica.com/docs/concepts/browser-intelligence/) gathers multiple categories of browser and edge context. KYD presents the resulting customer-facing artifacts:
- **Fingerprint identifier** — a site-scoped handle returned as `fingerprintId`.
- **Device history fields** — supported first-seen, last-submitted, and last-seen timestamps available through device lookup.
- **Risk score and level** — a 0–100 score and named tier for policy segmentation.
- **Confidence** — context for how strongly to rely on the assessment.
- **Flags or reasons** — contributing conditions an operator can investigate.
- **History and comparison** — in the operator console, find a device, review its visits, and compare profiles. Where enabled for your tenant, follow related devices; relationships are leads, not proof. History follows your workspace retention and access settings. See [Fingerprints, analytics and live monitoring](https://noxtica.com/docs/backoffice/fingerprints-and-analytics/).
The protected browser runtime is designed to raise the cost of result manipulation and replay. It does not make a browser impossible to inspect, guarantee continuity, or establish a hardware or legal identity.
## Outputs and decisions
| Output | Customer use |
| ----------------------- | ------------------------------------------------------------------- |
| `fingerprintId` | Associate permitted observations with a session or account workflow |
| First/last-seen context | Distinguish newly observed from previously observed context |
| `score` and `riskLevel` | Select a route-specific review or step-up band |
| `confidence` | Decide whether the available evidence supports a strong action |
| `flags` | Explain and investigate what contributed to risk |
For example, a newly observed identifier with elevated risk and limited confidence may warrant reversible step-up rather than a permanent denial. A familiar identifier still passes normal authentication and authorization; familiarity is not approval.
## Supported limitations
- Clearing storage, private browsing, browser or device changes, privacy tools, blocked scripts, and collection settings can affect continuity or available evidence.
- A fingerprint can represent a browser profile rather than a single immutable physical device.
- Cross-site tracking is not the customer contract; use the identifier only within the provisioned tenant and site context.
- Cached assessments can be older than the current visit. Use the configured refresh interval and timestamps when freshness matters.
- Native iOS or Android attestation is separate from browser KYD and requires its own supported integration and tenant eligibility.
- Risk output complements but does not replace identity verification, authentication, authorization, or transaction controls.
## Where it fits
KYD is the device part of the Intelligence pillar. It receives evidence from [Browser Intelligence](https://noxtica.com/docs/concepts/browser-intelligence/), complements eligible [Know Your Agent](https://noxtica.com/docs/concepts/know-your-agent/) context, and supplies inputs to [Browser Security](https://noxtica.com/docs/concepts/browser-security/) or customer-owned backend policy.
## Who it fits
Device evidence suits teams that own a defined decision and a fallback. [When it applies](https://noxtica.com/docs/concepts/know-your-device/#when-it-applies) lists the decisions it can inform, and [Outputs and decisions](https://noxtica.com/docs/concepts/know-your-device/#outputs-and-decisions) explains why a familiar handle is not approval.
- **Repeated signups.** Shared devices and shared networks can limit what you can conclude when you compare device context across sessions.
- **Support and fraud review.** Use the handle as a repeatable reference when you review a session or a transaction alongside account context.
## How teams connect
These are the current public integration surfaces. Both need Evaluation access.
- **Browser script.** Follow [Getting started](https://noxtica.com/docs/getting-started/#automatic-collection-recommended) and [Browser runtime](https://noxtica.com/docs/browser-runtime/). The script runs on pages of a provisioned origin and reports a device identifier or an unavailable state to your page code.
- **Authenticated server lookup.** Follow [Backend integration](https://noxtica.com/docs/backend-integration/). Your backend sends the device identifier and reads the tenant-scoped record with a server-held credential. Keep that credential out of browser code.
- **Technical evaluation.** The [developer overview](https://noxtica.com/developers/) shows the maintained path and the current support matrix. [Contact the team](https://noxtica.com/contact/) to request Evaluation access.
[Integration flow](https://noxtica.com/docs/integration-flow/) traces the whole path from browser to policy.
## Limits
Plan for these boundaries before you rely on the output.
- **Not a person, and continuity varies.** The opening definition and [Supported limitations](https://noxtica.com/docs/concepts/know-your-device/#supported-limitations) cover what a handle represents and what breaks continuity. A missing result is not a low-risk result; treat it as unknown. Consent choices can also reduce evidence.
- **Estimates, not facts.** Scores, risk levels, and reasons are probabilistic. They are not statements of fact or certifications. Your team makes every decision. Read the [disclaimer](https://noxtica.com/disclaimer/).
- **Your responsibilities.** Optional collection follows the consent and admission settings you configure. Device handles and browser characteristics can be personal data, depending on law and use. You own the notices, consent, and legal basis for collecting them.
## Common questions
### Does a device handle identify a person?
No. It identifies an assessed browser or device context under your site. Use [identity verification](https://noxtica.com/docs/identity-verification-integration/) when you need evidence about a person.
### Does Device Intelligence block traffic?
No. It returns evidence. Your backend, or policy controls you provision separately, decides whether to allow, step up, review, or deny.
### What happens if collection fails or is blocked?
Your page receives an error or unavailable state, and no fresh evidence arrives. Treat that state as unknown, not low risk, and define a fallback.
## Read deeper
- [Getting started](https://noxtica.com/docs/getting-started/#automatic-collection-recommended) — collect the current browser result.
- [Device API reference](https://noxtica.com/docs/api/reference/device/) — retrieve device risk with a scoped server key.
- [Browser runtime](https://noxtica.com/docs/browser-runtime/) — cache, lifecycle events, errors, and collection modes.
- [Features: device and browser intelligence](https://noxtica.com/docs/features/#device-and-browser-intelligence) — interpret the identifier and its risk context.
- [Why calibration, not verdicts](https://noxtica.com/docs/why-calibration/) — choose policy without treating risk as identity.
- [Browser Intelligence](https://noxtica.com/docs/concepts/browser-intelligence/) — the evidence categories that feed KYD.
---
Source: https://noxtica.com/docs/detection-signals/
Markdown: https://noxtica.com/docs/detection-signals/index.md
Last updated: 2026-09-11
# Detection Signals
Noxtica reads several evidence layers and checks whether the available picture is coherent. It then returns customer-facing policy inputs: score, risk tier, confidence, and named reasons where applicable. Optional modules can add agent, attestation, behavioral, identity, or policy status.
Signals describe a browser, device, connection, or interaction context—not a person's identity or intent. No single layer establishes “human,” “bot,” “fraudulent,” or “safe,” and this page intentionally does not publish hidden probes, exact weights, anti-evasion methods, or proprietary implementation.
## When to use detection signals
Collect at a decision point where additional context can change a proportionate action: signup, login, checkout, account recovery, promotion redemption, content/API access, or an investigation. Do not collect every optional signal simply because it exists. Match the enabled layers, cache cadence, retention, and downstream use to a documented purpose.
Use browser callbacks when the page needs a reversible experience choice. Send the device handle to your trusted backend and use a scoped server integration when authentication, money, account access, or another consequential decision is involved.
## Four questions, one answer
Noxtica groups customer-visible interpretation into four layers. The questions below are operational shorthand, not claims that one layer can prove the answer.
| Layer | Customer question | What the output can contribute | Common limitation |
| --------------- | ------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| **Browser** | Is this browser context internally consistent? | Automation, browser consistency, privacy-context, and tampering reason families | Restricted APIs, extensions, browser updates, and collection mode can reduce evidence |
| **Network** | Does the connection add risk context? | Coarse network type, reputation, location/provider context, or known-agent network evidence where enabled | VPNs, relays, mobile carriers, shared egress, and changing reputation are common |
| **Device** | Does the environment and history support the claimed context? | Tenant-scoped recognition, device consistency, and optional integrity/attestation status | Storage clearing, device/browser changes, unsupported clients, and missing attestation break continuity |
| **Interaction** | Does eligible timing or journey context corroborate the rest? | Lightweight timing/journey reasons and optional behavioral evidence | Short sessions, accessibility tools, UI changes, consent, and sampling can affect context |
Contradictions between independent layers can be useful, but agreement does not prove identity or intent. Absence also has meaning: a layer can be unavailable, disabled, unsupported, denied by policy, sampled out, cached, or simply inconclusive.
## Configure the evidence you need
### Core browser collection
1. Add the exact origin in **Backoffice → Domains** and copy its Site Key.
2. Install the supported collector pattern from [Getting Started](https://noxtica.com/docs/getting-started/#automatic-collection-recommended).
3. Select the collection mode supported by the current SDK and customer journey.
4. Use `checkOnce()` for the configured cache behavior, or request a fresh assessment only when the decision justifies the extra client work.
5. Monitor `noxtica:collected`, `noxtica:cache-hit`, and `noxtica:error` as documented in [Browser Runtime](https://noxtica.com/docs/browser-runtime/).
### Optional evidence
Enable attestation, behavioral biometrics, replay/RUM, detailed network context, KYA, identity, or investigation modules only when they are entitled and their domain/tenant settings, client support, quota, purpose, consent/legal basis, redaction, and retention have been reviewed.
A feature page in Backoffice normally shows its status and configuration links when the signed-in operator has access. If the page, toggle, or output is absent, treat the capability as unavailable for that deployment until provisioning or configuration is confirmed.
### Trusted consumption
Create the narrowest required Server API key under **API Config** and keep it on the backend. Handle authentication errors, authorization errors, missing/expired records, rate limits, timeouts, and unavailable optional providers as explicit states. Never make a missing result silently equivalent to `minimal` risk.
## One calibrated risk tier
The core web assessment maps the numeric score to a five-level customer contract:
- **Minimal (`0–19`)** — little risk evidence in the available assessment.
- **Low (`20–39`)** — minor or potentially explainable anomalies.
- **Medium (`40–59`)** — mixed or incomplete suspicious evidence.
- **High (`60–79`)** — strong suspicious evidence.
- **Critical (`80–100`)** — multiple or strong reason families agree.
The tier does not arrive alone. Read it with:
- **`confidence`:** how much usable evidence supported the assessment;
- **`flags` or reasons:** the public evidence families that influenced it;
- **`fingerprintId`:** the tenant-scoped device handle returned by the browser integration;
- **cache/freshness and timestamps:** whether the decision is using a current or reused assessment; and
- **optional statuses:** agent verification, device/app integrity, identity case, or policy action where enabled.
The ranges are integration vocabulary, not universal action thresholds. Use [Why Calibration, Not Verdicts](https://noxtica.com/docs/why-calibration/) to choose route-specific policy.
## Interpret risk and confidence together
| Risk | Confidence | Interpretation | Safer customer response |
| ---- | ---------- | ---------------------------------------------- | -------------------------------------------------------------- |
| Low | High | Available evidence is consistently ordinary | Allow under normal application controls |
| Low | Low | Little concern is visible, but little is known | Preserve ordinary controls; do not grant extra trust |
| High | High | Concern is strongly corroborated | Challenge, hold, review, or apply a reviewed block rule |
| High | Low | Concern exists but evidence is incomplete | Use reversible step-up or review; investigate missing evidence |
A policy can also consider the route's value, authentication state, transaction/account context, device familiarity, supported agent identity, and confirmed customer outcomes. Noxtica's output should complement—not replace—those controls.
## Sealed before it leaves the browser
Noxtica protects the assessment in transit from the browser so your supported verifier can detect invalid, expired, mismatched, or altered results. The customer contract is the outcome: trusted code validates the supported result before relying on it.
This integrity protection does not make all client data inherently trustworthy, does not prevent every replay or endpoint misuse by itself, and does not authorize the action. Keep secret credentials on your server, validate the result through the documented integration, bind it to the intended workflow where supported, enforce expiry, and retain your own authentication and authorization checks.
The exact cryptographic construction, challenge method, hidden signal probes, and internal anti-evasion controls are not customer configuration and are intentionally omitted here.
## How a signal becomes a decision
Walk through a signup attempt:
1. **Admission and collection.** The configured collector starts for the registered domain. Optional capture runs only if its policy, consent or legal-basis, sampling, and other admission conditions allow it.
2. **Assessment.** Noxtica evaluates the available browser, network, device, and eligible interaction context. Unsupported, disabled, denied, cached, or missing evidence affects what is available.
3. **Output.** The browser callback returns the documented fields. Your frontend can send the device handle with the signup request; it never sends a secret Server API key.
4. **Trusted lookup.** Your backend uses its scoped credential or supported SDK to read the eligible current record and handles errors, expiry, and `unknown` explicitly.
5. **Customer policy.** A route-specific rule combines risk, confidence, reasons, signup/account context, and any approved-agent or integrity status.
6. **Action.** The application allows, observes, requests a reversible step-up, holds for review, or blocks under the reviewed rule.
7. **Review.** Operators inspect Analytics, Fingerprints, Risk Actions, and Audit where enabled, then compare confirmed abuse with challenge completion, abandonment, support contacts, and reversals.
### Public policy example
```javascript
function decideSignup({ riskLevel, confidence, resultState }, confidenceFloor) {
if (resultState !== 'available') return 'step_up_or_defer';
if (confidence < confidenceFloor) return 'step_up_or_observe';
if (riskLevel === 'critical') return 'strong_challenge_or_review';
if (riskLevel === 'high') return 'step_up';
if (riskLevel === 'medium') return 'observe';
return 'allow_with_normal_controls';
}
```
The confidence floor and action mapping are intentionally yours. Determine them from representative shadow traffic and labeled outcomes rather than copying an internal or universal weight.
## Expected outputs by customer surface
| Surface | Use it for | Typical customer-visible output |
| --------------------------------- | ------------------------------------------------------- | --------------------------------------------------------------------------- |
| Browser callback/API | In-page experience and sending a handle to trusted code | Device handle, score, tier, confidence, flags/reasons, cache state |
| Server API or SDK | Trusted backend policy and record lookup | Eligible device/risk record, timestamps, reason context, explicit errors |
| Fingerprints and Compare | Individual review | Assessment detail, evidence families, history, comparison context |
| Analytics and Quality/Calibration | Population and policy review | Distribution, trends, cohorts, labels, or calibration context where enabled |
| Risk Actions | Enforcement rollout | Applied or shadow action, policy context, and operational history |
| Alerts, sinks, webhooks, exports | Downstream operations | Selected eligible events or records under configured scope and data policy |
## Eligibility and limitations
Core collection requires an activated account, registered domain, Site Key, and supported browser integration. Outputs depend on collection mode, browser capabilities, cache state, network, retention, and service availability. Optional families require their own entitlement, tenant/domain activation, role, scope, quota, supported client or provider, and sometimes consent or legal-basis review.
Detection signals are probabilistic and can be incomplete, stale, or wrong. They do not prove identity, account ownership, accessibility needs, fraud, or intent. No universal detection rate, false-positive rate, latency, availability, or privacy outcome is promised here. Measure the behavior of your actual integration and apply the terms in your current contract.
## Related reading
- [Threat categories](https://noxtica.com/docs/threat-categories/) — interpretation and limits for each public reason family.
- [Browser runtime](https://noxtica.com/docs/browser-runtime/) — collection modes, caching, events, CSP, and troubleshooting.
- [Backend integration](https://noxtica.com/docs/backend-integration/) — trusted lookups, response fields, errors, and rate limits.
- [Why calibration, not verdicts](https://noxtica.com/docs/why-calibration/) — choose route-specific action from risk and confidence.
- [Customer capability reference](https://noxtica.com/docs/features/) — every customer family, surface, output, eligibility, and limitation.
---
Source: https://noxtica.com/docs/threat-categories/
Markdown: https://noxtica.com/docs/threat-categories/index.md
Last updated: 2026-09-11
# Threat Categories
Threat categories are public explanation families. They tell an authorized customer operator what kind of evidence influenced an assessment without exposing hidden probes, exact scoring weights, anti-evasion methods, or proprietary implementation.
A category is not a verdict and does not map to one fixed action. Read it with the overall risk tier, confidence, other reasons, customer journey, and your own known outcomes. The exact reasons visible to you depend on collection mode, browser support, enabled modules, tenant/domain policy, role, retention, and consent or legal-basis controls.
## 01. Automation and bots
This category covers evidence consistent with scripted browsers, automation tooling, remote control, repeated machine-driven flows, or known automated clients.
**When to use it**
Use it to protect routes where automation creates cost or abuse: signup, login, promotion redemption, inventory, checkout, content/API access, or account changes. Define expected automation—monitoring, testing, integrations, or approved agents—before enforcement.
**What the customer sees**
The result or fingerprint detail can name an automation/bot reason family, while analytics and bot-intelligence views can show aggregate volume and known-agent context where enabled. Risk Actions shows the configured action or shadow outcome.
**How to interpret it**
Automation evidence is more useful when it repeats across events or agrees with consistency, infrastructure, device, agent, or interaction context. A legitimate automated client should follow an explicit allow or agent policy rather than forcing the whole route to ignore automation evidence.
**Outcome**
Prioritize likely scripted abuse, route approved automation predictably, and apply proportionate challenge or blocking to protected operations.
**Tuning**
Start in observe-only mode where available. Segment by route, client, and known agent; review false positives and operational tools; then promote reviewed policy. Do not infer the hidden detection method from a reason name or build a permanent deny rule from a single event.
**Limitations**
Automation changes, and no detector identifies every tool. Accessibility software, test harnesses, monitoring, remote-work tools, and enterprise automation can create similar context. Signed-agent verification, when enabled, establishes a supported identity state but does not prove safe intent.
## 02. Fingerprint tampering
This category covers material inconsistency between what a browser or environment claims and what its observable behavior supports. It is intended to distinguish unexplained contradiction from an ordinary privacy choice.
**When to use it**
Use it as corroboration for spoofing, replay, evasion, or synthetic-environment investigations, especially when a valuable action also has automation, network, device, or account context.
**What the customer sees**
A public consistency/tampering reason can appear with the overall score and confidence. Authorized operators can compare the record with domain population and prior device history through eligible fingerprint or investigation views.
**How to interpret it**
One inconsistency can come from browser changes, extensions, restricted APIs, compatibility layers, or partial collection. Repeated contradictions or agreement across independent categories deserve more weight than a single unusual characteristic.
**Outcome**
Surface sessions that need step-up or review without teaching an attacker which internal test fired.
**Tuning**
Review the affected browser/OS population, fresh versus cached state, collection mode, CSP, and recent client changes. Provide allow treatment for approved tooling and avoid treating a reason label as identity proof.
**Limitations**
The category does not prove deliberate deception. Browser privacy changes and software updates can shift the population. Some evidence is unavailable on restricted or unsupported clients, which can lower confidence.
## 03. Infrastructure abuse
This category covers network context associated with higher abuse risk, such as anonymization, hosting infrastructure, reputation sources, or inconsistent location/network information. It is corroborating evidence, not guilt by network.
**When to use it**
Use it to prioritize high-cost routes, rate-limit abusive patterns, enrich an investigation, or strengthen a decision already supported by automation or account evidence.
**What the customer sees**
Eligible results and console views can expose public network/infrastructure reasons, coarse geography or provider context, and reputation status. Detailed or retained network data, external feeds, and geo/investigation views have separate controls.
**How to interpret it**
Corporate VPNs, privacy relays, mobile carriers, shared egress, cloud workspaces, journalists, and travelers can resemble risky infrastructure. Interpret the category with route, device, behavior, history, and known outcome.
**Outcome**
Identify concentrated abuse and investigate network patterns while preserving a path for legitimate users on shared or privacy-preserving infrastructure.
**Tuning**
Keep network-only reasons out of irreversible block rules. Measure by provider type and route, maintain reviewed exceptions, and monitor reputation changes. Connect a customer-selected feed only where supported and approved.
**Limitations**
Addresses and reputation change, geolocation is approximate, and shared egress is common. Raw-network retention and some feeds can require explicit opt-in, entitlement, additional disclosure, or legal review.
## 04. Privacy-browser handling
This category provides context for browsers or modes that deliberately reduce, standardize, or restrict observable detail. A privacy choice is not itself a threat.
**When to use it**
Use it to prevent low detail or standardized output from being mistaken for automation, and to compare policy friction across privacy-preserving browser populations.
**What the customer sees**
Where recognized, the assessment can identify privacy-browser context separately from tampering. Analytics and fingerprint detail can help authorized operators compare risk, confidence, challenge, and error rates for that population.
**How to interpret it**
Privacy context explains why some evidence may be limited. Continue to evaluate independent automation, network, device, agent, or interaction reasons, but do not escalate merely because the browser protects users.
**Outcome**
Keep legitimate privacy-conscious users in the normal or proportionate path while retaining protection against abusive automation using the same browser family.
**Tuning**
Review challenge completion, abandonment, support contacts, and unknown/error rates by browser family. Prefer reversible step-up when independent evidence is concerning and confidence is limited.
**Limitations**
Browser identification and behavior evolve. Noxtica does not guarantee that every privacy browser is recognized or that its users will never be challenged. Your CSP, collection mode, consent choices, and browser support affect available evidence.
## 05. Hardware checks
This category covers eligible device-integrity and environment evidence used to corroborate whether a session is consistent with its claimed execution context.
**When to use it**
Use it for high-value or high-abuse operations where browser-only evidence needs corroboration. Optional browser, GPU/CPU, mobile-app, or platform attestation should be applied only to supported clients and entitled tenants/domains.
**What the customer sees**
A customer-facing integrity or attestation status, public reason, confidence contribution, and related console record can be available. The hidden challenge, precise measurement, and validation mechanism are intentionally not exposed.
**How to interpret it**
A successful supported check is one piece of integrity evidence. An unavailable, unsupported, timed-out, or missing result is `unknown`, not automatically malicious. A failed or inconsistent result should be combined with route and other evidence before consequential action.
**Outcome**
Raise the cost of synthetic environments and add device/app integrity context to authentication, fraud, or agent policy.
**Tuning**
Enable by selected domain or application, validate client coverage in observation first, and define explicit success, failure, and unknown paths. Monitor battery/performance, browser/platform support, challenge completion, and fallback behavior in your real customer journey.
**Limitations**
Hardware and mobile attestation require supported environments and separate configuration. They do not prove a natural person's identity or benevolent intent. Availability, quotas, and provider behavior vary by account and client.
## 06. Behavioral anomalies
This category covers eligible interaction and journey context that differs from the relevant population. It is supporting evidence, not a diagnosis of whether a person is human.
**When to use it**
Use lightweight timing and journey context to corroborate other risk on selected routes. Use behavioral biometrics only after the required entitlement, explicit activation, disclosure, consent/legal-basis, minimization, and retention review.
**What the customer sees**
Depending on configuration, the result and behavioral surfaces can show a public anomaly reason, aggregate or subject-level context, journey change, and policy effect. Exact motion, keystroke, timing, or detector mechanics are not published as a customer tuning recipe.
**How to interpret it**
Interaction patterns vary across accessibility tools, motor ability, devices, cultures, network delays, task familiarity, and page design. Behavioral evidence should corroborate other categories and should not be a sole blocking reason.
**Outcome**
Identify otherwise-clean sessions or journeys that merit observation or a reversible step-up while measuring customer friction.
**Tuning**
Start with lightweight, non-biometric context where appropriate. For optional biometrics, activate only reviewed domains and monitor counterfactual or shadow results, affected cohorts, challenge completion, support impact, and reversals.
**Limitations**
Short sessions and sparse interaction reduce confidence. Journey/UI changes can shift baselines. This category must not be used to infer health, disability, or other sensitive traits, and Noxtica does not promise that it distinguishes every person from every script.
## How the categories combine
Noxtica combines the evidence available to the enabled assessment into one score, risk tier, and confidence value, with named public reasons where applicable. Some modules also return a distinct status—such as agent verification, attestation, identity-case, or policy-action state—that should retain its own meaning.
A customer policy should ask:
1. Is the result fresh enough and valid for this route?
2. Which modules and evidence were available, and how confident is the assessment?
3. Do multiple independent reason families agree?
4. Is there an ordinary explanation or approved automation path?
5. How valuable and reversible is the requested action?
6. Is an accessible challenge, review, appeal, or recovery path available?
Do not reconstruct an internal formula from category names. Use your labeled outcomes and the supported Analytics, Fingerprints, Quality/Calibration, Risk Actions, and Audit surfaces to judge policy behavior.
## Availability and configuration checklist
- The correct tenant, domain, Site Key, and environment are selected.
- Collection mode and cache interval fit the decision point.
- Optional agent, reputation, attestation, behavioral, replay, identity, or investigation modules are entitled and activated where needed.
- Operator role and API-key scopes expose only required data.
- Consent/legal basis, redaction, retention, and downstream destinations have been reviewed.
- Shadow, unknown, error, rate-limit, and provider-down behavior is defined before enforcement.
## Related reading
- [Detection signals](https://noxtica.com/docs/detection-signals/) — how browser, network, device, and interaction layers become an assessment.
- [Why calibration, not verdicts](https://noxtica.com/docs/why-calibration/) — map risk and confidence to policy.
- [Customer capability reference](https://noxtica.com/docs/features/) — customer surfaces, outputs, eligibility, and limits.
- [Browser runtime details](https://noxtica.com/docs/browser-runtime/) — collection modes, events, caching, and troubleshooting.
- [Frequently asked questions](https://noxtica.com/docs/faq/) — common integration and privacy questions.
---
Source: https://noxtica.com/docs/why-calibration/
Markdown: https://noxtica.com/docs/why-calibration/index.md
Last updated: 2026-09-11
# Why we don't tell you "this is a bot."
A binary label hides uncertainty and invites the same action everywhere. A login, a checkout, a public article, and an account-recovery change have different costs when a decision is wrong. Noxtica therefore returns calibrated policy inputs: risk, confidence, and explainable reason categories.
Calibration does not mean the system knows a visitor's identity or intent. It means the output has ordered levels that your team can compare with labeled outcomes and map to proportionate action. Noxtica provides the measurement and eligible policy surfaces; your application and operators remain responsible for the decision.
## The receipt model
> Read the risk level, confidence, and reasons together.
> Apply the policy for this customer journey.
> Keep the decision reviewable.
A useful receipt answers five customer questions:
1. **What was assessed?** The tenant, domain, device or request handle, and time.
2. **What did Noxtica return?** Score, risk tier, confidence, and public reason categories.
3. **What context was available?** Cached or fresh result, enabled modules, and any missing or unknown evidence visible through supported surfaces.
4. **Which policy applied?** The customer-owned route or workflow rule.
5. **What happened next?** Allow, observe, challenge, hold, review, or block—and any appeal or later confirmed outcome.
Use browser events for reversible in-page experience choices and a scoped server lookup or supported server SDK when a trusted backend must decide. Use **Fingerprints**, **Analytics**, **Risk Actions**, **Quality & Calibration**, and **Audit** in Backoffice where those surfaces are enabled for your role and tenant.
The receipt deliberately does not disclose hidden probes, scoring weights, anti-evasion methods, or proprietary implementation. Explainability is a stable customer outcome and reason contract, not an attacker's recipe.
## Binary verdicts hide the cost of being wrong
A binary verdict has two familiar failure modes:
- **False positive:** legitimate activity receives an unnecessary challenge, hold, review, or denial. Possible costs include abandonment, inaccessible journeys, support load, and loss of trust.
- **False negative:** abusive automation or fraud receives ordinary treatment. Possible costs include account abuse, operational load, inventory or content extraction, and financial loss.
There are also two operational failures that a binary field tends to erase:
- **Unknown:** the required result, module, or evidence is absent or unavailable.
- **Low confidence:** the assessment has too little usable evidence for the action being considered.
These states need explicit policy. Treating missing data as “safe” creates bypasses; treating it as “malicious” punishes restricted browsers, outages, and integration mistakes. A common starting posture is to preserve ordinary controls, defer a high-impact action, or request a reversible step-up while the cause is investigated.
## The five-tier risk model
Noxtica's public web response uses five risk tiers:
| Tier | Current score range | Interpret as | Example starting action—not a default guarantee |
| ---------- | ------------------: | ------------------------------------------------ | ---------------------------------------------------- |
| `minimal` | 0–19 | Little risk evidence in the available assessment | Allow under normal application controls |
| `low` | 20–39 | Minor or explainable anomalies | Allow and observe |
| `medium` | 40–59 | Mixed or incomplete suspicious evidence | Observe, queue, or use low-friction step-up |
| `high` | 60–79 | Strong suspicious evidence | Challenge, hold, or review |
| `critical` | 80–100 | Multiple or strong reason families agree | Strong challenge or block only under reviewed policy |
The response ranges provide a consistent integration vocabulary. They are not a promise that one threshold fits every tenant or that a tier will never change meaning under a versioned service contract. Use Backoffice distributions and your own confirmed outcomes to select actions.
### Configure policy by surface
| Surface | What to configure | Why it differs |
| ----------------------------- | -------------------------------------------------------------------- | --------------------------------------------------- |
| Public content | Observe, rate limit, or apply agent-specific policy | The action is usually reversible and low value |
| Signup or promotion | Detect repeated or automated attempts; step up before granting value | Shared devices and legitimate retries are common |
| Login | Combine device familiarity with authentication and account context | A new device is not proof of takeover |
| Checkout | Combine assessment with transaction and account controls | The cost of a false denial and fraud both matter |
| Recovery or credential change | Require stronger authentication when risk or confidence warrants it | The operation is high impact even for known devices |
Start in shadow or observe-only mode where available. Record which action _would_ occur, compare it with confirmed outcomes and customer-friction measures, and promote only the reviewed route policy.
## Confidence is a separate axis
Risk answers “how concerning is the available evidence?” Confidence answers “how much usable evidence supported that assessment?” They are not substitutes.
| Risk | Confidence | Safer interpretation | Possible response |
| ---- | ---------- | --------------------------------------------- | ---------------------------------------------------------- |
| Low | High | Available evidence is consistently ordinary | Allow under normal controls |
| Low | Low | Little concern was seen, but little was known | Preserve normal controls; avoid granting extra trust |
| High | High | Strong concern with substantial corroboration | Challenge, hold, review, or apply a reviewed block rule |
| High | Low | Concern exists but evidence is incomplete | Reversible step-up or review; investigate missing evidence |
Confidence can be affected by collection mode, browser support, page timing, caching, consent choices, optional-module status, or integration errors. Do not infer a person's behavior or disability from a confidence value.
## The reasons are the audit trail
Named reasons tell an authorized operator which public evidence family influenced the result: for example automation, consistency/tampering, network/infrastructure, privacy-browser handling, device integrity, or interaction context. They help support and fraud teams answer “why did this assessment move?” without exposing the hidden test or its weight.
Use reasons to:
- distinguish a potentially explainable anomaly from corroborated abuse;
- find the relevant [threat category](https://noxtica.com/docs/threat-categories/);
- compare an individual record with its domain's population;
- choose a better step-up or allow treatment for approved automation;
- label a confirmed outcome through the supported customer surface; and
- investigate policy regressions after a browser, traffic, or configuration change.
Do not use reasons to:
- turn one flag into a permanent deny list;
- infer protected or sensitive traits;
- reproduce or probe the detection mechanism;
- assume two matching reasons prove the same person or actor; or
- promise a customer that the result is error-free.
## Calibrate with your own outcomes
1. **Define the unit:** signup, login, transaction, request, account change, or moderation case.
2. **Define known outcomes:** confirmed abuse, confirmed legitimate, challenge passed, appeal upheld, chargeback, review disposition, or another defensible label.
3. **Run observe-only:** collect enough representative traffic for the routes and cohorts you will govern.
4. **Compare:** inspect risk, confidence, reasons, unknown/error rates, customer friction, and action volume.
5. **Choose thresholds:** start with reversible actions and route-specific exceptions.
6. **Review after launch:** watch drift, challenge completion, abandonment, support contacts, reversals, and missed abuse.
7. **Change deliberately:** record the rationale, reviewer, effective time, and rollback condition.
Quality or calibration surfaces may be plan- or role-gated. If your account does not expose them, agree on the supported labeling and review process with your Noxtica contact before enforcement.
## Calibration over verdicts
The short version:
1. A risk tier is an ordered measurement, not identity or intent.
2. Confidence expresses evidence coverage, not safety.
3. Reasons make the outcome reviewable without publishing sensitive detection mechanics.
4. Different customer journeys need different actions.
5. Unknown, error, and low-confidence states need explicit safe handling.
6. Your labeled traffic and customer-friction data—not an unsupported universal metric—determine whether policy works.
## Eligibility and limitations
Core risk fields are available with an activated collection integration. Advanced scoring endpoints, quality/calibration tooling, attestation, behavioral, agent, identity, investigation, and enforcement modules can require plan entitlement, tenant or domain activation, operator permissions, quota, a supported client, or legal-basis review.
Calibration reduces hidden uncertainty; it does not eliminate model error, adversarial adaptation, incomplete data, or traffic drift. Exact false-positive rates, detection rates, latency, threshold stability, and change-notice commitments apply only when defined by a current measurement record or customer contract.
## Related reading
- [Threat categories](https://noxtica.com/docs/threat-categories/) — interpret the public reason families.
- [Detection signals](https://noxtica.com/docs/detection-signals/) — understand evidence layers and missing data.
- [Engineering principles](https://noxtica.com/docs/principles/) — the operating constraints for rollout and review.
- [Use cases](https://noxtica.com/docs/use-cases/) — route-specific reference patterns.
- [Customer capability reference](https://noxtica.com/docs/features/#risk-and-decisioning) — customer surfaces, outputs, eligibility, and limits.
---
Source: https://noxtica.com/docs/hunter/extension/
Markdown: https://noxtica.com/docs/hunter/extension/index.md
Last updated: 2026-10-27
# Hunter browser extension
noxtica Hunter is a browser extension that shows which scripts on one web page you choose to audit read your browser's fingerprint-related features, such as canvas, WebGL, audio, navigator and screen properties, fonts and timing. The analysis runs on your device.
Developers, security reviewers and privacy teams use it. You start every audit by hand. Sharing a report with your Noxtica workspace is a separate, optional step that is off by default.
## What it is
Availability: depends on your organisation and the modules enabled for it; ask your account team.
Hunter is not an automatic scanner. Nothing is observed until you press **Start audit** or **Quick look** for the current tab. This page describes the extension as built from source. How your organisation receives a build, and for which browsers, is arranged with your account team.
### What an audit gives you
- A **rating**: the share of fingerprint features the page touched, compared with published thresholds. The thresholds are marked Provisional until they are calibrated, so read the level as indicative.
- A **risk score** from 0 to 100 with a level (low, medium, high or critical) and the reasons behind it.
- **Detections** by feature area, with the calling script for each API.
- **Vendors** recognised from script addresses, code patterns and network traffic.
- **Script sources**, marked first party or third party.
- **Network findings**: requests whose payload looked like fingerprint data. Hunter keeps field names and keywords, never values.
- **Bot-signal observations** and **Environment context** labels (for example a privacy browser or developer tools) that explain why a reading may look unusual.
The report page says it is advisory: Hunter observes from inside the page, and a page can interfere with what it sees. Treat a report as a signal, never as evidence of intent.
### Two ways to run
| Mode | What happens | Limit |
| --- | --- | --- |
| Start audit | Asks once for access to that one site, reloads the page so it sees every call from the start, records until the timer ends or you press **Stop**, then gives the access back | Default 30 seconds; whole seconds from 1 to 600 |
| Quick look | No permission prompt and no reload; records from now on | Calls made before you pressed the button are missed ("Late attach") |
Hunter audits only `http` and `https` pages. It refuses to instrument a page that already runs the Noxtica SDK, so it cannot interfere with that page's integrity signals. Only one audit can run at a time.
### Permissions
| Permission | Why |
| --- | --- |
| `activeTab` | Lets Quick look run on the current tab after you click the extension |
| `scripting` | Installs the observer in the one origin you chose and removes it when the audit stops |
| `storage` | Keeps audit state, your preferences and the reports you save |
| `sidePanel` | Shows the live view and report next to the page |
| Optional host access to `http://*/*` and `https://*/*` | Requested at run time for one origin at a time, on your click |
The extension declares no static host permission and no always-on content script. It does not request `tabs`, `webRequest`, `debugger`, `cookies` or `history`. The minimum Chrome version is 116.
### What is recorded and what is not
The About page states that Hunter records which APIs were called, how often and by which script address (origin and path only). It states that Hunter never records values: no pixels, text, coordinates, clipboard or storage contents, and no request bodies. Reports are kept only if you save them: up to 50, for 30 days, in the browser's extension storage. You can delete one report or all of them at any time.
For how Noxtica handles data in general, see [Privacy](https://noxtica.com/privacy/) and [Security](https://noxtica.com/docs/security/).
### Optional: send one report to your Noxtica workspace
Some builds can send a report you choose to your organisation's Noxtica workspace. This is off by default and never automatic. A build without this feature shows no upload control and says "This build does not upload anything".
Sending needs all of the following:
1. You turn sending on in Options and allow the browser to give Hunter access to the Noxtica ingestion endpoint (`https://ingest.noxtica.com`).
2. A workspace administrator has created a short-lived upload token in Backoffice and you have pasted it into Hunter.
3. You press **Send** on a specific report after you have seen a preview of the exact JSON.
What is sent: the report you previewed, which holds the origin and path of the audited page and of its scripts, API names and counts, and a vendor and risk summary. Query strings and fragments are removed when the report is built, and the ingestion endpoint refuses a report that still contains one. What is never sent: cookies, page content, keystrokes and API argument values. If a path itself contains a name or other identifier, it is part of the report, so read the preview before you press Send.
The token names your organisation and the administrator who created it. Every report sent with it is stored under that organisation and linked to that administrator. The token is kept in the browser's session storage for that session and used for nothing else. Reports are stored in the EU and kept for 30 days; administrators can remove them sooner in Backoffice. See [Hunter reports in Backoffice](https://noxtica.com/docs/hunter/reports/).
## Prerequisites
- A Hunter build from your account team, in a Chromium-based browser at version 116 or later.
- A normal website (`http` or `https`) open in a tab. New-tab pages, `chrome://`, `about:` and browser store pages cannot be audited.
- For sending reports: a build that includes sending, a workspace administrator with the Hunter Reports page available (see the Backoffice page), and permission to let the extension reach `https://ingest.noxtica.com`.
## Steps
### 1. Run an audit
1. Open the website you want to audit in a tab.
2. Click the Hunter icon in the toolbar. If you cannot see it, open the extensions menu and pin Hunter.
3. Optionally set **Audit length (seconds)**.
4. Press **Start audit** and accept the browser prompt for access to that site. The page reloads.
5. Use the page normally. Press **Stop** when you are done, or wait for the timer.
For a quick read without a reload, press **Quick look** instead.
### 2. Open the report
Press **View report** in the popup or **Open side panel**. The report page has the sections Summary, Risk and rating, Detections, Vendors, Script sources, Network, Bot-signal observations, Environment context, Spy health, Frames and Errors.
Open the Hunter panel in the browser developer tools before you start an audit if you also want script-code analysis. It works only while that panel is open, and script text is analysed and then discarded; only pattern names, categories and counts are kept.
### 3. Export, save or delete the report
- **Export JSON**, **Export HTML** or **Export text** downloads the report. The HTML file is self-contained and loads nothing.
- **Save report** adds it to your saved reports (up to 50, kept for 30 days). **Saved reports** lists them with their expiry date and lets you view, delete one or **Delete all**.
- Under Options you can set a default audit length and turn on **Save finished reports automatically** (off by default).
### 4. Send a report to your workspace (optional)
1. A workspace administrator creates a token: Backoffice → Session Insights → Hunter Reports → **Create upload token**, picks a lifetime (5 minutes, 15 minutes, 1 hour, 4 hours or 12 hours) and copies the token. See [Hunter reports in Backoffice](https://noxtica.com/docs/hunter/reports/).
2. In Hunter, open Options → **Send reports to your organisation (optional)**. Press **Turn on sending to this endpoint** and allow the browser prompt.
3. Paste the token under **Report token** and press **Use this token**. Hunter refuses a collector secret key (`sk_…`) and any token that is not a Hunter report token.
4. Open a report and press **Send to my organisation…**. Read **Exact JSON that will be sent**, then press **Send this report**.
To stop, press **Turn off sending and remove access**, or **Forget token**. Forgetting a token removes it from the browser; it stays valid until it expires.
Limits at the ingestion endpoint (defaults): 512 KiB per report after decompression, 200 reports per organisation per day and one report per 5 seconds per token. Hunter tries a send up to 3 times for transient failures.
## Verify it works
- After an audit, the popup shows **Last audit** with a live or finished result and the reason it ended (you stopped it, the audit length ended, the tab closed, the browser restarted or the tab moved to another site).
- The toolbar button shows the rating level, and its tooltip lists the touched and aggressive feature counts.
- The report page shows the Summary with the page, start time, duration, mode (Audit or Quick look) and a Report ID, and **Export JSON** shows exactly what was recorded.
- After **Save report**, the popup says "Saved. Saved reports: N".
- After a send, the report page says "Sent. Your organisation's Noxtica workspace stored report until ", and the saved report shows "Sent