Skip to main content
Every Migration API endpoint shares one error model, one idempotency model, and one rate limit.

Status codes

Run-level failures are different from request errors: a POST /runs request can return 201 (accepted) and then resolve to a failed run. Read the run’s error field for the reason. See Poll a run.

Error body

Every error response is a JSON object with a single human-readable error string:
There is no machine-readable error code, field pointer, or request-id header today — branch on the HTTP status and surface the error message for debugging.

Rate limits

Each endpoint allows roughly 100 requests per minute per API key; over that you get a 429 with { "error": "Too many requests" }. There’s no Retry-After header — back off (a second or two) and retry. Space your run polling out so a fleet of concurrent migrations doesn’t burn the budget on status checks.

Idempotency

Migration creation is idempotent on the external_id you choose. Re-sending POST /migrations with the same external_id (and the same source) returns the existing migration — with a 200 instead of a 201 — rather than creating a second one. This makes create retries safe and doubles as recovery: if you lose a migration ID, re-POST with the same external_id to get it back. Runs are not keyed by an idempotency token. Instead, only one run runs at a time per migration — starting a second while one is in flight returns 409 with the active run_id, which is how you recover a run you lost track of. See Start a run.

Polling conventions

  • Poll runs on an interval of ≈2s, backing off as the run ages.
  • Treat awaiting_approval, completed, failed, and canceled as terminal for a given run; stop polling.
  • Make your handling idempotent — the same terminal state can be read more than once.
  • Prefer the thread stream (SSE) over tight polling when you want live progress.

Data region

Migrations are created in your account’s region. If you need data to land in a specific region for residency reasons, talk to us at vish@vern.so — additional regions are enabled per account.

Next