API de migração do Origin
O Origin está em Early Beta e sujeito a alterações. Revise a especificação OpenAPI ao atualizar uma integração.
A API de migração do Origin é destinada a operadores que migram repositórios entre espelhos do GitHub e do Origin. Chame esses endpoints a partir de um script de migração executado como usuário do Cherri Code, não a partir de um Origin App.
Faça login com origin auth login ou passe uma API key do Cherri Code por meio de origin api. Veja Solicitações de CLI autenticadas pelo usuário.
Os endpoints usam a base URL da API Origin, https://api.cursor.com/v1/origin, e o mesmo modelo de erros.
Scopes
repository:mirror:write, repository:mirror:delete e repository:metadata:read são scopes de policy de usuário. Fazer transição do espelhamento do repositório e Forçar transição do espelhamento do repositório exigem Write (repository:mirror:write). Desvincular espelho do repositório exige Admin (repository:mirror:delete). Obter job de transição de espelho e Obter job de transição de espelho ativo exigem repository:metadata:read. Você também precisa administrar o repositório na origem upstream dele no GitHub.
Esses scopes não podem ser solicitados durante uma instalação de Origin App. Um Origin App não pode chamar esses endpoints.
Referência de endpoints
Transition Repo Mirror
/v1/origin/repos/{ownerSlug}/{repoName}/mirror:transitionInicia uma transição de estado de espelhamento em um repositório espelhado e retorna o job que a rastreia. O repositório passa para um status de espelhamento em transição enquanto o job é executado, portanto consulte Get Active Mirror Transition Job ou Get Mirror Transition Job até que o job atinja um status terminal.
Um repositório que não esteja no estado inicial esperado da transição, ou que já tenha um job de transição ativo, retorna FailedPrecondition (HTTP 400). O chamador precisa ter permissão de administrador sobre o repositório na fonte upstream do espelho; um chamador sem esse acesso recebe 403.
Path Parameters
ownerSlug string Obrigatório
repoName string Obrigatório
Request Body
transition string Obrigatório
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"}'Formato da resposta:
{ "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:forceCutoverForça uma transição outbound_to_inbound sem enviar por push o estado divergente deste host de volta para a fonte upstream. A fonte é adotada como source of truth no estado em que está, e as referências do Git que existem apenas neste host são capturadas em um snapshot e abandonadas. Retorna o job que rastreia a transição forçada.
Aceito apenas para repositórios com status outbound ou para repositórios travados em uma transição outbound-to-inbound cujo job ativo relata requires_attention, caso em que esse job é substituído. Qualquer outro estado, incluindo um job de transição queued ou running, retorna FailedPrecondition (HTTP 400). O chamador precisa ter permissão de administração do repositório na fonte upstream do mirror; um chamador sem esse acesso recebe 403.
Path Parameters
ownerSlug string Obrigatório
repoName string Obrigatório
Request Body
A solicitação não recebe campos. Envie um JSON object vazio.
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 '{}'Formato da resposta:
{ "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" }}Desvincular espelho do repositório
/v1/origin/repos/{ownerSlug}/{repoName}/mirrorDesconecta permanentemente um repositório espelhado de sua fonte upstream. O repositório mantém o conteúdo atual e passa a ser um repositório nativo, a sincronização é interrompida em ambas as direções e a credencial de deploy do espelho é excluída. O corpo da resposta fica vazio.
A desvinculação não pode ser revertida por esta API. Um repositório que nunca teve espelho retorna FailedPrecondition (HTTP 400); desvincular um repositório já desvinculado é bem-sucedido, mas não tem efeito.
Parâmetros de caminho
ownerSlug string Obrigatório
repoName string Obrigatório
Campos da resposta
Solicitações bem-sucedidas não retornam corpo da resposta.
curl --request DELETE \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/mirror' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Resposta:
204 No ContentObter job de transição de espelhamento
/v1/origin/repos/{ownerSlug}/{repoName}/mirror/transition-jobs/{jobId}Retorna um job de transição de espelhamento por id. Um id de job desconhecido retorna 404.
Parâmetros de caminho
ownerSlug string Obrigatório
repoName string Obrigatório
jobId string Obrigatório
job.id.Campos da resposta
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 e superseded são terminais. requires_attention exige intervenção do operador ou um cutover forçado.phase string
status, para exibição e depuração. Um dos valores 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 ou completed. Novas fases podem surgir conforme o processo de transição evolui, portanto consulte status periodicamente para verificar a conclusão, em vez de se basear nas fases.attemptCount integer
drainUntil string
lastErrorCode string
InboundMirrorDrainTimeout ou MirrorIntegrityMismatch. Ausente enquanto o job não tiver falhado.lastErrorMessage string
lastErrorCode. Ausente enquanto o job não falhar.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'Formato da resposta:
{ "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"}Obter job de transição de espelho ativo
/v1/origin/repos/{ownerSlug}/{repoName}/mirror/transition-jobs:activeRetorna o job de transição de espelho atualmente ativo do repositório e o mais recente que chegou a um estado terminal. Ambos os campos são opcionais, portanto um repositório que nunca passou por uma transição retorna um objeto vazio. Faça poll neste endpoint para acompanhar uma transição: assim que activeJob desaparecer, lastJob indica como ela terminou.
Parâmetros de caminho
ownerSlug string Obrigatório
repoName string Obrigatório
Campos de resposta
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'Formato da resposta:
{ "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" }}