API Reference
Migrations

Migrations API

Start a Migration

POST /api/migrations/project/{projectId}/start

Starts a migration run for the given project. Returns the migration run object.

Request body:

{
  "type": "FULL",
  "enginePayload": {
    "source": {
      "org":         "yourorg",
      "project":     "YourProject",
      "pat":         "your-ado-pat",
      "area_filter": null,
      "type_filter": null
    },
    "target": {
      "base_url":    "https://yourorg.atlassian.net",
      "email":       "migration@yourcompany.com",
      "api_token":   "your-jira-token",
      "project_key": "PROJ"
    },
    "options": {
      "migrate_attachments": true,
      "migrate_comments":    true,
      "migrate_links":       true,
      "dry_run":             false,
      "type_overrides":  { "Feature": "Epic" },
      "state_overrides": { "Resolved": "Done" }
    }
  }
}
FieldTypeRequiredDescription
typeFULL | SAMPLE | INCREMENTALYesMigration scope
enginePayload.source.orgstringYesADO organisation name
enginePayload.source.projectstringYesADO project name
enginePayload.source.patstringYesADO Personal Access Token or OAuth Bearer token
enginePayload.source.area_filterstringNoFilter to a specific ADO area path
enginePayload.source.type_filterstringNoComma-separated work item types to include
enginePayload.target.base_urlstringYesJira Cloud base URL
enginePayload.target.emailstringYesJira service account email
enginePayload.target.api_tokenstringYesJira API token
enginePayload.target.project_keystringYesJira project key
enginePayload.options.dry_runbooleanNoPreview only; no writes to Jira
enginePayload.options.type_overridesobjectNoOverride AI type mappings
enginePayload.options.state_overridesobjectNoOverride default state mappings

Response (200 OK):

{
  "id":              "run-uuid",
  "projectId":       "project-uuid",
  "status":          "RUNNING",
  "type":            "FULL",
  "totalItems":      0,
  "successCount":    0,
  "failureCount":    0,
  "progressPercent": 0,
  "startedAt":       "2024-06-03T10:00:00Z",
  "createdAt":       "2024-06-03T10:00:00Z"
}

Get Migration Status

GET /api/migrations/{runId}/status

Returns the current status of a migration run including progress counts.

Response:

{
  "id":              "run-uuid",
  "status":          "RUNNING",
  "totalItems":      5000,
  "successCount":    2341,
  "failureCount":    3,
  "skippedCount":    0,
  "progressPercent": 47,
  "currentPhase":    2,
  "startedAt":       "2024-06-03T10:00:00Z"
}
StatusDescription
PENDINGQueued, not yet started
RUNNINGActive migration in progress
PAUSEDPaused by user or API call
COMPLETEDFinished successfully
PARTIALFinished with some item failures
FAILEDTerminal failure — could not complete
CANCELLEDCancelled by user

Stream Live Progress

GET /api/migrations/{runId}/stream

Server-Sent Events (SSE) stream delivering live migration events.

Event types:

event: progress
data: {"type":"progress","current":250,"total":5000,"percent":5,"speed":45.2}

event: log
data: {"type":"log","message":"✓ ADO #10432 [User Story] → PROJ-142"}

event: status
data: {"type":"status","status":"completed"}

event: done
data: {"type":"done","stats":{"created":4997,"skipped":0,"failed":3}}
Note:

EventSource connections cannot set custom headers. Pass the JWT as a query parameter: /api/migrations/{runId}/stream?token={accessToken}


Pause a Migration

POST /api/migrations/{runId}/pause

Sends a pause signal to the running migration. The migration stops cleanly at the next checkpoint (within seconds). No partial item writes are left open.

Response (200 OK):

{ "id": "run-uuid", "status": "PAUSED" }

Resume a Migration

POST /api/migrations/{runId}/resume

Resumes a paused migration from the last checkpoint. No items are duplicated.

Response (200 OK):

{ "id": "run-uuid", "status": "RUNNING" }

Cancel a Migration

POST /api/migrations/{runId}/cancel

Permanently cancels a migration. Cannot be undone. Items already migrated to Jira are not removed.

Response (200 OK):

{ "id": "run-uuid", "status": "CANCELLED" }

List Migration Runs

GET /api/migrations?projectId={projectId}

Lists all migration runs for a project, most recent first.

Query parameters:

ParamTypeDescription
projectIdUUIDFilter by project (required)
statusstringFilter by status

Error Codes

CodeHTTPDescription
MIGRATION_NOT_FOUND404Run ID does not exist or belongs to another tenant
MIGRATION_NOT_PAUSED400Attempted to resume a non-paused run
MIGRATION_ALREADY_RUNNING409Attempted to start when a run is already active
ENGINE_DISPATCH_FAILED502Could not start the migration worker (infrastructure issue)