
Transition an Origin repo mirror via the Migration API
Start a mirror-state change on a mirrored repository with POST https://api.cursor.com/v1/origin/repos/{ownerSlug}/{repoName}/mirror:transition. Official reference: Origin Migration API → Transition Repo Mirror.
Origin is in Early Beta and subject to change. Call these endpoints from a migration script you run as a Cursor user, not from an Origin App. Sign in with origin auth login, or pass a Cursor API key through origin api (see User-authenticated CLI requests on the Origin API docs). Availability: Early Beta per the API overview.
Required scope: repository:mirror:write (user policy). You must also administer the repository on its upstream GitHub source. These scopes are not requestable during an Origin App installation — an Origin App cannot call this endpoint.
The repository enters a transitioning mirror status while the job runs. Poll Get Active Mirror Transition Job or Get Mirror Transition Job until the job reaches a terminal status.
Path parameters
| Param | Required | Meaning |
|---|---|---|
ownerSlug |
yes | Owning entity's unique slug. |
repoName |
yes | Repo name, unique to the owner entity. |
Request body
| Field | Required | Meaning |
|---|---|---|
transition |
yes | Mirror-state change to start. Allowed: initial_to_inbound, inbound_to_outbound, outbound_to_inbound. |
curl --request POST \
--url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/mirror:transition' \
--header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"transition": "inbound_to_outbound"
}'
Response
| Field | Meaning |
|---|---|
repository |
The repository reflecting its transitioning mirror state (same fields as Get Repo). |
job |
The job tracking the transition (same fields as Get Mirror Transition Job). Poll until terminal. |
Example:
{
"repository": {
"id": "repo_01k2ja2000e0080000000000q4",
"name": "rocket",
"fullName": "acme/rocket",
"owner": {
"slug": "acme",
"id": "ns_01k2ja2000e0080000000000p3",
"type": "team"
},
"defaultBranch": "main",
"createdAt": "2026-08-01T09:30:00Z",
"updatedAt": "2026-08-02T15:00:00Z",
"pushedAt": "2026-08-02T14:45:00Z",
"cloneUrl": "https://origin.cursor.com/git/acme/rocket.git",
"mirror": {
"source": "github",
"sourceId": "R_kgDOAbc123",
"status": "inbound"
}
},
"job": {
"id": "rmt_01k2ja2000e0080000000000m3",
"transition": "inbound_to_outbound",
"status": "running",
"phase": "draining-writes",
"attemptCount": 1,
"drainUntil": "2026-08-02T15:05:00Z",
"startedAt": "2026-08-02T15:00:00Z",
"createdAt": "2026-08-02T14:59:30Z",
"updatedAt": "2026-08-02T15:01:00Z"
}
}
Errors
| Condition | Result |
|---|---|
| Repo not in the transition's expected start state, or an active transition job already exists | FailedPrecondition (HTTP 400) |
| Caller does not administer the upstream GitHub source | HTTP 403 |
Base URL for all Origin Migration endpoints: https://api.cursor.com/v1/origin. Same error model as the Origin API.