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.crtby default; override with--cert/--key
Authentication
All endpoints except/v1/health require a Bearer token:
api/config/api_keys.json. Create one before calling protected endpoints:
401 Unauthorized with error.code = "AUTH_FAILED".
Response Envelope
Every response uses the same JSON shape:result— endpoint-specific payload;nullon error.error—{ "code": "...", "message": "...", "details": {...} }on error;nullon success.logs— optional, included for synchronous operations.duration— optional, elapsed wall-clock time.
Error Codes
error.code | HTTP | Meaning |
|---|---|---|
AUTH_FAILED | 401 | Missing or invalid Bearer token |
INVALID_REQUEST | 400 | Malformed body / bad parameters |
MIGRATION_NOT_FOUND | 404 | Migration does not exist |
SOURCE_NOT_FOUND | 404 / 400 | Source does not exist / not created |
TARGET_NOT_FOUND | 404 / 400 | Target does not exist / not created |
OPERATION_CONFLICT | 409 | Another operation already running on this migration |
OPERATION_NOT_FOUND | 404 | Operation id unknown |
CONNECTION_REFUSED | 200 / 500 | Connection test failed (details in error.details) |
SCHEMA_APPLY_FAILED | 500 | Schema apply exited non-zero |
OBJECTS_APPLY_FAILED | 500 | Objects apply exited non-zero |
EXTRACTOR_FAILED | 500 | Data/change extractor exited non-zero |
LOADER_FAILED | 500 | Data/change loader exited non-zero |
ORCHESTRATOR_FAILED | 500 | Orchestrator startup failed |
RESET_FAILED | 500 | Reset operation failed |
VALIDATE_FAILED | 500 | Data validation failed |
DATA_FAILED | 500 | Data migration failed |
REPLICATION_FAILED | 500 | Replication failed |
FIREBOLT_SCHEMA_PUBLIC_ONLY | 400 | Firebolt target requires public schema (use schema_rename) |
Synchronous vs. Asynchronous
| Category | Behavior | Endpoints |
|---|---|---|
| Synchronous | HTTP blocks until done (≤ 15 min). Response includes result + logs + duration. | All CRUD, /prereqs, /validate, /schema/extract, /schema/apply, /objects/apply, /reset, /validate (data), /sources/test, /targets/test, /queues/test, pause/resume, health |
| Asynchronous | Returns immediately with operation_id. Poll /v1/migrations/:name/status or /v1/operations/:id. | /data, /replication, /replication-queue, /data-replication |
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
| Method | Path | Sync? |
|---|---|---|
| GET | /v1/health | sync (public) |
| PUT | /v1/sources/:name | sync |
| GET | /v1/sources/:name | sync |
| GET | /v1/sources | sync |
| DELETE | /v1/sources/:name | sync |
| POST | /v1/sources/test | sync |
| PUT | /v1/targets/:name | sync |
| GET | /v1/targets/:name | sync |
| GET | /v1/targets | sync |
| DELETE | /v1/targets/:name | sync |
| POST | /v1/targets/test | sync |
| POST | /v1/queues/test | sync |
| PUT | /v1/migrations/:name | sync |
| GET | /v1/migrations/:name | sync |
| GET | /v1/migrations | sync |
| DELETE | /v1/migrations/:name | sync |
| POST | /v1/prereqs | sync |
| POST | /v1/validate | sync |
| POST | /v1/migrations/:name/schema/extract | sync |
| POST | /v1/migrations/:name/schema/apply | sync |
| POST | /v1/migrations/:name/objects/apply | sync |
| POST | /v1/migrations/:name/data | async |
| POST | /v1/migrations/:name/replication | async |
| POST | /v1/migrations/:name/replication/pause | sync |
| POST | /v1/migrations/:name/replication/resume | sync |
| POST | /v1/migrations/:name/replication-queue | async |
| POST | /v1/migrations/:name/replication-queue/pause | sync |
| POST | /v1/migrations/:name/replication-queue/resume | sync |
| POST | /v1/migrations/:name/data-replication | async |
| POST | /v1/migrations/:name/reset | sync |
| POST | /v1/migrations/:name/validate | sync |
| GET | /v1/migrations/:name/status | sync |
| GET | /v1/operations | sync |
| GET | /v1/operations/:id | sync |
| POST | /v1/operations/:id/cancel | sync |
| POST | /v1/operations/:id/stop | sync |
Health
GET /v1/health
Public, no auth. Returns 200 OK.
Sources
Supportedtype: mysql, mariadb, postgres, oracle, sqlserver.
PUT /v1/sources/:name
Create or replace a source.
Request body:
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
Supportedtype:
- Database targets:
mysql,mariadb,postgres,oracle,sqlserver,snowflake,bigquery,spanner,firebolt,databricks,singlestore - Queue targets:
kafka,redpanda
PUT /v1/targets/:name
Create or replace a target.
Database target body (e.g. Spanner):
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.
result: { "ok": true, "message": "broker reachable, topic 'wirekite-changes' found" }
Migrations
A migration binds one source to one or both offileTarget (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:
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):
X-Request-Id: <uuid> for safe retries.
Response result:
/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 hasqueueTarget 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):
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" }