> ## Documentation Index
> Fetch the complete documentation index at: https://docs.videntic.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrate from Public API V1 to V2

> V1 deprecation status, the separately versioned V2 private preview, contract changes, prompt-import guidance, migration steps, and rollback guidance.

<Warning>
  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.
</Warning>

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 [info@videntic.com](mailto:info@videntic.com?subject=Public%20API%20V2%20private%20preview).

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:

| Method and route | Purpose |
| - | - |
| `GET /public/v2/websites` | List websites available to the authenticated workspace. |
| `GET /public/v2/websites/{website_id}` | Get one website. |
| `GET /public/v2/websites/{website_id}/analytics` | Get the latest finalized analytics snapshot. |
| `GET /public/v2/websites/{website_id}/analytics/history` | Page through immutable finalized analytics points. |

Two reads return paginated source evidence:

| Method and route | Purpose |
| - | - |
| `GET /public/v2/websites/{website_id}/mentions` | Page through brand-mention evidence. |
| `GET /public/v2/websites/{website_id}/citations` | Page through citation evidence. |

The private-preview contract also includes these read routes. Their
availability still depends on preview access; use the
[V2 OpenAPI document](https://api.videntic.com/public/v2/openapi.json) for
query parameters and response shapes.

| Route family | Reads |
| - | - |
| Analytics insights | `…/analytics/topics`, `…/analytics/providers`, `…/analytics/competitive-signals`, `…/analytics/content-gaps` |
| Technical Audit | `…/technical-audit`, `…/technical-audit/runs`, `…/technical-audit/findings`, `…/technical-audit/findings/{finding_id}`, `…/technical-audit/pages`, `…/technical-audit/pages/{page_id}`, `…/technical-audit/scope`, `…/technical-audit/fixes` |
| Reports | `…/reports`, `…/reports/{report_id}`, `…/reports/{report_id}/download` |

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:

| Method and route | Purpose |
| - | - |
| `POST /public/v2/websites/{website_id}/prompts:import` | Accept an append-only prompt batch and return an operation to poll. |
| `GET /public/v2/websites/{website_id}/prompt-imports/{import_id}` | Get an import's status and redacted receipt. |

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](/api/v2/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:

| Area | V1 | V2 private-preview contract |
| - | - | - |
| Versioning | Released contract under `/public/v1` | Independent contract under `/public/v2`; disabled unless your preview access is enabled |
| Resource identifiers | Existing V1 identifiers | Opaque, typed identifiers such as `web_…`, `ana_…`, and `pim_…`; do not parse or construct them |
| Success responses | V1 endpoint-specific envelopes | Data plus request metadata; tolerate additive response fields |
| Errors | V1 error and status behavior remains frozen | Versioned `{ error, meta }` envelope; insufficient authenticated scope is `403` rather than V1's `401` behavior |
| Pagination | V1 cursor behavior | Opaque cursors with stable ordering and a fixed scan boundary where supplied; never edit or reuse a cursor with different filters |
| Analytics | V1 metric shapes and formulas | Finalized, immutable snapshots with explicit contract, projection, metric-definition, precision, and taxonomy versions; missing measurements remain null rather than becoming zero |
| Evidence | V1 mention data | Separate mention and citation evidence feeds, scoped to a website and analysis |
| Prompt import | Website scope in the body, `dry_run`, and a synchronous V1 response | Website scope in the path, `validate_only`, an `Idempotency-Key`, asynchronous `202` acceptance, and a redacted receipt polled by import ID |
| Prompt write semantics | V1 accepts `mode`, `partial`, and caller-controlled `source` fields | Append-only and atomic; removes `mode`, `partial`, and caller-controlled source; automatically classifies missing fields unless `classification.mode=provided_only` |
| Prompt results | V1 results can echo prompt text | Receipt items correlate by zero-based `index` and optional `client_id`; prompt text is not returned |

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

Use `audit_id` from the overview or Audit Run list when fetching scope, Findings
and audited pages. Scope is the configuration captured for that run, not today's
settings. Older runs without a captured scope return `404 not_found` for scope;
start a new Technical Audit to capture it.

Page lists contain summaries. Evidence, performance samples and inbound-link
details are returned by the page-detail endpoint, not represented as empty
collections in the list. Overview summaries are published with the Audit Run;
an unpublished summary returns `503 temporarily_unavailable`.

### 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
   [info@videntic.com](mailto:info@videntic.com?subject=Public%20API%20V2%20private%20preview)
   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](/api/v2/prompt-imports) 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
   [info@videntic.com](mailto:info@videntic.com?subject=Public%20API%20V2%20preview%20support).
   Do not include API keys or prompt text.

## Existing V1 reference

The deprecated V1 reference remains discoverable for existing integrations:

<CardGroup cols={2}>
  <Card title="V1 authentication" icon="key" href="/api/authentication">
    Review the existing Bearer-key contract and V1-specific authentication
    behavior.
  </Card>

  <Card title="V1 conventions" icon="book" href="/api/conventions">
    Review the frozen V1 request, response, pagination, and ordering conventions.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.