Origin Migration API
Origin は Early Beta 段階であり、変更される可能性があります。連携を更新する際は OpenAPI specification を確認してください。
Origin Migration API は、GitHub と Origin ミラー間でリポジトリを移行する operator 向けです。これらのエンドポイントは、Origin App からではなく、Cherri Code ユーザーとして実行する移行スクリプトから呼び出してください。
origin auth login でサインインするか、origin api で Cherri Code API キーを渡してください。ユーザー認証済みの CLI リクエストを参照してください。
これらのエンドポイントは、Origin API の base URL である https://api.cursor.com/v1/origin と、同じエラーモデルを使用します。
Scopes
repository:mirror:write、repository:mirror:delete、repository:metadata:read は user policy scope です。移行 ミラーリポジトリ と Force ミラーリポジトリ Cutover には Write (repository:mirror:write) が必要です。リポジトリミラーのデタッチ には Admin (repository:mirror:delete) が必要です。ミラー移行ジョブの取得 と 有効なミラー移行ジョブの取得 には repository:metadata:read が必要です。さらに、上流 の GitHub ソース側でも対象リポジトリの管理権限が必要です。
これらの scope は Origin App のインストール時に要求することはできません。Origin App からこれらのエンドポイントを呼び出すことはできません。
Endpoint リファレンス
Transition Repo Mirror
/v1/origin/repos/{ownerSlug}/{repoName}/mirror:transitionミラーリポジトリのミラー状態の遷移を開始し、それを追跡するジョブを返します。ジョブの実行中、リポジトリは遷移中のミラーステータスになります。ジョブが終了ステータスに達するまで、Get Active Mirror Transition Job または Get Mirror Transition Job をポーリングしてください。
遷移が想定する開始状態にないリポジトリ、またはすでに実行中の遷移ジョブがあるリポジトリでは、FailedPrecondition (HTTP 400) が返ります。呼び出し元はミラーの上流ソースでそのリポジトリを管理できる必要があり、そのアクセス権がない場合は 403 が返ります。
Path Parameters
ownerSlug string 必須
repoName string 必須
Request Body
transition string 必須
initial_to_inbound、inbound_to_outbound、outbound_to_inbound。Response Fields
repository object
job object
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"}'レスポンスの構造:
{ "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" }}Force Repo Mirror Cutover
/v1/origin/repos/{ownerSlug}/{repoName}/mirror:forceCutoverこの host で分岐した状態を上流ソースへプッシュせずに、outbound_to_inbound のカットオーバーを強制します。ソースが現状のまま信頼できる情報源として採用され、この host にのみ存在する refs は snapshot を取得した上で破棄されます。強制カットオーバーを追跡する job を返します。
受け付けられるのは、outbound status のリポジトリ、または active な job が requires_attention を報告しているアウトバウンドからインバウンドへの移行で停止しているリポジトリのみで、後者の場合はその job が置き換えられます。それ以外の state (queued または running の移行 job を含む) では FailedPrecondition (HTTP 400) が返ります。caller は mirror の上流ソースでそのリポジトリを管理している必要があり、その access がない caller には 403 が返ります。
Path Parameters
ownerSlug string 必須
repoName string 必須
Request Body
このリクエストに fields はありません。空の JSON object を送信してください。
Response Fields
repository object
job object
curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/mirror:forceCutover' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{}'レスポンスの構造:
{ "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": "outbound" } }, "job": { "id": "rmt_01k2ja2000e0080000000000m4", "transition": "outbound_to_inbound", "status": "running", "phase": "snapshotting-refs", "attemptCount": 1, "startedAt": "2026-08-02T15:00:00Z", "createdAt": "2026-08-02T14:59:30Z", "updatedAt": "2026-08-02T15:01:00Z" }}リポジトリミラーのデタッチ
/v1/origin/repos/{ownerSlug}/{repoName}/mirrorミラーリポジトリを上流ソースから完全に切断します。リポジトリは現在のコンテンツを保持したまま native リポジトリとなり、双方向の同期が停止し、ミラーの deploy credential は削除されます。レスポンスボディは空です。
デタッチはこの API では元に戻せません。ミラーを持ったことがないリポジトリでは FailedPrecondition (HTTP 400) が返されます。すでにデタッチ済みのリポジトリに対しては、何も変更せずに成功します。
Path Parameters
ownerSlug string 必須
repoName string 必須
Response Fields
リクエストが成功した場合、レスポンスボディは返されません。
curl --request DELETE \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/mirror' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Response:
204 No Contentミラー移行ジョブの取得
/v1/origin/repos/{ownerSlug}/{repoName}/mirror/transition-jobs/{jobId}IDを指定して、mirror移行ジョブを1件返します。存在しないジョブIDの場合は 404 を返します。
パスパラメータ
ownerSlug string 必須
repoName string 必須
jobId string 必須
job.id として返される値です。レスポンスフィールド
id string
transition string
initial_to_inbound、inbound_to_outbound、outbound_to_inbound。status string
queued、running、succeeded、failed_rolled_back、requires_attention、superseded。succeeded、failed_rolled_back、superseded は終了状態です。requires_attention の場合は、オペレーターによる介入または強制的なカットオーバーが必要です。phase string
status 内の進捗詳細。queued、starting、draining-writes、initializing-mirror-fetch、finalizing-mirror-fetch、finalizing-mirror-push、snapshotting-refs、verifying-integrity、reopening-inbound-mirror、committing-target-status、rolling-back、completed のいずれか。移行プロセスの改善に伴って新しいフェーズが追加される場合があるため、フェーズ名で判定せず、status をポーリングして完了を確認してください。attemptCount integer
drainUntil string
lastErrorCode string
InboundMirrorDrainTimeout、MirrorIntegrityMismatch など) 。ジョブが失敗していない間は含まれません。lastErrorMessage string
lastErrorCode の人間が読める形式の詳細。ジョブが失敗していない場合は含まれません。startedAt string
completedAt string
createdAt string
updatedAt string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/mirror/transition-jobs/JOB_ID' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'レスポンスの構造:
{ "id": "rmt_01k2ja2000e0080000000000m3", "transition": "inbound_to_outbound", "status": "succeeded", "phase": "completed", "attemptCount": 1, "startedAt": "2026-08-02T15:00:00Z", "completedAt": "2026-08-02T15:12:00Z", "createdAt": "2026-08-02T14:59:30Z", "updatedAt": "2026-08-02T15:12:00Z"}有効なミラー移行ジョブの取得
/v1/origin/repos/{ownerSlug}/{repoName}/mirror/transition-jobs:activeリポジトリで現在有効なミラー移行ジョブと、直近の終了済みジョブを返します。どちらのフィールドも任意のため、一度も移行したことのないリポジトリでは空の object が返ります。移行の進行状況を追うには、この endpoint を poll してください。activeJob が消えた時点で、lastJob からどのように終了したかを確認できます。
Path Parameters
ownerSlug string 必須
repoName string 必須
Response Fields
activeJob object
lastJob object
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/mirror/transition-jobs:active' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'レスポンスの構造:
{ "activeJob": { "id": "rmt_01k2ja2000e0080000000000m4", "transition": "outbound_to_inbound", "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" }, "lastJob": { "id": "rmt_01k2ja2000e0080000000000m3", "transition": "inbound_to_outbound", "status": "succeeded", "phase": "completed", "attemptCount": 1, "startedAt": "2026-08-01T10:00:00Z", "completedAt": "2026-08-01T10:12:00Z", "createdAt": "2026-08-01T09:59:30Z", "updatedAt": "2026-08-01T10:12:00Z" }}