{
  "openapi": "3.1.0",
  "info": {
    "title": "Noxtica Server API (/v1)",
    "version": "1.3.0-2026-10-27",
    "summary": "Server-to-server tenant API: device intelligence, risk scoring and agent trust, protected actions, mobile attestation and device identity, telemetry ingestion and query, and the signed webhooks that report verdicts.",
    "description": "## Scope\n\nThis specification covers the server-to-server tenant API served from\n`https://collect.noxtica.com` (production), and the dedicated ingestion host\n`https://ingest.noxtica.com`, which\nalso serve the OTLP ingestion and coding-agent read operations. Identity,\nbusiness and merchant verification (`/v1/kyc/**`, `/v1/kyb/**`,\n`/v1/kym/**`) is described by the identity verification API.\n\nRoutes used only between Noxtica's own services and by payment, email and\nlog providers (billing, checkout, internal tooling, provider callbacks) are\npresent in the machine-readable file but are not part of the public API.\n\n## Authentication\n\n- **`sk_` server API key** (`ApiKeyAuth`) — `Authorization: Bearer sk_...`,\n  checked against the scope each operation lists. Use it from your own\n  servers only.\n- **`sk_apm_` ingestion key** (`ApmIngestKeyAuth`) — accepted only by the\n  telemetry ingestion operations.\n- **`cak_` coding-agent key** (`CodingAgentKeyAuth`) — accepted only by the\n  coding-agent read operations.\n\nThe other credential types in the file (internal shared secrets, provider\nwebhook signatures, a URL-embedded token for inbound log webhooks and a\ndevice-owner boundary key) belong to routes that only Noxtica's services and\nproviders call; a tenant `sk_` key never works there.\n\n## Capability gating\n\nSome operations belong to modules or capabilities that are not enabled by\ndefault. When one is not enabled for your organisation the route answers a\n`404` with `{\"error\":\"V1 endpoint not found\",...}` (`GatedNotFound`), which\nis byte-identical to the answer for a path that does not exist — by design,\nso that a `404` cannot be used to probe what exists. On those routes a `404`\ncan therefore mean \"not enabled for this account\" as well as \"wrong URL\".\n\n## Errors\n\nEvery error response is JSON and carries `requestId`; quote it when you\ncontact support. Key-authenticated routes share these answers:\n`401 invalid_api_key` (identical for a missing, malformed, unknown, revoked\nor suspended key), `403` with `API key does not have <scope> scope`, `404`\n`V1 endpoint not found` for a gated capability, `429` when rate limited and\n`500` for an unexpected fault. Route-specific error strings are listed on\neach operation. The telemetry ingestion operations answer in the OTLP wire\nstyle instead; see their descriptions.\n\n## Rate limits\n\nRequests are rate limited per API key, per project or per source IP,\ndepending on the route. A limited request answers `429` with a\n`Retry-After` header (seconds) and\n`{\"error\":\"Rate limit exceeded\",\"retryAfter\":<n>,\"requestId\":\"...\"}`; wait\nfor `Retry-After` seconds before retrying. No `X-RateLimit-*` headers are\nsent. Limit values can differ between environments and over time, and are\nnot part of this contract.\n\n## Webhook delivery and retries\n\nNoxtica sends events to the HTTPS endpoints your organisation registers in the Backoffice\n(Integrations & API, Webhooks); an endpoint receives only the event types ticked on it. An\nendpoint URL must be HTTPS without embedded credentials and must not point at a private,\nloopback or internal address, and an organisation can register at most 25 endpoints. The\nsigning secret is shown once when the endpoint is created or rotated; a rotation invalidates\nthe old secret at once.\n\n**Request.** Each delivery is `POST` with `Content-Type: application/json` and the headers\n`X-Noxtica-Signature`, `X-Noxtica-Timestamp` (Unix **milliseconds**), `X-Noxtica-Event` and\n`X-Noxtica-Delivery`. The body is the envelope `{\"id\",\"type\",\"created_at\",\"tenant_id\",\"data\"}`:\n`id` equals `X-Noxtica-Delivery`, `created_at` is Unix milliseconds and `tenant_id` is your\norganisation. Verdict payloads carry no raw IP address and no personal data.\n\n**Signature.** `X-Noxtica-Signature` is `sha256=` plus the lowercase hex HMAC-SHA256, keyed with\nthe endpoint's secret (its UTF-8 bytes), of the string `<X-Noxtica-Timestamp>.<raw body>`.\nRecompute it over the raw body bytes before parsing the JSON, compare in constant time, and\nreject a stale timestamp (Noxtica enforces no tolerance of its own; 300 seconds is\nrecommended). Every retry is re-signed with a fresh timestamp.\n\n```js\nimport { createHmac, timingSafeEqual } from 'node:crypto';\nfunction verify(secret, timestamp, rawBody, signatureHeader) {\n  const expected = createHmac('sha256', secret).update(`${timestamp}.${rawBody}`).digest('hex');\n  const given = signatureHeader.replace(/^sha256=/, '').toLowerCase();\n  return given.length === expected.length && timingSafeEqual(Buffer.from(given), Buffer.from(expected));\n}\n```\n\n**Delivery and retries.** Delivery is at-least-once, never exactly-once: deduplicate on\n`X-Noxtica-Delivery`, which is identical on every retry of the same delivery. Answer within\n5 seconds; redirects are never followed. Any `2xx` marks the delivery delivered. **Any `4xx`\n(including `408` and `429`) is final: it is never retried.** A `3xx`, a `5xx`, a timeout or a\nnetwork error is retried, up to 5 retries after the first attempt, after which the delivery is\nrecorded as dead and is not retried again. The spacing between retries is not published.\nRespond `2xx` first and process asynchronously. Events can arrive out of order. A webhook is a\nnotification, not authority: read the resource it refers to before taking an irreversible\naction. The Backoffice \"Send test\" button sends only a sample `submission.scored` event.\n",
    "contact": {
      "name": "Noxtica Platform",
      "url": "https://noxtica.com"
    },
    "license": {
      "name": "Proprietary",
      "identifier": "LicenseRef-Proprietary"
    }
  },
  "servers": [
    {
      "url": "https://collect.noxtica.com",
      "description": "Production",
      "x-noxtica-key-prefix": "sk_prod_"
    }
  ],
  "tags": [
    {
      "name": "Devices",
      "description": "Device fingerprint lookup and listing.",
      "externalDocs": {
        "description": "Device intelligence API: reference page",
        "url": "https://noxtica.com/docs/api/reference/device/"
      }
    },
    {
      "name": "Events & Visits",
      "description": "Raw event and visit reads.",
      "externalDocs": {
        "description": "Device intelligence API: reference page",
        "url": "https://noxtica.com/docs/api/reference/device/"
      }
    },
    {
      "name": "Exports",
      "description": "Bulk export of fingerprints/events/visits/scored-events, plus the emerging-threats feed.",
      "externalDocs": {
        "description": "Device intelligence API: reference page",
        "url": "https://noxtica.com/docs/api/reference/device/"
      }
    },
    {
      "name": "APM Observability",
      "description": "Project and environment inventory, bounded APM queries, asynchronous exports and privacy-request status. Customer and general capture are not yet available; an approved proof-of-concept is limited to synthetic, no-personal-data telemetry.",
      "externalDocs": {
        "description": "Observability query API: reference page",
        "url": "https://noxtica.com/docs/api/reference/observability/"
      }
    },
    {
      "name": "APM Ingest",
      "description": "OTLP/HTTP trace, metric, log and profile ingestion, plus deployment markers. Write-only telemetry, distinct from the read-only \"APM Observability\" tag. Authenticated with an `sk_apm_` ingestion key (never a server API key) and served from the ingestion hosts, and also from the collector hosts.",
      "externalDocs": {
        "description": "Telemetry ingestion API: reference page",
        "url": "https://noxtica.com/docs/api/reference/ingest/"
      }
    },
    {
      "name": "Sealed Results",
      "description": "Cryptographically sealed high-assurance result retrieval.",
      "externalDocs": {
        "description": "Device intelligence API: reference page",
        "url": "https://noxtica.com/docs/api/reference/device/"
      }
    },
    {
      "name": "Labels",
      "description": "Ground-truth fraud/legitimate labeling.",
      "externalDocs": {
        "description": "Device intelligence API: reference page",
        "url": "https://noxtica.com/docs/api/reference/device/"
      }
    },
    {
      "name": "Generator",
      "description": "Synthetic fingerprint generation for testing/load.",
      "externalDocs": {
        "description": "Device intelligence API: reference page",
        "url": "https://noxtica.com/docs/api/reference/device/"
      }
    },
    {
      "name": "Reputation",
      "description": "Email, website and phone reputation checks.",
      "externalDocs": {
        "description": "Risk scoring and agent trust API: reference page",
        "url": "https://noxtica.com/docs/api/reference/score/"
      }
    },
    {
      "name": "Crawl Vouchers",
      "description": "Signed crawler-access vouchers.",
      "externalDocs": {
        "description": "Risk scoring and agent trust API: reference page",
        "url": "https://noxtica.com/docs/api/reference/score/"
      }
    },
    {
      "name": "Behavioral Baseline",
      "description": "Behavioral-subject baseline read and erase (not enabled by default).",
      "externalDocs": {
        "description": "Device intelligence API: reference page",
        "url": "https://noxtica.com/docs/api/reference/device/"
      }
    },
    {
      "name": "Agent Trust",
      "description": "Web Bot Auth (RFC 9421) agent verification and signed Agent Passports.",
      "externalDocs": {
        "description": "Risk scoring and agent trust API: reference page",
        "url": "https://noxtica.com/docs/api/reference/score/"
      }
    },
    {
      "name": "IP & Risk Scoring",
      "description": "Standalone IP reputation and composite risk scoring.",
      "externalDocs": {
        "description": "Risk scoring and agent trust API: reference page",
        "url": "https://noxtica.com/docs/api/reference/score/"
      }
    },
    {
      "name": "Protected Actions",
      "description": "Server-side redemption of the `requestId` a browser obtains for a declared protected action (login, signup, checkout, ...).",
      "externalDocs": {
        "description": "Protected actions API: reference page",
        "url": "https://noxtica.com/docs/api/reference/protected-actions/"
      }
    },
    {
      "name": "Device Attestation",
      "description": "Mobile platform attestation (Play Integrity / App Attest) and PoW/integrity verification.",
      "externalDocs": {
        "description": "Mobile and device identity API: reference page",
        "url": "https://noxtica.com/docs/api/reference/mobile/"
      }
    },
    {
      "name": "Web/App Integrity",
      "description": "Web/app integrity verification distinct from device attestation.",
      "externalDocs": {
        "description": "Mobile and device identity API: reference page",
        "url": "https://noxtica.com/docs/api/reference/mobile/"
      }
    },
    {
      "name": "Mobile App Config",
      "description": "Mobile app runtime configuration delivery.",
      "externalDocs": {
        "description": "Mobile and device identity API: reference page",
        "url": "https://noxtica.com/docs/api/reference/mobile/"
      }
    },
    {
      "name": "Passkey",
      "description": "WebAuthn passkey challenge, register and assert (not enabled by default).",
      "externalDocs": {
        "description": "Mobile and device identity API: reference page",
        "url": "https://noxtica.com/docs/api/reference/mobile/"
      }
    },
    {
      "name": "Device Handoff",
      "description": "Cross-device session handoff mint and consume (not enabled by default).",
      "externalDocs": {
        "description": "Mobile and device identity API: reference page",
        "url": "https://noxtica.com/docs/api/reference/mobile/"
      }
    },
    {
      "name": "Device Delegation",
      "description": "Subject-scoped device delegation lifecycle (write:identity, not enabled by default).",
      "externalDocs": {
        "description": "Mobile and device identity API: reference page",
        "url": "https://noxtica.com/docs/api/reference/mobile/"
      }
    },
    {
      "name": "Account Recovery",
      "description": "Account-recovery case and appeal lifecycle (write:identity, not enabled by default).",
      "externalDocs": {
        "description": "Mobile and device identity API: reference page",
        "url": "https://noxtica.com/docs/api/reference/mobile/"
      }
    },
    {
      "name": "Wallet Status",
      "description": "Device-bound wallet status and suspend operations (write:identity, not enabled by default).",
      "externalDocs": {
        "description": "Mobile and device identity API: reference page",
        "url": "https://noxtica.com/docs/api/reference/mobile/"
      }
    },
    {
      "name": "Offline Capture",
      "description": "Offline-first nonce pool and capture-bundle intake.",
      "externalDocs": {
        "description": "Mobile and device identity API: reference page",
        "url": "https://noxtica.com/docs/api/reference/mobile/"
      }
    },
    {
      "name": "Coding Agent",
      "description": "Read-only access for coding agents to your organisation's recent errors, traces and signals, authenticated with a `cak_` key on the ingestion hosts.",
      "externalDocs": {
        "description": "Observability query API: reference page",
        "url": "https://noxtica.com/docs/api/reference/observability/"
      }
    },
    {
      "name": "Health and Keys",
      "description": "The unauthenticated collector health probe and the public signing-key documents used to verify signed envelopes offline.",
      "externalDocs": {
        "description": "Health and public key endpoints: reference page",
        "url": "https://noxtica.com/docs/api/reference/status/"
      }
    },
    {
      "name": "Verdict Webhooks",
      "description": "Signed events Noxtica POSTs to your registered endpoints when a submission is scored, flagged, or linked to an agent (documented in the top-level `webhooks` section).",
      "externalDocs": {
        "description": "Device intelligence API: reference page",
        "url": "https://noxtica.com/docs/api/reference/device/"
      }
    }
  ],
  "paths": {
    "/v1/device/{deviceId}": {
      "get": {
        "operationId": "v1GetDevice",
        "tags": [
          "Devices"
        ],
        "summary": "Look up a device by ID",
        "description": "Returns the current score and risk projection of one device — the `fingerprintId` your browser or mobile integration received — scoped to the calling organisation.\n\nThe route answers `404` with `{\"error\":\"Device not found\",\"deviceId\":\"...\",\"requestId\":\"...\"}` when the device is unknown, belongs to another organisation, or has not been seen within your organisation's configured retention window.\n\n- `reasonCodes` is the published, non-personal reason-code projection of the internal flags. It is an empty array unless reason-code output is enabled for your organisation, independently of the raw `flags` field.\n- `gpuAttestationTier` is masked: a stored `hardware` or `software` tier is reported as `attested` unless publication of the hardware attestation level is enabled for your organisation. `gpuVerified` is not masked and never asserts `hardware`.\n- `subscores` and `details` are the scorer's per-domain breakdown when present, otherwise `null`. `softwareSubfp`, `hardwareSubfp` and `environmentSubfp` are server-derived observational sub-fingerprints; they are `null` for devices recorded before those fields existed.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:device"
            ]
          }
        ],
        "parameters": [
          {
            "name": "deviceId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The `device_id` to look up (URL-decoded from the path segment)."
          }
        ],
        "responses": {
          "200": {
            "description": "The device's current score/risk projection.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "device"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "device": {
                      "type": "object",
                      "properties": {
                        "deviceId": {
                          "type": "string"
                        },
                        "domainId": {
                          "type": "string"
                        },
                        "score": {
                          "type": "number"
                        },
                        "riskLevel": {
                          "type": "string"
                        },
                        "confidence": {
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "flags": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "reasonCodes": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Empty unless reason-code output is enabled for your organisation."
                        },
                        "subscores": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "additionalProperties": true
                        },
                        "details": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "additionalProperties": true
                        },
                        "country": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "city": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "lastSubmittedAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        },
                        "lastSeenAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        },
                        "gpuVerified": {
                          "type": "boolean"
                        },
                        "gpuAttestationTier": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "attested",
                            "suspicious",
                            "unavailable",
                            "failed",
                            "hardware",
                            "software"
                          ],
                          "description": "Masked unless publication of the hardware attestation level is enabled for your organisation; see description above."
                        },
                        "softwareSubfp": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "hardwareSubfp": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "environmentSubfp": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      }
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "device": {
                    "deviceId": "dev_7a2b9c4d1e6f3a8b5c2d9e4f7a1b6c3d",
                    "domainId": "dom_3f2a8c91d6e5f470",
                    "score": 1,
                    "riskLevel": "low",
                    "confidence": 1,
                    "flags": [
                      "example-flags"
                    ],
                    "reasonCodes": [
                      "example-reasonCodes"
                    ],
                    "subscores": {},
                    "details": {},
                    "country": "US",
                    "city": "Istanbul",
                    "createdAt": "2026-09-13T12:00:00.000Z",
                    "updatedAt": "2026-09-13T12:00:00.000Z",
                    "lastSubmittedAt": "2026-09-13T12:00:00.000Z",
                    "lastSeenAt": "2026-09-13T12:00:00.000Z",
                    "gpuVerified": true,
                    "gpuAttestationTier": "attested",
                    "softwareSubfp": "example-softwareSubfp",
                    "hardwareSubfp": "example-hardwareSubfp",
                    "environmentSubfp": "example-environmentSubfp"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Missing/empty `deviceId`, or the path segment failed URL-decoding.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "404": {
            "description": "`{ error: 'Device not found', deviceId, requestId }` — tenant projection inactive/missing OR the row is absent/outside the retention window.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "Device not found"
                      ]
                    },
                    "deviceId": {
                      "type": "string"
                    },
                    "requestId": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "Device not found",
                  "deviceId": "dev_7a2b9c4d1e6f3a8b5c2d9e4f7a1b6c3d",
                  "requestId": "req-test"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/devices": {
      "get": {
        "operationId": "v1ListDevices",
        "tags": [
          "Devices"
        ],
        "summary": "List devices",
        "description": "Lists devices, most recently updated first, with filters and keyset pagination. `from` and `to` bound the range and may span at most 400 days. `source` selects real devices, synthetic devices (see the generator operations) or both; `all` merges both result sets by `(updated_at, device_id)` descending.\n\n`cursor` is opaque: pass the `nextCursor` of the previous page back unchanged and never construct one. `limit` defaults to 50 and is capped at 200.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:fingerprints"
            ]
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 200
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Opaque keyset cursor from a prior response's `nextCursor`."
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Defaults to 400 days before now."
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Defaults to now."
          },
          {
            "name": "domain_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "risk_level",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filter by risk level; the allowed set is deps-injected (`riskLevelFilterValues`)."
          },
          {
            "name": "source",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "real",
                "synthetic",
                "all"
              ],
              "default": "real"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of devices.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "devices",
                    "hasMore",
                    "nextCursor"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "devices": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "deviceId": {
                            "type": "string"
                          },
                          "domainId": {
                            "type": "string"
                          },
                          "score": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "riskLevel": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "flags": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "country": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "updatedAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "isSynthetic": {
                            "type": "boolean"
                          }
                        }
                      }
                    },
                    "hasMore": {
                      "type": "boolean"
                    },
                    "nextCursor": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "devices": [
                    {
                      "deviceId": "dev_7a2b9c4d1e6f3a8b5c2d9e4f7a1b6c3d",
                      "domainId": "dom_3f2a8c91d6e5f470",
                      "score": 1,
                      "riskLevel": "low",
                      "flags": [
                        "example-flags"
                      ],
                      "country": "US",
                      "createdAt": "2026-09-13T12:00:00.000Z",
                      "updatedAt": "2026-09-13T12:00:00.000Z",
                      "isSynthetic": true
                    }
                  ],
                  "hasMore": true,
                  "nextCursor": "cursor_000123"
                }
              }
            }
          },
          "400": {
            "description": "`Invalid source`, `Invalid risk_level`, or `Invalid date range` (bad/inverted/over-400-day `from`/`to`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "description": "`{ error: 'Failed to query devices', code: 'devices_list_query_failed' }` on a warehouse fault, or a generic internal error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/accounts/{accountHash}/devices": {
      "get": {
        "operationId": "v1ListAccountDevices",
        "tags": [
          "Devices"
        ],
        "summary": "List devices linked to an account",
        "description": "Lists the devices and agents linked to one of your end-user accounts, with their current score and risk only. `accountHash` must be the keyed 16-character lowercase-hex pseudonym your organisation already receives elsewhere (for example the `account_hash` filter of `GET /v1/events`); a raw account id is never accepted on this path.\n\nPagination is a keyset cursor over `(last_seen_at, id)` descending, with the same opaque cursor shape as `GET /v1/events`.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:fingerprints"
            ]
          }
        ],
        "parameters": [
          {
            "name": "accountHash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-f]{16}$"
            },
            "description": "The keyed 16-hex-lowercase account pseudonym."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 200
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The account's linked device/agent history.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "accountHash",
                    "links",
                    "hasMore",
                    "nextCursor"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "accountHash": {
                      "type": "string"
                    },
                    "links": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "agentKeyid": {
                            "type": "string"
                          },
                          "agentHost": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "deviceId": {
                            "type": "string"
                          },
                          "domainId": {
                            "type": "string"
                          },
                          "firstSeenAt": {
                            "type": "integer",
                            "description": "Epoch ms."
                          },
                          "lastSeenAt": {
                            "type": "integer",
                            "description": "Epoch ms."
                          },
                          "seenCount": {
                            "type": "integer"
                          },
                          "deviceScore": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "deviceRiskLevel": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "deviceUpdatedAt": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        }
                      }
                    },
                    "hasMore": {
                      "type": "boolean"
                    },
                    "nextCursor": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "accountHash": "a1b2c3d4e5f60718293a4b5c6d7e8f901a2b3c4d5e6f708192a3b4c5d6e7f89",
                  "links": [
                    {
                      "agentKeyid": "example-agentKeyid",
                      "agentHost": "example-agentHost",
                      "deviceId": "dev_7a2b9c4d1e6f3a8b5c2d9e4f7a1b6c3d",
                      "domainId": "dom_3f2a8c91d6e5f470",
                      "firstSeenAt": 1,
                      "lastSeenAt": 1,
                      "seenCount": 1,
                      "deviceScore": 1,
                      "deviceRiskLevel": "example-deviceRiskLevel",
                      "deviceUpdatedAt": "example-deviceUpdatedAt"
                    }
                  ],
                  "hasMore": true,
                  "nextCursor": "cursor_000123"
                }
              }
            }
          },
          "400": {
            "description": "`accountHash` fails the 16-hex-lowercase shape check.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "description": "`{ error: 'Failed to query account devices', code: 'account_devices_query_failed' }` or a generic internal error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/events": {
      "get": {
        "operationId": "v1ListEvents",
        "tags": [
          "Events & Visits"
        ],
        "summary": "List scoring events",
        "description": "Lists scored events, newest first, with a keyset cursor over `(created_at, id)`. The optional `account_hash` filter (a keyed 16-character lowercase-hex pseudonym) applies to `source=real` only: synthetic events and the merged `all` view carry no `account_hash`.\n\n`reasonCodes` is the published reason-code projection of the event's internal flags; it is empty unless reason-code output is enabled for your organisation.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:events"
            ]
          }
        ],
        "parameters": [
          {
            "name": "device_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "domain_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "account_hash",
            "in": "query",
            "schema": {
              "type": "string",
              "pattern": "^[0-9a-f]{16}$"
            },
            "description": "Applied only when `source` resolves to `real`."
          },
          {
            "name": "source",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "real",
                "synthetic",
                "all"
              ],
              "default": "real"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 200
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of events.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "events",
                    "hasMore",
                    "nextCursor"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "events": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "deviceId": {
                            "type": "string"
                          },
                          "domainId": {
                            "type": "string"
                          },
                          "score": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "riskLevel": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "confidence": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "flags": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "reasonCodes": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "country": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "payloadUnavailable": {
                            "type": [
                              "boolean",
                              "null"
                            ]
                          },
                          "isSynthetic": {
                            "type": "boolean"
                          }
                        }
                      }
                    },
                    "hasMore": {
                      "type": "boolean"
                    },
                    "nextCursor": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "events": [
                    {
                      "id": "example-id",
                      "deviceId": "dev_7a2b9c4d1e6f3a8b5c2d9e4f7a1b6c3d",
                      "domainId": "dom_3f2a8c91d6e5f470",
                      "score": 1,
                      "riskLevel": "low",
                      "confidence": 1,
                      "flags": [
                        "example-flags"
                      ],
                      "reasonCodes": [
                        "example-reasonCodes"
                      ],
                      "country": "US",
                      "createdAt": "2026-09-13T12:00:00.000Z",
                      "payloadUnavailable": true,
                      "isSynthetic": true
                    }
                  ],
                  "hasMore": true,
                  "nextCursor": "cursor_000123"
                }
              }
            }
          },
          "400": {
            "description": "`Invalid source`, or `account_hash` fails the 16-hex-lowercase shape check.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/visits": {
      "get": {
        "operationId": "v1ListVisits",
        "tags": [
          "Events & Visits"
        ],
        "summary": "List visits",
        "description": "Lists visit records, newest first, with a keyset cursor over `(created_at, id)`. Visits have no synthetic partition, so this route has no `source` filter. `meta` is the visit's own parsed JSON metadata and includes `external_user_id` when the submitting page set it.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:visits"
            ]
          }
        ],
        "parameters": [
          {
            "name": "device_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "domain_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "external_user_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 200
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of visits.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "visits",
                    "hasMore",
                    "nextCursor"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "visits": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "deviceId": {
                            "type": "string"
                          },
                          "domainId": {
                            "type": "string"
                          },
                          "country": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "city": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "meta": {
                            "type": "object",
                            "additionalProperties": true,
                            "description": "The row's own parsed JSON `meta` blob (e.g. `external_user_id`); shape is submitter-controlled and not locally validated."
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    },
                    "hasMore": {
                      "type": "boolean"
                    },
                    "nextCursor": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "visits": [
                    {
                      "id": "example-id",
                      "deviceId": "dev_7a2b9c4d1e6f3a8b5c2d9e4f7a1b6c3d",
                      "domainId": "dom_3f2a8c91d6e5f470",
                      "country": "US",
                      "city": "Istanbul",
                      "meta": {},
                      "createdAt": "2026-09-13T12:00:00.000Z"
                    }
                  ],
                  "hasMore": true,
                  "nextCursor": "cursor_000123"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/exports/fingerprints": {
      "get": {
        "operationId": "v1ExportFingerprints",
        "tags": [
          "Exports"
        ],
        "summary": "Export fingerprints as CSV or JSON",
        "description": "Bulk-exports device fingerprint records for a date range. `from` and `to` are required and are validated for both shape and calendar (a malformed string or an impossible date such as `2026-02-30` is rejected) before being echoed into the CSV `Content-Disposition` filename.\n\nEach request returns at most a fixed maximum number of rows. A capped page sets `truncated: true` (JSON) or the `X-Noxtica-Export-Truncated: true` header (CSV) and an opaque keyset `next_cursor` (JSON) or `X-Noxtica-Export-Next-Cursor` header (CSV) over `(created_at, id)` descending; request the next page with that cursor.\n\n`reason_codes` is the published reason-code projection (empty unless reason-code output is enabled for your organisation) and is the last CSV column, so fixed-position consumers are unaffected.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:export"
            ]
          }
        ],
        "parameters": [
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "json",
                "csv"
              ],
              "default": "json"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "REQUIRED. `YYYY-MM-DD`, `YYYY-MM-DD HH:MM:SS`, or ISO 8601 (optional ms/offset)."
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "domain_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "source",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "real",
                "synthetic",
                "all"
              ],
              "default": "real"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Opaque keyset cursor from a prior response's `next_cursor`. Omit for page 1."
          }
        ],
        "responses": {
          "200": {
            "description": "The exported page, as a JSON envelope or a raw CSV body depending on `format`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "count",
                    "limit",
                    "truncated",
                    "from",
                    "to",
                    "fingerprints"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "count": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "truncated": {
                      "type": "boolean"
                    },
                    "from": {
                      "type": "string"
                    },
                    "to": {
                      "type": "string"
                    },
                    "next_cursor": {
                      "type": "string"
                    },
                    "fingerprints": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "device_id": {
                            "type": "string"
                          },
                          "domain_id": {
                            "type": "string"
                          },
                          "score": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "risk_level": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "flags": {
                            "type": "string",
                            "description": "Semicolon-joined."
                          },
                          "reason_codes": {
                            "type": "string",
                            "description": "Semicolon-joined; empty unless reason-code output is enabled for your organisation."
                          },
                          "country": {
                            "type": "string"
                          },
                          "city": {
                            "type": "string"
                          },
                          "created_at": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "updated_at": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "is_synthetic": {
                            "type": "string",
                            "enum": [
                              "true",
                              "false"
                            ]
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "count": 1,
                  "limit": 1,
                  "truncated": true,
                  "from": "example-from",
                  "to": "example-to",
                  "next_cursor": "cursor_000123",
                  "fingerprints": [
                    {
                      "device_id": "dev_7a2b9c4d1e6f3a8b5c2d9e4f7a1b6c3d",
                      "domain_id": "dom_3f2a8c91d6e5f470",
                      "score": 1,
                      "risk_level": "low",
                      "flags": "example-flags",
                      "reason_codes": "example-reason_codes",
                      "country": "US",
                      "city": "Istanbul",
                      "created_at": "2026-09-13T12:00:00.000Z",
                      "updated_at": "2026-09-13T12:00:00.000Z",
                      "is_synthetic": "true"
                    }
                  ]
                }
              },
              "text/csv": {
                "schema": {
                  "type": "string"
                },
                "example": "example-v1ExportFingerprints"
              }
            },
            "headers": {
              "X-Noxtica-Export-Truncated": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "true",
                    "false"
                  ]
                }
              },
              "X-Noxtica-Export-Next-Cursor": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "`Invalid source`/`Invalid format`, missing `from`/`to`, or `from and to must be YYYY-MM-DD or ISO 8601 datetime values`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/exports/events": {
      "get": {
        "operationId": "v1ExportEvents",
        "tags": [
          "Exports"
        ],
        "summary": "Export events as CSV or JSON",
        "description": "Bulk-exports scored events for a date range. The contract is identical to `GET /v1/exports/fingerprints`: the same date validation, per-request row cap, and `truncated` / `next_cursor` pagination.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:export"
            ]
          }
        ],
        "parameters": [
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "json",
                "csv"
              ],
              "default": "json"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "domain_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "source",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "real",
                "synthetic",
                "all"
              ],
              "default": "real"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The exported page, as a JSON envelope or a raw CSV body depending on `format`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "count",
                    "limit",
                    "truncated",
                    "from",
                    "to",
                    "events"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "count": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "truncated": {
                      "type": "boolean"
                    },
                    "from": {
                      "type": "string"
                    },
                    "to": {
                      "type": "string"
                    },
                    "next_cursor": {
                      "type": "string"
                    },
                    "events": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "device_id": {
                            "type": "string"
                          },
                          "domain_id": {
                            "type": "string"
                          },
                          "score": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "risk_level": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "reason_codes": {
                            "type": "string",
                            "description": "Semicolon-joined; empty unless reason-code output is enabled for your organisation."
                          },
                          "country": {
                            "type": "string"
                          },
                          "created_at": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "is_synthetic": {
                            "type": "string",
                            "enum": [
                              "true",
                              "false"
                            ]
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "count": 1,
                  "limit": 1,
                  "truncated": true,
                  "from": "example-from",
                  "to": "example-to",
                  "next_cursor": "cursor_000123",
                  "events": [
                    {
                      "id": "example-id",
                      "device_id": "dev_7a2b9c4d1e6f3a8b5c2d9e4f7a1b6c3d",
                      "domain_id": "dom_3f2a8c91d6e5f470",
                      "score": 1,
                      "risk_level": "low",
                      "reason_codes": "example-reason_codes",
                      "country": "US",
                      "created_at": "2026-09-13T12:00:00.000Z",
                      "is_synthetic": "true"
                    }
                  ]
                }
              },
              "text/csv": {
                "schema": {
                  "type": "string"
                },
                "example": "example-v1ExportEvents"
              }
            },
            "headers": {
              "X-Noxtica-Export-Truncated": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "true",
                    "false"
                  ]
                }
              },
              "X-Noxtica-Export-Next-Cursor": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "`Invalid source`/`Invalid format`, missing `from`/`to`, or invalid date shape/calendar.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/exports/visits": {
      "get": {
        "operationId": "v1ExportVisits",
        "tags": [
          "Exports"
        ],
        "summary": "Export visits as CSV or JSON",
        "description": "Bulk-exports visit records for a date range, with the same date validation, per-request row cap and pagination as the other exports. Visits have no synthetic partition, so there is no `source` parameter.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:export"
            ]
          }
        ],
        "parameters": [
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "json",
                "csv"
              ],
              "default": "json"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "domain_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The exported page, as a JSON envelope or a raw CSV body depending on `format`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "count",
                    "limit",
                    "truncated",
                    "from",
                    "to",
                    "visits"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "count": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "truncated": {
                      "type": "boolean"
                    },
                    "from": {
                      "type": "string"
                    },
                    "to": {
                      "type": "string"
                    },
                    "next_cursor": {
                      "type": "string"
                    },
                    "visits": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "device_id": {
                            "type": "string"
                          },
                          "domain_id": {
                            "type": "string"
                          },
                          "country": {
                            "type": "string"
                          },
                          "city": {
                            "type": "string"
                          },
                          "external_user_id": {
                            "type": "string"
                          },
                          "created_at": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "count": 1,
                  "limit": 1,
                  "truncated": true,
                  "from": "example-from",
                  "to": "example-to",
                  "next_cursor": "cursor_000123",
                  "visits": [
                    {
                      "id": "example-id",
                      "device_id": "dev_7a2b9c4d1e6f3a8b5c2d9e4f7a1b6c3d",
                      "domain_id": "dom_3f2a8c91d6e5f470",
                      "country": "US",
                      "city": "Istanbul",
                      "external_user_id": "example-external_user_id",
                      "created_at": "2026-09-13T12:00:00.000Z"
                    }
                  ]
                }
              },
              "text/csv": {
                "schema": {
                  "type": "string"
                },
                "example": "example-v1ExportVisits"
              }
            },
            "headers": {
              "X-Noxtica-Export-Truncated": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "true",
                    "false"
                  ]
                }
              },
              "X-Noxtica-Export-Next-Cursor": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "`Invalid format`, missing `from`/`to`, or invalid date shape/calendar.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/exports/scored-events": {
      "get": {
        "operationId": "v1ExportScoredEvents",
        "tags": [
          "Exports"
        ],
        "summary": "Stream scored events as JSON Lines",
        "description": "Streams scored events as newline-delimited JSON, newest first: one scored-event object per line, followed by a trailing `_summary` line. The stream is capped at a fixed maximum number of rows per request.\n\n- `tier` is coarser than `gpuAttestationTier` on `GET /v1/device/{deviceId}`: only a hardware-attested device maps to `attested`; everything else is `suspicious`.\n- `band` is one of `critical`, `high`, `medium`, `low`, `minimal`; an unrecognised stored value is reported as `minimal`.\n- `reason_codes` holds at most 64 entries and is empty unless reason-code output is enabled for your organisation.\n\nThis route validates the shape of `from` and `to` only, not calendar validity, unlike the JSON/CSV exports.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:export"
            ]
          }
        ],
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "REQUIRED. `YYYY-MM-DD`, `YYYY-MM-DD HH:MM:SS`, or ISO 8601."
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "domain_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Opaque keyset cursor from a prior response's `next_cursor` (in the trailing `_summary` line). No cursor param on page 1."
          }
        ],
        "responses": {
          "200": {
            "description": "JSONL body: one scored-event object per line, then a trailing `_summary` line.",
            "content": {
              "application/x-ndjson": {
                "schema": {
                  "type": "string",
                  "description": "Newline-delimited JSON. Each event line: `{id, device_id, domain_id, score, tier, band, confidence, reason_codes, created_at}`. The final line is always `{_summary: true, count, from, to, explainabilityEnabled, limit, truncated, next_cursor?}`."
                },
                "example": "example-v1ExportScoredEvents"
              }
            },
            "headers": {
              "X-Noxtica-Export-Truncated": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "true",
                    "false"
                  ]
                }
              },
              "X-Noxtica-Export-Next-Cursor": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "Missing `from`/`to`, or a value not matching the accepted date shape (this route validates SHAPE only, not calendar validity, unlike the sibling JSON/CSV exports).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/emerging-threats": {
      "get": {
        "operationId": "v1GetEmergingThreats",
        "tags": [
          "Exports"
        ],
        "summary": "Read reason-code firing counts",
        "description": "Returns per-reason-code firing counts and rates over a bounded lookback window, aggregated from the published reason-code catalogue. It reuses the `read:export` scope.\n\nThe report is disabled unless it is enabled for the deployment. When it is, the route does no warehouse work and answers a neutral `200` with `{\"available\":false,\"reason\":\"feature_unavailable\",\"signals\":[]}`, so you can always probe it safely. A warehouse read fault degrades to an empty `signals` array and `window_sessions: 0`; this route never answers `500` for it.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:export"
            ]
          }
        ],
        "parameters": [
          {
            "name": "window",
            "in": "query",
            "schema": {
              "type": "integer",
              "enum": [
                1,
                6,
                24,
                168,
                720
              ],
              "default": 24
            },
            "description": "Lookback hours; any other value silently falls back to 24."
          }
        ],
        "responses": {
          "200": {
            "description": "The firing-count report, or the feature-disabled neutral empty state.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "available",
                    "window_hours",
                    "signals",
                    "count"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "available": {
                      "type": "boolean"
                    },
                    "reason": {
                      "type": "string",
                      "enum": [
                        "feature_unavailable"
                      ]
                    },
                    "window_hours": {
                      "type": "integer"
                    },
                    "window_sessions": {
                      "type": "integer",
                      "description": "Present only when available is true."
                    },
                    "signals": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "reason_code": {
                            "type": "string"
                          },
                          "domain": {
                            "type": "string"
                          },
                          "label": {
                            "type": "string"
                          },
                          "firing_count": {
                            "type": "integer"
                          },
                          "firing_rate": {
                            "type": [
                              "number",
                              "null"
                            ],
                            "description": "`null` when `window_sessions` is below the 20-session display floor."
                          }
                        }
                      }
                    },
                    "count": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "available": true,
                  "reason": "feature_unavailable",
                  "window_hours": 1,
                  "window_sessions": 1,
                  "signals": [
                    {
                      "reason_code": "example-reason_code",
                      "domain": "app.example.com",
                      "label": "example-label",
                      "firing_count": 1,
                      "firing_rate": 1
                    }
                  ],
                  "count": 1
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/sealed-results/key": {
      "get": {
        "operationId": "v1GetSealedResultsKey",
        "tags": [
          "Sealed Results"
        ],
        "summary": "Fetch the key that opens Sealed Client Results",
        "description": "Returns your organisation's symmetric key for opening Sealed Client Results envelopes. The key is derived on demand and never stored.\n\n`keyVersion` is optional. Each sealed envelope carries the cleartext `kv` (key version) it was sealed under, and this route serves any past version that has not been revoked, so rotation never orphans an archived envelope. `expiresAt` is present only when a key lifetime is configured.\n\n- `404 sealed_key_version_unavailable` — `keyVersion` is not a positive integer or is newer than the current version. No key material is returned.\n- `403` — the key lacks `read:sealed_results`, or the key is revoked for this organisation and version.\n- `500 server_misconfigured` — sealed results are not provisioned for this deployment; this is distinct from an authentication failure.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:sealed_results"
            ]
          }
        ],
        "parameters": [
          {
            "name": "keyVersion",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[1-9][0-9]{0,8}$"
            },
            "description": "Key version to fetch — the `kv` a Sealed Client Result envelope carries. Omitted = the current version (the response is unchanged). A past version is served from the server's master ring until it is REVOKED for the tenant (`403`, as for the current version). A malformed or future version answers `404 sealed_key_version_unavailable`."
          }
        ],
        "responses": {
          "200": {
            "description": "The tenant's sealed-results key material.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "keyVersion",
                    "key",
                    "alg",
                    "envelope"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "keyVersion": {
                      "type": "string"
                    },
                    "key": {
                      "type": "string",
                      "description": "base64-encoded raw derived key."
                    },
                    "alg": {
                      "type": "string"
                    },
                    "envelope": {
                      "type": "string",
                      "enum": [
                        "noxtica-sealed-v1"
                      ]
                    },
                    "expiresAt": {
                      "type": "integer",
                      "description": "Absolute epoch-ms expiry hint; present only when a TTL is configured."
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "keyVersion": "example-keyVersion",
                  "key": "example-key",
                  "alg": "example-alg",
                  "envelope": "noxtica-sealed-v1",
                  "expiresAt": 1768435200
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "description": "`API key does not have read:sealed_results scope`, OR the sealed-results key is revoked for this tenant/version (`sealed-results key revoked for this tenant/version`).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "requestId": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "404": {
            "description": "`sealed_key_version_unavailable` — the requested `keyVersion` is not a positive integer, or is newer than the current key version. Explicit (never a 500); no key material is returned.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "code"
                  ],
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "enum": [
                        "sealed_key_version_unavailable"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "sealed-results key version unavailable",
                  "code": "sealed_key_version_unavailable",
                  "requestId": "req-test"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/labels": {
      "get": {
        "operationId": "v1ListLabels",
        "tags": [
          "Labels"
        ],
        "summary": "List your organisation's ground-truth labels",
        "description": "Lists the labels your organisation has written with `POST /v1/labels`, with optional `device_id` and `label` filters and a keyset cursor over `(created_at, id)` (the same opaque cursor shape as `GET /v1/events`). It reuses the `read:device` scope; there is no separate read-labels scope.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:device"
            ]
          }
        ],
        "parameters": [
          {
            "name": "device_id",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "label",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "bot",
                "human",
                "fraud",
                "legit",
                "unknown"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 200
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of labels.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "labels",
                    "hasMore",
                    "nextCursor"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "labels": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "deviceId": {
                            "type": "string"
                          },
                          "eventId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "label": {
                            "type": "string",
                            "enum": [
                              "bot",
                              "human",
                              "fraud",
                              "legit",
                              "unknown"
                            ]
                          },
                          "source": {
                            "type": "string"
                          },
                          "note": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "updatedAt": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    },
                    "hasMore": {
                      "type": "boolean"
                    },
                    "nextCursor": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "labels": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "deviceId": "dev_7a2b9c4d1e6f3a8b5c2d9e4f7a1b6c3d",
                      "eventId": "evt_3c9b2f7e4a3d4c8e9f1a2b3c4d5e6f70",
                      "label": "bot",
                      "source": "example-source",
                      "note": "created via API",
                      "createdAt": "2026-09-13T12:00:00.000Z",
                      "updatedAt": "2026-09-13T12:00:00.000Z"
                    }
                  ],
                  "hasMore": true,
                  "nextCursor": "cursor_000123"
                }
              }
            }
          },
          "400": {
            "description": "`Invalid label. Expected one of: bot, human, fraud, legit, unknown`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "x-noxtica-status": "available"
      },
      "post": {
        "operationId": "v1WriteLabel",
        "tags": [
          "Labels"
        ],
        "summary": "Write a ground-truth label for a device",
        "description": "Records a confirmed fraud, legitimate or other label for a device, optionally scoped to one event, to calibrate scoring. The write is an upsert: repeating the same `(device_id, event_id)` updates `label`, `source`, `note` and `updated_at` on the existing row instead of creating a duplicate.\n\nThe body accepts only `device_id`, `label`, `event_id`, `note` and `source`; any other key is rejected with `400 Unknown field`. `label` must be one of `bot`, `human`, `fraud`, `legit`, `unknown`.",
        "security": [
          {
            "ApiKeyAuth": [
              "write:labels"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "device_id",
                  "label"
                ],
                "additionalProperties": false,
                "properties": {
                  "device_id": {
                    "type": "string",
                    "maxLength": 256
                  },
                  "label": {
                    "type": "string",
                    "enum": [
                      "bot",
                      "human",
                      "fraud",
                      "legit",
                      "unknown"
                    ]
                  },
                  "event_id": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 256,
                    "description": "Optional; blank/whitespace-only normalizes to NULL (collapses onto the device-level idempotency slot)."
                  },
                  "note": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 1024
                  },
                  "source": {
                    "type": "string",
                    "maxLength": 64,
                    "default": "api",
                    "description": "Truncated to 64 chars; defaults to 'api' when omitted/blank."
                  }
                }
              },
              "example": {
                "device_id": "dev_7a2b9c4d1e6f3a8b5c2d9e4f7a1b6c3d",
                "label": "bot",
                "event_id": "evt_3c9b2f7e4a3d4c8e9f1a2b3c4d5e6f70",
                "note": "created via API",
                "source": "api"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The upserted (inserted or updated) label row.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "label"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "label": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "deviceId": {
                          "type": "string"
                        },
                        "eventId": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "label": {
                          "type": "string",
                          "enum": [
                            "bot",
                            "human",
                            "fraud",
                            "legit",
                            "unknown"
                          ]
                        },
                        "source": {
                          "type": "string"
                        },
                        "note": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "label": {
                    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                    "deviceId": "dev_7a2b9c4d1e6f3a8b5c2d9e4f7a1b6c3d",
                    "eventId": "evt_3c9b2f7e4a3d4c8e9f1a2b3c4d5e6f70",
                    "label": "bot",
                    "source": "example-source",
                    "note": "created via API",
                    "createdAt": "2026-09-13T12:00:00.000Z",
                    "updatedAt": "2026-09-13T12:00:00.000Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Unknown body field, missing/oversized `device_id`, invalid `label`, or an oversized `event_id`/`note`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "413": {
            "$ref": "#/components/responses/BodyTooLarge"
          },
          "415": {
            "description": "`Content-Type must be application/json`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/generator/fingerprints": {
      "post": {
        "operationId": "v1GenerateFingerprintBatch",
        "tags": [
          "Generator"
        ],
        "summary": "Generate a batch of synthetic devices",
        "description": "Generates `count` synthetic devices, each with `eventsPerDevice` events, derived deterministically from real template fingerprints, for testing and load. Read them back with `source=synthetic`.\n\nThe call is idempotent on `(domain_id, seed)`: a repeated identical request returns the same existing batch with `isExisting: true` and HTTP `200`; a new batch answers `201`. `domain_id` must be an active domain of your organisation, otherwise the route answers `404`.",
        "security": [
          {
            "ApiKeyAuth": [
              "write:generate"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "domain_id",
                  "seed"
                ],
                "properties": {
                  "domain_id": {
                    "type": "string"
                  },
                  "seed": {
                    "type": "string",
                    "description": "Idempotency key for the whole batch."
                  },
                  "count": {
                    "type": "integer",
                    "default": 10,
                    "minimum": 1,
                    "maximum": 100,
                    "description": "Coerced via Number(); non-positive/non-finite falls back to 10."
                  },
                  "eventsPerDevice": {
                    "type": "integer",
                    "default": 3,
                    "minimum": 1,
                    "maximum": 10
                  },
                  "sourceFrom": {
                    "type": "string"
                  },
                  "sourceTo": {
                    "type": "string"
                  },
                  "sourceLimit": {
                    "type": "integer",
                    "default": 200,
                    "maximum": 500
                  },
                  "scrubIPs": {
                    "type": "boolean",
                    "default": true,
                    "description": "Any value other than the literal `false` is treated as true."
                  }
                }
              },
              "example": {
                "domain_id": "dom_3f2a8c91d6e5f470",
                "seed": "seed-01",
                "count": 10,
                "eventsPerDevice": 3,
                "sourceFrom": "example-sourceFrom",
                "sourceTo": "example-sourceTo",
                "sourceLimit": 200,
                "scrubIPs": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The existing batch, when `seed` already matches a committed batch for this `(tenant, domain)`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "isExisting",
                    "batchId",
                    "seed",
                    "tenantId",
                    "domainId",
                    "deviceIds",
                    "totalDevices",
                    "totalEvents",
                    "createdAt"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "isExisting": {
                      "type": "boolean"
                    },
                    "batchId": {
                      "type": "string"
                    },
                    "seed": {
                      "type": "string"
                    },
                    "tenantId": {
                      "type": "string"
                    },
                    "domainId": {
                      "type": "string"
                    },
                    "deviceIds": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "totalDevices": {
                      "type": "integer"
                    },
                    "totalEvents": {
                      "type": "integer"
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "isExisting": true,
                  "batchId": "batch_5a1f9c3e7b2d4a6f8091c2d3e4f5a6b7",
                  "seed": "seed-01",
                  "tenantId": "tenant_42",
                  "domainId": "dom_3f2a8c91d6e5f470",
                  "deviceIds": [
                    "example-deviceIds"
                  ],
                  "totalDevices": 1,
                  "totalEvents": 1,
                  "createdAt": "2026-09-13T12:00:00.000Z"
                }
              }
            }
          },
          "201": {
            "description": "A newly-committed batch.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "isExisting",
                    "batchId",
                    "seed",
                    "tenantId",
                    "domainId",
                    "deviceIds",
                    "totalDevices",
                    "totalEvents",
                    "createdAt"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "isExisting": {
                      "type": "boolean"
                    },
                    "batchId": {
                      "type": "string"
                    },
                    "seed": {
                      "type": "string"
                    },
                    "tenantId": {
                      "type": "string"
                    },
                    "domainId": {
                      "type": "string"
                    },
                    "deviceIds": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "totalDevices": {
                      "type": "integer"
                    },
                    "totalEvents": {
                      "type": "integer"
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "isExisting": true,
                  "batchId": "batch_5a1f9c3e7b2d4a6f8091c2d3e4f5a6b7",
                  "seed": "seed-01",
                  "tenantId": "tenant_42",
                  "domainId": "dom_3f2a8c91d6e5f470",
                  "deviceIds": [
                    "example-deviceIds"
                  ],
                  "totalDevices": 1,
                  "totalEvents": 1,
                  "createdAt": "2026-09-13T12:00:00.000Z"
                }
              }
            }
          },
          "400": {
            "description": "`domain_id and seed are required`, or `No template fingerprints found in the specified range`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "404": {
            "description": "`Domain not found or does not belong to tenant`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "413": {
            "$ref": "#/components/responses/BodyTooLarge"
          },
          "415": {
            "description": "`Content-Type must be application/json`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/generator/fingerprint": {
      "post": {
        "operationId": "v1GenerateSingleFingerprint",
        "tags": [
          "Generator"
        ],
        "summary": "Generate one seeded synthetic device",
        "description": "Generates one synthetic device from a filtered selection of real template fingerprints. It is idempotent on the derived seed key: a repeated request returns the existing device unchanged with `isExisting: true` and HTTP `200`; a new device answers `201`.\n\n`json_filters`, when present, constrain the candidate templates by JSONPath-style equality against the stored fingerprint, score and collector fields. Domain ownership, scope and body rules are the same as for `POST /v1/generator/fingerprints`.",
        "security": [
          {
            "ApiKeyAuth": [
              "write:generate"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "domain_id",
                  "seed"
                ],
                "properties": {
                  "domain_id": {
                    "type": "string"
                  },
                  "seed": {
                    "type": "string"
                  },
                  "platform": {
                    "type": "string"
                  },
                  "risk_level": {
                    "type": "string"
                  },
                  "country": {
                    "type": "string"
                  },
                  "language": {
                    "type": "string"
                  },
                  "timezone": {
                    "type": "string"
                  },
                  "score_min": {
                    "type": "number"
                  },
                  "score_max": {
                    "type": "number"
                  },
                  "json_filters": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "source",
                        "path"
                      ],
                      "properties": {
                        "source": {
                          "type": "string",
                          "enum": [
                            "fingerprint",
                            "score",
                            "cf"
                          ]
                        },
                        "path": {
                          "type": "string",
                          "description": "A JSONPath-style equality filter, e.g. $.signals.webgl.vendor."
                        },
                        "value": {}
                      }
                    },
                    "description": "Normalized/hashed into the deterministic seed key alongside `seed`."
                  },
                  "sourceFrom": {
                    "type": "string"
                  },
                  "sourceTo": {
                    "type": "string"
                  },
                  "sourceLimit": {
                    "type": "integer",
                    "default": 200,
                    "maximum": 500
                  },
                  "scrubIPs": {
                    "type": "boolean",
                    "default": true
                  }
                }
              },
              "example": {
                "domain_id": "dom_3f2a8c91d6e5f470",
                "seed": "seed-01",
                "platform": "example-platform",
                "risk_level": "low",
                "country": "US",
                "language": "example-language",
                "timezone": "example-timezone",
                "score_min": 1,
                "score_max": 1,
                "json_filters": [
                  {
                    "source": "fingerprint",
                    "path": "/v1/kyc/verify",
                    "value": "example-value"
                  }
                ],
                "sourceFrom": "example-sourceFrom",
                "sourceTo": "example-sourceTo",
                "sourceLimit": 200,
                "scrubIPs": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The existing seeded fingerprint (returned unchanged, `Cache-Control: no-store`).",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "isExisting",
                    "seed",
                    "filters",
                    "tenantId",
                    "domainId",
                    "batchId",
                    "deviceId",
                    "templateEventId",
                    "fingerprint",
                    "score",
                    "cf",
                    "createdAt",
                    "updatedAt"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "isExisting": {
                      "type": "boolean"
                    },
                    "seed": {
                      "type": "string"
                    },
                    "filters": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "The normalized template filters echoed back."
                    },
                    "tenantId": {
                      "type": "string"
                    },
                    "domainId": {
                      "type": "string"
                    },
                    "batchId": {
                      "type": "string"
                    },
                    "deviceId": {
                      "type": "string"
                    },
                    "templateEventId": {
                      "type": "string"
                    },
                    "fingerprint": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "The stored synthetic fingerprint blob (template-derived; shape not locally schema-validated)."
                    },
                    "score": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "The stored score blob copied verbatim from the selected template."
                    },
                    "cf": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "The stored Cloudflare-geo blob, IP-scrubbed when scrubIPs is true."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "updatedAt": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "isExisting": true,
                  "seed": "seed-01",
                  "filters": {},
                  "tenantId": "tenant_42",
                  "domainId": "dom_3f2a8c91d6e5f470",
                  "batchId": "batch_5a1f9c3e7b2d4a6f8091c2d3e4f5a6b7",
                  "deviceId": "dev_7a2b9c4d1e6f3a8b5c2d9e4f7a1b6c3d",
                  "templateEventId": "example-templateEventId",
                  "fingerprint": {},
                  "score": {},
                  "cf": {},
                  "createdAt": "2026-09-13T12:00:00.000Z",
                  "updatedAt": "2026-09-13T12:00:00.000Z"
                }
              }
            }
          },
          "201": {
            "description": "A newly-committed seeded fingerprint.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "no-store"
                  ]
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "isExisting",
                    "seed",
                    "filters",
                    "tenantId",
                    "domainId",
                    "batchId",
                    "deviceId",
                    "templateEventId",
                    "fingerprint",
                    "score",
                    "cf",
                    "createdAt",
                    "updatedAt"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "isExisting": {
                      "type": "boolean"
                    },
                    "seed": {
                      "type": "string"
                    },
                    "filters": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "The normalized template filters echoed back."
                    },
                    "tenantId": {
                      "type": "string"
                    },
                    "domainId": {
                      "type": "string"
                    },
                    "batchId": {
                      "type": "string"
                    },
                    "deviceId": {
                      "type": "string"
                    },
                    "templateEventId": {
                      "type": "string"
                    },
                    "fingerprint": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "The stored synthetic fingerprint blob (template-derived; shape not locally schema-validated)."
                    },
                    "score": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "The stored score blob copied verbatim from the selected template."
                    },
                    "cf": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "The stored Cloudflare-geo blob, IP-scrubbed when scrubIPs is true."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "updatedAt": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "isExisting": true,
                  "seed": "seed-01",
                  "filters": {},
                  "tenantId": "tenant_42",
                  "domainId": "dom_3f2a8c91d6e5f470",
                  "batchId": "batch_5a1f9c3e7b2d4a6f8091c2d3e4f5a6b7",
                  "deviceId": "dev_7a2b9c4d1e6f3a8b5c2d9e4f7a1b6c3d",
                  "templateEventId": "example-templateEventId",
                  "fingerprint": {},
                  "score": {},
                  "cf": {},
                  "createdAt": "2026-09-13T12:00:00.000Z",
                  "updatedAt": "2026-09-13T12:00:00.000Z"
                }
              }
            }
          },
          "400": {
            "description": "`domain_id and seed are required`, or `No template fingerprints found matching the specified filters`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "404": {
            "description": "`Domain not found or does not belong to tenant`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "413": {
            "$ref": "#/components/responses/BodyTooLarge"
          },
          "415": {
            "description": "`Content-Type must be application/json`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/verify/reputation": {
      "post": {
        "operationId": "v1VerifyReputation",
        "tags": [
          "Reputation"
        ],
        "summary": "Check email, website and phone reputation",
        "description": "Evaluates the reputation of an email address, a website and/or a phone number supplied by your backend and returns a fused verdict. At least one of `email`, `website` or `phone` is required. The checks are bounded and fail open: a check that cannot complete contributes no signal instead of failing the call.\n\nThis operation is not enabled by default. When the reputation module is not enabled for your organisation the route answers the `GatedNotFound` 404, and it does so before the API key is checked. A served call counts toward your organisation's reputation usage. Raw email and website values are not logged.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:reputation"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "At least one of `email`, `website`, `phone` is required.",
                "properties": {
                  "email": {
                    "type": "string"
                  },
                  "website": {
                    "type": "string"
                  },
                  "phone": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "email": "example-email",
                "website": "example-website",
                "phone": "example-phone"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The fused reputation verdict.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "verdict",
                    "signals",
                    "confidence"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "verdict": {
                      "type": "string"
                    },
                    "signals": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "Per-signal sub-scores from `evaluateReputation`; the engine's internal signal-shape union is not locally re-validated by this handler."
                    },
                    "confidence": {
                      "type": "number"
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "verdict": "example-verdict",
                  "signals": {},
                  "confidence": 1
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "404": {
            "$ref": "#/components/responses/GatedNotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/crawl/vouchers": {
      "post": {
        "operationId": "v1MintCrawlVoucher",
        "tags": [
          "Crawl Vouchers"
        ],
        "summary": "Mint a crawler-access voucher",
        "description": "Mints a signed, stateless voucher that a verified crawler (identified by `agentKey`) presents to your Noxtica edge to satisfy a `charge` pricing rule. The edge verifies only the signature and binding. The response's `header` field names the request header that carries the voucher.\n\nThe voucher is always scoped to the organisation that owns the API key; a tenant id in the body is never used. The route is fail-closed: it answers `503` when no signing key is available and never emits an unsigned voucher.\n\nPayment capture is not part of this operation. It does not verify that a payment was taken; it only checks that a payment reference (`paymentRef` in the body, or the payment-reference request header) is present, and only requires one when your deployment is configured to. Outstanding vouchers are capped per month, and the cap is claimed only after the voucher has been signed, so a signing failure never consumes it.",
        "security": [
          {
            "ApiKeyAuth": [
              "write:crawl_voucher"
            ]
          }
        ],
        "parameters": [
          {
            "name": "X-Nox-Payment-Ref",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Alternative to the body's `paymentRef`; operator-attested, not independently verified this iteration."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "agentKey"
                ],
                "properties": {
                  "agentKey": {
                    "type": "string",
                    "maxLength": 256,
                    "description": "The crawler identity this voucher pays for ('*' = the catch-all pricing rule)."
                  },
                  "ttlSeconds": {
                    "type": "integer",
                    "default": 3600,
                    "minimum": 60,
                    "maximum": 86400
                  },
                  "paymentRef": {
                    "type": "string",
                    "description": "Operator-attested payment reference; presence-only checked."
                  }
                }
              },
              "example": {
                "agentKey": "example-agentKey",
                "ttlSeconds": 3600,
                "paymentRef": "example-paymentRef"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The minted voucher.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "voucher",
                    "expiresAt",
                    "header"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "voucher": {
                      "type": "string",
                      "description": "`<base64url(payload)>.<base64url(hmac)>`, or the HMAC-signing-trust envelope form when that feature is armed."
                    },
                    "expiresAt": {
                      "type": "integer",
                      "description": "Epoch seconds."
                    },
                    "header": {
                      "type": "string",
                      "enum": [
                        "X-Nox-Crawl-Voucher"
                      ]
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "voucher": "example-voucher",
                  "expiresAt": 1768435200,
                  "header": "X-Nox-Crawl-Voucher"
                }
              }
            }
          },
          "400": {
            "description": "`agentKey (non-empty string) is required`, or `Invalid JSON body`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "402": {
            "description": "`Payment context required` — returned only when the deployment requires a payment reference and neither `paymentRef` nor the payment-reference header was supplied.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "413": {
            "$ref": "#/components/responses/BodyTooLarge"
          },
          "415": {
            "description": "`Content-Type must be application/json`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "description": "`Crawl voucher minting is not configured` (no signing key is available) or `Voucher quota authority unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/behavioral/subjects/{subjectRef}": {
      "get": {
        "operationId": "v1GetBehavioralSubject",
        "tags": [
          "Behavioral Baseline"
        ],
        "summary": "Read a subject's behavioral baseline",
        "description": "Reads a subject's current behavioral-baseline enrollment and its latest drift snapshot. `subjectRef` is your raw end-user account id: it is never stored, logged or echoed, only keyed-hashed server-side before any lookup.\n\nNot enabled by default: the whole `/v1/behavioral/*` family answers the `GatedNotFound` 404 unless behavioral baselines are enabled for the deployment, and only then is the `read:behavioral` scope checked.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:behavioral"
            ]
          }
        ],
        "parameters": [
          {
            "name": "subjectRef",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 256
            },
            "description": "The tenant's raw end-user account id (hashed server-side; never stored as given)."
          }
        ],
        "responses": {
          "200": {
            "description": "The subject's baseline enrollment + latest drift.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "subject"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "subject": {
                      "type": "object",
                      "properties": {
                        "enrollmentStatus": {
                          "type": "string",
                          "enum": [
                            "learning",
                            "active"
                          ],
                          "description": "A persisted value outside the closed set clamps to `learning`."
                        },
                        "sampleCount": {
                          "type": "integer"
                        },
                        "attestationProvenance": {
                          "type": "object",
                          "properties": {
                            "gpu_attested": {
                              "type": "integer"
                            },
                            "sealed": {
                              "type": "integer"
                            },
                            "unattested": {
                              "type": "integer"
                            }
                          }
                        },
                        "deviation": {
                          "type": [
                            "number",
                            "null"
                          ]
                        },
                        "families": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "properties": {
                            "pointer": {
                              "type": [
                                "number",
                                "null"
                              ]
                            },
                            "keystroke": {
                              "type": [
                                "number",
                                "null"
                              ]
                            },
                            "cadence": {
                              "type": [
                                "number",
                                "null"
                              ]
                            }
                          }
                        },
                        "lastDriftAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "subject": {
                    "enrollmentStatus": "learning",
                    "sampleCount": 1,
                    "attestationProvenance": {
                      "gpu_attested": 1,
                      "sealed": 1,
                      "unattested": 1
                    },
                    "deviation": 1,
                    "families": {
                      "pointer": 1,
                      "keystroke": 1,
                      "cadence": 1
                    },
                    "lastDriftAt": "2026-09-13T12:00:00.000Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "`Invalid subjectRef` — empty or over 256 chars.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "404": {
            "description": "`Subject not found` (no current snapshot exists), or `V1 endpoint not found` when behavioral baselines are not enabled for the deployment.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "x-noxtica-status": "available"
      },
      "delete": {
        "operationId": "v1EraseBehavioralSubject",
        "tags": [
          "Behavioral Baseline"
        ],
        "summary": "Erase a subject's behavioral baseline",
        "description": "Erases a subject's behavioral baseline, for data-subject erasure requests. Live profile state is erased first, then the stored snapshots and drift projections are hard-deleted. If the live-state erase fails the route answers `502` with `{\"ok\":false,\"profileErased\":false,...}` instead of a false `200`, because a surviving profile could otherwise re-flush the erased snapshot; the call is safe to retry. Erasing an unknown or already-erased subject is idempotent and answers `200 {\"deleted\":{\"snapshots\":0,\"driftEvents\":0}}`.\n\nThis erases account-scoped (`acct:`) subjects only. Device-scoped baselines and the raw behavioral tracks need the separate per-device erasure path in the Backoffice, so a subject with both needs both paths. Availability is the same as for `GET /v1/behavioral/subjects/{subjectRef}`.",
        "security": [
          {
            "ApiKeyAuth": [
              "erase:behavioral"
            ]
          }
        ],
        "parameters": [
          {
            "name": "subjectRef",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 256
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Erasure completed (or was already a no-op for an unknown subject).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "profileErased",
                    "deleted"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "profileErased": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "deleted": {
                      "type": "object",
                      "properties": {
                        "snapshots": {
                          "type": "integer"
                        },
                        "driftEvents": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "profileErased": true,
                  "deleted": {
                    "snapshots": 1,
                    "driftEvents": 1
                  }
                }
              }
            }
          },
          "400": {
            "description": "`Invalid subjectRef` — empty or over 256 chars.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "404": {
            "description": "`Subject not found`, or `V1 endpoint not found` when behavioral baselines are not enabled for the deployment.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "502": {
            "description": "`{ ok:false, profileErased:false, deleted, error: 'behavioral profile durable-object erase failed — retry (idempotent)' }` — the erase call is safe to retry.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "profileErased": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "deleted": {
                      "type": "object",
                      "properties": {
                        "snapshots": {
                          "type": "integer"
                        },
                        "driftEvents": {
                          "type": "integer"
                        }
                      }
                    },
                    "error": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "ok": false,
                  "profileErased": false,
                  "deleted": {
                    "snapshots": 1,
                    "driftEvents": 1
                  },
                  "error": "invalid_request"
                }
              }
            }
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/behavioral/subjects/{subjectRef}/timeline": {
      "get": {
        "operationId": "v1GetBehavioralSubjectTimeline",
        "tags": [
          "Behavioral Baseline"
        ],
        "summary": "Read a subject's drift-event history",
        "description": "Reads a subject's drift events, newest first. The row cap is clamped to 1–100 and there is no pagination cursor on this route. `subjectRef` handling and availability are the same as for `GET /v1/behavioral/subjects/{subjectRef}`.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:behavioral"
            ]
          }
        ],
        "parameters": [
          {
            "name": "subjectRef",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "maxLength": 256
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 50,
              "minimum": 1,
              "maximum": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The subject's drift-event timeline.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "events",
                    "count"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "events": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "deviation": {
                            "type": [
                              "number",
                              "null"
                            ]
                          },
                          "families": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "pointer": {
                                "type": [
                                  "number",
                                  "null"
                                ]
                              },
                              "keystroke": {
                                "type": [
                                  "number",
                                  "null"
                                ]
                              },
                              "cadence": {
                                "type": [
                                  "number",
                                  "null"
                                ]
                              }
                            }
                          },
                          "attestation": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "channel": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    },
                    "count": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "events": [
                    {
                      "deviation": 1,
                      "families": {
                        "pointer": 1,
                        "keystroke": 1,
                        "cadence": 1
                      },
                      "attestation": "example-attestation",
                      "channel": "example-channel",
                      "createdAt": "2026-09-13T12:00:00.000Z"
                    }
                  ],
                  "count": 1
                }
              }
            }
          },
          "400": {
            "description": "`Invalid subjectRef` — empty or over 256 chars.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "404": {
            "description": "`Subject not found`, or `V1 endpoint not found` when behavioral baselines are not enabled for the deployment.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/agent/passport": {
      "get": {
        "operationId": "getAgentPassport",
        "tags": [
          "Agent Trust"
        ],
        "summary": "Issue a signed Agent Passport (GET)",
        "description": "Runs the same Web Bot Auth verdict as `POST /v1/agent/verify` (RFC 9421 signature verification plus your organisation's agent policy registry) and returns one ES256-signed, offline-verifiable envelope. Verify the signature against the published JWKS (`GET /.well-known/noxtica/agent-passport-jwks.json`, falling back to `/.well-known/noxtica/jwks.json`) by `kid`; no round trip to Noxtica is needed.\n\nThe GET form reads only the three Web Bot Auth headers of the incoming request (`signature-input`, `signature`, `signature-agent`) and an optional forwarded attestation from the query parameters `tier`, `anchored`, `riskBand` and `jti`. `sub` is set only for a cryptographically `verified` verdict; every other verdict carries `sub: null`. An unverified `allow` is withheld or downgraded before signing.\n\n**Availability.** Agent Passports are not enabled by default. When they are not enabled for the deployment the route answers `404 {\"error\":\"Not found\"}`, a different body from the usual `V1 endpoint not found`; when your organisation has not opted into agent verification it answers `403 {\"error\":\"feature disabled\"}`. The route shares its rate-limit bucket with `POST /v1/agent/verify`, and a verified issuance counts toward your agent-verification usage.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:device"
            ]
          }
        ],
        "parameters": [
          {
            "name": "url",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "uri"
            },
            "description": "The signed target URI `@authority` is reconstructed from; degrades to the request's own URL when absent/malformed."
          },
          {
            "name": "tier",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "hardware",
                "software",
                "suspicious",
                "unavailable",
                "failed"
              ]
            },
            "description": "Optional caller-forwarded attestation tier; a non-member value is silently dropped (fail-open)."
          },
          {
            "name": "anchored",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "true",
                "false"
              ]
            },
            "description": "Optional caller-forwarded \"server-anchored single-use claim succeeded\" flag; only the literal string `true` is honoured."
          },
          {
            "name": "riskBand",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "critical",
                "high",
                "medium",
                "low",
                "minimal"
              ]
            }
          },
          {
            "name": "jti",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "OPTIONAL caller-forwarded device-correlation id, echoed back as the passport's untrusted `cid` (never the server-minted replay `jti`)."
          }
        ],
        "responses": {
          "200": {
            "description": "The ES256-signed Agent Passport envelope (`SignedEnvelope<AgentPassportPayload>`). A tenant backend verifies this OFFLINE against the published JWKS by `kid` — no round-trip to Noxtica is required.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "alg",
                    "kid",
                    "iat",
                    "payload",
                    "sig"
                  ],
                  "properties": {
                    "alg": {
                      "type": "string",
                      "enum": [
                        "ES256"
                      ]
                    },
                    "kid": {
                      "type": "string"
                    },
                    "iat": {
                      "type": "integer",
                      "description": "Epoch seconds."
                    },
                    "exp": {
                      "type": "integer",
                      "description": "Epoch seconds; the signed expiry window (== the payload `ttl`)."
                    },
                    "kv": {
                      "type": "integer",
                      "description": "OPTIONAL signing key-version; present only when the trust-lifecycle signer is in use."
                    },
                    "spv": {
                      "type": "integer",
                      "description": "OPTIONAL signing-policy-version; same presence contract as `kv`."
                    },
                    "sig": {
                      "type": "string",
                      "description": "base64url ES256 signature over the payload."
                    },
                    "payload": {
                      "type": "object",
                      "required": [
                        "typ",
                        "iss",
                        "aud",
                        "pv",
                        "verdict",
                        "attestation",
                        "riskBand",
                        "policyAction",
                        "jti",
                        "sub",
                        "tenantId",
                        "cid",
                        "disclosure",
                        "issuedAt",
                        "ttl"
                      ],
                      "properties": {
                        "typ": {
                          "type": "string",
                          "enum": [
                            "agent-passport"
                          ]
                        },
                        "iss": {
                          "type": "string",
                          "enum": [
                            "noxtica"
                          ]
                        },
                        "aud": {
                          "type": "string",
                          "description": "The authenticated tenant id (audience binding)."
                        },
                        "pv": {
                          "type": "integer",
                          "enum": [
                            1,
                            2
                          ],
                          "description": "Passport schema version: 1 = legacy claims, 2 = explicit `callerAsserted` trust marker (when enabled for the deployment)."
                        },
                        "verdict": {
                          "type": "string",
                          "enum": [
                            "verified",
                            "unsigned",
                            "invalid_signature",
                            "expired",
                            "replay"
                          ]
                        },
                        "attestation": {
                          "type": "object",
                          "properties": {
                            "tier": {
                              "type": "string",
                              "enum": [
                                "hardware",
                                "software",
                                "suspicious",
                                "unavailable",
                                "failed"
                              ]
                            },
                            "anchored": {
                              "type": "boolean"
                            },
                            "provenance": {
                              "type": "string",
                              "enum": [
                                "caller_attested"
                              ]
                            }
                          }
                        },
                        "callerAsserted": {
                          "type": "boolean",
                          "enum": [
                            true
                          ],
                          "description": "Present only when `pv:2`."
                        },
                        "riskBand": {
                          "type": "string",
                          "enum": [
                            "critical",
                            "high",
                            "medium",
                            "low",
                            "minimal"
                          ]
                        },
                        "policyAction": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "allow",
                            "deny"
                          ]
                        },
                        "graduatedAction": {
                          "type": "string",
                          "enum": [
                            "allow",
                            "observe",
                            "challenge",
                            "deny"
                          ],
                          "description": "Present only when graduated agent policy is enabled for your organisation."
                        },
                        "jti": {
                          "type": "string",
                          "format": "uuid",
                          "description": "SERVER-MINTED per-issuance id — the consumer MUST reject a repeated `jti` (replay)."
                        },
                        "sub": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "The verified subject (keyid, else the signature-agent host); null unless verdict is 'verified'."
                        },
                        "tenantId": {
                          "type": "string"
                        },
                        "cid": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "OPTIONAL untrusted caller-forwarded correlation id — never the replay id."
                        },
                        "disclosure": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "properties": {
                            "required": {
                              "type": "boolean",
                              "enum": [
                                true
                              ]
                            },
                            "regulation": {
                              "type": "string",
                              "enum": [
                                "eu_ai_act_art_50"
                              ]
                            },
                            "obligation": {
                              "type": "string"
                            },
                            "agentVerified": {
                              "type": "boolean"
                            }
                          }
                        },
                        "issuedAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "ttl": {
                          "type": "integer",
                          "description": "Seconds; the signed envelope `exp` window."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "alg": "ES256",
                  "kid": "kid-2026-09",
                  "iat": 1,
                  "exp": 1,
                  "kv": 1,
                  "spv": 1,
                  "sig": "example-sig",
                  "payload": {
                    "typ": "agent-passport",
                    "iss": "noxtica",
                    "aud": "example-aud",
                    "pv": 1,
                    "verdict": "verified",
                    "attestation": {
                      "tier": "hardware",
                      "anchored": true,
                      "provenance": "caller_attested"
                    },
                    "callerAsserted": true,
                    "riskBand": "critical",
                    "policyAction": "allow",
                    "graduatedAction": "allow",
                    "jti": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                    "sub": "example-sub",
                    "tenantId": "tenant_42",
                    "cid": "example-cid",
                    "disclosure": {
                      "required": true,
                      "regulation": "eu_ai_act_art_50",
                      "obligation": "example-obligation",
                      "agentVerified": true
                    },
                    "issuedAt": "2026-09-13T12:00:00.000Z",
                    "ttl": 1
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "description": "Your organisation has not opted into agent verification (`feature disabled`).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "feature disabled"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "feature disabled",
                  "requestId": "req-test"
                }
              }
            }
          },
          "404": {
            "description": "Agent Passports are not enabled for this deployment. The body is `{\"error\":\"Not found\"}`, returned before the API key is checked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "Not found"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "Not found",
                  "requestId": "req-test"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "description": "Unexpected fault; the handler otherwise never throws.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "503": {
            "description": "The signing key is unavailable or invalid (fail-closed: there is no silent fallback to another key).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          }
        },
        "x-noxtica-status": "available"
      },
      "post": {
        "operationId": "postAgentPassport",
        "tags": [
          "Agent Trust"
        ],
        "summary": "Issue a signed Agent Passport (POST)",
        "description": "Same verdict and signing pipeline as `GET /v1/agent/passport`; the POST form lets your backend forward the signature material in the JSON body instead of request headers, like `POST /v1/agent/verify`. The same availability rules, error responses, rate-limit bucket and usage counting apply.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:device"
            ]
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "headers": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "The forwarded Web Bot Auth signature headers (`signature-input`, `signature`, `signature-agent`, lower-cased keys); non-string values are dropped."
                  },
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "description": "The signed target URI; a malformed value degrades to the request's own URL."
                  },
                  "method": {
                    "type": "string",
                    "description": "The signed HTTP method the signature covers; defaults to `GET` when omitted/blank."
                  },
                  "attestation": {
                    "type": "object",
                    "properties": {
                      "tier": {
                        "type": "string",
                        "enum": [
                          "hardware",
                          "software",
                          "suspicious",
                          "unavailable",
                          "failed"
                        ]
                      },
                      "anchored": {
                        "type": "boolean"
                      }
                    }
                  },
                  "riskBand": {
                    "type": "string",
                    "enum": [
                      "critical",
                      "high",
                      "medium",
                      "low",
                      "minimal"
                    ]
                  },
                  "jti": {
                    "type": "string",
                    "description": "OPTIONAL caller-forwarded device-correlation id, echoed back as the passport's untrusted `cid`."
                  }
                }
              },
              "example": {
                "headers": {
                  "key": "example-headers"
                },
                "url": "https://verify.noxtica.com/s/kycs.tenant_42.9f3a8b7c6d5e4f3a2b1c0d9e8f7a6b5c",
                "method": "example-method",
                "attestation": {
                  "tier": "hardware",
                  "anchored": true
                },
                "riskBand": "critical",
                "jti": "example-jti"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The ES256-signed Agent Passport envelope (`SignedEnvelope<AgentPassportPayload>`). A tenant backend verifies this OFFLINE against the published JWKS by `kid` — no round-trip to Noxtica is required.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "alg",
                    "kid",
                    "iat",
                    "payload",
                    "sig"
                  ],
                  "properties": {
                    "alg": {
                      "type": "string",
                      "enum": [
                        "ES256"
                      ]
                    },
                    "kid": {
                      "type": "string"
                    },
                    "iat": {
                      "type": "integer",
                      "description": "Epoch seconds."
                    },
                    "exp": {
                      "type": "integer",
                      "description": "Epoch seconds; the signed expiry window (== the payload `ttl`)."
                    },
                    "kv": {
                      "type": "integer",
                      "description": "OPTIONAL signing key-version; present only when the trust-lifecycle signer is in use."
                    },
                    "spv": {
                      "type": "integer",
                      "description": "OPTIONAL signing-policy-version; same presence contract as `kv`."
                    },
                    "sig": {
                      "type": "string",
                      "description": "base64url ES256 signature over the payload."
                    },
                    "payload": {
                      "type": "object",
                      "required": [
                        "typ",
                        "iss",
                        "aud",
                        "pv",
                        "verdict",
                        "attestation",
                        "riskBand",
                        "policyAction",
                        "jti",
                        "sub",
                        "tenantId",
                        "cid",
                        "disclosure",
                        "issuedAt",
                        "ttl"
                      ],
                      "properties": {
                        "typ": {
                          "type": "string",
                          "enum": [
                            "agent-passport"
                          ]
                        },
                        "iss": {
                          "type": "string",
                          "enum": [
                            "noxtica"
                          ]
                        },
                        "aud": {
                          "type": "string",
                          "description": "The authenticated tenant id (audience binding)."
                        },
                        "pv": {
                          "type": "integer",
                          "enum": [
                            1,
                            2
                          ],
                          "description": "Passport schema version: 1 = legacy claims, 2 = explicit `callerAsserted` trust marker (when enabled for the deployment)."
                        },
                        "verdict": {
                          "type": "string",
                          "enum": [
                            "verified",
                            "unsigned",
                            "invalid_signature",
                            "expired",
                            "replay"
                          ]
                        },
                        "attestation": {
                          "type": "object",
                          "properties": {
                            "tier": {
                              "type": "string",
                              "enum": [
                                "hardware",
                                "software",
                                "suspicious",
                                "unavailable",
                                "failed"
                              ]
                            },
                            "anchored": {
                              "type": "boolean"
                            },
                            "provenance": {
                              "type": "string",
                              "enum": [
                                "caller_attested"
                              ]
                            }
                          }
                        },
                        "callerAsserted": {
                          "type": "boolean",
                          "enum": [
                            true
                          ],
                          "description": "Present only when `pv:2`."
                        },
                        "riskBand": {
                          "type": "string",
                          "enum": [
                            "critical",
                            "high",
                            "medium",
                            "low",
                            "minimal"
                          ]
                        },
                        "policyAction": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "allow",
                            "deny"
                          ]
                        },
                        "graduatedAction": {
                          "type": "string",
                          "enum": [
                            "allow",
                            "observe",
                            "challenge",
                            "deny"
                          ],
                          "description": "Present only when graduated agent policy is enabled for your organisation."
                        },
                        "jti": {
                          "type": "string",
                          "format": "uuid",
                          "description": "SERVER-MINTED per-issuance id — the consumer MUST reject a repeated `jti` (replay)."
                        },
                        "sub": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "The verified subject (keyid, else the signature-agent host); null unless verdict is 'verified'."
                        },
                        "tenantId": {
                          "type": "string"
                        },
                        "cid": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "OPTIONAL untrusted caller-forwarded correlation id — never the replay id."
                        },
                        "disclosure": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "properties": {
                            "required": {
                              "type": "boolean",
                              "enum": [
                                true
                              ]
                            },
                            "regulation": {
                              "type": "string",
                              "enum": [
                                "eu_ai_act_art_50"
                              ]
                            },
                            "obligation": {
                              "type": "string"
                            },
                            "agentVerified": {
                              "type": "boolean"
                            }
                          }
                        },
                        "issuedAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "ttl": {
                          "type": "integer",
                          "description": "Seconds; the signed envelope `exp` window."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "alg": "ES256",
                  "kid": "kid-2026-09",
                  "iat": 1,
                  "exp": 1,
                  "kv": 1,
                  "spv": 1,
                  "sig": "example-sig",
                  "payload": {
                    "typ": "agent-passport",
                    "iss": "noxtica",
                    "aud": "example-aud",
                    "pv": 1,
                    "verdict": "verified",
                    "attestation": {
                      "tier": "hardware",
                      "anchored": true,
                      "provenance": "caller_attested"
                    },
                    "callerAsserted": true,
                    "riskBand": "critical",
                    "policyAction": "allow",
                    "graduatedAction": "allow",
                    "jti": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                    "sub": "example-sub",
                    "tenantId": "tenant_42",
                    "cid": "example-cid",
                    "disclosure": {
                      "required": true,
                      "regulation": "eu_ai_act_art_50",
                      "obligation": "example-obligation",
                      "agentVerified": true
                    },
                    "issuedAt": "2026-09-13T12:00:00.000Z",
                    "ttl": 1
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "description": "Your organisation has not opted into agent verification (`feature disabled`).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "feature disabled"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "feature disabled",
                  "requestId": "req-test"
                }
              }
            }
          },
          "404": {
            "description": "Agent Passports are not enabled for this deployment. The body is `{\"error\":\"Not found\"}`, returned before the API key is checked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "enum": [
                        "Not found"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "Not found",
                  "requestId": "req-test"
                }
              }
            }
          },
          "413": {
            "description": "`Payload too large` — the request body exceeded the size limit.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "description": "Unexpected fault.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "503": {
            "description": "The signing key is unavailable or invalid (fail-closed: there is no silent fallback to another key).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/agent/verify": {
      "post": {
        "operationId": "postAgentVerify",
        "tags": [
          "Agent Trust"
        ],
        "summary": "Verify a Web Bot Auth agent signature",
        "description": "Your backend forwards an incoming request's signature headers and target URL. Noxtica verifies the Web Bot Auth (RFC 9421) signature and joins the verdict to your organisation's agent policy registry for an allow or deny decision.\n\nVerification fails open end to end: any fault yields verdict `unsigned` and `matchedAction: null`. The endpoint is advisory and never blocks an agent itself. A structurally matched but unverified identity can never receive a binary `allow` (it is withheld to `null`), and a graduated `allow` is downgraded to `challenge`.\n\nSome response fields are additive and appear only when the matching capability is enabled for your organisation: `kya` and `policyAction` (the graduated ladder) and `disclosure` (EU AI Act Article 50 disclosure, only for a detected or verified agent).",
        "security": [
          {
            "ApiKeyAuth": [
              "read:device"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "headers"
                ],
                "properties": {
                  "headers": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "description": "The forwarded Web Bot Auth signature headers (`signature-input`, `signature`, `signature-agent`)."
                  },
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "description": "The signed target URI the signature covers."
                  },
                  "attestation": {
                    "type": "object",
                    "properties": {
                      "tier": {
                        "type": "string",
                        "enum": [
                          "hardware",
                          "software",
                          "suspicious",
                          "unavailable",
                          "failed"
                        ]
                      },
                      "anchored": {
                        "type": "boolean"
                      }
                    }
                  },
                  "riskBand": {
                    "type": "string",
                    "enum": [
                      "critical",
                      "high",
                      "medium",
                      "low",
                      "minimal"
                    ]
                  },
                  "jti": {
                    "type": "string",
                    "description": "Device-correlated token id; when graduated agent policy is enabled for your organisation and it has registry rows, it completes an `agent_attestation_chain` link."
                  }
                }
              },
              "example": {
                "headers": {
                  "key": "example-headers"
                },
                "url": "https://verify.noxtica.com/s/kycs.tenant_42.9f3a8b7c6d5e4f3a2b1c0d9e8f7a6b5c",
                "attestation": {
                  "tier": "hardware",
                  "anchored": true
                },
                "riskBand": "critical",
                "jti": "example-jti"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A resolved Web Bot Auth verdict plus the KYA registry join.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "verdict",
                    "keyid",
                    "signatureAgent",
                    "matchedAction"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "verdict": {
                      "type": "string",
                      "enum": [
                        "verified",
                        "unsigned",
                        "invalid_signature",
                        "expired",
                        "replay"
                      ]
                    },
                    "keyid": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "signatureAgent": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "matchedAction": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "enum": [
                        "allow",
                        "deny"
                      ]
                    },
                    "attestation": {
                      "type": "object",
                      "description": "Present ONLY when the caller forwarded a valid `tier`.",
                      "properties": {
                        "tier": {
                          "type": "string",
                          "enum": [
                            "hardware",
                            "software",
                            "suspicious",
                            "unavailable",
                            "failed"
                          ]
                        },
                        "anchored": {
                          "type": "boolean"
                        },
                        "provenance": {
                          "type": "string",
                          "enum": [
                            "caller_attested"
                          ],
                          "description": "Always `caller_attested` — this handler never independently corroborates the forwarded tier."
                        }
                      }
                    },
                    "riskBand": {
                      "type": "string",
                      "enum": [
                        "critical",
                        "high",
                        "medium",
                        "low",
                        "minimal"
                      ]
                    },
                    "kya": {
                      "type": "object",
                      "description": "Present only when graduated agent policy is enabled for your organisation.",
                      "properties": {
                        "verified": {
                          "type": "boolean"
                        },
                        "agentId": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "source": {
                          "type": "string",
                          "enum": [
                            "web-bot-auth",
                            "skyfire"
                          ]
                        },
                        "attestationTier": {
                          "type": "string",
                          "enum": [
                            "hardware",
                            "software",
                            "suspicious",
                            "unavailable",
                            "failed"
                          ]
                        },
                        "attestationTierProvenance": {
                          "type": "string",
                          "enum": [
                            "caller_attested"
                          ]
                        },
                        "cfVerified": {
                          "type": "boolean",
                          "description": "Present ONLY on a Cloudflare Verified AI Agents match."
                        },
                        "cfVerifiedName": {
                          "type": "string"
                        },
                        "trustCaveat": {
                          "type": "string",
                          "enum": [
                            "structural_only_signature_unverified"
                          ],
                          "description": "Present ONLY when the identity came from the Skyfire interop adapter."
                        }
                      }
                    },
                    "disclosure": {
                      "type": "object",
                      "description": "Present only when EU AI Act disclosure is enabled for your organisation and a detected or verified agent is present.",
                      "properties": {
                        "required": {
                          "type": "boolean",
                          "enum": [
                            true
                          ]
                        },
                        "regulation": {
                          "type": "string",
                          "enum": [
                            "eu_ai_act_art_50"
                          ]
                        },
                        "obligation": {
                          "type": "string"
                        },
                        "agentVerified": {
                          "type": "boolean"
                        }
                      }
                    },
                    "policyAction": {
                      "type": "string",
                      "enum": [
                        "allow",
                        "observe",
                        "challenge",
                        "deny"
                      ],
                      "description": "Present only when graduated agent policy is enabled for your organisation and an attributable identity exists — the advisory graduated enforcement tier (Noxtica never acts on it)."
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "verdict": "verified",
                  "keyid": "example-keyid",
                  "signatureAgent": "example-signatureAgent",
                  "matchedAction": "allow",
                  "attestation": {
                    "tier": "hardware",
                    "anchored": true,
                    "provenance": "caller_attested"
                  },
                  "riskBand": "critical",
                  "kya": {
                    "verified": true,
                    "agentId": "example-agentId",
                    "source": "web-bot-auth",
                    "attestationTier": "hardware",
                    "attestationTierProvenance": "caller_attested",
                    "cfVerified": true,
                    "cfVerifiedName": "example-cfVerifiedName",
                    "trustCaveat": "structural_only_signature_unverified"
                  },
                  "disclosure": {
                    "required": true,
                    "regulation": "eu_ai_act_art_50",
                    "obligation": "example-obligation",
                    "agentVerified": true
                  },
                  "policyAction": "allow"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "413": {
            "$ref": "#/components/responses/BodyTooLarge"
          },
          "415": {
            "description": "`Content-Type must be application/json`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/ip/reputation": {
      "post": {
        "operationId": "postIpReputation",
        "tags": [
          "IP & Risk Scoring"
        ],
        "summary": "Look up IP reputation",
        "description": "Returns the reputation verdict `{category, source, confidence}` for one IP address supplied by your backend, from the same feed Noxtica uses to score its own submissions. When the address is not listed the response is `listed: false`; an unlisted address, an empty feed or a lookup fault never produces an error.\n\nThe queried IP is echoed back in the response, which is your own input. It is not stored or logged unless your organisation has opted into raw-IP storage; only the derived verdict is retained. A served call counts toward your organisation's IP-reputation usage.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:device"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "ip"
                ],
                "properties": {
                  "ip": {
                    "type": "string",
                    "description": "An IPv4 dotted-quad or IPv6 address."
                  }
                }
              },
              "example": {
                "ip": "example-ip"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The derived reputation verdict, or `listed:false` when the engine has no signal.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "ip",
                    "listed"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "ip": {
                      "type": "string",
                      "description": "Echoed back verbatim (the caller's own query input)."
                    },
                    "listed": {
                      "type": "boolean"
                    },
                    "verdict": {
                      "type": "object",
                      "description": "Present ONLY when `listed` is true.",
                      "properties": {
                        "category": {
                          "type": "string"
                        },
                        "source": {
                          "type": "string"
                        },
                        "confidence": {
                          "type": "number"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "ip": "example-ip",
                  "listed": true,
                  "verdict": {
                    "category": "example-category",
                    "source": "example-source",
                    "confidence": 1
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/score": {
      "post": {
        "operationId": "postScore",
        "tags": [
          "IP & Risk Scoring"
        ],
        "summary": "Score a signals payload",
        "description": "Scores an already-collected `signals` payload from your backend and returns the headline score, confidence, tier and flags that the Noxtica collector computes for its own submissions. Call it from a server with an `sk_` key that carries the `read:device` scope (the default scope of every key); never from a browser.\n\n**Request.** Send either the complete enriched payload `{\"signals\": {...}, \"serverSideSignals\": {...}, ...}` or, for older callers, the inner `signals` object on its own, which is wrapped once. The body may be up to 256 KiB. The raw payload is not logged.\n\n**Response.** `score` is the engine's score, `tier` its risk band and `flags` the flags that fired. `confidence` is an integer from 0 to 100 (50 is neutral). `attestation` is always `null` on this route: the payload is supplied by the caller and cannot be trusted as hardware evidence, so no hardware-verification claim is ever made.\n\n**Allowance.** Calls within your plan's monthly Score API allowance are included. Beyond it the score is still served and the response carries a `nudge` object with `code: free_tier_exceeded`; the score is never withheld.\n\n**Errors.** `400` `Invalid body` when the body is not a JSON object or is larger than 256 KiB, and `Invalid signals` when `signals` is present but is not an object; `401`, `403`, `429` and `500` as on every key-authenticated route. No `413` is returned: an oversized body is a `400`.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:device"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "The documented form is the complete enriched payload (`{ signals: {...}, serverSideSignals?: {...}, ... }`) submit scores; a legacy caller MAY instead POST the inner `signals` object directly and it is wrapped exactly once.",
                "additionalProperties": true
              },
              "example": {}
            }
          }
        },
        "responses": {
          "200": {
            "description": "The re-scored verdict, mapped onto the public 0-100 confidence scale.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "score",
                    "confidence",
                    "tier",
                    "flags",
                    "attestation"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "score": {
                      "type": "number"
                    },
                    "confidence": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 100,
                      "description": "Normalised to 0-100 (the engine's native value is 0-1), matching `/v1/attest/verify`'s scale."
                    },
                    "tier": {
                      "type": "string",
                      "description": "The engine's `riskLevel` band."
                    },
                    "flags": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "attestation": {
                      "type": "null",
                      "description": "ALWAYS `null` on this surface — see the honesty-gate note above."
                    },
                    "nudge": {
                      "type": "object",
                      "description": "Present ONLY once the free monthly allotment is exceeded — informational only, never withholds the score.",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "free_tier_exceeded"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "free_serving_allotment": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "score": 1,
                  "confidence": 0,
                  "tier": "example-tier",
                  "flags": [
                    "example-flags"
                  ],
                  "attestation": null,
                  "nudge": {
                    "code": "free_tier_exceeded",
                    "message": "example-message",
                    "free_serving_allotment": 1
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/protected-actions/verify": {
      "post": {
        "operationId": "postProtectedActionsVerify",
        "tags": [
          "Protected Actions"
        ],
        "summary": "Redeem a protected-action request id",
        "description": "Call this from your backend before letting a protected action (login, sign-up, checkout, ...) proceed. Send the `requestId` your browser integration obtained for the action: the resolved value of `noxticaClient.protect(name)`, the hidden `nox_request_id` input of a `data-nox-protect` form, or `form.dataset.noxRequestId` / the `noxtica:protected` event of a script-submitted form. Use an `sk_` key with the `read:device` scope, the default scope of every key.\n\n**Single use inside a 300-second window.** The first valid call consumes the receipt and answers `200` with `consumed: true`. A replay inside the window is `409 already_consumed`. An unknown, expired or other-organisation id is `404 request_not_found`, and after 300 seconds every id is `404`.\n\n**Binding.** `action` is required: an id minted for `login` never satisfies a `checkout` check (`422 action_mismatch`; the receipt is not consumed). `expectedDomain` (a hostname, origin or URL) additionally binds the page that ran the action (`422 domain_mismatch`; not consumed). A request that arrives without a `requestId` (a fail-open timeout, a blocked script) means \"no client signal\", never a pass.\n\n**Result.** `verdict` is the risk band (`minimal`, `low`, `medium`, `high`, `critical`); `score` (higher is riskier) and `confidence` (0 to 1) are the values the browser received, and this server-to-server call always returns them. The request body is limited to 2048 bytes. A `500` carries no `ok` field and never consumes the receipt.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:device"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "requestId",
                  "action"
                ],
                "properties": {
                  "requestId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "The protected submission's request id."
                  },
                  "action": {
                    "type": "string",
                    "pattern": "^[a-z][a-z0-9_-]{0,31}$",
                    "description": "The protected action name the tenant expects (`login`, `checkout`, ...)."
                  },
                  "expectedDomain": {
                    "type": "string",
                    "maxLength": 269,
                    "description": "Optional hostname/origin/URL the action must have run on."
                  }
                }
              },
              "example": {
                "requestId": "8f1c2a52-6a6e-4b0e-9d52-2a7c1d9e4b10",
                "action": "login",
                "expectedDomain": "www.example.com"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The receipt was valid and has now been consumed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "requestId",
                    "action",
                    "fingerprintId",
                    "verdict",
                    "score",
                    "confidence",
                    "domain",
                    "issuedAt",
                    "expiresAt",
                    "consumed",
                    "consumedAt"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "requestId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "action": {
                      "type": "string"
                    },
                    "fingerprintId": {
                      "type": "string",
                      "description": "The device id of the protected submission (the same value the dashboard keys on)."
                    },
                    "verdict": {
                      "type": "string",
                      "enum": [
                        "minimal",
                        "low",
                        "medium",
                        "high",
                        "critical"
                      ]
                    },
                    "score": {
                      "type": "number"
                    },
                    "confidence": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    },
                    "domain": {
                      "type": "string",
                      "description": "Hostname of the page that ran the action."
                    },
                    "issuedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "expiresAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "consumed": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "This call consumed the receipt."
                    },
                    "consumedAt": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "requestId": "8f1c2a52-6a6e-4b0e-9d52-2a7c1d9e4b10",
                  "action": "login",
                  "fingerprintId": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
                  "verdict": "low",
                  "score": 12,
                  "confidence": 0.91,
                  "domain": "www.example.com",
                  "issuedAt": "2026-10-08T10:00:00.000Z",
                  "expiresAt": "2026-10-08T10:05:00.000Z",
                  "consumed": true,
                  "consumedAt": "2026-10-08T10:00:02.000Z"
                }
              }
            }
          },
          "400": {
            "description": "`invalid_body`, `invalid_request_id`, `invalid_action` or `invalid_expected_domain`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProtectedActionVerifyError"
                },
                "example": {
                  "ok": false,
                  "error": "invalid_request_id",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "404": {
            "description": "`request_not_found` — unknown, expired (older than 300 s) or minted for another tenant.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProtectedActionVerifyError"
                },
                "example": {
                  "ok": false,
                  "error": "request_not_found",
                  "requestId": "req-test"
                }
              }
            }
          },
          "409": {
            "description": "`already_consumed` — the receipt was already redeemed (replay inside the window).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProtectedActionVerifyError"
                },
                "example": {
                  "ok": false,
                  "error": "already_consumed",
                  "consumed": true,
                  "consumedAt": "2026-10-08T10:00:02.000Z",
                  "requestId": "req-test"
                }
              }
            }
          },
          "413": {
            "description": "`payload_too_large` — over the 2048-byte cap.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProtectedActionVerifyError"
                },
                "example": {
                  "ok": false,
                  "error": "payload_too_large",
                  "requestId": "req-test"
                }
              }
            }
          },
          "422": {
            "description": "`action_mismatch` or `domain_mismatch` — the receipt is NOT consumed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProtectedActionVerifyError"
                },
                "example": {
                  "ok": false,
                  "error": "action_mismatch",
                  "requestId": "req-test"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/attest/android": {
      "post": {
        "operationId": "postAttestAndroid",
        "tags": [
          "Device Attestation"
        ],
        "summary": "Android Play Integrity attestation (mint / verify)",
        "description": "Server-to-server relay for Android Play Integrity attestation. Your backend — typically the backend-for-frontend a mobile app authenticates to — calls this route with an `sk_` key; the mobile app never calls it directly. Two actions are supported:\n\n1. `{\"action\":\"mint\"}` returns a single-use nonce, valid for 300 seconds and bound to your organisation and domain, that the app binds a Play Integrity standard token to.\n2. `{\"action\":\"verify\",\"nonce\":\"...\",\"token\":\"...\"}` (the older field name `integrityToken` is also accepted) claims the nonce exactly once, verifies the token with Google's Play Integrity service, records the result and returns the verdict. A `risk.flagged` webhook may be sent to subscribed endpoints.\n\n`{\"action\":\"assert\"}` is iOS-only and is refused on this route with the `GatedNotFound` 404. When verification with Google cannot complete, the verifier fails closed to `verificationLevel: \"unverified\"`: the result is stored but no verification credit is implied, and an unverified result is never silently upgraded.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:device"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "action": {
                    "type": "string",
                    "enum": [
                      "mint",
                      "verify"
                    ],
                    "default": "verify"
                  },
                  "domain_id": {
                    "type": "string",
                    "description": "OPTIONAL tenant-owned domain the nonce/claim is bound to."
                  },
                  "nonce": {
                    "type": "string",
                    "description": "REQUIRED for `verify` — the nonce returned by a prior `mint`."
                  },
                  "token": {
                    "type": "string",
                    "description": "REQUIRED for `verify` — the Play Integrity STANDARD token (also accepted under the legacy key `integrityToken`)."
                  }
                }
              },
              "example": {
                "action": "mint",
                "domain_id": "dom_3f2a8c91d6e5f470",
                "nonce": "nonce_5f3a8c1e2d4b6f709182a3b4c5d6e7f8",
                "token": "tok_9f2a1c3e5d7b4a6f8091c2d3e4f5a6b7"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The mint or verify outcome. A mint returns `{ok,nonce,ttlSeconds,platform}`; a verify returns `{ok,verdict,verificationLevel,platform,attestationId?}` (`attestationId` present only once a PostgreSQL authority row is recorded; `verdict:'error'` signals a recording fault, not a failed proof). IMPORTANT: `ok:true` is only the envelope-level \"request handled\" flag for BOTH mint and verify — it is present, and true, even when a `verify` call correctly REJECTS a forged/invalid token (fail-closed discipline; this route never returns a 4xx for a bad token). It is never a statement about the attestation's outcome. To determine pass/fail, check `verdict` (only ever `'pass'` when `verificationLevel` is `'verified'`) and `verificationLevel`, never `ok`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "platform"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Envelope-only \"request handled\" flag — always true on this 200 path for BOTH mint and a correctly-refused verify. NOT a verdict; check `verdict`/`verificationLevel` for the actual attestation outcome."
                    },
                    "platform": {
                      "type": "string",
                      "enum": [
                        "android"
                      ]
                    },
                    "nonce": {
                      "type": "string"
                    },
                    "ttlSeconds": {
                      "type": "integer"
                    },
                    "verdict": {
                      "type": "string",
                      "enum": [
                        "pass",
                        "fail",
                        "error",
                        "indeterminate"
                      ]
                    },
                    "verificationLevel": {
                      "type": "string",
                      "description": "e.g. `verified` / `unverified`."
                    },
                    "attestationId": {
                      "type": "string",
                      "format": "uuid"
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "platform": "android",
                  "nonce": "nonce_5f3a8c1e2d4b6f709182a3b4c5d6e7f8",
                  "ttlSeconds": 3600,
                  "verdict": "pass",
                  "verificationLevel": "verified",
                  "attestationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                }
              }
            }
          },
          "400": {
            "description": "`Missing nonce / token`, `Invalid Content-Length header`, or `Invalid JSON body`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "404": {
            "$ref": "#/components/responses/GatedNotFound"
          },
          "413": {
            "$ref": "#/components/responses/BodyTooLarge"
          },
          "415": {
            "description": "`Content-Type must be application/json`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "description": "`Could not mint challenge` — the tenant edge authority / single-use token store is unavailable.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/attest/ios": {
      "post": {
        "operationId": "postAttestIos",
        "tags": [
          "Device Attestation"
        ],
        "summary": "iOS App Attest attestation (mint / verify / assert)",
        "description": "Server-to-server relay for iOS App Attest, with the same posture as `POST /v1/attest/android`: your backend calls it with an `sk_` key and the app never does. Three actions are supported:\n\n1. `{\"action\":\"mint\"}` returns a single-use nonce, valid for 300 seconds, that the app generates an App Attest key and attestation over.\n2. `{\"action\":\"verify\",\"nonce\":\"...\",\"token\":\"...\"}` (the older field name `attestationObject` is also accepted) parses the attestation object, checks the nonce binding, records the result, may send a `risk.flagged` webhook and returns the verdict. Verification currently covers structure, `rpIdHash` and nonce binding (`verificationLevel: \"structure_only\"`); promotion to `verified` additionally requires certificate-chain validation against pinned Apple intermediate key material, which is available only when it is configured for the deployment.\n3. `{\"action\":\"assert\",\"nonce\":\"...\",\"assertion\":\"...\",\"keyId\":\"...\"}` is a destructive account-deletion possession proof, available only when it is enabled for your organisation (otherwise the `GatedNotFound` 404). It verifies an App Attest assertion against the stored enrollment binding for `keyId`, enforces a monotonic sign counter (replay defence) and on success returns the bound `subjectId` and the fixed `actionScope`. The nonce is consumed even when the assertion fails.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:device"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "action": {
                    "type": "string",
                    "enum": [
                      "mint",
                      "verify",
                      "assert"
                    ],
                    "default": "verify"
                  },
                  "domain_id": {
                    "type": "string"
                  },
                  "nonce": {
                    "type": "string",
                    "description": "REQUIRED for `verify`/`assert` — the nonce returned by a prior `mint`."
                  },
                  "token": {
                    "type": "string",
                    "description": "REQUIRED for `verify` — the base64 CBOR App Attest attestation object (also accepted under the legacy key `attestationObject`)."
                  },
                  "assertion": {
                    "type": "string",
                    "description": "REQUIRED for `assert` — the base64url App Attest assertion CBOR."
                  },
                  "keyId": {
                    "type": "string",
                    "description": "REQUIRED for `assert` — the App Attest key id from the prior enrollment (`verify`) response."
                  }
                }
              },
              "example": {
                "action": "mint",
                "domain_id": "dom_3f2a8c91d6e5f470",
                "nonce": "nonce_5f3a8c1e2d4b6f709182a3b4c5d6e7f8",
                "token": "tok_9f2a1c3e5d7b4a6f8091c2d3e4f5a6b7",
                "assertion": "example-assertion",
                "keyId": "example-keyId"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The mint / verify / assert outcome. A successful `assert` additionally carries `subjectId` (server-resolved from the stored binding — never request-derived). IMPORTANT: `ok:true` is only the envelope-level \"request handled\" flag for mint/verify/assert alike — it is present, and true, even when a `verify` call correctly REJECTS a forged/invalid attestation object (fail-closed discipline; this route never returns a 4xx for a bad token). It is never a statement about the attestation's outcome. To determine pass/fail, check `verdict` (only ever `'pass'` when `verificationLevel` is `'verified'`) and `verificationLevel`, never `ok`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "platform"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Envelope-only \"request handled\" flag — always true on this 200 path for mint/verify/assert alike, including a correctly-refused verify. NOT a verdict; check `verdict`/`verificationLevel` for the actual attestation outcome."
                    },
                    "platform": {
                      "type": "string",
                      "enum": [
                        "ios"
                      ]
                    },
                    "nonce": {
                      "type": "string"
                    },
                    "ttlSeconds": {
                      "type": "integer"
                    },
                    "verdict": {
                      "type": "string",
                      "enum": [
                        "pass",
                        "fail",
                        "error",
                        "indeterminate"
                      ]
                    },
                    "verificationLevel": {
                      "type": "string"
                    },
                    "attestationId": {
                      "type": "string",
                      "format": "uuid"
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "platform": "ios",
                  "nonce": "nonce_5f3a8c1e2d4b6f709182a3b4c5d6e7f8",
                  "ttlSeconds": 3600,
                  "verdict": "pass",
                  "verificationLevel": "verified",
                  "attestationId": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
                }
              }
            }
          },
          "400": {
            "description": "`Missing nonce / token`, `Missing nonce / assertion / keyId`, `Invalid Content-Length header`, or `Invalid JSON body`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "404": {
            "$ref": "#/components/responses/GatedNotFound"
          },
          "413": {
            "$ref": "#/components/responses/BodyTooLarge"
          },
          "415": {
            "description": "`Content-Type must be application/json`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          },
          "503": {
            "description": "`Could not mint challenge`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/attest/verify": {
      "post": {
        "operationId": "postAttestVerify",
        "tags": [
          "Device Attestation"
        ],
        "summary": "Verify a CPU/GPU attestation proof",
        "description": "Returns a synchronous verdict for a one-off CPU/GPU proof-of-work attestation, driven by your backend on behalf of its web client outside the normal `/client/submit` flow. `{\"action\":\"verify\",\"challengeId\":\"...\",\"proof\":{...}}` redeems a challenge minted by `POST /v1/attest/challenge`.\n\nNot enabled by default: when the capability is not enabled for your organisation this route does not answer 404: it fails open to a neutral HTTP 200. When the capability is not enabled, or on any internal fault, the response is `{\"ok\":true,\"featureEnabled\":false,\"tier\":\"unavailable\",\"confidence\":50,\"anchored\":false}`. \"No signal\" is always a pass-through, never an outage.\n\nAbsence is not a penalty: a proof that reports no CPU/GPU capability scores neutral. Only a proof that is present but rejected (after a successful single-use nonce claim) is a `failed` signal, and every rejected proof collapses to the same public reason `verification_rejected`. The literal tier `hardware` is published only when publication of the hardware attestation level is enabled for your organisation; otherwise `hardware` and `software` are both reported as `attested`.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:device"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "action": {
                    "type": "string",
                    "enum": [
                      "verify"
                    ],
                    "default": "verify",
                    "description": "This path always defaults/forces `verify`; use `POST /v1/attest/challenge` to mint."
                  },
                  "domain_id": {
                    "type": "string"
                  },
                  "kind": {
                    "type": "string",
                    "enum": [
                      "gpu",
                      "cpu"
                    ],
                    "default": "gpu"
                  },
                  "challengeId": {
                    "type": "string",
                    "description": "REQUIRED — the `challengeId` returned by a prior `POST /v1/attest/challenge`."
                  },
                  "proof": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "The CPU/GPU attestation proof payload narrowed by `narrowProof` against the obsidian VM's engine-internal proof shape. Left open (`additionalProperties: true`) — the exact engine field set (`adapterInfo`, ULP samples, raw multichannel evidence, etc.) is internal wire format with no independent public contract and is not safely documented from the handler alone."
                  }
                }
              },
              "example": {
                "action": "verify",
                "domain_id": "dom_3f2a8c91d6e5f470",
                "kind": "gpu",
                "challengeId": "chal_3c9b2f7e4a3d4c8e",
                "proof": {}
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Either the NEUTRAL feature-off/fail-open band, or a scored verdict with the M3-masked published tier.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "featureEnabled",
                    "tier",
                    "confidence",
                    "anchored",
                    "reasons",
                    "verifiedAt"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "featureEnabled": {
                      "type": "boolean"
                    },
                    "tier": {
                      "type": "string",
                      "enum": [
                        "hardware",
                        "software",
                        "attested",
                        "suspicious",
                        "failed",
                        "unavailable"
                      ]
                    },
                    "confidence": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 100
                    },
                    "anchored": {
                      "type": "boolean"
                    },
                    "reasons": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "verifiedAt": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "featureEnabled": true,
                  "tier": "hardware",
                  "confidence": 0,
                  "anchored": true,
                  "reasons": [
                    "example-reasons"
                  ],
                  "verifiedAt": "2026-09-13T12:00:00.000Z"
                }
              }
            }
          },
          "400": {
            "description": "`Invalid Content-Length header` or `Invalid JSON body`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "413": {
            "$ref": "#/components/responses/BodyTooLarge"
          },
          "415": {
            "description": "`Content-Type must be application/json`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/attest/challenge": {
      "post": {
        "operationId": "postAttestChallenge",
        "tags": [
          "Device Attestation"
        ],
        "summary": "Mint a CPU/GPU attestation challenge",
        "description": "Mints a single-use, organisation- and domain-bound, origin-anchored challenge and returns the directive your client feeds to the attestation runtime. The URL path forces `action: \"challenge\"` whatever the body says. Redeem the returned `challengeId` at `POST /v1/attest/verify`.\n\nThe availability and fail-open posture are the same as for `POST /v1/attest/verify`: a missing `Origin` header, an authority fault or a missing integrity pin all collapse to `{\"ok\":true,\"featureEnabled\":true,\"challenge\":null,\"reason\":\"challenge_unavailable\"}` with HTTP 200, never a 5xx.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:device"
            ]
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "domain_id": {
                    "type": "string"
                  },
                  "kind": {
                    "type": "string",
                    "enum": [
                      "gpu",
                      "cpu"
                    ],
                    "default": "gpu"
                  }
                }
              },
              "example": {
                "domain_id": "dom_3f2a8c91d6e5f470",
                "kind": "gpu"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A minted challenge directive, or the neutral `challenge_unavailable` refusal.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "featureEnabled",
                    "verifiedAt"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "featureEnabled": {
                      "type": "boolean"
                    },
                    "reason": {
                      "type": "string",
                      "enum": [
                        "challenge_unavailable",
                        "attest_verify_disabled",
                        "attest_verify_tenant_disabled"
                      ]
                    },
                    "challenge": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "properties": {
                        "challengeId": {
                          "type": "string"
                        },
                        "nonce": {
                          "type": "string"
                        },
                        "loaderUrl": {
                          "type": "string",
                          "format": "uri"
                        },
                        "wasmUrl": {
                          "type": "string",
                          "format": "uri"
                        },
                        "wasmSha256": {
                          "type": "string"
                        },
                        "seed": {
                          "type": "string"
                        },
                        "level": {
                          "type": "integer"
                        },
                        "rawEvidenceCommitmentVersion": {
                          "type": "integer"
                        },
                        "expiresAt": {
                          "type": "integer",
                          "description": "Epoch milliseconds."
                        }
                      }
                    },
                    "verifiedAt": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "featureEnabled": true,
                  "reason": "challenge_unavailable",
                  "challenge": {
                    "challengeId": "chal_3c9b2f7e4a3d4c8e",
                    "nonce": "nonce_5f3a8c1e2d4b6f709182a3b4c5d6e7f8",
                    "loaderUrl": "https://example.com",
                    "wasmUrl": "https://example.com",
                    "wasmSha256": "example-wasmSha256",
                    "seed": "seed-01",
                    "level": 1,
                    "rawEvidenceCommitmentVersion": 1,
                    "expiresAt": 1768435200
                  },
                  "verifiedAt": "2026-09-13T12:00:00.000Z"
                }
              }
            }
          },
          "400": {
            "description": "`Invalid Content-Length header` or `Invalid JSON body`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "413": {
            "$ref": "#/components/responses/BodyTooLarge"
          },
          "415": {
            "description": "`Content-Type must be application/json`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/integrity/verify": {
      "post": {
        "operationId": "postIntegrityVerify",
        "tags": [
          "Web/App Integrity"
        ],
        "summary": "Combined web/webview integrity verdict",
        "description": "Combines three existing signals into one integrity verdict for a web or webview session; it adds no new scoring path: (1) the CPU/GPU attestation verdict, from an optional `challengeId` / `proof` pair where absence is neutral, (2) the calibrated risk score over a caller-supplied `signals` payload, and (3) the virtualization-corroboration marker read from the score's flags.\n\nNot enabled by default. When the capability is not enabled for your organisation, or on any fault, the route fails open to a neutral HTTP 200 `{\"ok\":true,\"integrity\":\"unverified\",\"signals\":{\"attestation\":\"unavailable\",\"virtualization\":\"unavailable\",\"score\":\"minimal\"},\"confidence\":50}`; it never answers 5xx or 404. The `attestation` label is masked exactly as on `POST /v1/attest/verify`.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:device"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "domain_id": {
                    "type": "string"
                  },
                  "kind": {
                    "type": "string",
                    "enum": [
                      "gpu",
                      "cpu"
                    ],
                    "default": "gpu"
                  },
                  "challengeId": {
                    "type": "string",
                    "description": "OPTIONAL — a prior `/v1/attest/challenge` id; absence skips the attestation leg (neutral)."
                  },
                  "proof": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "OPTIONAL CPU/GPU attestation proof, same internal wire shape as `/v1/attest/verify`'s `proof` — left open for the same reason."
                  },
                  "signals": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "The caller-supplied calibrated-score signals payload (same lenient envelope as `/v1/score` — accepts `{signals:{...}}` or a bare object)."
                  }
                }
              },
              "example": {
                "domain_id": "dom_3f2a8c91d6e5f470",
                "kind": "gpu",
                "challengeId": "chal_3c9b2f7e4a3d4c8e",
                "proof": {},
                "signals": {}
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The combined integrity verdict, or the neutral feature-off/fail-open band.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "featureEnabled",
                    "integrity",
                    "signals",
                    "confidence",
                    "verifiedAt"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "featureEnabled": {
                      "type": "boolean"
                    },
                    "integrity": {
                      "type": "string",
                      "enum": [
                        "trusted",
                        "suspicious",
                        "unverified"
                      ]
                    },
                    "signals": {
                      "type": "object",
                      "properties": {
                        "attestation": {
                          "type": "string",
                          "enum": [
                            "hardware",
                            "software",
                            "attested",
                            "suspicious",
                            "failed",
                            "unavailable"
                          ]
                        },
                        "virtualization": {
                          "type": "string",
                          "enum": [
                            "corroborated",
                            "unavailable"
                          ]
                        },
                        "score": {
                          "type": "string",
                          "description": "The calibrated engine's `riskLevel` band."
                        }
                      }
                    },
                    "confidence": {
                      "type": "integer",
                      "minimum": 0,
                      "maximum": 100
                    },
                    "reason": {
                      "type": "string",
                      "description": "Present only on the neutral/feature-off band (e.g. noxtrust_disabled, noxtrust_tenant_disabled, tenant_db_unavailable, score_fault_neutral, internal_neutral)."
                    },
                    "verifiedAt": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "featureEnabled": true,
                  "integrity": "trusted",
                  "signals": {
                    "attestation": "hardware",
                    "virtualization": "corroborated",
                    "score": "example-score"
                  },
                  "confidence": 0,
                  "reason": "user_requested",
                  "verifiedAt": "2026-09-13T12:00:00.000Z"
                }
              }
            }
          },
          "400": {
            "description": "`Invalid Content-Length header`, `Invalid JSON body`, or `Invalid body`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "413": {
            "$ref": "#/components/responses/BodyTooLarge"
          },
          "415": {
            "description": "`Content-Type must be application/json`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/app-config": {
      "post": {
        "operationId": "postAppConfig",
        "tags": [
          "Mobile App Config"
        ],
        "summary": "Forced-update and kill-switch decision for an app launch",
        "description": "Server-to-server call from your backend (for example the backend-for-frontend a mobile app authenticates to) that decides one launch outcome for a mobile app. Send `platform`, `appVersion` and, on Android, the client-asserted Play Integrity `appRecognitionVerdict`. The first rule that applies wins:\n\n1. `reason: \"killed\"` — an emergency kill switch is active.\n2. `reason: \"forced_update\"` — `appVersion` is below the minimum version configured for the platform. This is a forced-update nudge, not an anti-tamper control: a patched app can report any version.\n3. `reason: \"app_not_recognized\"` — Android only, when `appRecognitionVerdict` is not `PLAY_RECOGNIZED`; a missing verdict counts as not recognised. This is advisory: the verdict is client-asserted and is not verified with Google, unlike `/v1/attest/android`. iOS is exempt.\n\nOtherwise `reason: \"ok\"`. Every decision is audited with coarse, non-personal facts. The request body is limited to 1024 bytes.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:device"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "platform",
                  "appVersion"
                ],
                "properties": {
                  "platform": {
                    "type": "string",
                    "enum": [
                      "android",
                      "ios"
                    ]
                  },
                  "appVersion": {
                    "type": "string"
                  },
                  "appRecognitionVerdict": {
                    "type": "string",
                    "description": "Client-asserted Play Integrity app-recognition verdict (e.g. `PLAY_RECOGNIZED`); Android only, ADVISORY, never independently verified."
                  }
                }
              },
              "example": {
                "platform": "android",
                "appVersion": "example-appVersion",
                "appRecognitionVerdict": "example-appRecognitionVerdict"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The resolved forced-update / kill-switch decision.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "allowed",
                    "reason",
                    "minVersion"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "allowed": {
                      "type": "boolean"
                    },
                    "reason": {
                      "type": "string",
                      "enum": [
                        "ok",
                        "killed",
                        "forced_update",
                        "app_not_recognized"
                      ]
                    },
                    "minVersion": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "The operator-configured floor for this platform, or `null` when unset."
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "allowed": true,
                  "reason": "ok",
                  "minVersion": "example-minVersion"
                }
              }
            }
          },
          "400": {
            "description": "`Invalid body`, `Invalid or missing platform`, `Invalid or missing appVersion`, or `Invalid appRecognitionVerdict`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "413": {
            "description": "`Payload too large` — over the 1024-byte cap.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/passkey/challenge": {
      "post": {
        "operationId": "postPasskeyChallenge",
        "tags": [
          "Passkey"
        ],
        "summary": "Mint a WebAuthn ceremony challenge",
        "description": "Server-to-server (`sk_` key, scope `write:passkey`). Mints a single-use, time-limited WebAuthn ceremony challenge. You supply an opaque `subject_id`, the exact `domain_id` of one of your active domains and the ceremony `purpose` (`register` or `assert`). The subject's existence is deliberately not checked at mint time. The domain must resolve to an active route of your organisation, and its origin is bound into the challenge, which prevents a later cross-domain ceremony.\n\nNot enabled by default: when the passkey capability is not enabled for your organisation, every passkey endpoint answers the `GatedNotFound` 404.",
        "security": [
          {
            "ApiKeyAuth": [
              "write:passkey"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "subject_id",
                  "domain_id",
                  "purpose"
                ],
                "properties": {
                  "subject_id": {
                    "type": "string",
                    "description": "Opaque caller-generated subject correlation id."
                  },
                  "domain_id": {
                    "type": "string",
                    "description": "The tenant's exact registered domain id this ceremony is bound to."
                  },
                  "purpose": {
                    "type": "string",
                    "enum": [
                      "register",
                      "assert"
                    ]
                  }
                }
              },
              "example": {
                "subject_id": "subj_4821",
                "domain_id": "dom_3f2a8c91d6e5f470",
                "purpose": "register"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A minted challenge plus the WebAuthn RP/ceremony parameters, or a closed `ok:false` refusal.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "required": [
                        "ok",
                        "challenge",
                        "purpose",
                        "ttlSeconds",
                        "rp",
                        "pubKeyCredParams"
                      ],
                      "properties": {
                        "ok": {
                          "type": "boolean",
                          "enum": [
                            true
                          ]
                        },
                        "challenge": {
                          "type": "string"
                        },
                        "purpose": {
                          "type": "string",
                          "enum": [
                            "register",
                            "assert"
                          ]
                        },
                        "ttlSeconds": {
                          "type": "integer"
                        },
                        "rp": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string",
                              "description": "The WebAuthn `rpId` derived from the tenant's registered origin."
                            },
                            "origins": {
                              "type": "array",
                              "items": {
                                "type": "string",
                                "format": "uri"
                              }
                            }
                          }
                        },
                        "pubKeyCredParams": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "type": {
                                "type": "string",
                                "enum": [
                                  "public-key"
                                ]
                              },
                              "alg": {
                                "type": "integer",
                                "description": "COSE algorithm id (ES256 -7 or RS256 -257)."
                              }
                            }
                          }
                        }
                      }
                    },
                    {
                      "type": "object",
                      "required": [
                        "ok",
                        "reason"
                      ],
                      "properties": {
                        "ok": {
                          "type": "boolean",
                          "enum": [
                            false
                          ]
                        },
                        "reason": {
                          "type": "string",
                          "enum": [
                            "invalid_request",
                            "purpose_mismatch",
                            "client_data_invalid",
                            "challenge_invalid",
                            "challenge_mismatch",
                            "origin_not_allowed",
                            "rp_id_mismatch",
                            "user_not_present",
                            "user_not_verified",
                            "attestation_invalid",
                            "attestation_signature_invalid",
                            "unsupported_algorithm",
                            "assertion_signature_invalid",
                            "sign_count_regression",
                            "subject_unverified",
                            "credential_exists",
                            "credential_unknown",
                            "storage_error",
                            "step_up_unconfigured",
                            "step_up_transport_error",
                            "step_up_provider_error",
                            "step_up_no_match",
                            "step_up_reference_required",
                            "aaguid_blocked",
                            "attestation_required",
                            "attestation_untrusted",
                            "aaguid_status_rejected",
                            "step_up_reference_replayed",
                            "step_up_claim_unavailable"
                          ]
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "ok": true,
                  "challenge": "Y2hhbGxlbmdlLW5vbmNlLTAx",
                  "purpose": "register",
                  "ttlSeconds": 3600,
                  "rp": {
                    "id": "example-id",
                    "origins": [
                      "https://example.com"
                    ]
                  },
                  "pubKeyCredParams": [
                    {
                      "type": "public-key",
                      "alg": 1
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "`{\"ok\":false,\"reason\":\"invalid_request\"}` — malformed body, missing fields, or an unresolvable `domain_id`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "reason"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "reason": {
                      "type": "string",
                      "enum": [
                        "invalid_request",
                        "purpose_mismatch",
                        "client_data_invalid",
                        "challenge_invalid",
                        "challenge_mismatch",
                        "origin_not_allowed",
                        "rp_id_mismatch",
                        "user_not_present",
                        "user_not_verified",
                        "attestation_invalid",
                        "attestation_signature_invalid",
                        "unsupported_algorithm",
                        "assertion_signature_invalid",
                        "sign_count_regression",
                        "subject_unverified",
                        "credential_exists",
                        "credential_unknown",
                        "storage_error",
                        "step_up_unconfigured",
                        "step_up_transport_error",
                        "step_up_provider_error",
                        "step_up_no_match",
                        "step_up_reference_required",
                        "aaguid_blocked",
                        "attestation_required",
                        "attestation_untrusted",
                        "aaguid_status_rejected",
                        "step_up_reference_replayed",
                        "step_up_claim_unavailable"
                      ]
                    }
                  }
                },
                "example": {
                  "ok": false,
                  "reason": "invalid_request"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "404": {
            "$ref": "#/components/responses/GatedNotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/passkey/register": {
      "post": {
        "operationId": "postPasskeyRegister",
        "tags": [
          "Passkey"
        ],
        "summary": "Verify a WebAuthn attestation and register a passkey",
        "description": "Server-to-server (`sk_` key, scope `write:passkey`). Verifies a WebAuthn attestation and registers the credential. In order: the `register` challenge is consumed (single use); the bound subject must have an active, verified device or KYC proof; the attestation is verified against only the exact active domain bound into the challenge; an optional authenticator (AAGUID) trust policy may reject the credential before storage when it runs in enforce mode; the credential is stored against the opaque `subject_id`, with no personal data.\n\nEvery ceremony or policy refusal returns the same closed reason-code catalogue at a uniform HTTP 200 `{\"ok\":false}`, except `invalid_request` and `purpose_mismatch`, which answer 400, so a status code never reveals whether a credential exists. Availability is the same as for `POST /v1/passkey/challenge`.",
        "security": [
          {
            "ApiKeyAuth": [
              "write:passkey"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "challenge",
                  "attestationObject",
                  "clientDataJSON"
                ],
                "properties": {
                  "challenge": {
                    "type": "string",
                    "description": "base64url — the challenge minted by `POST /v1/passkey/challenge` with `purpose:'register'`."
                  },
                  "attestationObject": {
                    "type": "string",
                    "description": "base64url CBOR WebAuthn attestation object."
                  },
                  "clientDataJSON": {
                    "type": "string",
                    "description": "base64url WebAuthn `clientDataJSON`."
                  },
                  "transports": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "OPTIONAL authenticator transports (e.g. `usb`, `nfc`, `internal`), persisted comma-joined."
                  }
                }
              },
              "example": {
                "challenge": "Y2hhbGxlbmdlLW5vbmNlLTAx",
                "attestationObject": "example-attestationObject",
                "clientDataJSON": "example-clientDataJSON",
                "transports": [
                  "example-transports"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The registered credential id + bound subject, or a closed `ok:false` refusal.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "required": [
                        "ok",
                        "credentialId",
                        "subjectId"
                      ],
                      "properties": {
                        "ok": {
                          "type": "boolean",
                          "enum": [
                            true
                          ]
                        },
                        "credentialId": {
                          "type": "string"
                        },
                        "subjectId": {
                          "type": "string"
                        }
                      }
                    },
                    {
                      "type": "object",
                      "required": [
                        "ok",
                        "reason"
                      ],
                      "properties": {
                        "ok": {
                          "type": "boolean",
                          "enum": [
                            false
                          ]
                        },
                        "reason": {
                          "type": "string",
                          "enum": [
                            "invalid_request",
                            "purpose_mismatch",
                            "client_data_invalid",
                            "challenge_invalid",
                            "challenge_mismatch",
                            "origin_not_allowed",
                            "rp_id_mismatch",
                            "user_not_present",
                            "user_not_verified",
                            "attestation_invalid",
                            "attestation_signature_invalid",
                            "unsupported_algorithm",
                            "assertion_signature_invalid",
                            "sign_count_regression",
                            "subject_unverified",
                            "credential_exists",
                            "credential_unknown",
                            "storage_error",
                            "step_up_unconfigured",
                            "step_up_transport_error",
                            "step_up_provider_error",
                            "step_up_no_match",
                            "step_up_reference_required",
                            "aaguid_blocked",
                            "attestation_required",
                            "attestation_untrusted",
                            "aaguid_status_rejected",
                            "step_up_reference_replayed",
                            "step_up_claim_unavailable"
                          ]
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "ok": true,
                  "credentialId": "example-credentialId",
                  "subjectId": "subj_4821"
                }
              }
            }
          },
          "400": {
            "description": "`{\"ok\":false,\"reason\":\"invalid_request\"}` or `{\"ok\":false,\"reason\":\"purpose_mismatch\"}` — the only two reasons that map to HTTP 400.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "reason"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "reason": {
                      "type": "string",
                      "enum": [
                        "invalid_request",
                        "purpose_mismatch",
                        "client_data_invalid",
                        "challenge_invalid",
                        "challenge_mismatch",
                        "origin_not_allowed",
                        "rp_id_mismatch",
                        "user_not_present",
                        "user_not_verified",
                        "attestation_invalid",
                        "attestation_signature_invalid",
                        "unsupported_algorithm",
                        "assertion_signature_invalid",
                        "sign_count_regression",
                        "subject_unverified",
                        "credential_exists",
                        "credential_unknown",
                        "storage_error",
                        "step_up_unconfigured",
                        "step_up_transport_error",
                        "step_up_provider_error",
                        "step_up_no_match",
                        "step_up_reference_required",
                        "aaguid_blocked",
                        "attestation_required",
                        "attestation_untrusted",
                        "aaguid_status_rejected",
                        "step_up_reference_replayed",
                        "step_up_claim_unavailable"
                      ]
                    }
                  }
                },
                "example": {
                  "ok": false,
                  "reason": "invalid_request"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "404": {
            "$ref": "#/components/responses/GatedNotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/passkey/assert": {
      "post": {
        "operationId": "postPasskeyAssert",
        "tags": [
          "Passkey"
        ],
        "summary": "Verify a WebAuthn assertion",
        "description": "Server-to-server (`sk_` key, scope `write:passkey`). Verifies a WebAuthn assertion against a stored credential. In order: the `assert` challenge is consumed (single use) and yields the bound `subject_id`; the active credential is looked up by credential id (an unknown id gives the closed `credential_unknown`); the credential must belong to the challenge's subject (otherwise `challenge_mismatch`, so a challenge minted for subject A can never assert subject B's credential); the signature is verified over `authenticatorData || SHA-256(clientDataJSON)` with the stored public key, against only the domain bound into the challenge; the signature counter must strictly advance (otherwise `sign_count_regression`, a replay defence). On success the counter is advanced and the bound `subjectId` is returned.\n\nEvery failure returns the same uniform HTTP 200 `{\"ok\":false}`; credential-level reasons are an integrator diagnostic, not an enumeration oracle, because this surface is intra-organisation and credential ids are high-entropy. Availability is the same as for `POST /v1/passkey/challenge`.",
        "security": [
          {
            "ApiKeyAuth": [
              "write:passkey"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "challenge",
                  "credentialId",
                  "authenticatorData",
                  "clientDataJSON",
                  "signature"
                ],
                "properties": {
                  "challenge": {
                    "type": "string",
                    "description": "base64url — minted with `purpose:'assert'`."
                  },
                  "credentialId": {
                    "type": "string"
                  },
                  "authenticatorData": {
                    "type": "string",
                    "description": "base64url WebAuthn `authenticatorData`."
                  },
                  "clientDataJSON": {
                    "type": "string",
                    "description": "base64url WebAuthn `clientDataJSON`."
                  },
                  "signature": {
                    "type": "string",
                    "description": "base64url WebAuthn assertion signature."
                  }
                }
              },
              "example": {
                "challenge": "Y2hhbGxlbmdlLW5vbmNlLTAx",
                "credentialId": "example-credentialId",
                "authenticatorData": "example-authenticatorData",
                "clientDataJSON": "example-clientDataJSON",
                "signature": "MEUCIQDx1F2a3B4c5D6e7F8a9B0c1D2e3F4a5B6c7D8e9F0a1B2c3D4e5F6a7B8c"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The verified bound subject, or a closed `ok:false` refusal.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "required": [
                        "ok",
                        "verified",
                        "subjectId"
                      ],
                      "properties": {
                        "ok": {
                          "type": "boolean",
                          "enum": [
                            true
                          ]
                        },
                        "verified": {
                          "type": "boolean",
                          "enum": [
                            true
                          ]
                        },
                        "subjectId": {
                          "type": "string"
                        }
                      }
                    },
                    {
                      "type": "object",
                      "required": [
                        "ok",
                        "reason"
                      ],
                      "properties": {
                        "ok": {
                          "type": "boolean",
                          "enum": [
                            false
                          ]
                        },
                        "reason": {
                          "type": "string",
                          "enum": [
                            "invalid_request",
                            "purpose_mismatch",
                            "client_data_invalid",
                            "challenge_invalid",
                            "challenge_mismatch",
                            "origin_not_allowed",
                            "rp_id_mismatch",
                            "user_not_present",
                            "user_not_verified",
                            "attestation_invalid",
                            "attestation_signature_invalid",
                            "unsupported_algorithm",
                            "assertion_signature_invalid",
                            "sign_count_regression",
                            "subject_unverified",
                            "credential_exists",
                            "credential_unknown",
                            "storage_error",
                            "step_up_unconfigured",
                            "step_up_transport_error",
                            "step_up_provider_error",
                            "step_up_no_match",
                            "step_up_reference_required",
                            "aaguid_blocked",
                            "attestation_required",
                            "attestation_untrusted",
                            "aaguid_status_rejected",
                            "step_up_reference_replayed",
                            "step_up_claim_unavailable"
                          ]
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "ok": true,
                  "verified": true,
                  "subjectId": "subj_4821"
                }
              }
            }
          },
          "400": {
            "description": "`{\"ok\":false,\"reason\":\"invalid_request\"}` or `{\"ok\":false,\"reason\":\"purpose_mismatch\"}`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "reason"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "reason": {
                      "type": "string",
                      "enum": [
                        "invalid_request",
                        "purpose_mismatch",
                        "client_data_invalid",
                        "challenge_invalid",
                        "challenge_mismatch",
                        "origin_not_allowed",
                        "rp_id_mismatch",
                        "user_not_present",
                        "user_not_verified",
                        "attestation_invalid",
                        "attestation_signature_invalid",
                        "unsupported_algorithm",
                        "assertion_signature_invalid",
                        "sign_count_regression",
                        "subject_unverified",
                        "credential_exists",
                        "credential_unknown",
                        "storage_error",
                        "step_up_unconfigured",
                        "step_up_transport_error",
                        "step_up_provider_error",
                        "step_up_no_match",
                        "step_up_reference_required",
                        "aaguid_blocked",
                        "attestation_required",
                        "attestation_untrusted",
                        "aaguid_status_rejected",
                        "step_up_reference_replayed",
                        "step_up_claim_unavailable"
                      ]
                    }
                  }
                },
                "example": {
                  "ok": false,
                  "reason": "invalid_request"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "404": {
            "$ref": "#/components/responses/GatedNotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/handoff/mint": {
      "post": {
        "operationId": "postHandoffMint",
        "tags": [
          "Device Handoff"
        ],
        "summary": "Mint a browser-to-app handoff claim",
        "description": "Server-to-server (`sk_` key, scope `write:handoff`): the caller is your own backend, never a browser or a mobile device. Mints a session-bound, single-use claim that hands a verified browser session to a native app. It returns two independent 256-bit secrets, stored only as hashes: `exchangeCode`, the only value meant for the QR code or deep link, and `challenge`, a separate binding secret that you convey through your own out-of-band channel and never embed in the QR code. Both are required together at `POST /v1/handoff/consume`. Minting again for the same `sessionId` atomically supersedes any pending claim for that session, which supports cross-device rescans.\n\nNot enabled by default: when the capability is not enabled for your organisation both handoff endpoints answer the `GatedNotFound` 404.\n\n**Key scope availability.** At the time of writing the `write:handoff` scope is not among the scopes that can be selected when creating a server API key in the Backoffice, so a key created there cannot call the handoff endpoints.",
        "security": [
          {
            "ApiKeyAuth": [
              "write:handoff"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "sessionId"
                ],
                "properties": {
                  "sessionId": {
                    "type": "string",
                    "maxLength": 256,
                    "description": "Opaque caller-generated correlation id; no PII."
                  }
                }
              },
              "example": {
                "sessionId": "01J8Z3K7QN6R2S4T6V8W0X2Y4Z"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The minted claim secrets and TTL.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "exchangeCode",
                    "challenge",
                    "sessionId",
                    "ttlSeconds",
                    "expiresAt"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "exchangeCode": {
                      "type": "string",
                      "description": "base64url(32 random bytes) — the ONLY secret meant for the QR/deep-link."
                    },
                    "challenge": {
                      "type": "string",
                      "description": "base64url(32 random bytes) — conveyed OUT-OF-BAND, never in the QR."
                    },
                    "sessionId": {
                      "type": "string"
                    },
                    "ttlSeconds": {
                      "type": "integer"
                    },
                    "expiresAt": {
                      "type": "integer",
                      "description": "Epoch milliseconds."
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "exchangeCode": "example-exchangeCode",
                  "challenge": "Y2hhbGxlbmdlLW5vbmNlLTAx",
                  "sessionId": "01J8Z3K7QN6R2S4T6V8W0X2Y4Z",
                  "ttlSeconds": 3600,
                  "expiresAt": 1768435200
                }
              }
            }
          },
          "400": {
            "description": "`Invalid or missing sessionId` or `Invalid body`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "404": {
            "$ref": "#/components/responses/GatedNotFound"
          },
          "413": {
            "description": "`Payload too large` — over the 1024-byte cap.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/handoff/consume": {
      "post": {
        "operationId": "postHandoffConsume",
        "tags": [
          "Device Handoff"
        ],
        "summary": "Consume a browser-to-app handoff claim",
        "description": "Server-to-server (`sk_` key, scope `write:handoff`): called by your app's own backend when it resolves the deep link, never by the mobile device. The caller must present all of `sessionId`, `exchangeCode` and `challenge`. An exact match on every bound field, a pending status and an unexpired claim are all required, and the claim is consumed atomically, so an incorrect attempt never burns the real claim.\n\nEvery mismatch — a replay, another organisation, another session, a swapped challenge or an expired claim — gives the same closed `claim_invalid` rejection at a uniform HTTP 200, never a 4xx, because revealing which field failed would expose the claim's binding. Availability and the key-scope note are the same as for `POST /v1/handoff/mint`.",
        "security": [
          {
            "ApiKeyAuth": [
              "write:handoff"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "sessionId",
                  "exchangeCode",
                  "challenge"
                ],
                "properties": {
                  "sessionId": {
                    "type": "string",
                    "maxLength": 256
                  },
                  "exchangeCode": {
                    "type": "string",
                    "maxLength": 512,
                    "description": "The `exchangeCode` scanned from the QR/deep-link."
                  },
                  "challenge": {
                    "type": "string",
                    "maxLength": 512,
                    "description": "The separately-conveyed binding secret."
                  }
                }
              },
              "example": {
                "sessionId": "01J8Z3K7QN6R2S4T6V8W0X2Y4Z",
                "exchangeCode": "example-exchangeCode",
                "challenge": "Y2hhbGxlbmdlLW5vbmNlLTAx"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The consume outcome — always HTTP 200 whether accepted or refused.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "type": "object",
                      "required": [
                        "ok",
                        "sessionId"
                      ],
                      "properties": {
                        "ok": {
                          "type": "boolean",
                          "enum": [
                            true
                          ]
                        },
                        "sessionId": {
                          "type": "string"
                        }
                      }
                    },
                    {
                      "type": "object",
                      "required": [
                        "ok",
                        "reason"
                      ],
                      "properties": {
                        "ok": {
                          "type": "boolean",
                          "enum": [
                            false
                          ]
                        },
                        "reason": {
                          "type": "string",
                          "enum": [
                            "claim_invalid"
                          ]
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "ok": true,
                  "sessionId": "01J8Z3K7QN6R2S4T6V8W0X2Y4Z"
                }
              }
            }
          },
          "400": {
            "description": "`Invalid or missing sessionId/exchangeCode/challenge` or `Invalid body`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "404": {
            "$ref": "#/components/responses/GatedNotFound"
          },
          "413": {
            "description": "`Payload too large` — over the 2048-byte cap.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "500": {
            "$ref": "#/components/responses/InternalError"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/device-delegation/create": {
      "post": {
        "operationId": "deviceDelegationCreate",
        "tags": [
          "Device Delegation"
        ],
        "summary": "Create a subject-scoped device delegation",
        "description": "Creates a delegation of device authority for a subject. The delegation is born `active`, subject to a cap on active delegations per subject (`device_delegation_limit_exceeded` when the cap is reached). The organisation is always the authenticated one: a tenant id in the body is never used and is omitted from the response. Every id field must match `^[a-zA-Z0-9._:-]{1,128}$`, except the server-generated delegation `id`, which is a UUID.\n\nNot enabled by default: when the device-registry capability is not enabled for your organisation the route answers the `GatedNotFound` 404. The three delegation operations share one rate-limit bucket per API key.",
        "security": [
          {
            "ApiKeyAuth": [
              "write:identity"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "subjectId",
                  "delegatorId",
                  "delegateId"
                ],
                "properties": {
                  "subjectId": {
                    "type": "string",
                    "pattern": "^[a-zA-Z0-9._:-]{1,128}$",
                    "description": "The subject the delegation concerns (opaque, never raw PII)."
                  },
                  "delegatorId": {
                    "type": "string",
                    "pattern": "^[a-zA-Z0-9._:-]{1,128}$",
                    "description": "The principal granting the delegation."
                  },
                  "delegateId": {
                    "type": "string",
                    "pattern": "^[a-zA-Z0-9._:-]{1,128}$",
                    "description": "The device/principal receiving the delegation."
                  },
                  "scope": {
                    "type": "string",
                    "enum": [
                      "device_use",
                      "device_manage"
                    ],
                    "default": "device_use",
                    "description": "Defaults to `device_use` when omitted or not one of the closed values."
                  },
                  "evidenceRef": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "pattern": "^[a-zA-Z0-9._:-]{1,128}$",
                    "description": "Optional opaque id referencing the evidence/consent record justifying the delegation."
                  },
                  "expiresAt": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "format": "int64",
                    "description": "Optional epoch-ms timestamp. Omitted ⇒ no expiry. When present MUST be finite and strictly within `[now + 60000, now + 31536000000]` (a 1-minute floor, 1-year ceiling) — rejected, never clamped, outside that window."
                  },
                  "createdBy": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "pattern": "^[a-zA-Z0-9._:-]{1,128}$",
                    "description": "Optional opaque actor id for the audit trail."
                  }
                }
              },
              "example": {
                "subjectId": "subj_4821",
                "delegatorId": "dev_7a2b9c4d1e6f3a8b",
                "delegateId": "dev_2b9c4d1e6f3a8b7a",
                "scope": "device_use",
                "evidenceRef": "obj-front",
                "expiresAt": 1768435200,
                "createdBy": "tenant_42"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The minted delegation, born `active`. `tenantId` is omitted (the caller already knows its own tenant).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "delegation",
                    "requestId"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "delegation": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "subjectId": {
                          "type": "string"
                        },
                        "delegatorId": {
                          "type": "string"
                        },
                        "delegateId": {
                          "type": "string"
                        },
                        "scope": {
                          "type": "string",
                          "enum": [
                            "device_use",
                            "device_manage"
                          ]
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "active"
                          ]
                        },
                        "evidenceRef": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "expiresAt": {
                          "type": [
                            "integer",
                            "null"
                          ],
                          "format": "int64"
                        },
                        "revokedAt": {
                          "type": [
                            "integer",
                            "null"
                          ],
                          "format": "int64"
                        },
                        "createdBy": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "createdAt": {
                          "type": "integer",
                          "format": "int64"
                        },
                        "updatedAt": {
                          "type": "integer",
                          "format": "int64"
                        }
                      }
                    },
                    "requestId": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "delegation": {
                    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                    "subjectId": "subj_4821",
                    "delegatorId": "dev_7a2b9c4d1e6f3a8b",
                    "delegateId": "dev_2b9c4d1e6f3a8b7a",
                    "scope": "device_use",
                    "status": "active",
                    "evidenceRef": "obj-front",
                    "expiresAt": 1768435200,
                    "revokedAt": 1,
                    "createdBy": "tenant_42",
                    "createdAt": 1,
                    "updatedAt": 1
                  },
                  "requestId": "req-test"
                }
              }
            }
          },
          "400": {
            "description": "`device_delegation_invalid_subject_id` / `_delegator_id` / `_delegate_id` / `_evidence_ref` / `_expiry` / `_created_by` / `_request` / `_limit_exceeded`, or a generic `invalid_request` for a malformed body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "404": {
            "$ref": "#/components/responses/GatedNotFound"
          },
          "413": {
            "$ref": "#/components/responses/BodyTooLarge"
          },
          "415": {
            "description": "Non-JSON `Content-Type` (`invalid_request`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "description": "`device_delegation_storage_unavailable` — a D1 write fault.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/device-delegation/list": {
      "post": {
        "operationId": "deviceDelegationList",
        "tags": [
          "Device Delegation"
        ],
        "summary": "List a subject's active device delegations",
        "description": "Lists the active, non-expired delegations of a subject. A subject with no active delegations, or an unknown subject, returns an empty array, never a distinguishing status (no existence oracle). Availability and rate-limit bucket are the same as for `POST /v1/device-delegation/create`; a `401` never consumes the bucket.",
        "security": [
          {
            "ApiKeyAuth": [
              "write:identity"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "subjectId"
                ],
                "properties": {
                  "subjectId": {
                    "type": "string",
                    "description": "The subject whose active delegations to list."
                  }
                }
              },
              "example": {
                "subjectId": "subj_4821"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The subject's active, non-expired delegations (empty array if none / unknown subject).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "delegations",
                    "requestId"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "delegations": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "subjectId": {
                            "type": "string"
                          },
                          "delegatorId": {
                            "type": "string"
                          },
                          "delegateId": {
                            "type": "string"
                          },
                          "scope": {
                            "type": "string",
                            "enum": [
                              "device_use",
                              "device_manage"
                            ]
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "active"
                            ]
                          },
                          "evidenceRef": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "expiresAt": {
                            "type": [
                              "integer",
                              "null"
                            ],
                            "format": "int64"
                          },
                          "revokedAt": {
                            "type": [
                              "integer",
                              "null"
                            ],
                            "format": "int64"
                          },
                          "createdBy": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "createdAt": {
                            "type": "integer",
                            "format": "int64"
                          },
                          "updatedAt": {
                            "type": "integer",
                            "format": "int64"
                          }
                        }
                      }
                    },
                    "requestId": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "delegations": [
                    {
                      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                      "subjectId": "subj_4821",
                      "delegatorId": "dev_7a2b9c4d1e6f3a8b",
                      "delegateId": "dev_2b9c4d1e6f3a8b7a",
                      "scope": "device_use",
                      "status": "active",
                      "evidenceRef": "obj-front",
                      "expiresAt": 1768435200,
                      "revokedAt": 1,
                      "createdBy": "tenant_42",
                      "createdAt": 1,
                      "updatedAt": 1
                    }
                  ],
                  "requestId": "req-test"
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request` — `subjectId` missing.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "404": {
            "$ref": "#/components/responses/GatedNotFound"
          },
          "413": {
            "$ref": "#/components/responses/BodyTooLarge"
          },
          "415": {
            "description": "Non-JSON `Content-Type` (`invalid_request`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "description": "`device_delegation_storage_unavailable` — a D1 read fault.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/device-delegation/revoke": {
      "post": {
        "operationId": "deviceDelegationRevoke",
        "tags": [
          "Device Delegation"
        ],
        "summary": "Revoke a device delegation",
        "description": "Revokes a delegation. Revocation is terminal: a revoked delegation is never honoured again, and restoring access means creating a new delegation. A delegation id that belongs to another organisation answers `device_delegation_not_found`, byte-identical to an unknown id (no existence oracle). Availability and rate-limit bucket are the same as for `POST /v1/device-delegation/create`.",
        "security": [
          {
            "ApiKeyAuth": [
              "write:identity"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "id"
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "format": "uuid",
                    "description": "The delegation's own server-minted id (not the subject/delegator/delegate id)."
                  },
                  "revokedBy": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Optional opaque actor id for the audit trail; omitted ⇒ recorded as a SYSTEM actor."
                  }
                }
              },
              "example": {
                "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                "revokedBy": "example-revokedBy"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The delegation was revoked.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "revoked",
                    "requestId"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "revoked": {
                      "type": "boolean"
                    },
                    "requestId": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "revoked": true,
                  "requestId": "req-test"
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request` — `id` missing.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "404": {
            "description": "Either the capability is not enabled for your organisation (the `GatedNotFound` body), or the delegation `id` does not resolve for your organisation (`device_delegation_not_found`, byte-identical for an unknown id and an id of another organisation).",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "$ref": "#/components/schemas/ErrorEnvelope"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "V1 endpoint not found"
                          ]
                        },
                        "path": {
                          "type": "string"
                        },
                        "requestId": {
                          "type": "string"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "413": {
            "$ref": "#/components/responses/BodyTooLarge"
          },
          "415": {
            "description": "Non-JSON `Content-Type` (`invalid_request`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "description": "`device_delegation_storage_unavailable` — a D1 write fault.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/recovery/cases": {
      "post": {
        "operationId": "recoveryOpenCase",
        "tags": [
          "Account Recovery"
        ],
        "summary": "Open a recovery case (currently always refused)",
        "description": "Self-service recovery case opening is not available today. A well-formed request never creates a case: the route validates the shape of `installId` (a UUID, then discarded — it is never treated as a subject reference) and answers the same closed business rejection with HTTP 200, which is the status the mobile backend contract inspects. A request that carries a `subjectId` of any type is rejected with `400 invalid_request`, so that no key holder can name a foreign subject.\n\nNot enabled by default: when the device-registry capability is not enabled for your organisation the route answers the `GatedNotFound` 404. The four `/v1/recovery/*` operations share one rate-limit bucket per API key.",
        "security": [
          {
            "ApiKeyAuth": [
              "write:identity"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "installId",
                  "tier"
                ],
                "properties": {
                  "installId": {
                    "type": "string",
                    "format": "uuid",
                    "description": "Validated for shape only (UUID v1-5) and discarded — never a subject reference."
                  },
                  "tier": {
                    "type": "string",
                    "enum": [
                      "fresh_reverification",
                      "trusted_referee",
                      "alternate_evidence",
                      "device_history_attestation",
                      "dual_control_override"
                    ]
                  },
                  "evidenceRef": {
                    "type": "string",
                    "pattern": "^[a-zA-Z0-9._:-]{1,128}$",
                    "description": "Optional opaque id."
                  },
                  "subjectId": {
                    "description": "NOT part of the frozen contract. Any own-property `subjectId` (of any type, including `null`) is rejected with `400 invalid_request` — never accepted-and-ignored."
                  }
                }
              },
              "example": {
                "installId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                "tier": "fresh_reverification",
                "evidenceRef": "obj-front",
                "subjectId": "subj_4821"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Always the closed business rejection today: no case is created.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "reason",
                    "requestId"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "reason": {
                      "type": "string",
                      "enum": [
                        "subject_resolution_required"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "ok": false,
                  "reason": "subject_resolution_required",
                  "requestId": "req-test"
                }
              }
            }
          },
          "400": {
            "description": "Missing/invalid `installId` or `tier`, an invalid `evidenceRef` shape, or any own-property `subjectId` present.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "404": {
            "$ref": "#/components/responses/GatedNotFound"
          },
          "413": {
            "$ref": "#/components/responses/BodyTooLarge"
          },
          "415": {
            "description": "Non-JSON `Content-Type` (`invalid_request`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "description": "`registry_write_failed` — unexpected handler error (never a raw exception).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "reason": {
                      "type": "string",
                      "enum": [
                        "registry_write_failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "ok": false,
                  "reason": "registry_write_failed",
                  "requestId": "req-test"
                }
              }
            }
          }
        },
        "x-noxtica-status": "partial"
      }
    },
    "/v1/recovery/cases/{caseId}": {
      "get": {
        "operationId": "recoveryGetCase",
        "tags": [
          "Account Recovery"
        ],
        "summary": "Read a recovery case's status",
        "description": "Polls the status of a recovery case. The stored case is redacted before it is returned: `subjectId`, `evidenceRef`, `refereeId`, `fraudReviewVerdict`, `createdBy` and `resolutionReasonCode` are never part of the response. A `caseId` that belongs to another organisation answers the same `404` as an unknown id (no existence oracle). Availability and rate-limit bucket are the same as for `POST /v1/recovery/cases`.",
        "security": [
          {
            "ApiKeyAuth": [
              "write:identity"
            ]
          }
        ],
        "parameters": [
          {
            "name": "caseId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-zA-Z0-9._:-]{1,128}$"
            },
            "description": "Opaque case id, decoded by the router and re-validated inside the handler."
          }
        ],
        "responses": {
          "200": {
            "description": "The redacted case projection.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "case",
                    "requestId"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "case": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "tenantId": {
                          "type": "string"
                        },
                        "tier": {
                          "type": "string",
                          "enum": [
                            "fresh_reverification",
                            "trusted_referee",
                            "alternate_evidence",
                            "device_history_attestation",
                            "dual_control_override"
                          ]
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "opened",
                            "pending_referee",
                            "pending_dual_control",
                            "pending_fraud_review",
                            "approved",
                            "denied",
                            "blocked_external",
                            "expired"
                          ]
                        },
                        "resultingVerificationLevel": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "resultingStatus": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "active",
                            "active_limited",
                            "proof_restored"
                          ]
                        },
                        "slaDueAt": {
                          "type": "integer",
                          "format": "int64"
                        },
                        "resolvedAt": {
                          "type": [
                            "integer",
                            "null"
                          ],
                          "format": "int64"
                        },
                        "createdAt": {
                          "type": "integer",
                          "format": "int64"
                        },
                        "updatedAt": {
                          "type": "integer",
                          "format": "int64"
                        }
                      }
                    },
                    "requestId": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "case": {
                    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                    "tenantId": "tenant_42",
                    "tier": "fresh_reverification",
                    "status": "opened",
                    "resultingVerificationLevel": "example-resultingVerificationLevel",
                    "resultingStatus": "active",
                    "slaDueAt": 1,
                    "resolvedAt": 1,
                    "createdAt": 1,
                    "updatedAt": 1
                  },
                  "requestId": "req-test"
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request` (opaque-id shape violation), or `Invalid caseId` (router-level `decodeURIComponent` throw on malformed percent-encoding).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "404": {
            "description": "Either the capability is not enabled for your organisation (the `GatedNotFound` body), or `recovery_case_not_found`: the `caseId` is well formed but no case exists for your organisation (a case of another organisation resolves identically).",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "V1 endpoint not found"
                          ]
                        },
                        "path": {
                          "type": "string"
                        },
                        "requestId": {
                          "type": "string"
                        }
                      }
                    },
                    {
                      "type": "object",
                      "properties": {
                        "ok": {
                          "type": "boolean",
                          "enum": [
                            false
                          ]
                        },
                        "reason": {
                          "type": "string",
                          "enum": [
                            "recovery_case_not_found"
                          ]
                        },
                        "requestId": {
                          "type": "string"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "error": "V1 endpoint not found",
                  "path": "/v1/kyc/verify",
                  "requestId": "req-test"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "description": "`registry_write_failed` — unexpected handler error.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "reason": {
                      "type": "string",
                      "enum": [
                        "registry_write_failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "ok": false,
                  "reason": "registry_write_failed",
                  "requestId": "req-test"
                }
              }
            }
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/recovery/appeals": {
      "post": {
        "operationId": "recoveryOpenAppeal",
        "tags": [
          "Account Recovery"
        ],
        "summary": "Open an appeal (currently always refused)",
        "description": "Opening an appeal is not available today. Because no case can be opened, the route refuses unconditionally with the same closed reason as `POST /v1/recovery/cases`, and it does not read or validate the request body: any body, or none, produces the identical response. Availability and rate-limit bucket are the same as for the other recovery routes.",
        "security": [
          {
            "ApiKeyAuth": [
              "write:identity"
            ]
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "caseId": {
                    "type": "string",
                    "description": "Nominal frozen-BFF-contract field. Never read or validated by this handler."
                  }
                }
              },
              "example": {
                "caseId": "example-caseId"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Always the closed business rejection today: no appeal is created.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "reason",
                    "requestId"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "reason": {
                      "type": "string",
                      "enum": [
                        "subject_resolution_required"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "ok": false,
                  "reason": "subject_resolution_required",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "404": {
            "$ref": "#/components/responses/GatedNotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "description": "`registry_write_failed` — unexpected handler error.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "reason": {
                      "type": "string",
                      "enum": [
                        "registry_write_failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "ok": false,
                  "reason": "registry_write_failed",
                  "requestId": "req-test"
                }
              }
            }
          }
        },
        "x-noxtica-status": "partial"
      }
    },
    "/v1/recovery/appeals/{appealId}": {
      "get": {
        "operationId": "recoveryGetAppeal",
        "tags": [
          "Account Recovery"
        ],
        "summary": "Read an appeal's status",
        "description": "Polls the status of an appeal. Unlike a case, no field of an appeal is redacted. A missing appeal reuses the case reason `recovery_case_not_found`; there is no separate appeal-not-found code. Availability and rate-limit bucket are the same as for the other recovery routes.",
        "security": [
          {
            "ApiKeyAuth": [
              "write:identity"
            ]
          }
        ],
        "parameters": [
          {
            "name": "appealId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-zA-Z0-9._:-]{1,128}$"
            },
            "description": "Opaque appeal id, decoded by the router and re-validated inside the handler."
          }
        ],
        "responses": {
          "200": {
            "description": "The full (unredacted) appeal projection.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "appeal",
                    "requestId"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "appeal": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "tenantId": {
                          "type": "string"
                        },
                        "caseId": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "openedAt": {
                          "type": "integer",
                          "format": "int64"
                        },
                        "slaDueAt": {
                          "type": "integer",
                          "format": "int64"
                        },
                        "resolvedAt": {
                          "type": [
                            "integer",
                            "null"
                          ],
                          "format": "int64"
                        },
                        "outcome": {
                          "type": "string",
                          "enum": [
                            "pending",
                            "upheld",
                            "overturned",
                            "expired"
                          ]
                        },
                        "resolvedBy": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "createdAt": {
                          "type": "integer",
                          "format": "int64"
                        },
                        "updatedAt": {
                          "type": "integer",
                          "format": "int64"
                        }
                      }
                    },
                    "requestId": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "appeal": {
                    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                    "tenantId": "tenant_42",
                    "caseId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
                    "openedAt": 1,
                    "slaDueAt": 1,
                    "resolvedAt": 1,
                    "outcome": "pending",
                    "resolvedBy": "example-resolvedBy",
                    "createdAt": 1,
                    "updatedAt": 1
                  },
                  "requestId": "req-test"
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request` (opaque-id shape violation), or `Invalid appealId` (router-level `decodeURIComponent` throw).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "404": {
            "description": "Either the capability is not enabled for your organisation (the `GatedNotFound` body), or `recovery_case_not_found`: no appeal with that id exists for your organisation.",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "type": "object",
                      "properties": {
                        "error": {
                          "type": "string",
                          "enum": [
                            "V1 endpoint not found"
                          ]
                        },
                        "path": {
                          "type": "string"
                        },
                        "requestId": {
                          "type": "string"
                        }
                      }
                    },
                    {
                      "type": "object",
                      "properties": {
                        "ok": {
                          "type": "boolean",
                          "enum": [
                            false
                          ]
                        },
                        "reason": {
                          "type": "string",
                          "enum": [
                            "recovery_case_not_found"
                          ]
                        },
                        "requestId": {
                          "type": "string"
                        }
                      }
                    }
                  ]
                },
                "example": {
                  "error": "V1 endpoint not found",
                  "path": "/v1/kyc/verify",
                  "requestId": "req-test"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "description": "`registry_write_failed` — unexpected handler error.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "reason": {
                      "type": "string",
                      "enum": [
                        "registry_write_failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "ok": false,
                  "reason": "registry_write_failed",
                  "requestId": "req-test"
                }
              }
            }
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/wallet/status": {
      "post": {
        "operationId": "walletStatus",
        "tags": [
          "Wallet Status"
        ],
        "summary": "Read a subject's device status and verification level",
        "description": "Read-only, organisation-scoped device status and `verificationLevel` for a subject. It is built on the same trust decision that `POST /v1/kyc/reverify` reads, plus relying-party log, consent-receipt and pairwise-pseudonym transparency reads, each independently fail-closed. This is the identity and device wallet, not a payment wallet.\n\n`verificationLevel` is present only on a trusted decision, never on a proof-only link; `proofOnly: true` marks a proof-only partition (status `proofed_unbound`, level `null`). `stepUpRequired` is reported, never enforced here, only when the decision demands it. An unexpected internal fault answers `200` with every field null (fail-closed: never a 5xx, never a positive status).\n\nNot enabled by default: when the device-registry capability is not enabled for your organisation the route answers the `GatedNotFound` 404.",
        "security": [
          {
            "ApiKeyAuth": [
              "write:identity"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "subjectId"
                ],
                "properties": {
                  "subjectId": {
                    "type": "string",
                    "description": "The opaque FR-8 pseudonym identifying the device/subject."
                  }
                }
              },
              "example": {
                "subjectId": "subj_4821"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The readout — ALWAYS 200, including on internal fault (every field nulled in that case; never a happy-path 5xx).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "verificationLevel",
                    "status",
                    "pairwisePseudonym",
                    "consent",
                    "rpLog",
                    "requestId"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "verificationLevel": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Present only on a trusted decision."
                    },
                    "status": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "pairwisePseudonym": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "consent": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "properties": {
                        "version": {
                          "type": "string"
                        },
                        "grantedAt": {
                          "type": "string"
                        },
                        "revoked": {
                          "type": "boolean"
                        }
                      }
                    },
                    "rpLog": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "event": {
                            "type": "string"
                          },
                          "at": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "proofOnly": {
                      "type": "boolean",
                      "description": "Present (true) only for the proof-only partition."
                    },
                    "stepUpRequired": {
                      "type": "boolean",
                      "description": "Present (true) only when the authoritative decision demands step-up."
                    },
                    "requestId": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "verificationLevel": "verified",
                  "status": "example-status",
                  "pairwisePseudonym": "example-pairwisePseudonym",
                  "consent": {
                    "version": "example-version",
                    "grantedAt": "example-grantedAt",
                    "revoked": true
                  },
                  "rpLog": [
                    {
                      "event": "example-event",
                      "at": "example-at"
                    }
                  ],
                  "proofOnly": true,
                  "stepUpRequired": true,
                  "requestId": "req-test"
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request` — malformed body or missing `subjectId`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "$ref": "#/components/responses/ScopeForbidden"
          },
          "404": {
            "$ref": "#/components/responses/GatedNotFound"
          },
          "413": {
            "$ref": "#/components/responses/BodyTooLarge"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/wallet/suspend": {
      "post": {
        "operationId": "walletSuspend",
        "tags": [
          "Wallet Status"
        ],
        "summary": "Suspend a subject's device-bound wallet state",
        "description": "Executes the `suspended` transition for a subject's device-bound wallet state. Name the subject in one of two ways: `attestationId` (preferred, and it takes precedence when both are present), resolved server-side from a fresh single-use device-attestation claim; or `subjectId` (a trusted-caller fallback), which additionally requires the `write:identity:trusted-subject` scope and otherwise answers a genuine `403`.\n\nEvery refusal collapses to a closed result so that no response reveals whether a subject exists: an attestation that cannot be resolved gives `status: \"subject_not_attested\"`, and any illegal transition or internal fault gives `status: \"suspend_failed\"`. The route always answers `200`, with `suspended: true` on a legal transition. It shares the write-family rate-limit bucket of `POST /v1/kyc/verify`. Availability is the same as for `POST /v1/wallet/status`.",
        "security": [
          {
            "ApiKeyAuth": [
              "write:identity"
            ]
          },
          {
            "ApiKeyAuth": [
              "write:identity",
              "write:identity:trusted-subject"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "description": "EXACTLY one of `attestationId` or `subjectId` must be present (both may be sent; `attestationId` takes precedence and `subjectId` is then silently ignored).",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "attestationId": {
                    "type": "string",
                    "description": "Preferred. A fresh device-attestation reference the collector resolves to a subject server-side; consumed single-use."
                  },
                  "subjectId": {
                    "type": "string",
                    "description": "Trusted-caller fallback. Requires the additive `write:identity:trusted-subject` scope; the caller already knows the subject it names."
                  }
                }
              },
              "example": {
                "attestationId": "att_9c6b2f7e4a3d4c8e9f1a2b3c4d5e6f70",
                "subjectId": "subj_4821"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "ALWAYS 200. `suspended:true` on a legal transition; `suspended:false` with `status:'subject_not_attested'` on an attestation-resolution miss; `suspended:false` with `status:'suspend_failed'` on any illegal-transition reason or an internal fault.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "suspended",
                    "status",
                    "requestId"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "suspended": {
                      "type": "boolean"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "suspended",
                        "subject_not_attested",
                        "suspend_failed"
                      ]
                    },
                    "requestId": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "suspended": true,
                  "status": "suspended",
                  "requestId": "req-test"
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request` — malformed body, or neither `subjectId` nor `attestationId` present.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "description": "The `subjectId` fallback was used WITHOUT the additive `write:identity:trusted-subject` scope (the base `write:identity`-scope-missing case uses the standard `ScopeForbidden` shape).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "example": "API key does not have write:identity:trusted-subject scope"
                    },
                    "requestId": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "error": "API key does not have write:identity:trusted-subject scope",
                  "requestId": "req-test"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/GatedNotFound"
          },
          "413": {
            "$ref": "#/components/responses/BodyTooLarge"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/offline/nonce-pool": {
      "post": {
        "operationId": "offlineNoncePoolMint",
        "tags": [
          "Offline Capture"
        ],
        "summary": "Mint a batch of offline-capture nonces",
        "description": "Mints 1 to 5 (default 1) single-use, time-limited nonces while the caller has connectivity, for later redemption at `POST /v1/offline/capture-bundle`. This is a resumable-upload scope, not a truly offline start: the client must be online when it mints. Each nonce is stored only as a keyed digest and the raw nonce is returned exactly once. The default lifetime is 72 hours.\n\nA caller classified as first-party capture on its API key must hold an active legal-basis receipt to mint; otherwise it is refused with `403 kyc_legal_basis_receipt_required`. Ordinary tenant traffic is unaffected. Not enabled by default: when the capability is not enabled for your organisation the route answers the `GatedNotFound` 404.",
        "security": [
          {
            "ApiKeyAuth": [
              "write:identity"
            ]
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "count": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 5,
                    "default": 1,
                    "description": "Non-integer or out-of-range values fall back to the default (1) rather than erroring."
                  }
                }
              },
              "example": {
                "count": 1
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The minted nonce pool. Raw nonces are visible exactly once.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "nonces",
                    "requestId"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "nonces": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "nonce": {
                            "type": "string"
                          },
                          "expiresAt": {
                            "type": "integer",
                            "format": "int64"
                          }
                        }
                      }
                    },
                    "requestId": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "nonces": [
                    {
                      "nonce": "nonce_5f3a8c1e2d4b6f709182a3b4c5d6e7f8",
                      "expiresAt": 1768435200
                    }
                  ],
                  "requestId": "req-test"
                }
              }
            }
          },
          "400": {
            "description": "Malformed body, bad `Content-Length`, or a non-JSON-object body (`invalid_request`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "description": "`kyc_legal_basis_receipt_required` (legal-basis gate refusal), OR the standard scope-forbidden shape.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/GatedNotFound"
          },
          "413": {
            "$ref": "#/components/responses/BodyTooLarge"
          },
          "415": {
            "description": "Non-JSON `Content-Type` (`invalid_request`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "description": "`offline_capture_storage_unavailable` (digest secret unset / mint fault), or `kyc_first_party_provenance_unavailable` (legal-basis gate fault).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/offline/capture-bundle": {
      "post": {
        "operationId": "offlineCaptureBundleAdmit",
        "tags": [
          "Offline Capture"
        ],
        "summary": "Admit a deferred-upload offline capture bundle",
        "description": "Redeems a nonce minted by `POST /v1/offline/nonce-pool` to admit an on-device-encrypted, time-limited capture bundle for deferred upload. This endpoint never sees the bundle's encryption key or media, only control-plane admission fields. It is capture-only: a body that carries any verdict- or attestation-shaped key (`verdict`, `verified`, `attestationId`, `reasonCodes` and similar) is rejected before any nonce lookup or write, because attestation stays online-only.\n\nThe call is idempotent on the `Idempotency-Key` header: a replay with an identical body returns the same stored response byte for byte, even long after the nonce's lifetime has elapsed, and a replay with a different body under the same key is a `409` conflict. The request body is limited to 1 MiB. Availability and the legal-basis rule are the same as for `POST /v1/offline/nonce-pool`.",
        "security": [
          {
            "ApiKeyAuth": [
              "write:identity"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKeyRequired"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "bundleId",
                  "nonce",
                  "capturedAt"
                ],
                "properties": {
                  "bundleId": {
                    "type": "string",
                    "maxLength": 256,
                    "description": "Caller-assigned bundle identifier (accepted as `bundleId` or `bundle_id`)."
                  },
                  "nonce": {
                    "type": "string",
                    "description": "A nonce previously minted by `POST /v1/offline/nonce-pool`."
                  },
                  "capturedAt": {
                    "type": "integer",
                    "format": "int64",
                    "minimum": 0,
                    "description": "Epoch-millisecond capture timestamp (accepted as `capturedAt` or `captured_at`); must be a finite, non-negative safe integer."
                  }
                }
              },
              "example": {
                "bundleId": "example-bundleId",
                "nonce": "nonce_5f3a8c1e2d4b6f709182a3b4c5d6e7f8",
                "capturedAt": 0
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "The bundle admission was accepted (fresh claim or a byte-identical idempotent replay).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "bundleId",
                    "status",
                    "capturedAt"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "bundleId": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "accepted"
                      ]
                    },
                    "capturedAt": {
                      "type": "integer",
                      "format": "int64"
                    }
                  }
                },
                "example": {
                  "ok": true,
                  "bundleId": "example-bundleId",
                  "status": "accepted",
                  "capturedAt": 1
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request` (missing/invalid `Idempotency-Key` or required fields, malformed body), `offline_capture_verdict_claim_rejected` (verdict-shaped key present), or `offline_capture_nonce_invalid` (unknown nonce).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/InvalidApiKey"
          },
          "403": {
            "description": "`kyc_legal_basis_receipt_required`, or the standard scope-forbidden shape.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "404": {
            "$ref": "#/components/responses/GatedNotFound"
          },
          "409": {
            "description": "`offline_capture_idempotency_conflict` (same key, differing body), or `offline_capture_nonce_replayed` (nonce already claimed by a different bundle).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "410": {
            "description": "`offline_capture_bundle_expired` — the nonce is past its TTL; the nonce row is deleted and the bundle is never processed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "413": {
            "description": "Body exceeds 1 MiB (`body_too_large`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "415": {
            "description": "Non-JSON `Content-Type` (`invalid_request`).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "description": "`offline_capture_storage_unavailable` (digest secret unset, or a storage/admission fault), or `kyc_first_party_provenance_unavailable` (legal-basis gate fault, or a ref-stamp fault after a fresh claim — the claimed row is then deleted).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": "invalid_request",
                  "requestId": "req-test"
                }
              }
            }
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/apm/projects": {
      "get": {
        "operationId": "v1ApmListProjects",
        "tags": [
          "APM Observability"
        ],
        "summary": "List APM projects",
        "description": "Lists tenant-owned observability projects from PostgreSQL authority. Results are cursor-paginated and never cached.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:apm"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ApmListLimit"
          },
          {
            "$ref": "#/components/parameters/ApmCursor"
          }
        ],
        "responses": {
          "200": {
            "description": "Project page.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApmProjectList"
                },
                "example": {
                  "ok": true,
                  "items": [
                    {
                      "project_id": "checkout",
                      "display_name": "Checkout",
                      "state": "active",
                      "region_id": "us-central1",
                      "data_plane_id": "primary",
                      "capture_enabled": false,
                      "enabled_signals": [
                        "traces"
                      ],
                      "authority_epoch": 7,
                      "erasure_epoch": 2,
                      "created_at": "2026-08-01T00:00:00.000Z",
                      "updated_at": "2026-09-01T00:00:00.000Z"
                    }
                  ],
                  "count": 1,
                  "truncated": false,
                  "next_cursor": null,
                  "freshness": "postgres_authority",
                  "completeness": "complete"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ApmInvalid"
          },
          "401": {
            "$ref": "#/components/responses/ApmUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/ApmForbidden"
          },
          "429": {
            "$ref": "#/components/responses/ApmRateLimited"
          },
          "503": {
            "$ref": "#/components/responses/ApmControlUnavailable"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/apm/projects/{projectId}/environments": {
      "get": {
        "operationId": "v1ApmListProjectEnvironments",
        "tags": [
          "APM Observability"
        ],
        "summary": "List project environments",
        "description": "Lists environments belonging to one tenant-owned APM project from PostgreSQL authority.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:apm"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ApmProjectIdPath"
          },
          {
            "$ref": "#/components/parameters/ApmListLimit"
          },
          {
            "$ref": "#/components/parameters/ApmCursor"
          }
        ],
        "responses": {
          "200": {
            "description": "Environment page.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApmEnvironmentList"
                },
                "example": {
                  "ok": true,
                  "project_id": "checkout",
                  "items": [
                    {
                      "project_id": "checkout",
                      "environment_id": "prod",
                      "display_name": "Production",
                      "environment_kind": "production",
                      "state": "active",
                      "region_id": "us-central1",
                      "data_plane_id": "primary",
                      "capture_enabled": false,
                      "allowed_signals": [
                        "traces"
                      ],
                      "sampling_policy_id": "baseline",
                      "retention_policy_version": 3,
                      "privacy_policy_version": 2,
                      "authority_epoch": 7,
                      "erasure_epoch": 2,
                      "quota_manifest_revision": 4,
                      "parser_manifest_revision": 5,
                      "created_at": "2026-08-01T00:00:00.000Z",
                      "updated_at": "2026-09-01T00:00:00.000Z"
                    }
                  ],
                  "count": 1,
                  "truncated": false,
                  "next_cursor": null,
                  "freshness": "postgres_authority",
                  "completeness": "complete"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ApmInvalid"
          },
          "401": {
            "$ref": "#/components/responses/ApmUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/ApmForbidden"
          },
          "404": {
            "$ref": "#/components/responses/ApmNotFound"
          },
          "429": {
            "$ref": "#/components/responses/ApmRateLimited"
          },
          "503": {
            "$ref": "#/components/responses/ApmControlUnavailable"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/apm/projects/{projectId}/environments/{environmentId}/policy": {
      "get": {
        "operationId": "v1ApmGetEnvironmentPolicy",
        "tags": [
          "APM Observability"
        ],
        "summary": "Read an environment policy",
        "description": "Returns the authoritative environment policy plus bounded sampling and retention policy inventories.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:apm"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ApmProjectIdPath"
          },
          {
            "$ref": "#/components/parameters/ApmEnvironmentIdPath"
          }
        ],
        "responses": {
          "200": {
            "description": "Policy snapshot.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApmPolicySnapshot"
                },
                "example": {
                  "ok": true,
                  "project_id": "checkout",
                  "environment_id": "prod",
                  "policy": {
                    "project_id": "checkout",
                    "environment_id": "prod",
                    "display_name": "Production",
                    "environment_kind": "production",
                    "state": "active",
                    "region_id": "us-central1",
                    "data_plane_id": "primary",
                    "capture_enabled": false,
                    "allowed_signals": [
                      "traces"
                    ],
                    "sampling_policy_id": "baseline",
                    "retention_policy_version": 3,
                    "privacy_policy_version": 2,
                    "authority_epoch": 7,
                    "erasure_epoch": 2,
                    "quota_manifest_revision": 4,
                    "parser_manifest_revision": 5,
                    "created_at": "2026-08-01T00:00:00.000Z",
                    "updated_at": "2026-09-01T00:00:00.000Z"
                  },
                  "sampling_policies": [],
                  "sampling_policy_count": 0,
                  "sampling_policies_truncated": false,
                  "retention_policies": [],
                  "retention_policy_count": 0,
                  "retention_policies_truncated": false,
                  "freshness": {
                    "source": "postgres_authority",
                    "updated_at": "2026-09-01T00:00:00.000Z"
                  },
                  "completeness": {
                    "sampling_policies": "complete",
                    "retention_policies": "complete"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ApmInvalid"
          },
          "401": {
            "$ref": "#/components/responses/ApmUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/ApmForbidden"
          },
          "404": {
            "$ref": "#/components/responses/ApmNotFound"
          },
          "429": {
            "$ref": "#/components/responses/ApmRateLimited"
          },
          "503": {
            "$ref": "#/components/responses/ApmControlUnavailable"
          }
        },
        "x-noxtica-status": "available"
      },
      "put": {
        "operationId": "v1ApmUpdateEnvironmentPolicy",
        "tags": [
          "APM Observability"
        ],
        "summary": "Update an environment policy",
        "description": "Updates a closed allowlist using optimistic authority-epoch concurrency. While capture rollout is OFF, `capture_enabled: true` is unavailable and returns 409 `capture_unavailable`; clients may only leave it absent or set it false.",
        "security": [
          {
            "ApiKeyAuth": [
              "write:apm"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ApmProjectIdPath"
          },
          {
            "$ref": "#/components/parameters/ApmEnvironmentIdPath"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApmPolicyUpdate"
              },
              "example": {
                "expected_authority_epoch": 7,
                "capture_enabled": false,
                "allowed_signals": [
                  "traces"
                ],
                "sampling_policy_id": "baseline"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated authoritative policy.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApmPolicyUpdateResult"
                },
                "example": {
                  "ok": true,
                  "project_id": "checkout",
                  "environment_id": "prod",
                  "policy": {
                    "project_id": "checkout",
                    "environment_id": "prod",
                    "display_name": "Production",
                    "environment_kind": "production",
                    "state": "active",
                    "region_id": "us-central1",
                    "data_plane_id": "primary",
                    "capture_enabled": false,
                    "allowed_signals": [
                      "traces"
                    ],
                    "sampling_policy_id": "baseline",
                    "retention_policy_version": 3,
                    "privacy_policy_version": 2,
                    "authority_epoch": 8,
                    "erasure_epoch": 2,
                    "quota_manifest_revision": 4,
                    "parser_manifest_revision": 5,
                    "created_at": "2026-08-01T00:00:00.000Z",
                    "updated_at": "2026-09-21T00:00:00.000Z"
                  },
                  "count": 1,
                  "truncated": false,
                  "freshness": {
                    "source": "postgres_authority",
                    "updated_at": "2026-09-21T00:00:00.000Z"
                  },
                  "completeness": "complete"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ApmInvalid"
          },
          "401": {
            "$ref": "#/components/responses/ApmUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/ApmForbidden"
          },
          "404": {
            "$ref": "#/components/responses/ApmNotFound"
          },
          "409": {
            "description": "Capture is unavailable or the expected authority epoch is stale.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApmConflict"
                },
                "example": {
                  "ok": false,
                  "error": "capture_unavailable",
                  "available": false,
                  "reason": "capture_rollout_disabled",
                  "requestId": "req-test"
                }
              }
            }
          },
          "503": {
            "$ref": "#/components/responses/ApmControlUnavailable"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/apm/traces": {
      "get": {
        "operationId": "v1ApmSearchTraces",
        "tags": [
          "APM Observability"
        ],
        "summary": "Search traces",
        "description": "Searches the warehouse within one explicit project/environment and a range no longer than 31 days. Rows expose only the query allowlist; completeness and freshness are not inferred.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:apm"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ApmProjectIdQuery"
          },
          {
            "$ref": "#/components/parameters/ApmEnvironmentIdQuery"
          },
          {
            "$ref": "#/components/parameters/ApmFrom"
          },
          {
            "$ref": "#/components/parameters/ApmTo"
          },
          {
            "$ref": "#/components/parameters/ApmQueryLimit"
          },
          {
            "$ref": "#/components/parameters/ApmCursor"
          },
          {
            "name": "service_name",
            "in": "query",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256,
              "pattern": "^[A-Za-z0-9._:/-]+$"
            }
          },
          {
            "name": "release_id",
            "in": "query",
            "schema": {
              "$ref": "#/components/schemas/ApmScopedId"
            }
          },
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "ok",
                "error"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Trace summary page.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApmTraceSearchResult"
                },
                "example": {
                  "ok": true,
                  "available": true,
                  "project_id": "checkout",
                  "environment_id": "prod",
                  "items": [
                    {
                      "traceId": "0123456789abcdef0123456789abcdef",
                      "startTime": "2026-09-20T12:00:00.000Z",
                      "partial": false,
                      "completeness": "complete",
                      "freshnessWatermark": "2026-09-20T12:01:00.000Z",
                      "ingestedAt": "2026-09-20T12:01:01.000Z"
                    }
                  ],
                  "count": 1,
                  "truncated": false,
                  "next_cursor": null,
                  "partial": false,
                  "completeness": "complete",
                  "freshness": {
                    "watermark": "2026-09-20T12:01:00.000Z",
                    "ingested_at": "2026-09-20T12:01:01.000Z"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ApmInvalid"
          },
          "401": {
            "$ref": "#/components/responses/ApmUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/ApmForbidden"
          },
          "404": {
            "$ref": "#/components/responses/ApmNotFound"
          },
          "429": {
            "$ref": "#/components/responses/ApmRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ApmInternal"
          },
          "503": {
            "$ref": "#/components/responses/ApmWarehouseUnavailable"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/apm/traces/{traceId}": {
      "get": {
        "operationId": "v1ApmGetTrace",
        "tags": [
          "APM Observability"
        ],
        "summary": "Read trace detail",
        "description": "Returns a trace summary and a bounded timeline. Parent-edge completeness is explicitly false in this launch contract.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:apm"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ApmTraceIdPath"
          },
          {
            "$ref": "#/components/parameters/ApmProjectIdQuery"
          },
          {
            "$ref": "#/components/parameters/ApmEnvironmentIdQuery"
          },
          {
            "$ref": "#/components/parameters/ApmFrom"
          },
          {
            "$ref": "#/components/parameters/ApmTo"
          },
          {
            "$ref": "#/components/parameters/ApmQueryLimit"
          }
        ],
        "responses": {
          "200": {
            "description": "Trace detail and timeline.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApmTraceDetailResult"
                },
                "example": {
                  "ok": true,
                  "available": true,
                  "project_id": "checkout",
                  "environment_id": "prod",
                  "summary": {
                    "traceId": "0123456789abcdef0123456789abcdef",
                    "startTime": "2026-09-20T12:00:00.000Z",
                    "partial": false,
                    "completeness": "complete",
                    "freshnessWatermark": "2026-09-20T12:01:00.000Z",
                    "ingestedAt": "2026-09-20T12:01:01.000Z"
                  },
                  "timeline": [
                    {
                      "traceId": "0123456789abcdef0123456789abcdef",
                      "spanId": "aaaaaaaaaaaaaaaa",
                      "parentSpanId": "bbbbbbbbbbbbbbbb",
                      "completeness": "partial",
                      "ingestedAt": "2026-09-20T12:01:01.000Z"
                    }
                  ],
                  "count": 1,
                  "truncated": false,
                  "partial": true,
                  "completeness": {
                    "summary": "complete",
                    "timeline": "partial"
                  },
                  "freshness": {
                    "watermark": "2026-09-20T12:01:00.000Z",
                    "ingested_at": "2026-09-20T12:01:01.000Z"
                  },
                  "parent_edges_complete": false
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ApmInvalid"
          },
          "401": {
            "$ref": "#/components/responses/ApmUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/ApmForbidden"
          },
          "404": {
            "$ref": "#/components/responses/ApmNotFound"
          },
          "429": {
            "$ref": "#/components/responses/ApmRateLimited"
          },
          "500": {
            "$ref": "#/components/responses/ApmInternal"
          },
          "503": {
            "$ref": "#/components/responses/ApmWarehouseUnavailable"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/apm/services": {
      "get": {
        "operationId": "v1ApmListServices",
        "tags": [
          "APM Observability"
        ],
        "summary": "List service health",
        "description": "Returns bounded aggregate health rows for one project/environment and a range no longer than 31 days.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:apm"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ApmProjectIdQuery"
          },
          {
            "$ref": "#/components/parameters/ApmEnvironmentIdQuery"
          },
          {
            "$ref": "#/components/parameters/ApmFrom"
          },
          {
            "$ref": "#/components/parameters/ApmTo"
          },
          {
            "$ref": "#/components/parameters/ApmQueryLimit"
          }
        ],
        "responses": {
          "200": {
            "description": "Service health page.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApmServiceListResult"
                },
                "example": {
                  "ok": true,
                  "available": true,
                  "project_id": "checkout",
                  "environment_id": "prod",
                  "items": [
                    {
                      "service_name": "checkout-api",
                      "trace_count": 120,
                      "error_trace_count": 3,
                      "error_rate": 0.025,
                      "p50_duration_ms": 42,
                      "p95_duration_ms": 310,
                      "completeness": "unknown",
                      "freshness_watermark": "2026-09-20T12:01:00.000Z"
                    }
                  ],
                  "count": 1,
                  "truncated": false,
                  "partial": false,
                  "completeness": "unknown",
                  "freshness_watermark": "2026-09-20T12:01:00.000Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ApmInvalid"
          },
          "401": {
            "$ref": "#/components/responses/ApmUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/ApmForbidden"
          },
          "404": {
            "$ref": "#/components/responses/ApmNotFound"
          },
          "429": {
            "$ref": "#/components/responses/ApmRateLimited"
          },
          "503": {
            "$ref": "#/components/responses/ApmWarehouseUnavailable"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/apm/services/{serviceName}/health": {
      "get": {
        "operationId": "v1ApmGetServiceHealth",
        "tags": [
          "APM Observability"
        ],
        "summary": "Read service health and dependencies",
        "description": "Returns health plus dependency aggregates. Either warehouse subquery may be unavailable; `partial`, availability booleans, and `reason` report that honestly.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:apm"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ApmServiceNamePath"
          },
          {
            "$ref": "#/components/parameters/ApmProjectIdQuery"
          },
          {
            "$ref": "#/components/parameters/ApmEnvironmentIdQuery"
          },
          {
            "$ref": "#/components/parameters/ApmFrom"
          },
          {
            "$ref": "#/components/parameters/ApmTo"
          },
          {
            "$ref": "#/components/parameters/ApmQueryLimit"
          }
        ],
        "responses": {
          "200": {
            "description": "Service health and dependencies.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApmServiceHealthResult"
                },
                "example": {
                  "ok": true,
                  "available": true,
                  "partial": false,
                  "reason": null,
                  "project_id": "checkout",
                  "environment_id": "prod",
                  "service_name": "checkout-api",
                  "health": {
                    "service_name": "checkout-api",
                    "trace_count": 120,
                    "error_trace_count": 3,
                    "error_rate": 0.025,
                    "p50_duration_ms": 42,
                    "p95_duration_ms": 310,
                    "completeness": "unknown",
                    "freshness_watermark": "2026-09-20T12:01:00.000Z"
                  },
                  "health_available": true,
                  "items": [
                    {
                      "source_service": "checkout-api",
                      "target_service": "payments",
                      "protocol": "http",
                      "request_count": 50,
                      "error_count": 1,
                      "p50_duration_ms": 25,
                      "p95_duration_ms": 80,
                      "p99_duration_ms": 140,
                      "freshness_watermark": "2026-09-20T12:01:00.000Z"
                    }
                  ],
                  "count": 1,
                  "dependencies_available": true,
                  "truncated": false,
                  "completeness": "unknown",
                  "freshness_watermark": "2026-09-20T12:01:00.000Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ApmInvalid"
          },
          "401": {
            "$ref": "#/components/responses/ApmUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/ApmForbidden"
          },
          "404": {
            "$ref": "#/components/responses/ApmNotFound"
          },
          "429": {
            "$ref": "#/components/responses/ApmRateLimited"
          },
          "503": {
            "$ref": "#/components/responses/ApmWarehouseUnavailable"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/apm/releases/{releaseId}/health": {
      "get": {
        "operationId": "v1ApmGetReleaseHealth",
        "tags": [
          "APM Observability"
        ],
        "summary": "Read release health",
        "description": "Returns bounded aggregate health rows for one release within the required project/environment and time range.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:apm"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ApmReleaseIdPath"
          },
          {
            "$ref": "#/components/parameters/ApmProjectIdQuery"
          },
          {
            "$ref": "#/components/parameters/ApmEnvironmentIdQuery"
          },
          {
            "$ref": "#/components/parameters/ApmFrom"
          },
          {
            "$ref": "#/components/parameters/ApmTo"
          },
          {
            "$ref": "#/components/parameters/ApmQueryLimit"
          }
        ],
        "responses": {
          "200": {
            "description": "Release health page.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApmReleaseHealthResult"
                },
                "example": {
                  "ok": true,
                  "available": true,
                  "project_id": "checkout",
                  "environment_id": "prod",
                  "release_id": "2026.09.20",
                  "items": [
                    {
                      "release_id": "2026.09.20",
                      "build_id": "build-42",
                      "trace_count": 100,
                      "error_trace_count": 2,
                      "error_rate": 0.02,
                      "p50_duration_ms": 40,
                      "p95_duration_ms": 300,
                      "completeness": "unknown",
                      "freshness_watermark": "2026-09-20T12:01:00.000Z"
                    }
                  ],
                  "count": 1,
                  "truncated": false,
                  "partial": false,
                  "completeness": "unknown",
                  "freshness_watermark": "2026-09-20T12:01:00.000Z"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ApmInvalid"
          },
          "401": {
            "$ref": "#/components/responses/ApmUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/ApmForbidden"
          },
          "404": {
            "$ref": "#/components/responses/ApmNotFound"
          },
          "429": {
            "$ref": "#/components/responses/ApmRateLimited"
          },
          "503": {
            "$ref": "#/components/responses/ApmWarehouseUnavailable"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/apm/exports": {
      "post": {
        "operationId": "v1ApmCreateExport",
        "tags": [
          "APM Observability"
        ],
        "summary": "Create an asynchronous APM export",
        "description": "Creates a tenant-scoped manifest for a range no longer than 31 days. This endpoint never returns storage references, credentials, or a download URL.",
        "security": [
          {
            "ApiKeyAuth": [
              "write:apm"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApmExportCreate"
              },
              "example": {
                "project_id": "checkout",
                "environment_id": "prod",
                "from": "2026-09-20T00:00:00.000Z",
                "to": "2026-09-21T00:00:00.000Z",
                "fact_names": [
                  "apm_spans",
                  "apm_trace_summaries"
                ],
                "purpose": "incident_review",
                "expires_in_seconds": 3600
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Pending export manifest.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApmExportStatus"
                },
                "example": {
                  "ok": true,
                  "project_id": "checkout",
                  "environment_id": "prod",
                  "export_manifest_id": "550e8400-e29b-41d4-a716-446655440000",
                  "purpose": "incident_review",
                  "fact_names": [
                    "apm_spans",
                    "apm_trace_summaries"
                  ],
                  "state": "pending",
                  "row_count": null,
                  "byte_count": null,
                  "created_at": "2026-09-21T00:00:00.000Z",
                  "expires_at": "2026-09-21T01:00:00.000Z",
                  "completed_at": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ApmInvalid"
          },
          "401": {
            "$ref": "#/components/responses/ApmUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/ApmForbidden"
          },
          "404": {
            "$ref": "#/components/responses/ApmNotFound"
          },
          "503": {
            "$ref": "#/components/responses/ApmControlUnavailable"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/apm/exports/{exportId}": {
      "get": {
        "operationId": "v1ApmGetExport",
        "tags": [
          "APM Observability"
        ],
        "summary": "Read asynchronous export status",
        "description": "Returns the safe manifest projection and its real asynchronous state; no object reference or signing credential is exposed.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:export"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ApmExportIdPath"
          }
        ],
        "responses": {
          "200": {
            "description": "Export status.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApmExportStatus"
                },
                "example": {
                  "ok": true,
                  "project_id": "checkout",
                  "environment_id": "prod",
                  "export_manifest_id": "550e8400-e29b-41d4-a716-446655440000",
                  "purpose": "incident_review",
                  "fact_names": [
                    "apm_spans"
                  ],
                  "state": "running",
                  "row_count": null,
                  "byte_count": null,
                  "created_at": "2026-09-21T00:00:00.000Z",
                  "expires_at": "2026-09-21T01:00:00.000Z",
                  "completed_at": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ApmInvalid"
          },
          "401": {
            "$ref": "#/components/responses/ApmUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/ApmForbidden"
          },
          "404": {
            "$ref": "#/components/responses/ApmNotFound"
          },
          "429": {
            "$ref": "#/components/responses/ApmRateLimited"
          },
          "503": {
            "$ref": "#/components/responses/ApmControlUnavailable"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/apm/exports/{exportId}/download-grant": {
      "post": {
        "operationId": "v1ApmCreateExportDownloadGrant",
        "tags": [
          "APM Observability"
        ],
        "summary": "Request an export download grant",
        "description": "Reports readiness only. Collector signing authority is intentionally unavailable, so this launch contract never returns a URL, object reference, bearer token, or credential.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:export"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ApmExportIdPath"
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApmDownloadGrantRequest"
              },
              "example": {
                "expires_in_seconds": 60
              }
            }
          }
        },
        "responses": {
          "400": {
            "$ref": "#/components/responses/ApmInvalid"
          },
          "401": {
            "$ref": "#/components/responses/ApmUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/ApmForbidden"
          },
          "404": {
            "$ref": "#/components/responses/ApmNotFound"
          },
          "409": {
            "description": "Export is not ready or failed.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApmGrantUnavailable"
                },
                "example": {
                  "ok": false,
                  "available": false,
                  "reason": "export_not_ready",
                  "state": "running",
                  "requestId": "req-test"
                }
              }
            }
          },
          "410": {
            "description": "Export expired or was deleted.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApmGrantUnavailable"
                },
                "example": {
                  "ok": false,
                  "available": false,
                  "reason": "export_expired",
                  "state": "expired",
                  "requestId": "req-test"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/ApmRateLimited"
          },
          "503": {
            "description": "Signing authority or control-plane storage is unavailable.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/ApmGrantUnavailable"
                    },
                    {
                      "$ref": "#/components/schemas/ApmUnavailable"
                    }
                  ]
                },
                "example": {
                  "ok": false,
                  "available": false,
                  "reason": "download_signing_unavailable",
                  "state": "available",
                  "requestId": "req-test"
                }
              }
            }
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/apm/privacy/subjects/{subjectHandle}/exports/{requestId}": {
      "get": {
        "operationId": "v1ApmGetPrivacyExport",
        "tags": [
          "APM Observability"
        ],
        "summary": "Read subject export status",
        "description": "Hashes the opaque subject handle before repository access and returns only the safe export projection. The cleartext handle and its hash are never returned.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:privacy_request"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ApmSubjectHandlePath"
          },
          {
            "$ref": "#/components/parameters/ApmPrivacyRequestIdPath"
          }
        ],
        "responses": {
          "200": {
            "description": "Subject export status.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApmPrivacyExportStatus"
                },
                "example": {
                  "ok": true,
                  "privacy_request_id": "dsar-42",
                  "project_id": "checkout",
                  "environment_id": "prod",
                  "export_manifest_id": "550e8400-e29b-41d4-a716-446655440000",
                  "purpose": "privacy_subject_export",
                  "fact_names": [
                    "apm_spans"
                  ],
                  "state": "pending",
                  "row_count": null,
                  "byte_count": null,
                  "created_at": "2026-09-21T00:00:00.000Z",
                  "expires_at": "2026-09-21T01:00:00.000Z",
                  "completed_at": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ApmInvalid"
          },
          "401": {
            "$ref": "#/components/responses/ApmUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/ApmForbidden"
          },
          "404": {
            "$ref": "#/components/responses/ApmNotFound"
          },
          "429": {
            "$ref": "#/components/responses/ApmRateLimited"
          },
          "503": {
            "$ref": "#/components/responses/ApmControlUnavailable"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/apm/privacy/subjects/{subjectHandle}/erasures/{requestId}": {
      "get": {
        "operationId": "v1ApmGetPrivacyErasure",
        "tags": [
          "APM Observability"
        ],
        "summary": "Read subject erasure status",
        "description": "Returns aggregate deletion progress only. Subject identifiers, per-store object references, SQL, credentials, and PII are never exposed.",
        "security": [
          {
            "ApiKeyAuth": [
              "read:privacy_request"
            ]
          }
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/ApmSubjectHandlePath"
          },
          {
            "$ref": "#/components/parameters/ApmPrivacyRequestIdPath"
          }
        ],
        "responses": {
          "200": {
            "description": "Subject erasure status.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApmErasureStatus"
                },
                "example": {
                  "ok": true,
                  "privacy_request_id": "dsar-42",
                  "project_id": "checkout",
                  "environment_id": "prod",
                  "state": "running",
                  "attempts": 1,
                  "created_at": "2026-09-21T00:00:00.000Z",
                  "updated_at": "2026-09-21T00:05:00.000Z",
                  "completed_at": null,
                  "stores": {
                    "count": 3,
                    "pending": 1,
                    "running": 1,
                    "succeeded": 1,
                    "failed": 0
                  },
                  "deleted": {
                    "rows": 120,
                    "objects": 2,
                    "bytes": 4096
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ApmInvalid"
          },
          "401": {
            "$ref": "#/components/responses/ApmUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/ApmForbidden"
          },
          "404": {
            "$ref": "#/components/responses/ApmNotFound"
          },
          "429": {
            "$ref": "#/components/responses/ApmRateLimited"
          },
          "503": {
            "$ref": "#/components/responses/ApmControlUnavailable"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/traces": {
      "post": {
        "operationId": "v1ApmIngestTraces",
        "tags": [
          "APM Ingest"
        ],
        "summary": "Ingest an OTLP/HTTP trace export",
        "description": "OTLP/HTTP trace ingestion. Any OpenTelemetry SDK or Collector OTLP/HTTP exporter can send to it: the body is a proto3-JSON `ExportTraceServiceRequest` (`application/json`) or its protobuf encoding (`application/x-protobuf`), and any other Content-Type is rejected with `415`. `Content-Encoding: gzip` or `deflate` is accepted. The collector hosts reject a wire body above 1 MiB, a decompressed body above 4 MiB, and a request with more than 500 spans, so size your exporter batches accordingly.\n\nAuthenticate with an ingestion key (`Authorization: Bearer sk_apm_...`) whose allowed signals include `traces`; a server API key is never accepted.\n\n**Hosts.** Send the request to `https://ingest.noxtica.com` (production): this is the host the Backoffice shows next to an ingestion key. The same path and credential are also served by the collector hosts listed under `servers`.\n\nPer-key and per-project rate limits apply; a limited request answers `429` with a `Retry-After` header. The limit values differ between host implementations and are not part of this contract.\n\n**Errors.** Error bodies are JSON. The collector hosts answer a `google.rpc.Status`-shaped body (`code` is the gRPC status code and `details[0].reason` the reason); the dedicated ingest hosts answer `{\"code\": <HTTP status>, \"message\": \"...\", \"error\": \"<reason>\"}`. The reason strings (for example `apm_auth_invalid`, `apm_rate_limited`) are the same on both, so branch on the HTTP status and the reason, never on `code`. Success bodies follow the OTLP wire contract and use the request's own media type.",
        "security": [
          {
            "ApmIngestKeyAuth": []
          }
        ],
        "servers": [
          {
            "url": "https://ingest.noxtica.com",
            "description": "Production ingest host"
          },
          {
            "url": "https://collect.noxtica.com",
            "description": "Production collector host (same path and credential)"
          }
        ],
        "parameters": [
          {
            "name": "Content-Encoding",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "identity",
                "gzip",
                "deflate"
              ]
            },
            "description": "Defaults to `identity` (uncompressed) when absent. Any other value is rejected with 415."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OtlpExportTraceServiceRequest"
              },
              "example": {
                "resourceSpans": [
                  {
                    "resource": {
                      "attributes": [
                        {
                          "key": "service.name",
                          "value": {
                            "stringValue": "checkout-api"
                          }
                        }
                      ]
                    },
                    "scopeSpans": [
                      {
                        "scope": {
                          "name": "@noxtica/otel-shim",
                          "version": "1.0.0"
                        },
                        "spans": [
                          {
                            "traceId": "AAAAAAAAAAAAAAAAAAAAAA==",
                            "spanId": "AAAAAAAAAAA=",
                            "name": "GET /health",
                            "kind": "SPAN_KIND_SERVER",
                            "startTimeUnixNano": "1700000000000000000",
                            "endTimeUnixNano": "1700000000010000000",
                            "status": {
                              "code": "STATUS_CODE_OK"
                            }
                          }
                        ]
                      }
                    ]
                  }
                ]
              }
            },
            "application/x-protobuf": {
              "schema": {
                "type": "string",
                "format": "binary",
                "description": "Protobuf-encoded `ExportTraceServiceRequest` — the default wire format most OpenTelemetry SDK/Collector OTLP exporters send."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Export accepted. An empty object means every span was accepted; `partialSuccess` reports spans dropped during validation without failing the whole request.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OtlpTraceIngestResult"
                },
                "examples": {
                  "all_spans_accepted": {
                    "summary": "Every span accepted.",
                    "value": {}
                  },
                  "spans_partially_rejected": {
                    "summary": "Some spans failed validation.",
                    "value": {
                      "partialSuccess": {
                        "rejectedSpans": "3",
                        "errorMessage": "One or more spans failed validation and were not accepted"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`apm_malformed_otlp_json`/`apm_malformed_otlp_protobuf` — the body does not decode as a valid `ExportTraceServiceRequest` in its declared Content-Type.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OtlpStatus"
                },
                "examples": {
                  "malformed_json": {
                    "summary": "Body is not a valid proto3-JSON ExportTraceServiceRequest.",
                    "value": {
                      "code": 3,
                      "message": "Malformed OTLP JSON: invalid_json",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_malformed_otlp_json",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  },
                  "malformed_protobuf": {
                    "summary": "Body does not decode as a valid ExportTraceServiceRequest protobuf message.",
                    "value": {
                      "code": 3,
                      "message": "Malformed OTLP protobuf: decode_failed",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_malformed_otlp_protobuf",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid `sk_apm_` bearer credential, or the credential's `effective_at`/`expires_at` window excludes now. A tenant `ApiKeyAuth` `sk_` key is never accepted here.",
            "headers": {
              "WWW-Authenticate": {
                "schema": {
                  "type": "string"
                },
                "description": "On the collector hosts always `Bearer realm=\"noxtica-otlp\", charset=\"UTF-8\"`; the ingest hosts do not send it."
              },
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OtlpStatus"
                },
                "examples": {
                  "auth_missing": {
                    "summary": "No Authorization header.",
                    "value": {
                      "code": 16,
                      "message": "Authentication failed",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_auth_missing",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  },
                  "auth_invalid": {
                    "summary": "Credential does not resolve to an active key.",
                    "value": {
                      "code": 16,
                      "message": "Authentication failed",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_auth_invalid",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  },
                  "auth_expired": {
                    "summary": "now is outside [effective_at, expires_at).",
                    "value": {
                      "code": 16,
                      "message": "Authentication failed",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_auth_expired",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "The credential is active but not authorized for trace ingest.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OtlpStatus"
                },
                "examples": {
                  "scope_denied": {
                    "summary": "\"traces\" is not in the credential's allowed_signals.",
                    "value": {
                      "code": 7,
                      "message": "Trace ingest is not authorized",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_scope_denied",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  },
                  "purpose_disabled": {
                    "summary": "The credential's purpose_enabled flag is 0.",
                    "value": {
                      "code": 7,
                      "message": "Trace ingest is not authorized",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_purpose_disabled",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The wire or decompressed body exceeds its byte cap, or the request carries more than 500 spans.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OtlpStatus"
                },
                "examples": {
                  "body_too_large": {
                    "summary": "Wire body exceeds the 1 MiB cap.",
                    "value": {
                      "code": 8,
                      "message": "Request body exceeds the OTLP JSON limit",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_body_too_large",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  },
                  "decompressed_too_large": {
                    "summary": "Decompressed body exceeds the 4 MiB cap.",
                    "value": {
                      "code": 8,
                      "message": "Decompressed request body exceeds the OTLP JSON limit",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_body_too_large",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  },
                  "batch_too_large": {
                    "summary": "More than 500 spans in one request.",
                    "value": {
                      "code": 8,
                      "message": "A request may contain at most 500 spans",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_batch_too_large",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "415": {
            "description": "Content-Type is not `application/json`, or Content-Encoding is set to a value other than `identity`, `gzip`, or `deflate`.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OtlpStatus"
                },
                "examples": {
                  "unsupported_content_type": {
                    "summary": "Content-Type header is missing or not application/json.",
                    "value": {
                      "code": 3,
                      "message": "Content-Type must be application/json",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_unsupported_media_type",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  },
                  "unsupported_content_encoding": {
                    "summary": "Content-Encoding is set to something other than identity/gzip/deflate.",
                    "value": {
                      "code": 3,
                      "message": "Unsupported Content-Encoding",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_unsupported_media_type",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Trace ingest rate limit exceeded (600 requests / 60s per `tenantId:projectId`).",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the bucket allows another request."
              },
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OtlpStatus"
                },
                "example": {
                  "code": 8,
                  "message": "Trace ingest rate limit exceeded",
                  "details": [
                    {
                      "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                      "reason": "apm_rate_limited",
                      "domain": "ingest.noxtica.com",
                      "metadata": {
                        "requestId": "req-test",
                        "retryable": "true"
                      }
                    }
                  ]
                }
              }
            }
          },
          "503": {
            "description": "The tenant authority scope could not be confirmed, or the durable ingest queue is unavailable.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always `5` on this status."
              },
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OtlpStatus"
                },
                "examples": {
                  "authority_unavailable": {
                    "summary": "Tenant authority scope confirmation failed.",
                    "value": {
                      "code": 14,
                      "message": "Authority unavailable",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_authority_unavailable",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "true"
                          }
                        }
                      ]
                    }
                  },
                  "queue_unavailable": {
                    "summary": "The durable ingest queue binding is missing or rejected the message.",
                    "value": {
                      "code": 14,
                      "message": "Trace ingest queue is unavailable",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_queue_unavailable",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "true"
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-noxtica-status": "partial"
      }
    },
    "/v1/metrics": {
      "post": {
        "operationId": "v1ApmIngestMetrics",
        "tags": [
          "APM Ingest"
        ],
        "summary": "Ingest an OTLP/HTTP metrics export",
        "description": "OTLP/HTTP metrics ingestion: a proto3-JSON `ExportMetricsServiceRequest` (`application/json`) or its protobuf encoding (`application/x-protobuf`); any other Content-Type is rejected with `415`. `Content-Encoding: gzip` or `deflate` is accepted. The collector hosts reject a wire body above 1 MiB, a decompressed body above 4 MiB, and a request with more than 500 data points across every metric's `gauge`, `sum`, `histogram`, `exponentialHistogram` and `summary` arrays.\n\nAuthenticate with an ingestion key (`Authorization: Bearer sk_apm_...`) whose allowed signals include `metrics`.\n\n**Hosts.** Send the request to `https://ingest.noxtica.com` (production): this is the host the Backoffice shows next to an ingestion key. The same path and credential are also served by the collector hosts listed under `servers`.\n\nPer-key and per-project rate limits apply; a limited request answers `429` with a `Retry-After` header. The limit values differ between host implementations and are not part of this contract.\n\n**Errors.** Error bodies are JSON. The collector hosts answer a `google.rpc.Status`-shaped body (`code` is the gRPC status code and `details[0].reason` the reason); the dedicated ingest hosts answer `{\"code\": <HTTP status>, \"message\": \"...\", \"error\": \"<reason>\"}`. The reason strings (for example `apm_auth_invalid`, `apm_rate_limited`) are the same on both, so branch on the HTTP status and the reason, never on `code`. Success bodies follow the OTLP wire contract and use the request's own media type.",
        "security": [
          {
            "ApmIngestKeyAuth": []
          }
        ],
        "servers": [
          {
            "url": "https://ingest.noxtica.com",
            "description": "Production ingest host"
          },
          {
            "url": "https://collect.noxtica.com",
            "description": "Production collector host (same path and credential)"
          }
        ],
        "parameters": [
          {
            "name": "Content-Encoding",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "identity",
                "gzip",
                "deflate"
              ]
            },
            "description": "Defaults to `identity` (uncompressed) when absent. Any other value is rejected with 415."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OtlpExportMetricsServiceRequest"
              },
              "example": {
                "resourceMetrics": [
                  {
                    "resource": {
                      "attributes": [
                        {
                          "key": "service.name",
                          "value": {
                            "stringValue": "checkout-api"
                          }
                        }
                      ]
                    },
                    "scopeMetrics": [
                      {
                        "scope": {
                          "name": "@noxtica/otel-shim",
                          "version": "1.0.0"
                        },
                        "metrics": [
                          {
                            "name": "http.server.duration",
                            "unit": "ms",
                            "gauge": {
                              "dataPoints": [
                                {
                                  "timeUnixNano": "1700000000000000000",
                                  "asDouble": 12.5
                                }
                              ]
                            }
                          }
                        ]
                      }
                    ]
                  }
                ]
              }
            },
            "application/x-protobuf": {
              "schema": {
                "type": "string",
                "format": "binary",
                "description": "Protobuf-encoded `ExportMetricsServiceRequest` — the default wire format most OpenTelemetry SDK/Collector OTLP exporters send."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Export accepted. An empty object means every data point was accepted; `partialSuccess` reports data points dropped during validation without failing the whole request.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OtlpMetricsIngestResult"
                },
                "examples": {
                  "all_points_accepted": {
                    "summary": "Every data point accepted.",
                    "value": {}
                  },
                  "points_partially_rejected": {
                    "summary": "Some data points failed validation.",
                    "value": {
                      "partialSuccess": {
                        "rejectedDataPoints": "3",
                        "errorMessage": "One or more metric data points failed validation and were not accepted"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`apm_malformed_metrics_payload` — the body does not decode as a valid `ExportMetricsServiceRequest` in its declared Content-Type.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OtlpStatus"
                },
                "example": {
                  "code": 3,
                  "message": "Malformed OTLP metrics payload: decode_failed",
                  "details": [
                    {
                      "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                      "reason": "apm_malformed_metrics_payload",
                      "domain": "ingest.noxtica.com",
                      "metadata": {
                        "requestId": "req-test",
                        "retryable": "false"
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid `sk_apm_` bearer credential, or the credential's `effective_at`/`expires_at` window excludes now. A tenant `ApiKeyAuth` `sk_` key is never accepted here.",
            "headers": {
              "WWW-Authenticate": {
                "schema": {
                  "type": "string"
                },
                "description": "On the collector hosts always `Bearer realm=\"noxtica-otlp\", charset=\"UTF-8\"`; the ingest hosts do not send it."
              },
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OtlpStatus"
                },
                "examples": {
                  "auth_missing": {
                    "summary": "No Authorization header.",
                    "value": {
                      "code": 16,
                      "message": "Authentication failed",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_auth_missing",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  },
                  "auth_invalid": {
                    "summary": "Credential does not resolve to an active key.",
                    "value": {
                      "code": 16,
                      "message": "Authentication failed",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_auth_invalid",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  },
                  "auth_expired": {
                    "summary": "now is outside [effective_at, expires_at).",
                    "value": {
                      "code": 16,
                      "message": "Authentication failed",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_auth_expired",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "The credential is active but not authorized for metrics ingest.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OtlpStatus"
                },
                "examples": {
                  "scope_denied": {
                    "summary": "\"metrics\" is not in the credential's allowed_signals.",
                    "value": {
                      "code": 7,
                      "message": "Metrics ingest is not authorized",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_scope_denied",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  },
                  "purpose_disabled": {
                    "summary": "The credential's purpose_enabled flag is 0.",
                    "value": {
                      "code": 7,
                      "message": "Metrics ingest is not authorized",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_purpose_disabled",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The wire or decompressed body exceeds its byte cap, or the request carries more than 500 data points.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OtlpStatus"
                },
                "examples": {
                  "body_too_large": {
                    "summary": "Wire body exceeds the 1 MiB cap.",
                    "value": {
                      "code": 8,
                      "message": "Request body exceeds the OTLP payload limit",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_body_too_large",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  },
                  "decompressed_too_large": {
                    "summary": "Decompressed body exceeds the 4 MiB cap.",
                    "value": {
                      "code": 8,
                      "message": "Decompressed request body exceeds the OTLP payload limit",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_body_too_large",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  },
                  "batch_too_large": {
                    "summary": "More than 500 data points in one request.",
                    "value": {
                      "code": 8,
                      "message": "A request may contain at most 500 data points",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_batch_too_large",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "415": {
            "description": "Content-Type is not `application/json` or `application/x-protobuf`, or Content-Encoding is set to a value other than `identity`, `gzip`, or `deflate`.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OtlpStatus"
                },
                "example": {
                  "code": 3,
                  "message": "Content-Type must be application/json or application/x-protobuf",
                  "details": [
                    {
                      "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                      "reason": "apm_unsupported_media_type",
                      "domain": "ingest.noxtica.com",
                      "metadata": {
                        "requestId": "req-test",
                        "retryable": "false"
                      }
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Metrics ingest rate limit exceeded (600 requests / 60s per `tenantId:projectId`).",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the bucket allows another request."
              },
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OtlpStatus"
                },
                "example": {
                  "code": 8,
                  "message": "Metrics ingest rate limit exceeded",
                  "details": [
                    {
                      "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                      "reason": "apm_rate_limited",
                      "domain": "ingest.noxtica.com",
                      "metadata": {
                        "requestId": "req-test",
                        "retryable": "true"
                      }
                    }
                  ]
                }
              }
            }
          },
          "503": {
            "description": "The tenant authority scope could not be confirmed, or the durable ingest queue is unavailable.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always `5` on this status."
              },
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OtlpStatus"
                },
                "examples": {
                  "authority_unavailable": {
                    "summary": "Tenant authority scope confirmation failed.",
                    "value": {
                      "code": 14,
                      "message": "Authority unavailable",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_authority_unavailable",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "true"
                          }
                        }
                      ]
                    }
                  },
                  "queue_unavailable": {
                    "summary": "The durable ingest queue binding is missing or rejected the message.",
                    "value": {
                      "code": 14,
                      "message": "Metrics ingest queue is unavailable",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_queue_unavailable",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "true"
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-noxtica-status": "partial"
      }
    },
    "/v1/logs": {
      "post": {
        "operationId": "v1ApmIngestLogs",
        "tags": [
          "APM Ingest"
        ],
        "summary": "Ingest an OTLP/HTTP logs export",
        "description": "OTLP/HTTP logs ingestion: a proto3-JSON `ExportLogsServiceRequest` (`application/json`) or its protobuf encoding (`application/x-protobuf`); any other Content-Type is rejected with `415`. `Content-Encoding: gzip` or `deflate` is accepted. The collector hosts reject a wire body above 1 MiB, a decompressed body above 4 MiB, and a request with more than 500 log records across every `resourceLogs[].scopeLogs[].logRecords[]`.\n\nAuthenticate with an ingestion key (`Authorization: Bearer sk_apm_...`) whose allowed signals include `logs`.\n\n**Hosts.** Send the request to `https://ingest.noxtica.com` (production): this is the host the Backoffice shows next to an ingestion key. The same path and credential are also served by the collector hosts listed under `servers`.\n\nPer-key and per-project rate limits apply; a limited request answers `429` with a `Retry-After` header. The limit values differ between host implementations and are not part of this contract.\n\n**Errors.** Error bodies are JSON. The collector hosts answer a `google.rpc.Status`-shaped body (`code` is the gRPC status code and `details[0].reason` the reason); the dedicated ingest hosts answer `{\"code\": <HTTP status>, \"message\": \"...\", \"error\": \"<reason>\"}`. The reason strings (for example `apm_auth_invalid`, `apm_rate_limited`) are the same on both, so branch on the HTTP status and the reason, never on `code`. Success bodies follow the OTLP wire contract and use the request's own media type.",
        "security": [
          {
            "ApmIngestKeyAuth": []
          }
        ],
        "servers": [
          {
            "url": "https://ingest.noxtica.com",
            "description": "Production ingest host"
          },
          {
            "url": "https://collect.noxtica.com",
            "description": "Production collector host (same path and credential)"
          }
        ],
        "parameters": [
          {
            "name": "Content-Encoding",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "identity",
                "gzip",
                "deflate"
              ]
            },
            "description": "Defaults to `identity` (uncompressed) when absent. Any other value is rejected with 415."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OtlpExportLogsServiceRequest"
              },
              "example": {
                "resourceLogs": [
                  {
                    "resource": {
                      "attributes": [
                        {
                          "key": "service.name",
                          "value": {
                            "stringValue": "checkout-api"
                          }
                        }
                      ]
                    },
                    "scopeLogs": [
                      {
                        "scope": {
                          "name": "@noxtica/otel-shim",
                          "version": "1.0.0"
                        },
                        "logRecords": [
                          {
                            "timeUnixNano": "1700000000000000000",
                            "severityNumber": 9,
                            "severityText": "INFO",
                            "body": {
                              "stringValue": "order placed"
                            }
                          }
                        ]
                      }
                    ]
                  }
                ]
              }
            },
            "application/x-protobuf": {
              "schema": {
                "type": "string",
                "format": "binary",
                "description": "Protobuf-encoded `ExportLogsServiceRequest` — the default wire format most OpenTelemetry SDK/Collector OTLP exporters send."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Export accepted. An empty object means every log record was accepted; `partialSuccess` reports log records dropped during validation without failing the whole request.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OtlpLogsIngestResult"
                },
                "examples": {
                  "all_records_accepted": {
                    "summary": "Every log record accepted.",
                    "value": {}
                  },
                  "records_partially_rejected": {
                    "summary": "Some log records failed validation.",
                    "value": {
                      "partialSuccess": {
                        "rejectedLogRecords": "3",
                        "errorMessage": "One or more log records failed validation and were not accepted"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`apm_malformed_logs_payload` — the body does not decode as a valid `ExportLogsServiceRequest` in its declared Content-Type.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OtlpStatus"
                },
                "example": {
                  "code": 3,
                  "message": "Malformed OTLP logs payload: decode_failed",
                  "details": [
                    {
                      "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                      "reason": "apm_malformed_logs_payload",
                      "domain": "ingest.noxtica.com",
                      "metadata": {
                        "requestId": "req-test",
                        "retryable": "false"
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid `sk_apm_` bearer credential, or the credential's `effective_at`/`expires_at` window excludes now. A tenant `ApiKeyAuth` `sk_` key is never accepted here.",
            "headers": {
              "WWW-Authenticate": {
                "schema": {
                  "type": "string"
                },
                "description": "On the collector hosts always `Bearer realm=\"noxtica-otlp\", charset=\"UTF-8\"`; the ingest hosts do not send it."
              },
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OtlpStatus"
                },
                "examples": {
                  "auth_missing": {
                    "summary": "No Authorization header.",
                    "value": {
                      "code": 16,
                      "message": "Authentication failed",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_auth_missing",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  },
                  "auth_invalid": {
                    "summary": "Credential does not resolve to an active key.",
                    "value": {
                      "code": 16,
                      "message": "Authentication failed",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_auth_invalid",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  },
                  "auth_expired": {
                    "summary": "now is outside [effective_at, expires_at).",
                    "value": {
                      "code": 16,
                      "message": "Authentication failed",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_auth_expired",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "The credential is active but not authorized for logs ingest.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OtlpStatus"
                },
                "examples": {
                  "scope_denied": {
                    "summary": "\"logs\" is not in the credential's allowed_signals.",
                    "value": {
                      "code": 7,
                      "message": "Logs ingest is not authorized",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_scope_denied",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  },
                  "purpose_disabled": {
                    "summary": "The credential's purpose_enabled flag is 0.",
                    "value": {
                      "code": 7,
                      "message": "Logs ingest is not authorized",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_purpose_disabled",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The wire or decompressed body exceeds its byte cap, or the request carries more than 500 log records.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OtlpStatus"
                },
                "examples": {
                  "body_too_large": {
                    "summary": "Wire body exceeds the 1 MiB cap.",
                    "value": {
                      "code": 8,
                      "message": "Request body exceeds the OTLP payload limit",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_body_too_large",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  },
                  "decompressed_too_large": {
                    "summary": "Decompressed body exceeds the 4 MiB cap.",
                    "value": {
                      "code": 8,
                      "message": "Decompressed request body exceeds the OTLP payload limit",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_body_too_large",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  },
                  "batch_too_large": {
                    "summary": "More than 500 log records in one request.",
                    "value": {
                      "code": 8,
                      "message": "A request may contain at most 500 log records",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_batch_too_large",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "415": {
            "description": "Content-Type is not `application/json` or `application/x-protobuf`, or Content-Encoding is set to a value other than `identity`, `gzip`, or `deflate`.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OtlpStatus"
                },
                "example": {
                  "code": 3,
                  "message": "Content-Type must be application/json or application/x-protobuf",
                  "details": [
                    {
                      "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                      "reason": "apm_unsupported_media_type",
                      "domain": "ingest.noxtica.com",
                      "metadata": {
                        "requestId": "req-test",
                        "retryable": "false"
                      }
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Logs ingest rate limit exceeded (600 requests / 60s per `tenantId:projectId`).",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the bucket allows another request."
              },
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OtlpStatus"
                },
                "example": {
                  "code": 8,
                  "message": "Logs ingest rate limit exceeded",
                  "details": [
                    {
                      "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                      "reason": "apm_rate_limited",
                      "domain": "ingest.noxtica.com",
                      "metadata": {
                        "requestId": "req-test",
                        "retryable": "true"
                      }
                    }
                  ]
                }
              }
            }
          },
          "503": {
            "description": "The tenant authority scope could not be confirmed, or the durable ingest queue is unavailable.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always `5` on this status."
              },
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OtlpStatus"
                },
                "examples": {
                  "authority_unavailable": {
                    "summary": "Tenant authority scope confirmation failed.",
                    "value": {
                      "code": 14,
                      "message": "Authority unavailable",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_authority_unavailable",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "true"
                          }
                        }
                      ]
                    }
                  },
                  "queue_unavailable": {
                    "summary": "The durable ingest queue binding is missing or rejected the message.",
                    "value": {
                      "code": 14,
                      "message": "Logs ingest queue is unavailable",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_queue_unavailable",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "true"
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-noxtica-status": "partial"
      }
    },
    "/v1/profiles": {
      "post": {
        "operationId": "v1ApmIngestProfiles",
        "tags": [
          "APM Ingest"
        ],
        "summary": "Ingest an OTLP/HTTP JSON profiles export",
        "description": "OTLP/HTTP JSON profiles ingestion, a proto3-JSON `ProfilesData` (`opentelemetry.proto.profiles.v1development`; profiling is still an OpenTelemetry development signal). Unlike traces, metrics and logs, `application/json` is the only media type on the collector hosts: protobuf is rejected with `415`. `Content-Encoding: gzip` or `deflate` is accepted. The collector hosts reject a wire body above 2 MiB, a decompressed body above 8 MiB, and a request with more than 20 profiles across every `resourceProfiles[].scopeProfiles[].profiles[]`. The dedicated ingest hosts additionally accept the multipart upload format sent by the Noxtica host agent; that format is internal to the agent and not part of this contract.\n\nEach accepted profile's raw bytes are stored before the row is queued, so if profile storage is unavailable the whole request fails with `503 apm_profile_storage_unavailable` even though authentication and validation succeeded.\n\nAuthenticate with an ingestion key (`Authorization: Bearer sk_apm_...`) whose allowed signals include `profiles`.\n\n**Hosts.** Send the request to `https://ingest.noxtica.com` (production): this is the host the Backoffice shows next to an ingestion key. The same path and credential are also served by the collector hosts listed under `servers`.\n\nPer-key and per-project rate limits apply; a limited request answers `429` with a `Retry-After` header. The limit values differ between host implementations and are not part of this contract.\n\n**Errors.** Error bodies are JSON. The collector hosts answer a `google.rpc.Status`-shaped body (`code` is the gRPC status code and `details[0].reason` the reason); the dedicated ingest hosts answer `{\"code\": <HTTP status>, \"message\": \"...\", \"error\": \"<reason>\"}`. The reason strings (for example `apm_auth_invalid`, `apm_rate_limited`) are the same on both, so branch on the HTTP status and the reason, never on `code`. Success bodies follow the OTLP wire contract and use the request's own media type.",
        "security": [
          {
            "ApmIngestKeyAuth": []
          }
        ],
        "servers": [
          {
            "url": "https://ingest.noxtica.com",
            "description": "Production ingest host"
          },
          {
            "url": "https://collect.noxtica.com",
            "description": "Production collector host (same path and credential)"
          }
        ],
        "parameters": [
          {
            "name": "Content-Encoding",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "identity",
                "gzip",
                "deflate"
              ]
            },
            "description": "Defaults to `identity` (uncompressed) when absent. Any other value is rejected with 415."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OtlpProfilesData"
              },
              "example": {
                "resourceProfiles": [
                  {
                    "resource": {
                      "attributes": [
                        {
                          "key": "service.name",
                          "value": {
                            "stringValue": "checkout-api"
                          }
                        }
                      ]
                    },
                    "scopeProfiles": [
                      {
                        "scope": {
                          "name": "@noxtica/otel-shim",
                          "version": "1.0.0"
                        },
                        "profiles": [
                          {
                            "profileId": "AAAAAAAAAAAAAAAAAAAAAA==",
                            "startTimeUnixNano": "1700000000000000000",
                            "endTimeUnixNano": "1700000001000000000"
                          }
                        ]
                      }
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Export accepted. An empty object means every profile was accepted and persisted; `partialSuccess` reports profiles dropped during validation, or stored with an unrecognized `profileType`, without failing the whole request.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OtlpProfilesIngestResult"
                },
                "examples": {
                  "all_profiles_accepted": {
                    "summary": "Every profile accepted.",
                    "value": {}
                  },
                  "profiles_partially_rejected": {
                    "summary": "Some profiles failed validation.",
                    "value": {
                      "partialSuccess": {
                        "rejectedProfiles": "1",
                        "errorMessage": "1 profile(s) failed validation and were not accepted"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`apm_malformed_profile_json` — the body is not a valid proto3-JSON `ProfilesData`.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OtlpStatus"
                },
                "example": {
                  "code": 3,
                  "message": "Malformed OTLP profiles JSON: invalid_resource_profiles",
                  "details": [
                    {
                      "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                      "reason": "apm_malformed_profile_json",
                      "domain": "ingest.noxtica.com",
                      "metadata": {
                        "requestId": "req-test",
                        "retryable": "false"
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid `sk_apm_` bearer credential, or the credential's `effective_at`/`expires_at` window excludes now. A tenant `ApiKeyAuth` `sk_` key is never accepted here.",
            "headers": {
              "WWW-Authenticate": {
                "schema": {
                  "type": "string"
                },
                "description": "On the collector hosts always `Bearer realm=\"noxtica-otlp\", charset=\"UTF-8\"`; the ingest hosts do not send it."
              },
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OtlpStatus"
                },
                "examples": {
                  "auth_missing": {
                    "summary": "No Authorization header.",
                    "value": {
                      "code": 16,
                      "message": "Authentication failed",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_auth_missing",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  },
                  "auth_invalid": {
                    "summary": "Credential does not resolve to an active key.",
                    "value": {
                      "code": 16,
                      "message": "Authentication failed",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_auth_invalid",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  },
                  "auth_expired": {
                    "summary": "now is outside [effective_at, expires_at).",
                    "value": {
                      "code": 16,
                      "message": "Authentication failed",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_auth_expired",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "The credential is active but not authorized for profile ingest.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OtlpStatus"
                },
                "examples": {
                  "scope_denied": {
                    "summary": "\"profiles\" is not in the credential's allowed_signals.",
                    "value": {
                      "code": 7,
                      "message": "Profile ingest is not authorized",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_scope_denied",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  },
                  "purpose_disabled": {
                    "summary": "The credential's purpose_enabled flag is 0.",
                    "value": {
                      "code": 7,
                      "message": "Profile ingest is not authorized",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_purpose_disabled",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The wire or decompressed body exceeds its byte cap, or the request carries more than 20 profiles.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OtlpStatus"
                },
                "examples": {
                  "body_too_large": {
                    "summary": "Wire body exceeds the 2 MiB cap.",
                    "value": {
                      "code": 8,
                      "message": "Request body exceeds the OTLP profiles limit",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_body_too_large",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  },
                  "decompressed_too_large": {
                    "summary": "Decompressed body exceeds the 8 MiB cap.",
                    "value": {
                      "code": 8,
                      "message": "Decompressed request body exceeds the OTLP profiles limit",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_body_too_large",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  },
                  "batch_too_large": {
                    "summary": "More than 20 profiles in one request.",
                    "value": {
                      "code": 8,
                      "message": "A request may contain at most 20 profiles",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_batch_too_large",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "false"
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "415": {
            "description": "Content-Type is not `application/json` (protobuf is never accepted on this route), or Content-Encoding is set to a value other than `identity`, `gzip`, or `deflate`.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OtlpStatus"
                },
                "example": {
                  "code": 3,
                  "message": "Content-Type must be application/json",
                  "details": [
                    {
                      "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                      "reason": "apm_unsupported_media_type",
                      "domain": "ingest.noxtica.com",
                      "metadata": {
                        "requestId": "req-test",
                        "retryable": "false"
                      }
                    }
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Profile ingest rate limit exceeded (600 requests / 60s per `tenantId:projectId`).",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the bucket allows another request."
              },
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OtlpStatus"
                },
                "example": {
                  "code": 8,
                  "message": "Profile ingest rate limit exceeded",
                  "details": [
                    {
                      "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                      "reason": "apm_rate_limited",
                      "domain": "ingest.noxtica.com",
                      "metadata": {
                        "requestId": "req-test",
                        "retryable": "true"
                      }
                    }
                  ]
                }
              }
            }
          },
          "503": {
            "description": "The tenant authority scope could not be confirmed, the profile object store is unavailable, or the durable ingest queue is unavailable.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always `5` on this status."
              },
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OtlpStatus"
                },
                "examples": {
                  "authority_unavailable": {
                    "summary": "Tenant authority scope confirmation failed.",
                    "value": {
                      "code": 14,
                      "message": "Authority unavailable",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_authority_unavailable",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "true"
                          }
                        }
                      ]
                    }
                  },
                  "profile_storage_unavailable": {
                    "summary": "The profile-payload object store binding is missing or rejected the write.",
                    "value": {
                      "code": 14,
                      "message": "Profile object storage is unavailable",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_profile_storage_unavailable",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "true"
                          }
                        }
                      ]
                    }
                  },
                  "queue_unavailable": {
                    "summary": "The durable ingest queue binding is missing or rejected the message.",
                    "value": {
                      "code": 14,
                      "message": "Profile ingest queue is unavailable",
                      "details": [
                        {
                          "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                          "reason": "apm_queue_unavailable",
                          "domain": "ingest.noxtica.com",
                          "metadata": {
                            "requestId": "req-test",
                            "retryable": "true"
                          }
                        }
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-noxtica-status": "partial"
      }
    },
    "/v1/deployments": {
      "post": {
        "operationId": "v1ApmIngestDeploymentMarker",
        "tags": [
          "APM Ingest"
        ],
        "summary": "Ingest a deployment marker",
        "description": "Records one service deployment (a release marker) as a small single-row JSON payload. It is not an OTLP batch, so its request and response shapes are its own rather than the OTLP contract used by traces, metrics, logs and profiles. Only `application/json` is accepted (otherwise `415`), compression is not supported, and the request body is limited to 16 KiB.\n\n`environment` is supplied by the caller but must equal the `environmentId` the ingestion key is bound to: the key's organisation, project and environment decide where a marker lands, and a mismatched value is rejected with `403 apm_environment_mismatch` instead of redirecting the marker. `version` is also the release id.\n\nAuthenticate with an ingestion key (`Authorization: Bearer sk_apm_...`) whose allowed signals include `deployments`.\n\n**Hosts.** Send the request to `https://ingest.noxtica.com` (production): this is the host the Backoffice shows next to an ingestion key. The same path and credential are also served by the collector hosts listed under `servers`.\n\nPer-key and per-project rate limits apply; a limited request answers `429` with a `Retry-After` header. The limit values differ between host implementations and are not part of this contract.",
        "security": [
          {
            "ApmIngestKeyAuth": []
          }
        ],
        "servers": [
          {
            "url": "https://ingest.noxtica.com",
            "description": "Production ingest host"
          },
          {
            "url": "https://collect.noxtica.com",
            "description": "Production collector host (same path and credential)"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ApmDeploymentMarkerRequest"
              },
              "example": {
                "service": "checkout-api",
                "version": "2026.09.25-1",
                "environment": "prod",
                "commit": "4f3c2a1",
                "timestamp": "2026-09-25T00:00:00.000Z"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Deployment marker accepted and queued to the warehouse.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApmDeploymentMarkerAccepted"
                },
                "example": {
                  "ok": true,
                  "deployment_id": "dep-test",
                  "service": "checkout-api",
                  "version": "2026.09.25-1",
                  "environment": "prod",
                  "commit": "4f3c2a1",
                  "timestamp": "2026-09-25T00:00:00.000Z"
                }
              }
            }
          },
          "400": {
            "description": "`apm_malformed_json` — the body is not valid JSON; or `apm_invalid_payload` — a required field is missing, an unknown field is present, or a field fails its own pattern/format check (e.g. `commit` not a 7-64 char lowercase-hex SHA, or `timestamp` after the receipt time).",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApmDeploymentError"
                },
                "examples": {
                  "malformed_json": {
                    "summary": "Body is not valid JSON.",
                    "value": {
                      "ok": false,
                      "error": "apm_malformed_json",
                      "message": "Malformed JSON body",
                      "requestId": "req-test"
                    }
                  },
                  "invalid_payload": {
                    "summary": "A field failed validation.",
                    "value": {
                      "ok": false,
                      "error": "apm_invalid_payload",
                      "message": "Invalid deployment marker payload",
                      "requestId": "req-test"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid `sk_apm_` bearer credential, or the credential's `effective_at`/`expires_at` window excludes now. A tenant `ApiKeyAuth` `sk_` key is never accepted here.",
            "headers": {
              "WWW-Authenticate": {
                "schema": {
                  "type": "string"
                },
                "description": "On the collector hosts always `Bearer realm=\"noxtica-otlp\", charset=\"UTF-8\"`; the ingest hosts do not send it."
              },
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApmDeploymentError"
                },
                "examples": {
                  "auth_missing": {
                    "summary": "No Authorization header.",
                    "value": {
                      "ok": false,
                      "error": "apm_auth_missing",
                      "message": "Authentication failed",
                      "requestId": "req-test"
                    }
                  },
                  "auth_invalid": {
                    "summary": "Credential does not resolve to an active key.",
                    "value": {
                      "ok": false,
                      "error": "apm_auth_invalid",
                      "message": "Authentication failed",
                      "requestId": "req-test"
                    }
                  },
                  "auth_expired": {
                    "summary": "now is outside [effective_at, expires_at).",
                    "value": {
                      "ok": false,
                      "error": "apm_auth_expired",
                      "message": "Authentication failed",
                      "requestId": "req-test"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "The credential is active but not authorized for deployment marker ingest, or the request's `environment` does not match the credential's own `environmentId` scope.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApmDeploymentError"
                },
                "examples": {
                  "scope_denied": {
                    "summary": "\"deployments\" is not in the credential's allowed_signals.",
                    "value": {
                      "ok": false,
                      "error": "apm_scope_denied",
                      "message": "Deployment marker ingest is not authorized",
                      "requestId": "req-test"
                    }
                  },
                  "purpose_disabled": {
                    "summary": "The credential's purpose_enabled flag is 0.",
                    "value": {
                      "ok": false,
                      "error": "apm_purpose_disabled",
                      "message": "Deployment marker ingest is not authorized",
                      "requestId": "req-test"
                    }
                  },
                  "environment_mismatch": {
                    "summary": "Request environment does not match the credential's own environment scope.",
                    "value": {
                      "ok": false,
                      "error": "apm_environment_mismatch",
                      "message": "environment does not match the authenticated key scope",
                      "requestId": "req-test"
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The request body exceeds the 16 KiB cap.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApmDeploymentError"
                },
                "example": {
                  "ok": false,
                  "error": "apm_body_too_large",
                  "message": "Request body exceeds the deployment marker limit",
                  "requestId": "req-test"
                }
              }
            }
          },
          "415": {
            "description": "Content-Type is not `application/json`.",
            "headers": {
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApmDeploymentError"
                },
                "example": {
                  "ok": false,
                  "error": "apm_unsupported_media_type",
                  "message": "Content-Type must be application/json",
                  "requestId": "req-test"
                }
              }
            }
          },
          "429": {
            "description": "Deployment marker rate limit exceeded (120 requests / 60s per `tenantId:projectId`).",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the bucket allows another request."
              },
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApmDeploymentError"
                },
                "example": {
                  "ok": false,
                  "error": "apm_rate_limited",
                  "message": "Deployment marker rate limit exceeded",
                  "requestId": "req-test"
                }
              }
            }
          },
          "503": {
            "description": "The tenant authority scope could not be confirmed, or the durable ingest queue is unavailable.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Always `5` on this status."
              },
              "Cache-Control": {
                "$ref": "#/components/headers/NoStore"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApmDeploymentError"
                },
                "examples": {
                  "authority_unavailable": {
                    "summary": "Tenant authority scope confirmation failed.",
                    "value": {
                      "ok": false,
                      "error": "apm_authority_unavailable",
                      "message": "Authority unavailable",
                      "requestId": "req-test"
                    }
                  },
                  "queue_unavailable": {
                    "summary": "The durable ingest queue binding is missing or rejected the message.",
                    "value": {
                      "ok": false,
                      "error": "apm_queue_unavailable",
                      "message": "Deployment marker queue is unavailable",
                      "requestId": "req-test"
                    }
                  }
                }
              }
            }
          }
        },
        "x-noxtica-status": "partial"
      }
    },
    "/health": {
      "get": {
        "operationId": "getHealth",
        "tags": [
          "Health and Keys"
        ],
        "summary": "Collector health probe",
        "description": "Unauthenticated liveness and readiness probe of the collector. It performs no datastore\nconnectivity check: it answers whether the collector worker itself is alive.\n\n`status` is `ok`, or `degraded` while a background dead-letter watch reports unprocessed\nitems (still HTTP `200`). HTTP `503` is returned only when the deployment refuses\nreadiness; the body then also has `status: degraded`. The body can carry additional\ndiagnostic members; ignore members you do not recognise. `version` is the deployed\ncollector version, or `unknown` when none is reported.\n\nThe response sets no CORS headers, so call it from a server or a monitor, never from a\nbrowser. Excessive probing from one source address is rate limited (`429` with\n`Retry-After`). For incident history see the public status page.",
        "security": [],
        "responses": {
          "200": {
            "description": "The collector is alive.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "no-cache"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthStatus"
                },
                "example": {
                  "status": "ok",
                  "version": "1.0.0",
                  "timestamp": "2026-10-27T10:00:00.000Z"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "503": {
            "description": "The deployment refuses readiness. `status` is `degraded`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HealthStatus"
                },
                "example": {
                  "status": "degraded",
                  "version": "1.0.0",
                  "timestamp": "2026-10-27T10:00:00.000Z"
                }
              }
            }
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/.well-known/noxtica/jwks.json": {
      "get": {
        "operationId": "getCollectorJwks",
        "tags": [
          "Health and Keys"
        ],
        "summary": "Public signing keys (JWKS)",
        "description": "The public keys Noxtica signs its envelopes with, as a standard JSON Web Key Set, so your\nbackend can verify a signed envelope offline, by `kid`, without calling Noxtica: the signed\npolicy and result envelopes of the browser integration and, unless a dedicated passport key\nis published (see `GET /.well-known/noxtica/agent-passport-jwks.json`), Agent Passports.\n\nThe document is unauthenticated and public by design: only the public members `kty`,\n`crv`, `x`, `y` and the descriptors `kid`, `use` and `alg` are ever served. During a key\nrotation it holds both the current and the incoming key (current first), so a verifier can\nresolve the new `kid` before the signer cuts over. The response is cacheable for 5 minutes.\nThe route answers `404` when signing is not configured for the deployment.",
        "security": [],
        "responses": {
          "200": {
            "description": "The public key set.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "public, max-age=300"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Jwks"
                },
                "example": {
                  "keys": [
                    {
                      "kty": "EC",
                      "crv": "P-256",
                      "x": "f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU",
                      "y": "x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0",
                      "kid": "nox-2026-01",
                      "use": "sig",
                      "alg": "ES256"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Signing is not configured for this deployment. The body is `{\"error\":\"Not found\"}`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotFoundError"
                },
                "example": {
                  "error": "Not found"
                }
              }
            }
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/.well-known/noxtica/agent-passport-jwks.json": {
      "get": {
        "operationId": "getAgentPassportJwks",
        "tags": [
          "Health and Keys"
        ],
        "summary": "Public Agent Passport signing keys (JWKS)",
        "description": "The public key of the dedicated Agent Passport signing key, when one is provisioned, as a\nstandard JSON Web Key Set. It is deliberately a separate document from\n`GET /.well-known/noxtica/jwks.json` so a result verifier that fetches only the main\ndocument can never accept a passport. Use this document, and only for Agent Passports.\n\nThe route answers `404` when no dedicated passport key exists; passports are then signed\nunder a key published on the main JWKS. During a rotation both the current and the\nincoming key are published (current first). The document is unauthenticated, public by\ndesign and cacheable for 5 minutes.",
        "security": [],
        "responses": {
          "200": {
            "description": "The public key set of the dedicated passport signing key.",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "const": "public, max-age=300"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Jwks"
                },
                "example": {
                  "keys": [
                    {
                      "kty": "EC",
                      "crv": "P-256",
                      "x": "f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU",
                      "y": "x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0",
                      "kid": "nox-passport-2026-01",
                      "use": "sig",
                      "alg": "ES256"
                    }
                  ]
                }
              }
            }
          },
          "404": {
            "description": "No dedicated passport key is configured. The body is `{\"error\":\"Not found\"}`.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotFoundError"
                },
                "example": {
                  "error": "Not found"
                }
              }
            }
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/coding-agent/findings": {
      "get": {
        "operationId": "codingAgentListFindings",
        "tags": [
          "Coding Agent"
        ],
        "summary": "List recent findings for a coding agent",
        "description": "Reads recent raw signals for your organisation, narrowed to the scopes the coding-agent key\nholds. Results from every scope the key holds are merged: this route has no single required\nscope, and a scope narrows what is read instead of denying the call. At the time of writing\nthe scopes `rum_errors`, `apm_traces`, `apm_errors`, `apm_metrics` and `logs` have a findings\nsource; the other scopes a key can carry (`profiles`, `fingerprint_bot_signals`,\n`kyc_risk_summaries`) add nothing to this route. The `signal` field names the scope a row\ncame from. An empty array is a normal answer; this route never answers `404`.\n\n`since` defaults to 24 hours ago and `limit` to 50 (maximum 200). Create a coding-agent\nkey in the Backoffice under Integrations & API, Coding agent keys; keys start with `cak_`.",
        "security": [
          {
            "CodingAgentKeyAuth": []
          }
        ],
        "servers": [
          {
            "url": "https://ingest.noxtica.com",
            "description": "Production"
          }
        ],
        "parameters": [
          {
            "name": "since",
            "in": "query",
            "required": false,
            "description": "Only signals observed at or after this RFC 3339 instant. Defaults to 24 hours ago.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of signals to return. Defaults to 50; values above 200 are clamped to 200.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A (possibly empty) array of signals.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/CodingAgentSignal"
                  }
                },
                "example": [
                  {
                    "signal": "rum_errors",
                    "reference_id": "evt_8f1c2a",
                    "excerpt": "error /checkout",
                    "observed_at": "2026-10-27T09:58:12Z"
                  }
                ]
              }
            }
          },
          "400": {
            "description": "`schema_invalid` — `since` or `limit` could not be parsed.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CodingAgentError"
                },
                "example": {
                  "code": 400,
                  "message": "invalid query",
                  "error": "schema_invalid"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/CodingAgentUnauthorized"
          },
          "429": {
            "$ref": "#/components/responses/CodingAgentRateLimited"
          },
          "502": {
            "$ref": "#/components/responses/CodingAgentQueryFailed"
          },
          "503": {
            "$ref": "#/components/responses/CodingAgentUnavailable"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/coding-agent/traces/{trace_id}": {
      "get": {
        "operationId": "codingAgentGetTrace",
        "tags": [
          "Coding Agent"
        ],
        "summary": "Read one trace for a coding agent",
        "description": "Returns the spans of one trace (a narrow projection: attributes, events and links are never\nreturned) from roughly the last 30 days. Requires the `apm_traces` scope on the key;\nwithout it the route answers `403 coding_agent_scope_denied`. An unknown trace id, or one\nthat belongs to another organisation, is a normal `200` with an empty `spans` array: this\nroute never answers `404`.",
        "security": [
          {
            "CodingAgentKeyAuth": []
          }
        ],
        "servers": [
          {
            "url": "https://ingest.noxtica.com",
            "description": "Production"
          }
        ],
        "parameters": [
          {
            "name": "trace_id",
            "in": "path",
            "required": true,
            "description": "The trace id.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The trace; `spans` is empty when the id is unknown.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CodingAgentTrace"
                },
                "example": {
                  "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
                  "spans": [
                    {
                      "span_id": "00f067aa0ba902b7",
                      "service_name": "checkout-api",
                      "operation_name": "GET /health",
                      "start_time": "2026-10-27T09:58:00Z",
                      "end_time": "2026-10-27T09:58:00.010Z",
                      "duration_ns": 10000000,
                      "status_code": "STATUS_CODE_OK"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/CodingAgentUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/CodingAgentScopeDenied"
          },
          "429": {
            "$ref": "#/components/responses/CodingAgentRateLimited"
          },
          "502": {
            "$ref": "#/components/responses/CodingAgentQueryFailed"
          },
          "503": {
            "$ref": "#/components/responses/CodingAgentUnavailable"
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "/v1/coding-agent/errors/{error_group_id}": {
      "get": {
        "operationId": "codingAgentGetErrorGroup",
        "tags": [
          "Coding Agent"
        ],
        "summary": "Read one error group for a coding agent",
        "description": "Returns one error group with its aggregate counts and a bounded list of recent occurrences\n(a narrow projection: stack frames are never returned) from roughly the last 30 days.\nRequires the `apm_errors` scope on the key; without it the route answers\n`403 coding_agent_scope_denied`. `404 coding_agent_error_group_not_found` means the group is\nunknown or belongs to another organisation; the two cases are indistinguishable by design.",
        "security": [
          {
            "CodingAgentKeyAuth": []
          }
        ],
        "servers": [
          {
            "url": "https://ingest.noxtica.com",
            "description": "Production"
          }
        ],
        "parameters": [
          {
            "name": "error_group_id",
            "in": "path",
            "required": true,
            "description": "The error group id.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The error group.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CodingAgentErrorGroup"
                },
                "example": {
                  "error_group_id": "eg_5d41402abc4b2a76",
                  "first_seen": "2026-10-26T08:00:00Z",
                  "last_seen": "2026-10-27T09:58:12Z",
                  "occurrence_count": 42,
                  "affected_release_ids": [
                    "2026.10.26"
                  ],
                  "occurrences": [
                    {
                      "occurrence_id": "occ_91",
                      "exception_type": "TypeError",
                      "exception_message": "Cannot read properties of undefined",
                      "observed_at": "2026-10-27T09:58:12Z",
                      "release_id": "2026.10.26"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/CodingAgentUnauthorized"
          },
          "403": {
            "$ref": "#/components/responses/CodingAgentScopeDenied"
          },
          "404": {
            "description": "`coding_agent_error_group_not_found` — the group is unknown or belongs to another organisation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CodingAgentError"
                },
                "example": {
                  "code": 404,
                  "message": "Unknown error group",
                  "error": "coding_agent_error_group_not_found"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/CodingAgentRateLimited"
          },
          "502": {
            "$ref": "#/components/responses/CodingAgentQueryFailed"
          },
          "503": {
            "$ref": "#/components/responses/CodingAgentUnavailable"
          }
        },
        "x-noxtica-status": "available"
      }
    }
  },
  "webhooks": {
    "submission.scored": {
      "post": {
        "operationId": "webhookSubmissionScored",
        "tags": [
          "Verdict Webhooks"
        ],
        "summary": "A submission was scored",
        "description": "Sent for every scored browser or app submission of your organisation (the broadest\nsubscription: use `risk.high` or `risk.flagged` if you only need the notable ones). The\nBackoffice \"Send test\" button sends a sample of this event type, with placeholder verdict\ndata and a valid signature.\n\n`data.event_id` is the request id of the submission: correlate it with the `X-Request-Id`\nyour browser integration received. `data.device_id` is the opaque device id\n(`fingerprintId`). This is a notification, not authority; read the device\n(`GET /v1/device/{deviceId}`) before taking an irreversible action.\n\nSee \"Webhook delivery and retries\" in the API description for the headers, the signature,\nretries and deduplication.",
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookTimestampHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VerdictWebhookEvent"
              },
              "example": {
                "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"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Acknowledge with any 2xx status. See \"Webhook delivery and retries\" for how other statuses are treated."
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "risk.high": {
      "post": {
        "operationId": "webhookRiskHigh",
        "tags": [
          "Verdict Webhooks"
        ],
        "summary": "A submission was scored high or critical",
        "description": "Sent when a scored submission lands in the `high` or `critical` risk band. The payload is\nthe same verdict shape as `submission.scored`. A submission in that band also produces\n`submission.scored` (and `risk.flagged` when a flag fired) for endpoints subscribed to\nthose types.\n\nSee \"Webhook delivery and retries\" in the API description for the headers, the signature,\nretries and deduplication.",
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookTimestampHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VerdictWebhookEvent"
              },
              "example": {
                "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"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Acknowledge with any 2xx status. See \"Webhook delivery and retries\" for how other statuses are treated."
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "risk.flagged": {
      "post": {
        "operationId": "webhookRiskFlagged",
        "tags": [
          "Verdict Webhooks"
        ],
        "summary": "A risk flag fired",
        "description": "Sent when at least one risk flag fired on a scored submission, whatever its risk band.\n\nThe same event type is also sent after each mobile attestation `verify` (see\n`POST /v1/attest/android` and `POST /v1/attest/ios`), with `flags` of the form\n`mobile_attest:<platform>`, `mobile_attest_level:<level>` and `mobile_attest_verdict:<verdict>`.\nThere `data.device_id` can be an empty string, which means that no stable per-device\nidentity is available for the event: do not group events on an empty `device_id`, and use\n`data.event_id`, which is always present, as the per-event key.\n\nSee \"Webhook delivery and retries\" in the API description for the headers, the signature,\nretries and deduplication.",
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookTimestampHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VerdictWebhookEvent"
              },
              "example": {
                "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"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Acknowledge with any 2xx status. See \"Webhook delivery and retries\" for how other statuses are treated."
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "risk.cluster_flagged": {
      "post": {
        "operationId": "webhookRiskClusterFlagged",
        "tags": [
          "Verdict Webhooks"
        ],
        "summary": "A device cluster was flagged as bad",
        "description": "Sent once, on the first escalation, when a cluster of devices (devices sharing an\nobservational sub-fingerprint) is flagged bad in real time because a high or critical\nsubmission came with strong cluster evidence. It lets you react to an emerging cluster\nbefore slower offline feeds catch up. A cluster that is already flagged does not produce\na new delivery for every further submission.\n\nThe payload has the same verdict shape as `submission.scored`; `data.risk_level` is the\ncluster's band. It carries no raw IP address and no personal data. Available only when\nreal-time cluster propagation is enabled for the deployment.\n\nSee \"Webhook delivery and retries\" in the API description for the headers, the signature,\nretries and deduplication.",
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookTimestampHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VerdictWebhookEvent"
              },
              "example": {
                "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"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Acknowledge with any 2xx status. See \"Webhook delivery and retries\" for how other statuses are treated."
          }
        },
        "x-noxtica-status": "available"
      }
    },
    "account.agent_linked": {
      "post": {
        "operationId": "webhookAccountAgentLinked",
        "tags": [
          "Verdict Webhooks"
        ],
        "summary": "A verified agent was linked to an account for the first time",
        "description": "Sent once, when a cryptographically verified signed agent (Web Bot Auth, RFC 9421) is linked\nto one of your end-user accounts for the first time, that is when the (agent, account)\npair had no earlier link. It lets you react when a new agent starts acting on an account.\n\nThe payload carries the keyed `account_hash` (a 16-character lowercase-hex pseudonym; the\nraw account id is never stored or sent), the verified agent's `agent_keyid` and\n`agent_host`, and the usual `device_id`, `domain_id` and `event_id`. It carries no raw IP\naddress and no personal data. Use `GET /v1/accounts/{accountHash}/devices` to list the\ndevices and agents linked to the account.\n\nSee \"Webhook delivery and retries\" in the API description for the headers, the signature,\nretries and deduplication.",
        "security": [],
        "parameters": [
          {
            "$ref": "#/components/parameters/WebhookSignatureHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookTimestampHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookEventHeader"
          },
          {
            "$ref": "#/components/parameters/WebhookDeliveryHeader"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AgentLinkedWebhookEvent"
              },
              "example": {
                "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"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Acknowledge with any 2xx status. See \"Webhook delivery and retries\" for how other statuses are treated."
          }
        },
        "x-noxtica-status": "available"
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "sk_<random>",
        "description": "Server-to-server tenant API key, sent as `Authorization: Bearer sk_...` (`sk_prod_...` keys). Keys carry scopes: the scope an operation requires is listed in its `security` block, and a valid key without it receives `403`. A missing, malformed, unknown or revoked key, or a key of a suspended organisation, receives a `401` whose body is identical for every cause. Create and revoke keys in the Backoffice under Integrations & API. Use a key only from your own servers — never from a browser or a mobile app."
      },
      "ApmIngestKeyAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "sk_apm_<random>",
        "description": "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."
      },
      "CodingAgentKeyAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "cak_<random>",
        "description": "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."
      }
    },
    "headers": {
      "NoStore": {
        "description": "APM control/query responses are never cacheable.",
        "schema": {
          "type": "string",
          "const": "no-store"
        }
      }
    },
    "parameters": {
      "IdempotencyKeyRequired": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": true,
        "schema": {
          "type": "string",
          "minLength": 8,
          "maxLength": 128
        },
        "description": "A replayed key returns the byte-identical stored response — no second provider call, no double charge."
      },
      "ApmListLimit": {
        "name": "limit",
        "in": "query",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 200,
          "default": 50
        }
      },
      "ApmQueryLimit": {
        "name": "limit",
        "in": "query",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 200,
          "default": 50
        }
      },
      "ApmCursor": {
        "name": "cursor",
        "in": "query",
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 512
        }
      },
      "ApmProjectIdPath": {
        "name": "projectId",
        "in": "path",
        "required": true,
        "schema": {
          "$ref": "#/components/schemas/ApmScopedId"
        }
      },
      "ApmEnvironmentIdPath": {
        "name": "environmentId",
        "in": "path",
        "required": true,
        "schema": {
          "$ref": "#/components/schemas/ApmScopedId"
        }
      },
      "ApmProjectIdQuery": {
        "name": "project_id",
        "in": "query",
        "required": true,
        "schema": {
          "$ref": "#/components/schemas/ApmScopedId"
        }
      },
      "ApmEnvironmentIdQuery": {
        "name": "environment_id",
        "in": "query",
        "required": true,
        "schema": {
          "$ref": "#/components/schemas/ApmScopedId"
        }
      },
      "ApmFrom": {
        "name": "from",
        "in": "query",
        "required": true,
        "description": "Inclusive RFC 3339 range start. The interval to `to` must not exceed 31 days.",
        "schema": {
          "type": "string",
          "format": "date-time"
        }
      },
      "ApmTo": {
        "name": "to",
        "in": "query",
        "required": true,
        "description": "Exclusive RFC 3339 range end, after `from`; the interval must not exceed 31 days.",
        "schema": {
          "type": "string",
          "format": "date-time"
        }
      },
      "ApmTraceIdPath": {
        "name": "traceId",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "pattern": "^(?!0{32}$)[0-9a-f]{32}$"
        }
      },
      "ApmServiceNamePath": {
        "name": "serviceName",
        "in": "path",
        "required": true,
        "schema": {
          "type": "string",
          "minLength": 1,
          "maxLength": 256,
          "pattern": "^[A-Za-z0-9._:/-]+$"
        }
      },
      "ApmReleaseIdPath": {
        "name": "releaseId",
        "in": "path",
        "required": true,
        "schema": {
          "$ref": "#/components/schemas/ApmScopedId"
        }
      },
      "ApmExportIdPath": {
        "name": "exportId",
        "in": "path",
        "required": true,
        "schema": {
          "$ref": "#/components/schemas/ApmScopedId"
        }
      },
      "ApmSubjectHandlePath": {
        "name": "subjectHandle",
        "in": "path",
        "required": true,
        "description": "Opaque subject handle; hashed before authentication, logging, storage, or repository access.",
        "schema": {
          "type": "string",
          "minLength": 16,
          "maxLength": 512,
          "pattern": "^[A-Za-z0-9._~:/+-]+$"
        }
      },
      "ApmPrivacyRequestIdPath": {
        "name": "requestId",
        "in": "path",
        "required": true,
        "schema": {
          "$ref": "#/components/schemas/ApmScopedId"
        }
      },
      "WebhookSignatureHeader": {
        "name": "X-Noxtica-Signature",
        "in": "header",
        "required": true,
        "description": "`sha256=` followed by the lowercase hex HMAC-SHA256 of the string `<X-Noxtica-Timestamp>.<raw request body>`, 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.",
        "schema": {
          "type": "string",
          "pattern": "^sha256=[0-9a-f]{64}$",
          "example": "sha256=9f2c4b7e1a8d3c6f0b5e7a9d2c4f6e8b1a3d5c7e9f0b2d4f6a8c0e1b3d5f7a9c"
        }
      },
      "WebhookTimestampHeader": {
        "name": "X-Noxtica-Timestamp",
        "in": "header",
        "required": true,
        "description": "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`.",
        "schema": {
          "type": "integer",
          "format": "int64",
          "example": 1790762445123
        }
      },
      "WebhookEventHeader": {
        "name": "X-Noxtica-Event",
        "in": "header",
        "required": true,
        "description": "The event type; equals `type` in the body.",
        "schema": {
          "type": "string",
          "example": "submission.scored"
        }
      },
      "WebhookDeliveryHeader": {
        "name": "X-Noxtica-Delivery",
        "in": "header",
        "required": true,
        "description": "The delivery id; equals `id` in the body and is identical on every retry of the same delivery. Deduplicate on it.",
        "schema": {
          "type": "string"
        }
      }
    },
    "responses": {
      "InvalidRequest": {
        "description": "The request failed validation. `error` is a route-specific string such as `Invalid body` or `invalid_request`; read the operation description for the exact values it can return.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "error": "Invalid body",
              "requestId": "req-test"
            }
          }
        }
      },
      "InvalidApiKey": {
        "description": "The `Authorization: Bearer sk_...` header is missing or malformed, or the key is unknown, revoked, or belongs to a suspended or deleted organisation. The body is deliberately identical for every cause.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/InvalidApiKeyError"
            },
            "example": {
              "error": "invalid_api_key",
              "message": "Invalid or revoked API key",
              "requestId": "req-test"
            }
          }
        }
      },
      "ScopeForbidden": {
        "description": "The API key is valid but does not carry the scope this operation requires; `error` names the missing scope.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ScopeForbiddenError"
            },
            "example": {
              "error": "API key does not have read:device scope",
              "requestId": "req-test"
            }
          }
        }
      },
      "GatedNotFound": {
        "description": "The byte-identical \"V1 endpoint not found\" response returned when the route's module is not enabled for your organisation, and also for a path that does not exist — indistinguishable by design (anti-enumeration), so do not treat it as proof the path is wrong.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "error": {
                  "type": "string",
                  "enum": [
                    "V1 endpoint not found"
                  ]
                },
                "path": {
                  "type": "string"
                },
                "requestId": {
                  "type": "string"
                }
              }
            },
            "example": {
              "error": "V1 endpoint not found",
              "path": "/v1/score",
              "requestId": "req-test"
            }
          }
        }
      },
      "BodyTooLarge": {
        "description": "The request body exceeded this route's byte cap.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "error": "body_too_large",
              "requestId": "req-test"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Rate limit exceeded. Wait `Retry-After` seconds (also `retryAfter` in the body) before retrying; the response carries no other rate-limit headers.",
        "headers": {
          "Retry-After": {
            "schema": {
              "type": "integer"
            },
            "description": "Seconds until the bucket allows another request."
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": [
                "error",
                "retryAfter"
              ],
              "properties": {
                "error": {
                  "type": "string",
                  "enum": [
                    "Rate limit exceeded"
                  ]
                },
                "retryAfter": {
                  "type": "integer",
                  "description": "Seconds to wait; equals the `Retry-After` header."
                },
                "requestId": {
                  "type": "string"
                }
              }
            },
            "example": {
              "error": "Rate limit exceeded",
              "retryAfter": 12,
              "requestId": "req-test"
            }
          }
        }
      },
      "InternalError": {
        "description": "Unexpected server fault. Retry with backoff and quote `requestId` to support if it persists.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "error": "Internal server error",
              "requestId": "req-test"
            }
          }
        }
      },
      "ApmInvalid": {
        "description": "Closed-input validation failed.",
        "headers": {
          "Cache-Control": {
            "$ref": "#/components/headers/NoStore"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApmError"
            },
            "example": {
              "ok": false,
              "error": "invalid_request",
              "reason": "invalid_range",
              "requestId": "req-test"
            }
          }
        }
      },
      "ApmUnauthorized": {
        "description": "Missing, invalid, or ingest-only credential. An `sk_apm_` key is never accepted here.",
        "headers": {
          "Cache-Control": {
            "$ref": "#/components/headers/NoStore"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApmError"
            },
            "example": {
              "ok": false,
              "error": "Unauthorized",
              "requestId": "req-test"
            }
          }
        }
      },
      "ApmForbidden": {
        "description": "The server API key lacks the operation's required scope.",
        "headers": {
          "Cache-Control": {
            "$ref": "#/components/headers/NoStore"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApmError"
            },
            "example": {
              "ok": false,
              "error": "API key does not have read:apm scope",
              "requestId": "req-test"
            }
          }
        }
      },
      "ApmNotFound": {
        "description": "The tenant-scoped resource was not found.",
        "headers": {
          "Cache-Control": {
            "$ref": "#/components/headers/NoStore"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApmError"
            },
            "example": {
              "ok": false,
              "error": "resource_not_found",
              "requestId": "req-test"
            }
          }
        }
      },
      "ApmRateLimited": {
        "description": "V1 read rate limit exceeded.",
        "headers": {
          "Cache-Control": {
            "$ref": "#/components/headers/NoStore"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApmRateLimitError"
            },
            "example": {
              "ok": false,
              "error": "Rate limit exceeded",
              "retryAfter": 60,
              "requestId": "req-test"
            }
          }
        }
      },
      "ApmControlUnavailable": {
        "description": "Authoritative control-plane data is unavailable.",
        "headers": {
          "Cache-Control": {
            "$ref": "#/components/headers/NoStore"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApmUnavailable"
            },
            "example": {
              "ok": false,
              "available": false,
              "reason": "control_plane_unavailable",
              "requestId": "req-test"
            }
          }
        }
      },
      "ApmWarehouseUnavailable": {
        "description": "Warehouse query or mandatory access audit is unavailable.",
        "headers": {
          "Cache-Control": {
            "$ref": "#/components/headers/NoStore"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApmUnavailable"
            },
            "example": {
              "ok": false,
              "available": false,
              "reason": "warehouse_unavailable",
              "requestId": "req-test"
            }
          }
        }
      },
      "ApmInternal": {
        "description": "Unexpected internal trace-query failure.",
        "headers": {
          "Cache-Control": {
            "$ref": "#/components/headers/NoStore"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ApmError"
            },
            "example": {
              "ok": false,
              "error": "internal_error",
              "requestId": "req-test"
            }
          }
        }
      },
      "CodingAgentUnauthorized": {
        "description": "`coding_agent_auth_missing` (no `Authorization` header) or `coding_agent_auth_invalid` (a malformed, unknown, revoked or inactive coding-agent key).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/CodingAgentError"
            },
            "example": {
              "code": 401,
              "message": "Authentication failed",
              "error": "coding_agent_auth_invalid"
            }
          }
        }
      },
      "CodingAgentScopeDenied": {
        "description": "`coding_agent_scope_denied` — the key is valid but lacks the scope this route requires.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/CodingAgentError"
            },
            "example": {
              "code": 403,
              "message": "Authentication failed",
              "error": "coding_agent_scope_denied"
            }
          }
        }
      },
      "CodingAgentRateLimited": {
        "description": "`coding_agent_rate_limited` — the per-key request limit was exceeded. Wait `Retry-After` seconds before retrying.",
        "headers": {
          "Retry-After": {
            "schema": {
              "type": "integer"
            },
            "description": "Seconds until the key may call again."
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/CodingAgentError"
            },
            "example": {
              "code": 429,
              "message": "Rate limit exceeded for this coding-agent key",
              "error": "coding_agent_rate_limited"
            }
          }
        }
      },
      "CodingAgentQueryFailed": {
        "description": "`coding_agent_query_failed` — the read query failed. Retry with backoff.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/CodingAgentError"
            },
            "example": {
              "code": 502,
              "message": "Read query failed",
              "error": "coding_agent_query_failed"
            }
          }
        }
      },
      "CodingAgentUnavailable": {
        "description": "`coding_agent_authority_unavailable` (the key could not be checked) or `coding_agent_bq_unavailable` (the read store is not available). Retry with backoff.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/CodingAgentError"
            },
            "example": {
              "code": 503,
              "message": "Authority lookup failed",
              "error": "coding_agent_authority_unavailable"
            }
          }
        }
      }
    },
    "schemas": {
      "ProtectedActionVerifyError": {
        "type": "object",
        "required": [
          "ok",
          "error",
          "requestId"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "enum": [
              false
            ]
          },
          "error": {
            "type": "string",
            "enum": [
              "invalid_body",
              "invalid_request_id",
              "invalid_action",
              "invalid_expected_domain",
              "payload_too_large",
              "request_not_found",
              "already_consumed",
              "action_mismatch",
              "domain_mismatch"
            ]
          },
          "consumed": {
            "type": "boolean",
            "description": "Present on `already_consumed`."
          },
          "consumedAt": {
            "type": "string",
            "format": "date-time",
            "description": "Present on `already_consumed`."
          },
          "requestId": {
            "type": "string",
            "description": "The collector's own correlation id for this call."
          }
        }
      },
      "ApmScopedId": {
        "type": "string",
        "minLength": 1,
        "maxLength": 128,
        "pattern": "^[A-Za-z0-9._:-]+$"
      },
      "ApmError": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "error",
          "requestId"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": false
          },
          "error": {
            "type": "string"
          },
          "reason": {
            "type": "string"
          },
          "requestId": {
            "type": "string"
          }
        }
      },
      "ApmRateLimitError": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "error",
          "retryAfter",
          "requestId"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": false
          },
          "error": {
            "type": "string"
          },
          "retryAfter": {
            "type": "integer",
            "minimum": 1
          },
          "requestId": {
            "type": "string"
          }
        }
      },
      "ApmUnavailable": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "available",
          "reason",
          "requestId"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": false
          },
          "available": {
            "type": "boolean",
            "const": false
          },
          "reason": {
            "type": "string"
          },
          "requestId": {
            "type": "string"
          }
        }
      },
      "ApmConflict": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "ok",
          "error",
          "requestId"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": false
          },
          "error": {
            "type": "string",
            "enum": [
              "capture_unavailable",
              "authority_epoch_conflict"
            ]
          },
          "available": {
            "type": "boolean",
            "const": false
          },
          "reason": {
            "type": "string",
            "enum": [
              "capture_rollout_disabled"
            ]
          },
          "expected_authority_epoch": {
            "type": "integer",
            "minimum": 1
          },
          "actual_authority_epoch": {
            "type": "integer",
            "minimum": 1
          },
          "requestId": {
            "type": "string"
          }
        }
      },
      "ApmGrantUnavailable": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "ok",
          "available",
          "reason",
          "state",
          "requestId"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": false
          },
          "available": {
            "type": "boolean",
            "const": false
          },
          "reason": {
            "type": "string",
            "enum": [
              "export_not_ready",
              "export_expired",
              "export_failed",
              "download_signing_unavailable"
            ]
          },
          "state": {
            "type": "string"
          },
          "requestId": {
            "type": "string"
          }
        }
      },
      "ApmProject": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "project_id",
          "display_name",
          "state",
          "region_id",
          "data_plane_id",
          "capture_enabled",
          "enabled_signals",
          "authority_epoch",
          "erasure_epoch",
          "created_at",
          "updated_at"
        ],
        "properties": {
          "project_id": {
            "$ref": "#/components/schemas/ApmScopedId"
          },
          "display_name": {
            "type": "string"
          },
          "state": {
            "type": "string"
          },
          "region_id": {
            "type": "string"
          },
          "data_plane_id": {
            "type": "string"
          },
          "capture_enabled": {
            "type": "boolean"
          },
          "enabled_signals": {
            "type": "array",
            "maxItems": 2,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "enum": [
                "traces",
                "rum_events"
              ]
            }
          },
          "authority_epoch": {
            "type": "integer",
            "minimum": 0
          },
          "erasure_epoch": {
            "type": "integer",
            "minimum": 0
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ApmEnvironmentPolicy": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "project_id",
          "environment_id",
          "display_name",
          "environment_kind",
          "state",
          "region_id",
          "data_plane_id",
          "capture_enabled",
          "allowed_signals",
          "sampling_policy_id",
          "retention_policy_version",
          "privacy_policy_version",
          "authority_epoch",
          "erasure_epoch",
          "quota_manifest_revision",
          "parser_manifest_revision",
          "created_at",
          "updated_at"
        ],
        "properties": {
          "project_id": {
            "$ref": "#/components/schemas/ApmScopedId"
          },
          "environment_id": {
            "$ref": "#/components/schemas/ApmScopedId"
          },
          "display_name": {
            "type": "string"
          },
          "environment_kind": {
            "type": "string"
          },
          "state": {
            "type": "string"
          },
          "region_id": {
            "type": "string"
          },
          "data_plane_id": {
            "type": "string"
          },
          "capture_enabled": {
            "type": "boolean"
          },
          "allowed_signals": {
            "type": "array",
            "maxItems": 2,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "enum": [
                "traces",
                "rum_events"
              ]
            }
          },
          "sampling_policy_id": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ApmScopedId"
              },
              {
                "type": "null"
              }
            ]
          },
          "retention_policy_version": {
            "type": "integer",
            "minimum": 1
          },
          "privacy_policy_version": {
            "type": "integer",
            "minimum": 1
          },
          "authority_epoch": {
            "type": "integer",
            "minimum": 0
          },
          "erasure_epoch": {
            "type": "integer",
            "minimum": 0
          },
          "quota_manifest_revision": {
            "type": "integer",
            "minimum": 0
          },
          "parser_manifest_revision": {
            "type": "integer",
            "minimum": 0
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ApmProjectList": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "ok",
          "items",
          "count",
          "truncated",
          "next_cursor",
          "freshness",
          "completeness"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApmProject"
            }
          },
          "count": {
            "type": "integer",
            "minimum": 0,
            "maximum": 200
          },
          "truncated": {
            "type": "boolean"
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          },
          "freshness": {
            "type": "string",
            "const": "postgres_authority"
          },
          "completeness": {
            "type": "string",
            "enum": [
              "complete",
              "truncated"
            ]
          }
        }
      },
      "ApmEnvironmentList": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "ok",
          "project_id",
          "items",
          "count",
          "truncated",
          "next_cursor",
          "freshness",
          "completeness"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "project_id": {
            "$ref": "#/components/schemas/ApmScopedId"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApmEnvironmentPolicy"
            }
          },
          "count": {
            "type": "integer",
            "minimum": 0,
            "maximum": 200
          },
          "truncated": {
            "type": "boolean"
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          },
          "freshness": {
            "type": "string",
            "const": "postgres_authority"
          },
          "completeness": {
            "type": "string",
            "enum": [
              "complete",
              "truncated"
            ]
          }
        }
      },
      "ApmSamplingPolicy": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "policy_id",
          "policy_version",
          "signal",
          "schema_version",
          "sampling_class",
          "mode",
          "enabled",
          "rate_ppm",
          "tail_window_seconds",
          "tail_budget_events",
          "effective_from",
          "effective_until"
        ],
        "properties": {
          "policy_id": {
            "type": "string"
          },
          "policy_version": {
            "type": "integer"
          },
          "signal": {
            "type": "string"
          },
          "schema_version": {
            "type": "integer"
          },
          "sampling_class": {
            "type": "string"
          },
          "mode": {
            "type": "string"
          },
          "enabled": {
            "type": "boolean"
          },
          "rate_ppm": {
            "type": [
              "integer",
              "null"
            ]
          },
          "tail_window_seconds": {
            "type": [
              "integer",
              "null"
            ]
          },
          "tail_budget_events": {
            "type": [
              "integer",
              "null"
            ]
          },
          "effective_from": {
            "type": "string",
            "format": "date-time"
          },
          "effective_until": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "ApmRetentionPolicy": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "signal",
          "retention_class",
          "policy_version",
          "duration_seconds",
          "minimum_seconds",
          "maximum_seconds",
          "region_id",
          "deletion_mode",
          "legal_hold_state",
          "enabled",
          "effective_from",
          "effective_until"
        ],
        "properties": {
          "signal": {
            "type": "string"
          },
          "retention_class": {
            "type": "string"
          },
          "policy_version": {
            "type": "integer"
          },
          "duration_seconds": {
            "type": [
              "integer",
              "null"
            ]
          },
          "minimum_seconds": {
            "type": "integer"
          },
          "maximum_seconds": {
            "type": "integer"
          },
          "region_id": {
            "type": "string"
          },
          "deletion_mode": {
            "type": "string"
          },
          "legal_hold_state": {
            "type": "string"
          },
          "enabled": {
            "type": "boolean"
          },
          "effective_from": {
            "type": "string",
            "format": "date-time"
          },
          "effective_until": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "ApmAuthorityFreshness": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "source",
          "updated_at"
        ],
        "properties": {
          "source": {
            "type": "string",
            "const": "postgres_authority"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ApmPolicySnapshot": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "ok",
          "project_id",
          "environment_id",
          "policy",
          "sampling_policies",
          "sampling_policy_count",
          "sampling_policies_truncated",
          "retention_policies",
          "retention_policy_count",
          "retention_policies_truncated",
          "freshness",
          "completeness"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "project_id": {
            "$ref": "#/components/schemas/ApmScopedId"
          },
          "environment_id": {
            "$ref": "#/components/schemas/ApmScopedId"
          },
          "policy": {
            "$ref": "#/components/schemas/ApmEnvironmentPolicy"
          },
          "sampling_policies": {
            "type": "array",
            "maxItems": 100,
            "items": {
              "$ref": "#/components/schemas/ApmSamplingPolicy"
            }
          },
          "sampling_policy_count": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100
          },
          "sampling_policies_truncated": {
            "type": "boolean"
          },
          "retention_policies": {
            "type": "array",
            "maxItems": 100,
            "items": {
              "$ref": "#/components/schemas/ApmRetentionPolicy"
            }
          },
          "retention_policy_count": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100
          },
          "retention_policies_truncated": {
            "type": "boolean"
          },
          "freshness": {
            "$ref": "#/components/schemas/ApmAuthorityFreshness"
          },
          "completeness": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "sampling_policies",
              "retention_policies"
            ],
            "properties": {
              "sampling_policies": {
                "type": "string",
                "enum": [
                  "complete",
                  "truncated"
                ]
              },
              "retention_policies": {
                "type": "string",
                "enum": [
                  "complete",
                  "truncated"
                ]
              }
            }
          }
        }
      },
      "ApmPolicyUpdate": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "expected_authority_epoch"
        ],
        "minProperties": 2,
        "properties": {
          "expected_authority_epoch": {
            "type": "integer",
            "minimum": 1
          },
          "capture_enabled": {
            "type": "boolean",
            "const": false,
            "description": "`true` is unavailable while capture rollout is OFF."
          },
          "allowed_signals": {
            "type": "array",
            "maxItems": 2,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "enum": [
                "traces",
                "rum_events"
              ]
            }
          },
          "sampling_policy_id": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ApmScopedId"
              },
              {
                "type": "null"
              }
            ]
          },
          "retention_policy_version": {
            "type": "integer",
            "minimum": 1
          },
          "privacy_policy_version": {
            "type": "integer",
            "minimum": 1
          },
          "region_id": {
            "$ref": "#/components/schemas/ApmScopedId"
          },
          "data_plane_id": {
            "$ref": "#/components/schemas/ApmScopedId"
          }
        }
      },
      "ApmPolicyUpdateResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "ok",
          "project_id",
          "environment_id",
          "policy",
          "count",
          "truncated",
          "freshness",
          "completeness"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "project_id": {
            "$ref": "#/components/schemas/ApmScopedId"
          },
          "environment_id": {
            "$ref": "#/components/schemas/ApmScopedId"
          },
          "policy": {
            "$ref": "#/components/schemas/ApmEnvironmentPolicy"
          },
          "count": {
            "type": "integer",
            "const": 1
          },
          "truncated": {
            "type": "boolean",
            "const": false
          },
          "freshness": {
            "$ref": "#/components/schemas/ApmAuthorityFreshness"
          },
          "completeness": {
            "type": "string",
            "const": "complete"
          }
        }
      },
      "ApmFreshness": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "watermark",
          "ingested_at"
        ],
        "properties": {
          "watermark": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "ingested_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "ApmTraceSummary": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "traceId",
          "completeness"
        ],
        "properties": {
          "traceId": {
            "type": "string",
            "pattern": "^(?!0{32}$)[0-9a-f]{32}$"
          },
          "rootSpanName": {
            "type": [
              "string",
              "null"
            ]
          },
          "rootServiceName": {
            "type": [
              "string",
              "null"
            ]
          },
          "startTime": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "endTime": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "durationMs": {
            "type": [
              "number",
              "null"
            ]
          },
          "spanCount": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "errorCount": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "status": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "ok",
              "error",
              null
            ]
          },
          "releaseId": {
            "type": [
              "string",
              "null"
            ]
          },
          "buildId": {
            "type": [
              "string",
              "null"
            ]
          },
          "samplingClass": {
            "type": [
              "string",
              "null"
            ]
          },
          "headSamplingDecision": {
            "type": [
              "string",
              "null"
            ]
          },
          "tailSamplingDecision": {
            "type": [
              "string",
              "null"
            ]
          },
          "samplingReason": {
            "type": [
              "string",
              "null"
            ]
          },
          "retentionDecision": {
            "type": [
              "string",
              "null"
            ]
          },
          "headState": {
            "type": [
              "string",
              "null"
            ]
          },
          "tailState": {
            "type": [
              "string",
              "null"
            ]
          },
          "partial": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "late": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "completeness": {
            "type": [
              "string",
              "null"
            ]
          },
          "samplingPolicyId": {
            "type": [
              "string",
              "null"
            ]
          },
          "retentionPolicyVersion": {
            "type": [
              "integer",
              "null"
            ]
          },
          "freshnessWatermark": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "ingestedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "schemaVersion": {
            "type": [
              "integer",
              "null"
            ]
          }
        }
      },
      "ApmTraceSpan": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "traceId",
          "spanId",
          "completeness"
        ],
        "properties": {
          "traceId": {
            "type": "string",
            "pattern": "^(?!0{32}$)[0-9a-f]{32}$"
          },
          "spanId": {
            "type": "string",
            "pattern": "^(?!0{16}$)[0-9a-f]{16}$"
          },
          "parentSpanId": {
            "type": [
              "string",
              "null"
            ]
          },
          "spanName": {
            "type": [
              "string",
              "null"
            ]
          },
          "serviceName": {
            "type": [
              "string",
              "null"
            ]
          },
          "spanKind": {
            "type": [
              "string",
              "null"
            ]
          },
          "startTime": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "endTime": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "durationMs": {
            "type": [
              "number",
              "null"
            ]
          },
          "statusCode": {
            "type": [
              "string",
              "null"
            ]
          },
          "statusMessage": {
            "type": [
              "string",
              "null"
            ]
          },
          "releaseId": {
            "type": [
              "string",
              "null"
            ]
          },
          "buildId": {
            "type": [
              "string",
              "null"
            ]
          },
          "claimedRumLinkId": {
            "type": [
              "string",
              "null"
            ]
          },
          "confirmedRumLinkId": {
            "type": [
              "string",
              "null"
            ]
          },
          "correlationState": {
            "type": "string",
            "enum": [
              "confirmed",
              "claimed",
              "unavailable"
            ]
          },
          "completeness": {
            "type": [
              "string",
              "null"
            ]
          },
          "eventTime": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "ingestedAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "ApmTraceSearchResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "ok",
          "available",
          "project_id",
          "environment_id",
          "items",
          "count",
          "truncated",
          "next_cursor",
          "partial",
          "completeness",
          "freshness"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "available": {
            "type": "boolean",
            "const": true
          },
          "project_id": {
            "$ref": "#/components/schemas/ApmScopedId"
          },
          "environment_id": {
            "$ref": "#/components/schemas/ApmScopedId"
          },
          "items": {
            "type": "array",
            "maxItems": 200,
            "items": {
              "$ref": "#/components/schemas/ApmTraceSummary"
            }
          },
          "count": {
            "type": "integer",
            "minimum": 0,
            "maximum": 200
          },
          "truncated": {
            "type": "boolean"
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          },
          "partial": {
            "type": "boolean"
          },
          "completeness": {
            "type": "string"
          },
          "freshness": {
            "$ref": "#/components/schemas/ApmFreshness"
          }
        }
      },
      "ApmTraceDetailResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "ok",
          "available",
          "project_id",
          "environment_id",
          "summary",
          "timeline",
          "count",
          "truncated",
          "partial",
          "completeness",
          "freshness",
          "parent_edges_complete"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "available": {
            "type": "boolean",
            "const": true
          },
          "project_id": {
            "$ref": "#/components/schemas/ApmScopedId"
          },
          "environment_id": {
            "$ref": "#/components/schemas/ApmScopedId"
          },
          "summary": {
            "$ref": "#/components/schemas/ApmTraceSummary"
          },
          "timeline": {
            "type": "array",
            "maxItems": 200,
            "items": {
              "$ref": "#/components/schemas/ApmTraceSpan"
            }
          },
          "count": {
            "type": "integer",
            "minimum": 0,
            "maximum": 200
          },
          "truncated": {
            "type": "boolean"
          },
          "partial": {
            "type": "boolean"
          },
          "completeness": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "summary",
              "timeline"
            ],
            "properties": {
              "summary": {
                "type": "string"
              },
              "timeline": {
                "type": "string"
              }
            }
          },
          "freshness": {
            "$ref": "#/components/schemas/ApmFreshness"
          },
          "parent_edges_complete": {
            "type": "boolean",
            "const": false
          }
        }
      },
      "ApmServiceHealth": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "service_name",
          "trace_count",
          "error_trace_count",
          "error_rate",
          "p50_duration_ms",
          "p95_duration_ms",
          "completeness",
          "freshness_watermark"
        ],
        "properties": {
          "service_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "trace_count": {
            "type": [
              "number",
              "null"
            ]
          },
          "error_trace_count": {
            "type": [
              "number",
              "null"
            ]
          },
          "error_rate": {
            "type": [
              "number",
              "null"
            ]
          },
          "p50_duration_ms": {
            "type": [
              "number",
              "null"
            ]
          },
          "p95_duration_ms": {
            "type": [
              "number",
              "null"
            ]
          },
          "completeness": {
            "type": "string",
            "enum": [
              "partial",
              "unknown"
            ]
          },
          "freshness_watermark": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "ApmDependencyHealth": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "source_service",
          "target_service",
          "protocol",
          "request_count",
          "error_count",
          "p50_duration_ms",
          "p95_duration_ms",
          "p99_duration_ms",
          "freshness_watermark"
        ],
        "properties": {
          "source_service": {
            "type": [
              "string",
              "null"
            ]
          },
          "target_service": {
            "type": [
              "string",
              "null"
            ]
          },
          "protocol": {
            "type": [
              "string",
              "null"
            ]
          },
          "request_count": {
            "type": [
              "number",
              "null"
            ]
          },
          "error_count": {
            "type": [
              "number",
              "null"
            ]
          },
          "p50_duration_ms": {
            "type": [
              "number",
              "null"
            ]
          },
          "p95_duration_ms": {
            "type": [
              "number",
              "null"
            ]
          },
          "p99_duration_ms": {
            "type": [
              "number",
              "null"
            ]
          },
          "freshness_watermark": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "ApmReleaseHealth": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "release_id",
          "build_id",
          "trace_count",
          "error_trace_count",
          "error_rate",
          "p50_duration_ms",
          "p95_duration_ms",
          "completeness",
          "freshness_watermark"
        ],
        "properties": {
          "release_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "build_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "trace_count": {
            "type": [
              "number",
              "null"
            ]
          },
          "error_trace_count": {
            "type": [
              "number",
              "null"
            ]
          },
          "error_rate": {
            "type": [
              "number",
              "null"
            ]
          },
          "p50_duration_ms": {
            "type": [
              "number",
              "null"
            ]
          },
          "p95_duration_ms": {
            "type": [
              "number",
              "null"
            ]
          },
          "completeness": {
            "type": "string",
            "enum": [
              "partial",
              "unknown"
            ]
          },
          "freshness_watermark": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "ApmServiceListResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "ok",
          "available",
          "project_id",
          "environment_id",
          "items",
          "count",
          "truncated",
          "partial",
          "completeness",
          "freshness_watermark"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "available": {
            "type": "boolean",
            "const": true
          },
          "project_id": {
            "$ref": "#/components/schemas/ApmScopedId"
          },
          "environment_id": {
            "$ref": "#/components/schemas/ApmScopedId"
          },
          "items": {
            "type": "array",
            "maxItems": 200,
            "items": {
              "$ref": "#/components/schemas/ApmServiceHealth"
            }
          },
          "count": {
            "type": "integer",
            "minimum": 0,
            "maximum": 200
          },
          "truncated": {
            "type": "boolean"
          },
          "partial": {
            "type": "boolean"
          },
          "completeness": {
            "type": "string",
            "enum": [
              "partial",
              "unknown"
            ]
          },
          "freshness_watermark": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "ApmServiceHealthResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "ok",
          "available",
          "partial",
          "reason",
          "project_id",
          "environment_id",
          "service_name",
          "health",
          "health_available",
          "items",
          "count",
          "dependencies_available",
          "truncated",
          "completeness",
          "freshness_watermark"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "available": {
            "type": "boolean",
            "const": true
          },
          "partial": {
            "type": "boolean"
          },
          "reason": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "partial_warehouse_unavailable",
              "source_incomplete",
              null
            ]
          },
          "project_id": {
            "$ref": "#/components/schemas/ApmScopedId"
          },
          "environment_id": {
            "$ref": "#/components/schemas/ApmScopedId"
          },
          "service_name": {
            "type": "string"
          },
          "health": {
            "oneOf": [
              {
                "$ref": "#/components/schemas/ApmServiceHealth"
              },
              {
                "type": "null"
              }
            ]
          },
          "health_available": {
            "type": "boolean"
          },
          "items": {
            "type": "array",
            "maxItems": 200,
            "items": {
              "$ref": "#/components/schemas/ApmDependencyHealth"
            }
          },
          "count": {
            "type": "integer",
            "minimum": 0,
            "maximum": 200
          },
          "dependencies_available": {
            "type": "boolean"
          },
          "truncated": {
            "type": "boolean"
          },
          "completeness": {
            "type": "string",
            "enum": [
              "partial",
              "unknown"
            ]
          },
          "freshness_watermark": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "ApmReleaseHealthResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "ok",
          "available",
          "project_id",
          "environment_id",
          "release_id",
          "items",
          "count",
          "truncated",
          "partial",
          "completeness",
          "freshness_watermark"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "available": {
            "type": "boolean",
            "const": true
          },
          "project_id": {
            "$ref": "#/components/schemas/ApmScopedId"
          },
          "environment_id": {
            "$ref": "#/components/schemas/ApmScopedId"
          },
          "release_id": {
            "$ref": "#/components/schemas/ApmScopedId"
          },
          "items": {
            "type": "array",
            "maxItems": 200,
            "items": {
              "$ref": "#/components/schemas/ApmReleaseHealth"
            }
          },
          "count": {
            "type": "integer",
            "minimum": 0,
            "maximum": 200
          },
          "truncated": {
            "type": "boolean"
          },
          "partial": {
            "type": "boolean"
          },
          "completeness": {
            "type": "string",
            "enum": [
              "partial",
              "unknown"
            ]
          },
          "freshness_watermark": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "ApmExportCreate": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "project_id",
          "environment_id",
          "from",
          "to",
          "fact_names",
          "purpose"
        ],
        "properties": {
          "project_id": {
            "$ref": "#/components/schemas/ApmScopedId"
          },
          "environment_id": {
            "$ref": "#/components/schemas/ApmScopedId"
          },
          "from": {
            "type": "string",
            "format": "date-time",
            "description": "Range start; interval must not exceed 31 days."
          },
          "to": {
            "type": "string",
            "format": "date-time",
            "description": "Range end after `from`; interval must not exceed 31 days."
          },
          "fact_names": {
            "type": "array",
            "minItems": 1,
            "maxItems": 10,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "enum": [
                "apm_spans",
                "apm_trace_summaries",
                "rum_events",
                "rum_vital_facts",
                "rum_session_summaries",
                "apm_metric_points",
                "apm_log_records",
                "apm_service_edge_facts",
                "apm_error_occurrences",
                "apm_error_group_facts"
              ]
            }
          },
          "purpose": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "pattern": "^[A-Za-z0-9][A-Za-z0-9 ._:/-]{0,127}$"
          },
          "expires_in_seconds": {
            "type": "integer",
            "minimum": 60,
            "maximum": 604800,
            "default": 3600
          }
        }
      },
      "ApmExportStatus": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "ok",
          "project_id",
          "environment_id",
          "export_manifest_id",
          "purpose",
          "fact_names",
          "state",
          "row_count",
          "byte_count",
          "created_at",
          "expires_at",
          "completed_at"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "project_id": {
            "$ref": "#/components/schemas/ApmScopedId"
          },
          "environment_id": {
            "$ref": "#/components/schemas/ApmScopedId"
          },
          "export_manifest_id": {
            "$ref": "#/components/schemas/ApmScopedId"
          },
          "purpose": {
            "type": "string"
          },
          "fact_names": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "state": {
            "type": "string",
            "description": "Asynchronous manifest state reported by the runtime; consumers must tolerate future states."
          },
          "row_count": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "byte_count": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "created_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "expires_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "completed_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "ApmDownloadGrantRequest": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "expires_in_seconds": {
            "type": "integer",
            "minimum": 1,
            "maximum": 300,
            "default": 60
          }
        }
      },
      "ApmPrivacyExportStatus": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "ok",
          "privacy_request_id",
          "project_id",
          "environment_id",
          "export_manifest_id",
          "purpose",
          "fact_names",
          "state",
          "row_count",
          "byte_count",
          "created_at",
          "expires_at",
          "completed_at"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "privacy_request_id": {
            "$ref": "#/components/schemas/ApmScopedId"
          },
          "project_id": {
            "$ref": "#/components/schemas/ApmScopedId"
          },
          "environment_id": {
            "$ref": "#/components/schemas/ApmScopedId"
          },
          "export_manifest_id": {
            "$ref": "#/components/schemas/ApmScopedId"
          },
          "purpose": {
            "type": "string"
          },
          "fact_names": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "state": {
            "type": "string",
            "description": "Asynchronous manifest state reported by the runtime; consumers must tolerate future states."
          },
          "row_count": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "byte_count": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 0
          },
          "created_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "expires_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "completed_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          }
        }
      },
      "ApmErasureStatus": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "ok",
          "privacy_request_id",
          "project_id",
          "environment_id",
          "state",
          "attempts",
          "created_at",
          "updated_at",
          "completed_at",
          "stores",
          "deleted"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "privacy_request_id": {
            "$ref": "#/components/schemas/ApmScopedId"
          },
          "project_id": {
            "$ref": "#/components/schemas/ApmScopedId"
          },
          "environment_id": {
            "$ref": "#/components/schemas/ApmScopedId"
          },
          "state": {
            "type": "string"
          },
          "attempts": {
            "type": "integer",
            "minimum": 0
          },
          "created_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "updated_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "completed_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "stores": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "count",
              "pending",
              "running",
              "succeeded",
              "failed"
            ],
            "properties": {
              "count": {
                "type": "integer",
                "minimum": 0
              },
              "pending": {
                "type": "integer",
                "minimum": 0
              },
              "running": {
                "type": "integer",
                "minimum": 0
              },
              "succeeded": {
                "type": "integer",
                "minimum": 0
              },
              "failed": {
                "type": "integer",
                "minimum": 0
              }
            }
          },
          "deleted": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "rows",
              "objects",
              "bytes"
            ],
            "properties": {
              "rows": {
                "type": "integer",
                "minimum": 0
              },
              "objects": {
                "type": "integer",
                "minimum": 0
              },
              "bytes": {
                "type": "integer",
                "minimum": 0
              }
            }
          }
        }
      },
      "OtlpAnyValue": {
        "type": "object",
        "description": "Proto3-JSON mapping of `opentelemetry.proto.common.v1.AnyValue` — exactly one property is present per the proto3 JSON oneof convention.",
        "properties": {
          "stringValue": {
            "type": "string"
          },
          "boolValue": {
            "type": "boolean"
          },
          "intValue": {
            "type": [
              "string",
              "integer"
            ],
            "description": "Proto3-JSON int64 mapping; a decimal string once the value exceeds Number.isSafeInteger range."
          },
          "doubleValue": {
            "type": "number"
          },
          "arrayValue": {
            "type": "object",
            "properties": {
              "values": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/OtlpAnyValue"
                }
              }
            }
          },
          "kvlistValue": {
            "type": "object",
            "properties": {
              "values": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/OtlpKeyValue"
                }
              }
            }
          },
          "bytesValue": {
            "type": "string",
            "format": "byte",
            "description": "Base64-encoded (proto3-JSON `bytes` mapping)."
          }
        }
      },
      "OtlpKeyValue": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string"
          },
          "value": {
            "$ref": "#/components/schemas/OtlpAnyValue"
          }
        }
      },
      "OtlpSpanEvent": {
        "type": "object",
        "properties": {
          "timeUnixNano": {
            "type": "string",
            "description": "Proto3-JSON int64 mapping (nanoseconds since the Unix epoch), encoded as a decimal string."
          },
          "name": {
            "type": "string"
          },
          "attributes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OtlpKeyValue"
            }
          },
          "droppedAttributesCount": {
            "type": "integer",
            "minimum": 0
          }
        }
      },
      "OtlpSpanLink": {
        "type": "object",
        "properties": {
          "traceId": {
            "type": "string",
            "format": "byte",
            "description": "Base64-encoded 16-byte trace id (proto3-JSON `bytes` mapping)."
          },
          "spanId": {
            "type": "string",
            "format": "byte",
            "description": "Base64-encoded 8-byte span id (proto3-JSON `bytes` mapping)."
          },
          "traceState": {
            "type": "string"
          },
          "attributes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OtlpKeyValue"
            }
          },
          "droppedAttributesCount": {
            "type": "integer",
            "minimum": 0
          },
          "flags": {
            "type": "integer",
            "minimum": 0
          }
        }
      },
      "OtlpSpan": {
        "type": "object",
        "description": "A single decoded span may still be dropped during post-decode validation — see `partialSuccess` on `OtlpTraceIngestResult` — so no property is `required` here; the wire format itself never rejects a well-formed but incomplete span.",
        "properties": {
          "traceId": {
            "type": "string",
            "format": "byte",
            "description": "Base64-encoded 16-byte trace id."
          },
          "spanId": {
            "type": "string",
            "format": "byte",
            "description": "Base64-encoded 8-byte span id."
          },
          "traceState": {
            "type": "string"
          },
          "parentSpanId": {
            "type": "string",
            "format": "byte",
            "description": "Base64-encoded 8-byte parent span id; absent for a root span."
          },
          "flags": {
            "type": "integer",
            "minimum": 0
          },
          "name": {
            "type": "string"
          },
          "kind": {
            "type": [
              "string",
              "integer"
            ],
            "description": "Proto3-JSON enum mapping — the OTLP SpanKind name (e.g. SPAN_KIND_SERVER) or its raw numeric value."
          },
          "startTimeUnixNano": {
            "type": "string"
          },
          "endTimeUnixNano": {
            "type": "string"
          },
          "attributes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OtlpKeyValue"
            }
          },
          "droppedAttributesCount": {
            "type": "integer",
            "minimum": 0
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OtlpSpanEvent"
            }
          },
          "droppedEventsCount": {
            "type": "integer",
            "minimum": 0
          },
          "links": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OtlpSpanLink"
            }
          },
          "droppedLinksCount": {
            "type": "integer",
            "minimum": 0
          },
          "status": {
            "type": "object",
            "properties": {
              "message": {
                "type": "string"
              },
              "code": {
                "type": [
                  "string",
                  "integer"
                ],
                "description": "Proto3-JSON enum mapping — STATUS_CODE_UNSET / STATUS_CODE_OK / STATUS_CODE_ERROR, or its raw numeric value."
              }
            }
          }
        }
      },
      "OtlpScopeSpans": {
        "type": "object",
        "properties": {
          "scope": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              },
              "attributes": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/OtlpKeyValue"
                }
              },
              "droppedAttributesCount": {
                "type": "integer",
                "minimum": 0
              }
            }
          },
          "spans": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OtlpSpan"
            }
          },
          "schemaUrl": {
            "type": "string"
          }
        }
      },
      "OtlpResourceSpans": {
        "type": "object",
        "properties": {
          "resource": {
            "type": "object",
            "properties": {
              "attributes": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/OtlpKeyValue"
                }
              },
              "droppedAttributesCount": {
                "type": "integer",
                "minimum": 0
              }
            }
          },
          "scopeSpans": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OtlpScopeSpans"
            }
          },
          "schemaUrl": {
            "type": "string"
          }
        }
      },
      "OtlpExportTraceServiceRequest": {
        "type": "object",
        "description": "Proto3-JSON mapping of OTLP's `opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest` — the exact JSON shape an OpenTelemetry SDK or Collector's OTLP/HTTP JSON exporter already sends. The 500-span cap (`POST /v1/traces`'s 413 `apm_batch_too_large`) is counted across every `resourceSpans[].scopeSpans[].spans[]` in the whole request and is therefore not expressible as a single array's `maxItems`.",
        "properties": {
          "resourceSpans": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OtlpResourceSpans"
            }
          }
        }
      },
      "OtlpTraceIngestResult": {
        "type": "object",
        "additionalProperties": false,
        "description": "Proto3-JSON mapping of OTLP's `ExportTraceServiceResponse`. An empty object means every span was accepted; `partialSuccess` is present only when one or more spans failed validation and were dropped — the whole request is never rejected once past authentication, decoding, and the batch-size cap.",
        "properties": {
          "partialSuccess": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "rejectedSpans"
            ],
            "properties": {
              "rejectedSpans": {
                "type": "string",
                "description": "Decimal count of rejected spans, encoded as a string (proto3-JSON int64 mapping)."
              },
              "errorMessage": {
                "type": "string"
              }
            }
          }
        }
      },
      "OtlpErrorDetail": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "@type",
          "reason",
          "domain",
          "metadata"
        ],
        "properties": {
          "@type": {
            "type": "string",
            "const": "type.googleapis.com/google.rpc.ErrorInfo"
          },
          "reason": {
            "type": "string",
            "enum": [
              "apm_auth_missing",
              "apm_auth_invalid",
              "apm_auth_expired",
              "apm_scope_denied",
              "apm_purpose_disabled",
              "apm_authority_unavailable",
              "apm_rate_limited",
              "apm_unsupported_media_type",
              "apm_body_too_large",
              "apm_malformed_otlp_json",
              "apm_malformed_otlp_protobuf",
              "apm_malformed_metrics_payload",
              "apm_malformed_logs_payload",
              "apm_malformed_profile_json",
              "apm_profile_storage_unavailable",
              "apm_batch_too_large",
              "apm_queue_unavailable"
            ],
            "description": "Union of every reason code any of the four OTLP-flavoured ingest routes (`POST /v1/traces`, `/v1/metrics`, `/v1/logs`, `/v1/profiles`) can return — not every operation returns every value (e.g. only `/v1/profiles` returns `apm_profile_storage_unavailable`; only `/v1/traces` returns `apm_malformed_otlp_json`/`apm_malformed_otlp_protobuf`)."
          },
          "domain": {
            "type": "string",
            "const": "ingest.noxtica.com"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "requestId",
              "retryable"
            ],
            "properties": {
              "requestId": {
                "type": "string"
              },
              "retryable": {
                "type": "string",
                "enum": [
                  "true",
                  "false"
                ]
              }
            }
          }
        }
      },
      "OtlpStatus": {
        "type": "object",
        "required": [
          "code",
          "message"
        ],
        "description": "The error body of the OTLP ingestion operations (`POST /v1/traces`, `/v1/metrics`, `/v1/logs` and `/v1/profiles`), distinct from the `{error, requestId}` envelope of every other operation. Two shapes exist and either can be returned: the collector hosts answer a `google.rpc.Status`-shaped body (`code` is the gRPC status code and `details[0].reason` the reason), and the dedicated ingest hosts answer `{code, message, error}` (`code` is the HTTP status and `error` the reason). The reason strings are the same. Branch on the HTTP status and the reason, never on `code`. `POST /v1/deployments` uses its own envelope (`ApmDeploymentError`).",
        "properties": {
          "code": {
            "type": "integer",
            "description": "On the collector hosts the gRPC status code mapped from the HTTP status (400->3 INVALID_ARGUMENT, 401->16 UNAUTHENTICATED, 403->7 PERMISSION_DENIED, 413->8 RESOURCE_EXHAUSTED, 415->3 INVALID_ARGUMENT, 429->8 RESOURCE_EXHAUSTED, 502 and 503->14 UNAVAILABLE); on the ingest hosts the HTTP status itself."
          },
          "message": {
            "type": "string"
          },
          "error": {
            "type": "string",
            "description": "The reason string on the ingest hosts (the same value as `details[0].reason` on the collector hosts)."
          },
          "details": {
            "type": "array",
            "minItems": 1,
            "maxItems": 1,
            "items": {
              "$ref": "#/components/schemas/OtlpErrorDetail"
            },
            "description": "Present on the collector hosts only."
          }
        }
      },
      "OtlpExportMetricsServiceRequest": {
        "type": "object",
        "description": "Proto3-JSON mapping of OTLP's `opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceRequest`. Modeled at the top-level `resourceMetrics` shape only, per this spec's OTLP-payload convention (see `OtlpExportTraceServiceRequest`'s own note) — each metric's own `gauge`/`sum`/`histogram`/ `exponentialHistogram`/`summary` data-point union is real proto3-JSON the collector decodes but is not exhaustively re-typed here. The 500-data-point cap (`POST /v1/metrics`'s 413 `apm_batch_too_large`) is counted across every data-point array in the whole request and is therefore not expressible as a single array's `maxItems`.",
        "properties": {
          "resourceMetrics": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true,
              "description": "One proto3-JSON `ResourceMetrics` entry (`resource`, `scopeMetrics[]`, `schemaUrl`) — see the OTLP metrics proto3-JSON schema for the full nested shape."
            }
          }
        }
      },
      "OtlpMetricsIngestResult": {
        "type": "object",
        "additionalProperties": false,
        "description": "Proto3-JSON mapping of OTLP's `ExportMetricsServiceResponse`. An empty object means every data point was accepted; `partialSuccess` is present only when one or more data points failed validation and were dropped — the whole request is never rejected once past authentication, decoding, and the batch-size cap.",
        "properties": {
          "partialSuccess": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "rejectedDataPoints"
            ],
            "properties": {
              "rejectedDataPoints": {
                "type": "string",
                "description": "Decimal count of rejected data points, encoded as a string (proto3-JSON int64 mapping)."
              },
              "errorMessage": {
                "type": "string"
              }
            }
          }
        }
      },
      "OtlpExportLogsServiceRequest": {
        "type": "object",
        "description": "Proto3-JSON mapping of OTLP's `opentelemetry.proto.collector.logs.v1.ExportLogsServiceRequest`. Modeled at the top-level `resourceLogs` shape only, per this spec's OTLP-payload convention (see `OtlpExportTraceServiceRequest`'s own note). The 500-log-record cap (`POST /v1/logs`'s 413 `apm_batch_too_large`) is counted across every `resourceLogs[].scopeLogs[].logRecords[]` in the whole request and is therefore not expressible as a single array's `maxItems`.",
        "properties": {
          "resourceLogs": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true,
              "description": "One proto3-JSON `ResourceLogs` entry (`resource`, `scopeLogs[]`, `schemaUrl`) — see the OTLP logs proto3-JSON schema for the full nested shape."
            }
          }
        }
      },
      "OtlpLogsIngestResult": {
        "type": "object",
        "additionalProperties": false,
        "description": "Proto3-JSON mapping of OTLP's `ExportLogsServiceResponse`. An empty object means every log record was accepted; `partialSuccess` is present only when one or more log records failed validation and were dropped — the whole request is never rejected once past authentication, decoding, and the batch-size cap.",
        "properties": {
          "partialSuccess": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "rejectedLogRecords"
            ],
            "properties": {
              "rejectedLogRecords": {
                "type": "string",
                "description": "Decimal count of rejected log records, encoded as a string (proto3-JSON int64 mapping)."
              },
              "errorMessage": {
                "type": "string"
              }
            }
          }
        }
      },
      "OtlpProfilesData": {
        "type": "object",
        "description": "Proto3-JSON mapping of OTLP profiling's `ProfilesData` container (`opentelemetry.proto.profiles.v1development.ProfilesData`) — profiling is still an OTel \"development\" signal, hence the bare data-container shape rather than an `ExportXServiceRequest` envelope like traces/metrics/logs use. Modeled at the top-level `resourceProfiles` shape only, per this spec's OTLP-payload convention (see `OtlpExportTraceServiceRequest`'s own note). The 20-profile cap (`POST /v1/profiles`'s 413 `apm_batch_too_large`) is counted across every `resourceProfiles[].scopeProfiles[].profiles[]` in the whole request and is therefore not expressible as a single array's `maxItems`.",
        "properties": {
          "resourceProfiles": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": true,
              "description": "One proto3-JSON `ResourceProfiles` entry (`resource`, `scopeProfiles[]`) — see the OTLP profiles proto3-JSON schema for the full nested shape."
            }
          }
        }
      },
      "OtlpProfilesIngestResult": {
        "type": "object",
        "additionalProperties": false,
        "description": "An empty object means every profile was accepted and persisted; `partialSuccess` is present only when one or more profiles failed validation, or were stored with an unrecognized `profileType`, without failing the whole request.",
        "properties": {
          "partialSuccess": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "rejectedProfiles"
            ],
            "properties": {
              "rejectedProfiles": {
                "type": "string",
                "description": "Decimal count of rejected profiles, encoded as a string."
              },
              "errorMessage": {
                "type": "string"
              }
            }
          }
        }
      },
      "ApmDeploymentMarkerRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "service",
          "version",
          "environment"
        ],
        "description": "`POST /v1/deployments`'s own single-row REST body — never an OTLP batch.",
        "properties": {
          "service": {
            "type": "string",
            "pattern": "^[A-Za-z0-9._:/-]{1,128}$"
          },
          "version": {
            "type": "string",
            "pattern": "^[A-Za-z0-9_.:/-]{1,128}$",
            "description": "Also becomes the canonical spine's `release_id` — `release_id` equals the request `version`, byte-for-byte."
          },
          "environment": {
            "type": "string",
            "pattern": "^[A-Za-z0-9._:-]{1,256}$",
            "description": "MUST equal the authenticated credential's own `environmentId` scope — a mismatch is rejected with 403 `apm_environment_mismatch` rather than redirecting the marker."
          },
          "commit": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^[0-9a-f]{7,64}$",
            "description": "Git commit SHA, 7-64 lowercase hex characters. Omit or send `null` if not applicable."
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "Defaults to the server's receipt time if omitted. MUST be less than or equal to the receipt time — a deployment marker can never be timestamped in the future."
          }
        }
      },
      "ApmDeploymentMarkerAccepted": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "ok",
          "deployment_id",
          "service",
          "version",
          "environment",
          "commit",
          "timestamp"
        ],
        "properties": {
          "ok": {
            "type": "boolean",
            "const": true
          },
          "deployment_id": {
            "type": "string",
            "description": "Server-generated `dep_<uuid>` identifier."
          },
          "service": {
            "type": "string"
          },
          "version": {
            "type": "string"
          },
          "environment": {
            "type": "string"
          },
          "commit": {
            "type": [
              "string",
              "null"
            ]
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "ApmDeploymentError": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "ok",
          "error",
          "message",
          "requestId"
        ],
        "description": "`POST /v1/deployments`'s own plain-JSON error envelope — distinct from the `google.rpc.Status`-shaped `OtlpStatus` the other three OTLP ingest routes plus `/v1/traces` share.",
        "properties": {
          "ok": {
            "type": "boolean",
            "const": false
          },
          "error": {
            "type": "string",
            "enum": [
              "apm_auth_missing",
              "apm_auth_invalid",
              "apm_auth_expired",
              "apm_scope_denied",
              "apm_purpose_disabled",
              "apm_authority_unavailable",
              "apm_rate_limited",
              "apm_unsupported_media_type",
              "apm_body_too_large",
              "apm_malformed_json",
              "apm_invalid_payload",
              "apm_environment_mismatch",
              "apm_queue_unavailable"
            ]
          },
          "message": {
            "type": "string"
          },
          "requestId": {
            "type": "string"
          }
        }
      },
      "ErrorEnvelope": {
        "type": "object",
        "required": [
          "error",
          "requestId"
        ],
        "properties": {
          "error": {
            "type": "string",
            "description": "Machine-readable error string; route-specific values are listed on each operation."
          },
          "requestId": {
            "type": "string",
            "description": "Correlation id for this call; quote it when you contact support."
          }
        }
      },
      "InvalidApiKeyError": {
        "type": "object",
        "required": [
          "error",
          "requestId"
        ],
        "properties": {
          "error": {
            "type": "string",
            "enum": [
              "invalid_api_key",
              "server_misconfigured"
            ]
          },
          "message": {
            "type": "string"
          },
          "requestId": {
            "type": "string"
          }
        }
      },
      "ScopeForbiddenError": {
        "type": "object",
        "required": [
          "error",
          "requestId"
        ],
        "properties": {
          "error": {
            "type": "string",
            "description": "Always \"API key does not have <scope> scope\", naming the missing scope."
          },
          "requestId": {
            "type": "string"
          }
        }
      },
      "NotFoundError": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string",
            "enum": [
              "Not found"
            ]
          }
        }
      },
      "HealthStatus": {
        "type": "object",
        "required": [
          "status",
          "version",
          "timestamp"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "ok",
              "degraded"
            ]
          },
          "version": {
            "type": "string",
            "description": "The deployed collector version, or `unknown`."
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "Server time of the response."
          }
        }
      },
      "Jwks": {
        "type": "object",
        "required": [
          "keys"
        ],
        "properties": {
          "keys": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "kty",
                "crv",
                "x",
                "y",
                "kid",
                "use",
                "alg"
              ],
              "properties": {
                "kty": {
                  "type": "string",
                  "enum": [
                    "EC"
                  ]
                },
                "crv": {
                  "type": "string",
                  "enum": [
                    "P-256"
                  ]
                },
                "x": {
                  "type": "string",
                  "description": "base64url X coordinate."
                },
                "y": {
                  "type": "string",
                  "description": "base64url Y coordinate."
                },
                "kid": {
                  "type": "string",
                  "description": "Key id; matches the `kid` of the envelopes signed with it."
                },
                "use": {
                  "type": "string",
                  "enum": [
                    "sig"
                  ]
                },
                "alg": {
                  "type": "string",
                  "enum": [
                    "ES256"
                  ]
                }
              }
            }
          }
        }
      },
      "CodingAgentError": {
        "type": "object",
        "required": [
          "code",
          "message",
          "error"
        ],
        "properties": {
          "code": {
            "type": "integer",
            "description": "The HTTP status code."
          },
          "message": {
            "type": "string"
          },
          "error": {
            "type": "string",
            "description": "Machine-readable reason; branch on it, not on `message`."
          }
        }
      },
      "CodingAgentSignal": {
        "type": "object",
        "required": [
          "signal",
          "reference_id",
          "excerpt",
          "observed_at"
        ],
        "properties": {
          "signal": {
            "type": "string",
            "description": "The key scope the row came from, for example `rum_errors` or `apm_traces`."
          },
          "reference_id": {
            "type": "string",
            "description": "The id of the source record (event, trace, error group, metric series)."
          },
          "excerpt": {
            "type": "string",
            "description": "A short human-readable summary of the record."
          },
          "observed_at": {
            "type": "string",
            "format": "date-time"
          },
          "metric_value": {
            "type": "number",
            "description": "Present when the record carries a numeric value."
          }
        }
      },
      "CodingAgentSpan": {
        "type": "object",
        "required": [
          "span_id",
          "service_name",
          "operation_name",
          "start_time",
          "end_time",
          "duration_ns",
          "status_code"
        ],
        "properties": {
          "span_id": {
            "type": "string"
          },
          "parent_span_id": {
            "type": "string"
          },
          "service_name": {
            "type": "string"
          },
          "operation_name": {
            "type": "string"
          },
          "start_time": {
            "type": "string",
            "format": "date-time"
          },
          "end_time": {
            "type": "string",
            "format": "date-time"
          },
          "duration_ns": {
            "type": "integer",
            "format": "int64"
          },
          "status_code": {
            "type": "string"
          },
          "status_message": {
            "type": "string"
          }
        }
      },
      "CodingAgentTrace": {
        "type": "object",
        "required": [
          "trace_id",
          "spans"
        ],
        "properties": {
          "trace_id": {
            "type": "string"
          },
          "spans": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CodingAgentSpan"
            }
          }
        }
      },
      "CodingAgentErrorOccurrence": {
        "type": "object",
        "required": [
          "occurrence_id",
          "exception_type",
          "observed_at"
        ],
        "properties": {
          "occurrence_id": {
            "type": "string"
          },
          "exception_type": {
            "type": "string"
          },
          "exception_message": {
            "type": "string"
          },
          "observed_at": {
            "type": "string",
            "format": "date-time"
          },
          "release_id": {
            "type": "string"
          }
        }
      },
      "CodingAgentErrorGroup": {
        "type": "object",
        "required": [
          "error_group_id",
          "first_seen",
          "last_seen",
          "occurrence_count",
          "affected_release_ids",
          "occurrences"
        ],
        "properties": {
          "error_group_id": {
            "type": "string"
          },
          "first_seen": {
            "type": "string",
            "format": "date-time"
          },
          "last_seen": {
            "type": "string",
            "format": "date-time"
          },
          "occurrence_count": {
            "type": "integer",
            "format": "int64"
          },
          "affected_release_ids": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "occurrences": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CodingAgentErrorOccurrence"
            }
          }
        }
      },
      "VerdictWebhookData": {
        "type": "object",
        "description": "The verdict of one scored submission. Never carries a raw IP address or personal data.",
        "required": [
          "device_id",
          "domain_id",
          "event_id"
        ],
        "properties": {
          "score": {
            "type": "number",
            "description": "The numeric risk score."
          },
          "risk_level": {
            "type": "string",
            "description": "The verdict band, for example `low`, `medium`, `high` or `critical`."
          },
          "confidence": {
            "type": "number",
            "description": "Model confidence from 0 to 1."
          },
          "flags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The risk flags that fired."
          },
          "reason_codes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The published reason-code projection of `flags`; empty unless reason-code output is enabled for your organisation."
          },
          "device_id": {
            "type": "string",
            "description": "The opaque device id. An empty string means that no stable per-device identity is available for this event."
          },
          "domain_id": {
            "type": "string",
            "description": "Your domain id."
          },
          "event_id": {
            "type": "string",
            "description": "The request id of the submission or attestation; always present."
          }
        }
      },
      "VerdictWebhookEvent": {
        "type": "object",
        "description": "The JSON body of a verdict webhook delivery.",
        "required": [
          "id",
          "type",
          "created_at",
          "tenant_id",
          "data"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "The delivery id; equals `X-Noxtica-Delivery`."
          },
          "type": {
            "type": "string",
            "enum": [
              "submission.scored",
              "risk.high",
              "risk.flagged",
              "risk.cluster_flagged"
            ]
          },
          "created_at": {
            "type": "integer",
            "format": "int64",
            "description": "Unix ms the event was produced."
          },
          "tenant_id": {
            "type": "string"
          },
          "data": {
            "$ref": "#/components/schemas/VerdictWebhookData"
          }
        }
      },
      "AgentLinkedWebhookData": {
        "type": "object",
        "description": "The first link between a verified agent and one of your accounts. Never carries a raw account id, IP address or personal data.",
        "required": [
          "account_hash",
          "agent_keyid",
          "agent_host",
          "device_id",
          "domain_id",
          "event_id"
        ],
        "properties": {
          "account_hash": {
            "type": "string",
            "description": "The keyed 16-character lowercase-hex account pseudonym."
          },
          "agent_keyid": {
            "type": "string",
            "description": "The verified agent's `Signature-Input` key id."
          },
          "agent_host": {
            "type": [
              "string",
              "null"
            ],
            "description": "The verified agent's directory host, or `null`."
          },
          "device_id": {
            "type": "string"
          },
          "domain_id": {
            "type": "string"
          },
          "event_id": {
            "type": "string"
          }
        }
      },
      "AgentLinkedWebhookEvent": {
        "type": "object",
        "description": "The JSON body of an `account.agent_linked` delivery.",
        "required": [
          "id",
          "type",
          "created_at",
          "tenant_id",
          "data"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "The delivery id; equals `X-Noxtica-Delivery`."
          },
          "type": {
            "type": "string",
            "enum": [
              "account.agent_linked"
            ]
          },
          "created_at": {
            "type": "integer",
            "format": "int64",
            "description": "Unix ms the event was produced."
          },
          "tenant_id": {
            "type": "string"
          },
          "data": {
            "$ref": "#/components/schemas/AgentLinkedWebhookData"
          }
        }
      }
    }
  },
  "security": [
    {
      "ApiKeyAuth": []
    }
  ]
}
