/api/v1/openapi.json. The unversioned
paths are kept for CLI compatibility.
Endpoints
Authentication
Cloud import uses a migration token, not absk_live_... API key. Header auth is
preferred:
Migration-Token: mig_.... Every cloud
import endpoint (single-request import, sessions, chunks, and finalize) also
accepts JSON-body token fields for clients that cannot set headers: token,
migrationToken, or migration_token, either at the root or inside a nested
export or data object.
Invalid, expired, or already-used tokens return 419 with an unauthorized
problem response. Missing or malformed tokens return 401.
Migration Tokens
A migration token is bound to one project by design: it authorizes importing into exactly the project it was minted for, is single use, and expires afterBISIBILITY_MIGRATION_TOKEN_TTL_MINUTES. This is what lets the exporting side
push data into a destination project without ever holding that project’s API
key. There is no instance-global token; a broader credential would grant more
than an import needs.
Tokens are minted and managed through the ordinary project-scoped REST API
using an Authorization: Bearer <api_key> key for the destination project:
The raw
mig_... value is returned only when minted. Tokens can also be minted
from the in-app wizard.
Compatibility Preflight
Call the public compatibility endpoint before generating an export:latest_migration is null when
the migration table cannot be read.
Single Request Import
Post the export package directly to/api/v1/cloud/import:
{ "export": { ... } } and { "data": { ... } }
payloads. Top-level sections include keywords, alertRules or alert_rules,
competitors, notificationPreferences or notification_preferences,
savedViews or saved_views, and CLI-style rank_checks.
Keyword fields:
History fields:
Imported history rows use provider value
self-hosted-import.
Success returns 201.
Chunked Session Import
Use sessions when the package is large enough that one request may exceed body limits or timeout. A session has three phases: create, upload chunks, finalize.1. Create the Session
version must be 3. chunk_count must be between 1 and 500. totals is
optional and is stored with the session manifest.
Success returns 201.
receiving or importing session is allowed per token. A second
live session returns 409.
2. Upload Chunks
Upload each chunk by zero-based index:{sessionId, index} with the same checksum returns 200; retrying that
index with a different checksum returns 409. Clients should compute the
sha256: value over the JSON bytes they intend to send before gzip compression.
To gzip a chunk, send the gzip-compressed JSON body with:
413.
Success returns:
3. Finalize
Finalize after every chunk has been accepted:{}. If chunks are missing, finalize returns 409.
If another finalize is already importing the session, it returns 409. Once the
session is done, a repeated finalize call returns the completed job response.
Crash Resume
Persistsession_id, chunk_count, and every chunk checksum on the client.
After a client crash, re-upload all chunks whose success was not recorded. The
server accepts already stored chunks when the checksum matches.
If the connection drops during finalize, call finalize again. A 200 means the
session completed. A 409 means chunks are still missing or a finalize is still
running. Stale receiving and importing jobs are marked failed by maintenance
after 30 minutes, after which a new migration token and session are required.
Status Codes
Environment Knobs
Existing App Surfaces
The app also implements cloud-import state with server actions:In-App Wizard
Open/cloud/import, generate or paste a migration token, then upload the JSON
package from the wizard. The wizard uses the same import handlers as the REST
endpoints.