Skip to main content
Cloud import accepts an export package and restores keywords plus optional rank history into the project associated with a migration token. Use the single request endpoint for small packages and the session protocol for large packages. The versioned paths are included in /api/v1/openapi.json. The unversioned paths are kept for CLI compatibility.

Endpoints

Authentication

Cloud import uses a migration token, not a bsk_live_... API key. Header auth is preferred:
The import endpoints also accept 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 after BISIBILITY_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:
Response:
The endpoint is anonymous and rate limited. latest_migration is null when the migration table cannot be read.

Single Request Import

Post the export package directly to /api/v1/cloud/import:
The endpoint also accepts nested { "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.
Top-level fields: Keyword fields: History fields: Imported history rows use provider value self-hosted-import.
Historical rows may be nested under each keyword’s rankingHistory array or sent in a CLI-style top-level rank_checks array. Top-level checks are merged into keyword history by source keyword id first, then by keyword text. Checks that match no keyword are dropped and are counted only in history_received.
Success returns 201.
Section counts are included when the corresponding section was present in the request:

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.
Only one live receiving or importing session is allowed per token. A second live session returns 409.

2. Upload Chunks

Upload each chunk by zero-based index:
Keyword chunks carry keyword rows:
Section chunks carry non-keyword package sections and optional source keyword ids used to map imported alert targets:
The checksum is the chunk content identity for idempotent retries. Retrying the same {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:
The body limit applies before and after decompression. Oversized chunks return 413. Success returns:

3. Finalize

Finalize after every chunk has been accepted:
The body may be empty or {}. 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

Persist session_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.