Docs · For developers

Developer overview Public API is pre-release

VirtualID is API-first: everything the app does, it does through the versioned JSON API. This section describes the v1 contract, conventions, and the interactive reference generated straight from the OpenAPI 3.1 spec.

The API reference is the machine-readable source of truth for every endpoint. The prose on this page is a summary. Spec-only for now — no public implementation yet.

Base & versioning

  • Hosts: https://api.virtualid.one/api/v1 (EU), https://api.virtualid.us/api/v1 (US, placeholder domain).
  • Version in path: /api/v1/…; clients pin a major version. Additive-only within v1; breaking changes ⇒ /api/v2 with a deprecation window.
  • Media type: application/json for requests and responses.
  • Optional VID-API-Version response header; Deprecation/Sunset headers when applicable.

Authentication

Authorization: Bearer <access_token> — short-lived tokens obtained via the passkey (later OAuth) flows, cryptographically sender-bound with DPoP. Sensitive operations require step-up via VID-Step-Up: <assertion>, else 403 step_up_required. See Authentication for the full sign-in and cross-device flows.

Conventions

Idempotency

All unsafe writes accept an Idempotency-Key: <uuid> header; it's required for POSTs that create resources or grant/subscribe. The server stores the key + result for 24h (scoped to endpoint + principal):

  • Same key + same body → the original response (no duplicate side effect), with VID-Idempotent-Replay: true.
  • Same key + different body → 409 idempotency_key_reused.

Optimistic concurrency

Updates take If-Match: <version>412 on mismatch.

Pagination

Cursor-based: ?limit=50&cursor=…{ "data": [...], "next_cursor": "…", "has_more": true }. Single resources return the entity directly (with schema_version).

Errors

A shared error envelope plus standard HTTP codes: 400 validation · 401 unauthenticated · 403 forbidden / step-up · 404 not found · 409 conflict/idempotency · 422 semantic · 429 rate-limited · 5xx server. Every response carries VID-Request-Id.

Rate limits & quotas

RateLimit-* headers, plus monthly Quota-Limit/Quota-Remaining/Quota-Reset. On 429 honour Retry-After; under load shedding the API may return 503 + Retry-After.

Resource groups (v1)

The full path/operation list is in the API reference. In brief:

  • auth — passkey register/login, OAuth, token refresh, methods, TOTP, recovery key.
  • identity & fields/me, /me/fields.
  • field-catalog/field-types (read-only, with per-country validation).
  • profiles — profiles, /exposures, /preview.
  • subscriptions — owner-side approve/deny/move/revoke.
  • my-contacts — subscriber-side list, pull, unsubscribe.
  • annotations — private notes/labels.
  • sharing — share links + redeem.
  • public — public profiles + vCard export.
  • keys-events — split-key material + event stream.
  • lifecycle — export, delete, undelete.

Events (live updates)

Event-then-pull: GET /events/stream (SSE/WS) delivers "changed" signals carrying no data; clients then pull the updated resource. A poll fallback exists at GET /events?since=cursor.

Deferred (post-MVP / preview): the Developer Platform — OAuth apps, service accounts, scopes, per-principal throttling/billing. Not part of the MVP.