Skip to main content

Session and Exposition contracts

Staging reference

The Exposition and CVE/KEV contracts on this page target staging. Download the separate OpenAPI JSON or YAML. This is a selected browser-session reference, not a complete workspace API or a promise of production availability. It is distinct from the personal API and organization service API.

Authentication and permissions​

Browser requests use the __Host-ps session cookie. Unsafe methods also require the __Host-pc CSRF cookie and matching X-CSRF-Token header. Personal API keys and organization service credentials are not substitutes. An organization-scoped session remains restricted to that organization.

Exposition reads require access to an Exposition organization and the selected scope. External/client members and general-research spaces cannot use these endpoints. Writes require a writable organization; creation, lifecycle, timezone, monitoring and notification settings also require an owner or administrator. A member's assigned scope still limits decisions, history and reports. Authentication does not bypass those checks.

HTTP 401 means missing/invalid authentication; 403 a permission or CSRF refusal; 402 an entitlement or budget refusal; 409 a version/capacity conflict; 422 invalid input; 429 a rate/cadence limit. Read the actual error code, and refetch/reconcile after a version conflict.

Personal credit state​

GET /api/v2/auth/credits returns monthly_credits, credits_used, purchased balance, lifetime_purchased, cycle_start, cycle_end, has_paid_entitlement, plan_label and is_legacy. These are session endpoints with no search charge. has_paid_entitlement is not a substitute for the live API-data access check: a Free account with a depleted purchased balance cannot spend its monthly allocation through /common/data.

GET /api/v2/auth/credits/usage returns the current cycle_start, usage and usage_mcp arrays of {category, credits}. The MCP array is a subset of the total, not an additional charge. Categories are host, dns, whois, certs, alerting, subdomains, exports and tools. Eligible session JSON object responses may also contain profundis_credits; streams and array responses do not use that injected object. See Credits.

Scope lifecycle​

Paths below are relative to /api/v2/organizations/{orgId}. A scope is represented by a client resource in these routes.

Method and pathContract
POST /exposure/scopesname, domain, IANA timezone, optional addresses (up to 16 IPs), monitoring, credit_limit; returns a client view with 201
PATCH /clients/{clientId}name and state (active or archived), with current quoted If-Match version
DELETE /clients/{clientId}Exact name in confirmation, with If-Match; 204 on success
GET /clients/deletedUp to 100 recoverable metadata entries for managers
POST /clients/{clientId}/restoreCurrent If-Match; only before erase_after and before erasure begins

Capacity billing ignores credit_limit; legacy credit billing requires 6–1,000,000. Creating a capacity-based scope starts an initial refresh from stored observations. Scheduled monitoring remains a separate setting. Declaring an asset does not authorize an active vulnerability scan.

Archiving stops queued/running work and monitoring, cancels deliveries and revokes guest report links. Deletion immediately removes access and starts a seven-day cancellation window; audit/accounting records remain. Restoration returns the scope to archived state. Grants, links and scheduled spending are not silently restored.

Inventory, decisions and history​

Paths below use /api/v2/organizations/{orgId}/clients/{clientId}/exposure as their prefix. The inventory GET uses the prefix itself, without another segment.

Method and suffixContract
GET (prefix itself)Inventory and observations; fixed pages of 100, offset 0–50,000, optional group_by=host
PATCH /subjects/{subjectId}Decision/note with current body version; this does not use If-Match
GET /historyOptional subject, offset 0–100,000; 50 newest events per page
PUT /timezoneIANA timezone and current body version; manager only
POST /assets/{assetKey}/enrichCatalogue association for a stored observation, no asset request
GET /controlsRead up to 100 historical control records, optionally filtered by asset

Use returned totals, partial, observation dates, evaluation completeness and filter_options to interpret inventory coverage. An absent observation is not evidence that an asset is secure or absent. Badge search criteria apply to the search surface; they do not imply an additional scope filter.

Service decisions use new, investigating or acknowledged. An acknowledged decision records a conclusion: kept, closed, updated, not_concerned or other. closed/updated requires according_to; not_concerned/other requires a note. An optional announced_date is a nonfuture YYYY-MM-DD date interpreted in the scope timezone. These are attributed declarations. They do not delete the original observation, and a later observation can reopen the subject. renewal applies to domain-expiry subjects.

Catalogue coverage and retained evidence​

Each service's coverage separates three facts: availability of an evaluation (state, reasons, eligible), the displayed result (result_state, result_at, retained_result) and the latest attempt or actual processing (last_attempt_at, processing). Older deployments and frozen reports can lack these new fields.

coverage.stateMeaning
evaluatedA complete catalogue evaluation is available; this can include a match
no_identifiers, imprecise_identifiers, identifier_limitMissing, insufficiently precise or too many software identifiers
not_evaluatedNo usable evaluation has been recorded
catalogue_unavailable, catalogue_incompleteCatalogue data could not support a complete evaluation
processing_errorA corresponding evaluation task failed before a result was available
shared_edgeShared infrastructure is excluded from these service coverage counts

result_state is kev, matched, no_match or indeterminate. A failed refresh does not turn an old negative into a current clean result: it becomes indeterminate. Positive evidence may remain visible with retained_result: true; its result_at is distinct from last_attempt_at. evaluation.last_attempt can also contain the recorded reasons and retained_result. A complete catalogue result is still not an active vulnerability check.

processing.state is idle, paused, unknown, queued, retry_scheduled, running, interrupted, failed or cancelled. Queue and job fields come from an actual task corresponding to the current evaluation input. A legacy task that cannot be associated reliably is unknown. available_at is a queued task's eligibility time, not a completion deadline. Reading the inventory creates no job.

Filter with evaluation=coverage:catalogue_unavailable, for example. summary.coverage contains services, excluded_shared_edge and counts by states and processing. Shared-edge observations are counted separately. A KEV subject's optional observed_products lists only {vendor, product, version} entries associated with its findings.

Frozen reports​

GET /reports lists up to 100 summaries. POST /reports freezes the current view and returns 201 with a report; GET /reports/{reportId} reads its saved document under current permissions. The snapshot includes the organization/scope names, author, timezone, reference time, observations and at most 500 history entries. history_partial identifies a truncated history. Limits are 100 frozen reports per scope and 16 MiB per document.

Freezing a report does not run a search, scan an asset, publish a guest link or send email. The saved document remains the view at its recorded time; opening it does not substitute today's inventory.

Observation refresh and email preferences​

PUT /monitoring takes {"enabled":true} or false and changes scheduled observation watches. POST /run takes a stable key of 16–64 characters for an observation refresh; cadence, billing and quotas apply. These operations read existing Profundis datasets.

GET /notifications reads the scope email preference. PUT /notifications requires an owner/administrator and a body with enabled, recipients (0–20 member user IDs), language (fr or en) and current version. At least one recipient is required when enabled. Recipients must still have access; delivery rechecks eligibility and observation freshness. Preferences start disabled. Saving them is not confirmation of email delivery. Personal alert preferences and organization in-app notifications are separate systems.

Active scanning is unavailable​

The dedicated active CVE scan engine is not available on staging or production. There is no launch-control endpoint in this contract. Existing control records are historical evidence only. A catalogue CVE match, KEV association, observation refresh or user declaration must never be presented as a newly executed vulnerability check. Unconfirmed discovery candidates use previously collected observations only.

Coverage of this download​

The session download covers the operations above, the session twins of search and enrichment, and existing IP intelligence, pipeline, portfolio and favicon-extraction tools. The public caller-IP route is explicitly unauthenticated. Account/login flows, checkout, personal alert-rule management and remaining workspace collaboration/administration routes are not yet modeled in this download; use their dedicated guides. It must not be used as a complete account or organization SDK contract.