Skip to main content
Public API V1 is protocol-deprecated. Its prompt-import route remains operational only as a temporary bridge until the Public API V2 prompt-import production gate passes; it does not return 410 today and will retire without a redirect only after that gate. No Sunset date has been announced for the separately governed V1 read routes.
Public API V2 is a separately versioned contract under /public/v2. It is currently a private preview, is disabled by default, and should not be treated as generally available or production-ready. To request preview access, email [email protected]. This page describes the current migration boundary so you can plan and test a move without disrupting an existing V1 integration. The complete field map, SDK examples, and warehouse recipes will be added before a broader release.

V1 and V2 coexistence

  • V1 continues to serve its released routes under /public/v1 while it is deprecated.
  • V2 uses independent routes, schemas, OpenAPI documentation, and versioned client defaults. Changing a V1 base URL is always your decision.
  • V1 requests are not redirected or translated into V2 requests, including prompt imports.
  • The V1 prompt-import route is an accelerated exception to the broader V1 read-retirement process. It remains operational only until the V2 prompt-import production gate passes, then returns 410 version_retired. There is no redirect, translation, mirroring, or dual write between versions.
  • No Sunset date or retirement date has been announced for the broader V1 read surface.
  • The Videntic MCP integration remains on V1 pending a separate consumer audit and rollout. Do not migrate or override its base URL as part of an API V2 preview.

Current V2 private-preview surface

Four routes return website or analytics data: Two reads return paginated source evidence: The private-preview contract also includes these read routes. Their availability still depends on preview access; use the V2 OpenAPI document for query parameters and response shapes. Each abbreviated route above starts with GET /public/v2/websites/{website_id}.

V2 prompt-import surface

The implemented private-preview write surface is an append-only, one-way, asynchronous bulk prompt workflow: V2 does not expose a prompt-library read, update, or delete API, and uploading a batch does not start an analysis. Both operations now appear in the separate V2 OpenAPI document served from GET /public/v2/openapi.json, but the production-readiness gate has not passed. Use them only in a preview-enabled workspace. See Bulk prompt imports for exact limits, classification, idempotency, polling, retry, redaction, and migration rules.

Contract differences to plan for

Do not migrate by changing only v1 to v2 in the base URL. Adapt and validate these boundaries explicitly: V1 retains its existing request and response contract. It does not gain V2 classification, receipt, idempotency, or atomic-operation semantics.

Behaviors to design your client around

These are not bugs and they will not change; they are contract properties your integration has to account for.

A website appears before it has any analytics

GET /public/v2/websites and GET /public/v2/websites/{website_id} return a website as soon as it is added to your workspace, before its first analysis has run. Such a website has a null last_analysis_at, and its GET …/analytics returns 404 not_found until the first snapshot is published. This is intentional: the website directory reflects what you are tracking, not what has already been measured. A warehouse load should expect rows with null metrics and treat them as “tracked, not yet measured,” not as an error.

Incremental sync is at-least-once

Every updated_since scan is inclusive at both ends of its window. A row whose timestamp falls exactly on a page boundary is returned by the scan that ends there and by the next scan that begins there, so the same row can arrive twice across two syncs. Remove duplicates by the resource’s opaque id when you load — do not assume a row is delivered exactly once. This is the standard trade for never dropping a row: we would rather hand you a duplicate you can discard than miss one you cannot recover. For directory and analytics/evidence scans, advance a durable watermark between syncs by carrying the scan_upper_bound from a page’s metadata and pass it back as the next sync’s updated_since. Because the bound is a committed publication frontier, resuming from it never skips a row that committed after your scan began. Each resource family has its own frontier; do not reuse a website-directory frontier for an analytics feed. Revoked or deleted websites disappear immediately, including from in-flight scans. The directory does not emit deletion events: periodically reconcile a full listing if you need to detect removals. Reports support cursor pagination and updated_since, but do not expose an immutable publication frontier.

Technical Audit reads refer to a specific Audit Run

Every Technical Audit read names one Audit Run. audit_id (aud_…) is an opaque token for the run; take it from the overview (data.id) or the run list. Without audit_id, a read answers from the latest complete run, the only kind whose Findings are final, and a paginated read keeps the run its first page used. The overview returns 404 not_found until a run is complete, and its newer_run names a run that is still running or failed. Findings of a run that is not complete return 409 conflict with reason: run_not_complete; its pages can be read while it runs. Paging through a running run’s pages never repeats a page, but a page audited behind your cursor is not added to it; list again once the run is complete for every page. Single reads accept only audit_id: a repeated or unknown query parameter is 400 invalid_request. Page lists contain summaries of the pages the Crawl requested; addresses found outside the Audit Scope are counted, never listed. Every page check, inbound links and the Lighthouse lab sample are returned by the page-detail endpoint.

What changed when the Technical Audit moved to the new engine (2026-10)

The paths and query parameters stayed; the data now comes from the new Technical Audit. Audit Runs from before the change are not returned, and aud_… values issued before it return 404 not_found.

Fix Technical Audit issues with your own agent

Keys with the technical_audit_fixes_write scope (created in Settings by a workspace owner or admin; they include read access) can prepare and change fixes in the website’s connected WordPress. The key’s creator needs Technical Audit edit access to the website, and a view-only workspace is refused. apply, revert and discard require an Idempotency-Key header. Repeating a key replays the earlier request (meta.replayed: true, the fix as it is now); using it for a different request returns 409 idempotency_conflict. A fix is fixed only when its verification.outcome is confirmed. Every write is logged and can be reverted.

Rate limits are per workspace

V2 permits 100 requests per minute across your workspace’s keys and endpoints. Exhaustion returns 429 rate_limited. A rate-limit storage outage returns 503 temporarily_unavailable, not an indication that you used your quota. Honor Retry-After in either case.

A snapshot may be published before it is complete

An analytics snapshot can be published while some post-processing is still outstanding. When that is the case the response carries is_partial_data: true alongside a postprocess_status describing what is still pending. A partial snapshot is a real, usable measurement — but if you gate business logic on completeness, branch on is_partial_data rather than assuming every published snapshot is final.

A dry run does not cost your quota

A prompt import submitted with validate_only: true does not count against your per-minute, per-hour, or per-day import allowance. You can validate a batch as often as you need before committing it. A pending dry run does still occupy a worker slot briefly, so it counts toward the concurrent-import limit while it runs — but it never consumes the volume allowance a real write would.

Practical migration plan

  1. Request private-preview access. Email [email protected] with your workspace, current V1 routes, expected volume, and whether you use prompt imports. V2 remains unavailable until access is explicitly enabled.
  2. Inventory your V1 dependency. Record every route, selected field, pagination assumption, metric calculation, retry rule, and downstream table. Treat MCP as a separate V1 consumer and leave it unchanged.
  3. Build a version-specific adapter. Keep independent V1 and V2 base URLs, response parsers, cursor storage, and error handling. Store opaque V2 IDs as strings and preserve the version metadata returned with analytics.
  4. Run bounded dual reads. For preview-approved read routes, fetch V1 and V2 independently into separate staging tables. Compare resource coverage, nullability, finalized-analysis timestamps, metric definitions, evidence counts, and pagination completion. Do not overwrite your V1 analytical baseline with V2 values during comparison.
  5. Approve a separate V2 baseline before cutover. Do not pass this gate until your integration owner has recorded and explained every expected metric delta found during dual reads; preserved the returned V2 contract, projection, metric-definition, precision, and taxonomy version metadata; and approved a distinct V2 checkpoint and analytical baseline. Never splice V2 values into the V1 historical series.
  6. Test the write cutover in private preview. Follow the bulk prompt-import guide to build the dedicated write-key, two-idempotency-key validation, explicit bulk partitioning, asynchronous polling, and redacted-receipt paths behind a disabled client flag. You may exercise them in a preview-enabled workspace, but do not enable production use until Videntic announces that the production-readiness gate passed. The V1 prompt-import route remains operational today; after the gate it retires and is not a write fallback.
  7. Cut over in your client. Move one controlled consumer at a time by changing its configured API version. Monitor your own results and retain the last known-good V1 configuration until the V2 preview is signed off for your integration.

Roll back safely

For read integrations, V1 remains operational and is never redirected, so rollback is a client configuration change rather than an API redirect. Prompt imports have a stricter boundary: after the V2 production gate passes, the V1 prompt-import route is retired and is not a rollback target.
  1. Restore the affected read consumer’s last known-good /public/v1 base URL, V1-specific parser, credentials, and cursor state. Do not feed a V2 cursor or opaque ID into a V1 request.
  2. Resume reads from the last committed V1 checkpoint. For an accepted V2 prompt import, continue polling its receipt to a terminal state; do not retry the batch through V1 or assume that changing the read version cancels it.
  3. Disable new V2 prompt submissions in your client if the write path is unhealthy, retain the original idempotency key for transport-uncertain retries, and contact support before creating a replacement operation.
  4. Send the request IDs, import IDs, timestamps, and affected routes to [email protected]. Do not include API keys or prompt text.

Existing V1 reference

The deprecated V1 reference remains discoverable for existing integrations:

V1 authentication

Review the existing Bearer-key contract and V1-specific authentication behavior.

V1 conventions

Review the frozen V1 request, response, pagination, and ordering conventions.
Last modified on October 27, 2026