Skip to main content

Getting Started

Server

The API is a single Go binary, wirekite-api, listening on HTTPS.
  • Default port: 9443 (override with --port)
  • Base URL: https://<host>:9443
  • Version prefix: every path begins with /v1/
  • TLS: self-signed cert at api/certs/server.crt by default; override with --cert / --key
Start command:

Authentication

All endpoints except /v1/health require a Bearer token:
Keys live in api/config/api_keys.json. Create one before calling protected endpoints:
Auth failures return 401 Unauthorized with error.code = "AUTH_FAILED".

Response Envelope

Every response uses the same JSON shape:
  • result — endpoint-specific payload; null on error.
  • error{ "code": "...", "message": "...", "details": {...} } on error; null on success.
  • logs — optional, included for synchronous operations.
  • duration — optional, elapsed wall-clock time.

Error Codes

Synchronous vs. Asynchronous

Async endpoints accept an optional X-Request-Id: <uuid> header. Repeating the same request id returns the same operation — safe for retries across flaky networks.

Conventions in examples

The examples below use these shell variables:

All Endpoints at a Glance


Health

GET /v1/health

Public, no auth. Returns 200 OK.

Sources

Supported type: mysql, mariadb, postgres, oracle, sqlserver.

PUT /v1/sources/:name

Create or replace a source. Request body:
Response result: { "name": "mysql-prod", "type": "mysql" }

GET /v1/sources/:name

Returns the source; sensitive params (password, etc.) are masked as "***".

GET /v1/sources

Returns { "sources": [ { name, type, parameters } ... ] } (sensitive masked).

DELETE /v1/sources/:name

Deletes the source. Fails with INVALID_REQUEST if any migration still references it.

POST /v1/sources/test

Test a connection without saving. Body has the same shape as PUT. Response result: { "connected": true, "message": "…" }

Targets

Supported type:
  • Database targets: mysql, mariadb, postgres, oracle, sqlserver, snowflake, bigquery, spanner, firebolt, databricks, singlestore, mongodb
  • Queue targets: kafka, redpanda, pubsub

PUT /v1/targets/:name

Create or replace a target. Database target body (e.g. Spanner):
Queue target body (Kafka/Redpanda):
batchSize optional (default 1); compression optional (none|snappy|lz4|zstd). Response result: { "name": "...", "type": "..." }

GET /v1/targets/:name

Get one (sensitive masked).

GET /v1/targets

List all.

DELETE /v1/targets/:name

Fails if referenced by a migration.

POST /v1/targets/test

Test a database target connection. Body same shape as PUT. Queue types are rejected — use /v1/queues/test instead.

POST /v1/queues/test

Test a Kafka/Redpanda broker + topic without saving.
Response result: { "ok": true, "message": "broker reachable, topic 'wirekite-changes' found" }

Migrations

A migration binds one source to one or both of fileTarget (DB target) and queueTarget (Kafka/Redpanda target). At least one must be provided. Most operations require fileTarget; queue-only CDC uses /replication-queue.

PUT /v1/migrations/:name

Create or replace a migration. Body:
Required: source, tables, and at least one of fileTarget / queueTarget. Optional: threads, rows_per_file, schema_rename, logDetail ("basic" default, or "verbose"). Response result: { "name": "...", "source": "...", "fileTarget": "...", "queueTarget": "...", "tables": <count> }

GET /v1/migrations/:name

Return the migration config.

GET /v1/migrations

List all as { "migrations": [ { name, source, fileTarget, queueTarget, tables: <count> } ... ] }.

DELETE /v1/migrations/:name

Delete migration + working directory. Rejects with OPERATION_CONFLICT if an operation is still running.

Prerequisites & Validation

POST /v1/prereqs

Get SQL that must be run on source and target before migration works. Does not execute anything. Body:
mode: one of data, replication, data+replication (controls which grants are included). Response result:

POST /v1/validate

Actually connect and check every prerequisite is satisfied. Body same shape as /prereqs, plus valid password values. Response result:

Schema

POST /v1/migrations/:name/schema/extract

Extract DDL from source. Requires fileTarget. Produces tables-schema.sql, objects-schema.sql, drop-tables.sql inside the migration working directory. Times out after 15 minutes. Response result: { "sql_file": "/path/to/tables-schema.sql", "tables": <count> }

POST /v1/migrations/:name/schema/apply

Apply DDL to target. Idempotent. Body (optional): { "sql_file": "/custom/path.sql" } — defaults to the extracted tables-schema.sql. Response result: { "tables_created": <count> }

Objects

POST /v1/migrations/:name/objects/apply

Apply database objects (views, procedures, triggers, functions) to the target. Runs after schema/extract. Partial failures are reported rather than aborting. Response result: { "objects_succeeded": <count>, "objects_failed": <count> }

Data Migration (async)

POST /v1/migrations/:name/data

Start data load (extract → move → load). Returns immediately. Body (optional):
Optional header: X-Request-Id: <uuid> for safe retries. Response result:
Poll /v1/migrations/:name/status or /v1/operations/:id for progress.

Replication (async)

POST /v1/migrations/:name/replication

Start CDC replication to fileTarget. Requires schema/extract to have been run. Body (optional):
position format is source-type-specific (MySQL: file:offset; Oracle: SCN; SQL Server: hex LSN). Ignored when resume=true. Response result: { "operation_id": "...", "status": "running", "started_at": "..." }

POST /v1/migrations/:name/replication/pause

Pause the running replication (process stays alive).

POST /v1/migrations/:name/replication/resume

Resume a paused replication. Response result: { "migration": "...", "action": "paused" | "resumed" }

Replication to Queue (async)

Use when the migration has queueTarget only (no fileTarget). Migrations that have a fileTarget are rejected by this endpoint.

POST /v1/migrations/:name/replication-queue

Start queue-only CDC. No schema extract required. Body (optional): { "resume": false, "position": "..." } Response result: { "operation_id": "...", "status": "running", "started_at": "...", "mode": "change-queue" }

POST /v1/migrations/:name/replication-queue/pause and /resume

Same shape as /replication/pause|resume.

Data + Replication (async, chained)

POST /v1/migrations/:name/data-replication

Two-phase: data load → hand off position → start CDC. Requires fileTarget. Body (optional): { "resume": false, "position": "..." } Smart resume: if position.pkt already exists the data phase is skipped and CDC resumes from there; otherwise the data phase re-runs. Response result: { "operation_id": "...", "status": "running", "started_at": "..." }

Reset

POST /v1/migrations/:name/reset

Reset the target. Requires fileTarget. Body (optional): { "mode": "drop" | "truncate" | "metadata" } (default drop). Response result:
  • drop: { "mode": "drop", "tables_dropped": N, "drop_failed": M }
  • truncate: { "mode": "truncate", "tables_truncated": N, "truncate_failed": M }
  • metadata: { "mode": "metadata" }

Validate Data

POST /v1/migrations/:name/validate

Compare row counts / checksums between source and target. Safe to run during active replication. Requires fileTarget. Body (optional): { "sample_percent": 100 } (0 or 100 = all rows; 1–99 = sample). Response result:

Status

GET /v1/migrations/:name/status

Get live progress of the currently running operation, or a summary of the last completed operation when idle. Running (data phase):
Running (change phase):
Idle:

Operations

Generic long-running-operation tracking across all async ops.

GET /v1/operations

List with filters + pagination. Query params (all optional): migration=<name>, status=<running|completed|failed|cancelled|stopped>, mode=<data|change|change-queue|data-replication>, page_size=<1-200> (default 50), page_token=<offset>. Response result:

GET /v1/operations/:id

Full detail including result, error, and per-binary logs tails.

POST /v1/operations/:id/cancel

Graceful termination (SIGTERM). Response result: { "operation_id":"…", "status":"cancelled" }

POST /v1/operations/:id/stop

Force kill (SIGKILL) + cleanup of orphaned child processes. Response result: { "operation_id":"…", "status":"stopped" }