Origin API
Origin находится на раннем этапе бета-тестирования и может измениться. При обновлении интеграции сверяйтесь со спецификацией OpenAPI.
Origin — платформа Cursor для разработки кода. Её публичный REST API позволяет приложениям и инструментам работать с репозиториями Origin, коммитами, проверками, pull request и установками приложений.
- Origin Apps проходят аутентификацию с помощью JWT приложений и токенов доступа установки. См. раздел Аутентификация.
- Полную спецификацию OpenAPI с подробными схемами и примерами можно посмотреть здесь.
- Агенты могут загрузить индекс llms.txt или полную справочную документацию в формате Markdown по адресу llms-full.txt.
Обзор
Приложения Origin используют модель согласия на установку в стиле OAuth и модель аутентификации в стиле GitHub App:
- Приложение подписывает краткосрочный EdDSA JWT своим приватным ключом Ed25519.
- Приложение обменивает этот JWT и идентификатор установки на краткосрочный токен доступа установки (
oit_…). - Токен установки обращается к API репозиториев и аутентифицирует Git по HTTPS в пределах одобренных для установки репозиториев и областей доступа.
- Origin отправляет подписанные доставки вебхука на зарегистрированный URL вебхука приложения.
Базовый URL
https://api.cursor.com/v1/originПути к конечной точке в справочнике включают полный префикс /v1/origin.
Соглашения протокола
Для запросов и ответов используется application/json. В именах полей JSON используется camelCase. Метки времени указываются в виде строк RFC 3339. 64-битные целые числа Protobuf, включая номера pull request и номера версий, кодируются как строки JSON.
Ответы содержат поля со значениями по умолчанию, а не опускают их, поэтому логическое значение false, число 0, пустая строка и пустой массив присутствуют в теле. Считывайте само значение, а не трактуйте отсутствующий ключ как значение по умолчанию. Поля, описанные в документации как отсутствующие или опускаемые, являются необязательными в контракте и не включаются в тело, если не заданы.
Начало работы
Доступ к Origin
- Откройте Origin на cursor.com/codebase.
- Управляйте настройками приложений на cursor.com/codebase/settings/apps.
- Создайте ключ подписи приложения и зарегистрируйте только открытый ключ.
Origin CLI
Установите Origin CLI и войдите в систему:
curl -fsSL https://downloads.cursor.com/origin/install.sh | shorigin auth loginКлонируйте существующий репозиторий:
origin repo clone '{ownerSlug}/{repoName}'# или напрямую через gitgit clone 'https://origin.cursor.com/{ownerSlug}/{repoName}.git'Apps клонируют через аутентификацию Git по HTTPS с токеном доступа установки, а не с учётными данными пользователя.
Установка
Попросите администратора рабочей области клиента перейти по ссылке:
https://cursor.com/codebase/apps/install ?client_id=APP_ID &scope=SPACE_SEPARATED_SCOPES &redirect_uri=REGISTERED_CALLBACK &state=RANDOM_ANTI_FORGERY_VALUE &summary=SHORT_REASON_FOR_ACCESS &include_granted_scopes=true| Параметр | Обязательный | Описание |
|---|---|---|
client_id | Да | идентификатор приложения Origin. |
scope | Да | Области доступа, разделённые пробелами. repository:metadata:read добавляется автоматически. |
redirect_uri | Да при установке по инициативе партнёра | Точный зарегистрированный URI обратного вызова. |
state | Настоятельно рекомендуется | Случайное значение для защиты от подделки, дублируемое в качестве утверждения state в квитанции об установке. Создайте его перед перенаправлением и проверьте утверждение в обратном вызове. |
summary | Нет | Краткое пояснение, отображаемое при предоставлении согласия. |
include_granted_scopes | Нет | Если true, сохраняет существующие разрешения и запрашивает только дополнительные. |
Администратор рабочей области выбирает целевого владельца, одобренные области доступа, а также все репозитории или выбранные репозитории. Доступ к репозиториям контролирует клиент, а не приложение.
После одобрения Origin перенаправляет на зарегистрированный обратный вызов:
https://ci.example.com/origin/callback?installation_receipt=RECEIPT_JWTПроверьте квитанцию об установке, затем сохраните идентификатор установки из утверждения sub. Он понадобится при выпуске токена доступа установки.
Установки используют один из двух режимов выбора репозиториев:
all: установка может получать доступ ко всем репозиториям, принадлежащим выбранной цели.selected: установка может получать доступ только к репозиториям, выбранным администратором рабочей области.
Оба режима распространяются на зеркалированные репозитории и нативные репозитории Origin, поэтому зеркало появляется в GET /installation/repos и его можно выбрать. Зеркало доступно только для чтения, пока не станет стабильным исходящим зеркалом: см. Зеркалированные репозитории.
Используйте GET /installation/repos с токеном установки, чтобы узнать, какие репозитории доступны для этой установки. Конечные точки App JWT позволяют выводить список установок приложения, просматривать их и удалять. Удаление установки предотвращает выпуск новых токенов.
Квитанция об установке
installation_receipt — это краткосрочный компактный JWT, подписанный Origin. Он подтверждает, что одобрение установки поступило от Origin, а не было подделано при перенаправлении, и содержит всё необходимое для обратного вызова. Cursor не выполняет перенаправление без него, поэтому он всегда включается во внешние обратные вызовы.
Заголовок JOSE:
{ "alg": "EdDSA", "kid": "origin-key-id", "typ": "origin-installation-receipt+jwt"}Утверждения:
{ "iss": "https://api.cursor.com/v1/origin", "aud": "app_01...", "sub": "i_01...", "namespace_id": "ns_01...", "iat": 1786465200, "exp": 1786465500, "jti": "RECEIPT_UUID", "installedBy": { "id": "user_01...", "email": "[email protected]", "displayName": "Jane Doe" }, "state": "ORIGINAL_VALUE"}aud— идентификатор вашего приложения, аsub— идентификатор установки, который следует использовать при выпуске токенов доступа установки.namespace_id— стабильный идентификатор пространства имён, в котором установлено приложение.installedByопределяет пользователя, выполнившего эту установку или повторное согласие. Он описывает текущее действие, поэтому при повторном согласии может отличаться от устойчивогоinstalledByв Получить установку приложения. Он содержитdisplayName, если у аккаунта есть имя, и никогда не содержитhandle; вместо этого считывайте handle из ответа REST или payload вебхука.- Срок действия квитанции об установке истекает через пять минут после выпуска.
jtiуникален для каждой квитанции об установке. stateприсутствует, только если URL установки содержал непустойstate, и повторяет его значение. Сопоставьте его со значением защиты от подделки, которое вы создали до перенаправления.
Проверяйте квитанцию об установке, прежде чем доверять обратному вызову: определите ключ подписи из JWKS по заголовку kid, требуйте alg EdDSA и typ origin-installation-receipt+jwt, а также проверяйте подпись, iss, aud и exp. Отклоняйте обратный вызов, если проверка не пройдена.
Квитанция об установке не является токеном доступа установки. Никогда не отправляйте её как учётные данные Bearer; вместо этого выпускайте токены установки через Создать токен доступа установки.
Аутентификация
Передавайте учетные данные REST по схеме Bearer. Значки Auth у каждой конечной точки показывают, какие типы учетных данных он принимает:
curl --request GET \ --url https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME \ --header "Authorization: Bearer $ORIGIN_BEARER_TOKEN"API-ключи Cursor — это не Bearer-токены Origin. Для запросов с аутентификацией пользователя используйте Origin CLI: он обменивает личный пользовательский API-ключ на краткосрочный токен доступа, который принимает Origin. Не указывайте API-ключ Cursor напрямую в заголовке Authorization.
Создание ключа подписи приложения
Origin Apps используют для аутентификации пару ключей Ed25519. Создайте пару локально, затем зарегистрируйте только открытый ключ на cursor.com/codebase/settings/apps. Приложение может иметь до 10 активных ключей подписи.
Приватный ключ должен оставаться секретным. Не загружайте его, не вставляйте в настройки приложения, не коммитьте в репозиторий и не передавайте другим. Храните его в менеджере секретов. Cursor хранит только открытый ключ.
Создайте приватный ключ PKCS#8 и открытый ключ PEM SPKI с помощью OpenSSL:
openssl genpkey -algorithm ED25519 -out origin-app-private.pemopenssl pkey -in origin-app-private.pem -pubout -out origin-app-public.pemФайл открытого ключа начинается с -----BEGIN PUBLIC KEY-----. Вставьте этот PEM при добавлении ключа подписи. Используйте соответствующий приватный ключ только для подписи app JWT.
App JWT
Подпишите краткосрочный JWT приватным ключом Ed25519, соответствующим одному из активных ключей подписи приложения. Создайте эту пару, как описано в разделе Создание ключа подписи приложения.
Заголовок JOSE:
{ "alg": "EdDSA", "kid": "app_01...", "typ": "JWT"}Утверждения:
{ "iss": "app_01...", "aud": "origin-apps", "iat": 1782928800, "exp": 1782929100}Задайте для iss и kid идентификатор приложения. Установите срок действия около пяти минут.
Authorization: Bearer APP_JWTИспользуйте App JWT для операций на уровне приложения: чтения его метаданных, управления установками, выпуска токенов установки и повторной доставки вебхука.
Токен доступа установки
Выполните запрос POST /app/installations/{installationId}/access_tokens с App JWT. Токены установки начинаются с oit_.
Authorization: Bearer oit_...Ответ содержит expiresAt. Выпускайте токены непосредственно перед использованием, обновляйте их до истечения срока действия, обращайтесь с ними как с паролями и никогда не записывайте в журналы.
Удаление установки или приложения делает токены установки недействительными до expiresAt. После этого REST API и Git по HTTPS отклоняют токен с кодом 401. Не повторяйте попытку с тем же токеном; приложение необходимо переустановить, прежде чем оно сможет выпустить рабочий токен.
Токен установки не может предоставлять больше прав, чем одобренные для установки область доступа или доступ к репозиториям. Токен можно ограничить меньшим набором область доступа или repositoryIds. Пустые или пропущенные массивы наследуют полный набор разрешений установки.
Используйте токены установки для операций, ограниченных репозиторием, включая pull requests, запись результатов проверок и Git по HTTPS.
Аутентификация Git по HTTPS
Токены доступа установки используются для аутентификации Git по HTTPS. Конечная точка Git использует базовую аутентификацию HTTP: пароль — токен установки, имя пользователя — x-access-token. Учетные данные Bearer предназначены для REST API; Git по HTTPS их не принимает.
Выпускайте токен с помощью Создать токен доступа установки непосредственно перед операцией Git. Срок действия токена — не более 15 минут.
Для клонирования, fetch и pull требуется repository:contents:read. Для push требуется repository:contents:write. Токен должен включать целевой репозиторий в предоставленных разрешениях.
Для push также требуется, чтобы владелец репозитория имел право записи в Origin — такое же требование действует для Создать репозиторий. Владелец-пользователь должен использовать тариф Pro, Pro Student, Pro+, Ultra или Start. Владелец-команда должна иметь активный платный тариф команды, не использовать режим конфиденциальности (устаревшая версия), а Origin не должен быть отключён администратором команды. Push в репозиторий, владелец которого не соответствует этим требованиям, возвращает 403. Для клонирования, fetch и pull это требование не действует.
Получите cloneUrl из Получить репозиторий или Список репозиториев установки приложения. Клонирование поддерживается как по пути в формате GitHub (https://origin.cursor.com/OWNER_SLUG/REPO_NAME.git), так и по устаревшему пути /git/.
git clone "https://x-access-token:${INSTALLATION_TOKEN}@origin.cursor.com/OWNER_SLUG/REPO_NAME.git"Токен, встроенный в URL, сохраняется в .git/config. После успешного клонирования измените URL удалённого репозитория, чтобы последующие команды не использовали истёкший секрет:
git remote set-url origin "https://origin.cursor.com/OWNER_SLUG/REPO_NAME.git"Чтобы не указывать токен в URL удалённого репозитория, передайте его через помощник Git для учётных данных:
git -c credential.helper="!f() { echo username=x-access-token; echo password=${INSTALLATION_TOKEN}; }; f" \ clone "https://origin.cursor.com/OWNER_SLUG/REPO_NAME.git"Помощник учётных данных Origin CLI предназначен для входа пользователей. Интеграции приложений передают токен установки, как показано здесь. Обращайтесь с токеном как с паролем: никогда не записывайте его в логи и выпускайте новый до expiresAt, если задаче по-прежнему нужен доступ к Git.
В зеркальном репозитории токен установки позволяет клонировать, выполнять fetch и pull, а Origin отклоняет git push с кодом 403, пока зеркало не станет стабильным исходящим зеркалом. См. Зеркалированные репозитории.
Запросы CLI с аутентификацией пользователя
Используйте origin api для запросов с аутентификацией пользователя. Для интерактивной сессии войдите в систему через браузер:
origin auth loginorigin api /repos/OWNER_SLUG/REPO_NAME/pullsДля неинтерактивной сессии укажите личный пользовательский API-ключ из Cursor Dashboard → API Keys:
export CURSOR_API_KEY="YOUR_PERSONAL_USER_API_KEY"origin api /repos/OWNER_SLUG/REPO_NAME/pullsCLI обменивает личный пользовательский API-ключ на краткосрочный пользовательский токен доступа и передаёт этот токен в заголовке Authorization. Не отправляйте сам API-ключ на конечную точку Origin. Интеграциям приложений следует вместо этого использовать app JWT и токены доступа установки.
Discovery и ключи подписи
Origin публикует общедоступные метаданные Discovery и свои активные ключи подписи. Эти же ключи подписывают доставки вебхуков и квитанции об установке.
Метаданные Discovery содержат issuer и jwks_uri:
curl https://api.cursor.com/v1/origin/.well-known/openid-configuration{ "issuer": "https://api.cursor.com/v1/origin", "jwks_uri": "https://api.cursor.com/v1/origin/keys", "response_types_supported": ["id_token"], "subject_types_supported": ["public"], "id_token_signing_alg_values_supported": ["EdDSA"]}/keys возвращает активные JWK Ed25519:
curl https://api.cursor.com/v1/origin/keys{ "keys": [ { "kty": "OKP", "crv": "Ed25519", "use": "sig", "alg": "EdDSA", "kid": "origin-key-id", "x": "PUBLIC_KEY_MATERIAL" } ]}Кэшируйте JWKS. /keys отправляет Cache-Control: public, max-age=600, stale-if-error=600, поэтому используйте кэшированный ответ в течение 10 минут, затем обновляйте его; если обновление не удалось, используйте последние корректные ключи не более ещё 10 минут, прежде чем проверка завершится ошибкой. Также обновляйте при подписи, которую не удаётся проверить ни одним ключом, — это исключит идентификатор выведенного из обращения ключа. Ключи меняются еженедельно.
Подписи вебхуков не содержат идентификатор ключа, поэтому при проверке следует попробовать все активные ключи Ed25519. Квитанции об установке содержат kid ключа подписи в заголовке JOSE, поэтому ключ для проверки квитанции можно определить напрямую.
Области доступа
Запрашивайте только те области доступа, которые действительно нужны вашему приложению. repository:metadata:read, а также доступ к метаданным приложения или установки предоставляются автоматически и не должны отдельно добавляться в URL установки.
| Область доступа | Разрешает |
|---|---|
repository:metadata:read | Читать метаданные репозитория. Добавляется автоматически. |
repository:contents:read | Читать коммиты, ветки, содержимое, файлы сравнения и низкоуровневые объекты Git. Искать текст в файлах. Скачать архив репозитория. Клонировать, выполнять fetch и выполнять pull через Git по HTTPS. Синхронизировать зеркальный репозиторий с исходным репозиторием. |
repository:contents:write | Выполнять push через Git по HTTPS. Объединять pull request. Создавать ветки и коммитить изменения файлов через конечные точки git data. Повторно запрашивать запуск проверки. |
repository:pull_requests:read | Читать pull request, изменённые файлы, коммиты pull request, назначенные метки и возможность объединения. |
repository:pull_requests:write | Создавать и обновлять pull request. Назначать и удалять метки pull request. |
repository:pull_requests:reviews:read | Читать комментарии к pull request, треды комментариев, отправленные ревью и запрошенных ревьюеров. |
repository:pull_requests:reviews:write | Создавать и обновлять комментарии; разрешать и повторно открывать треды комментариев; создавать, обновлять и отклонять ревью; запрашивать и удалять ревьюеров. |
repository:checks:read | Читать наборы, запуски проверок и аннотации запусков проверок. |
repository:checks:write | Создавать и обновлять наборы и запуски проверок. Добавлять аннотации запусков проверок. |
repository:labels:read | Читать определения меток, принадлежащие репозиторию. |
repository:labels:write | Создавать, обновлять и удалять определения меток репозитория. |
repository:rulesets:read | Читать наборы правил репозитория. |
repository:rulesets:write | Создавать, обновлять и удалять наборы правил репозитория. |
repository:settings:read | Читать разрешения, выданные непосредственно на репозиторий. |
repository:settings:write | Обновлять настройки репозитория: ветку по умолчанию, видимость, методы объединения и автоматическое удаление head-ветки. Выполнять upsert и удаление разрешений на репозиторий. |
namespace:settings:read | Читать разрешения, выданные непосредственно на владельца. |
namespace:settings:write | Выполнять upsert и удаление разрешений на владельца. |
Запрос области доступа :write также предоставляет соответствующую область доступа :read, поэтому repository:labels:write включает repository:labels:read, и вам не нужно указывать обе. Обратное неверно: область доступа для чтения никогда не предоставляет права на запись.
Токен установки может только сужать эти разрешения. Он не может добавить область доступа или репозиторий, не одобренные администратором рабочей области.
Изменения состояния зеркала не входят в эту таблицу. Transition Repo Mirror, Force Repo Mirror Cutover и Detach Repo Mirror используют repository:mirror:write или repository:mirror:delete, которые приложение не может запросить при установке: они входят в учётные данные пользователя Cursor, а вызывающая сторона также должна администрировать репозиторий в вышестоящем источнике зеркала.
Управление приложениями не входит в неё по той же причине. создать приложение использует namespace:apps:create, List Namespace Apps — namespace:apps:read, Get App — app:settings:read, а Update App, Add ключ подписи приложения и Revoke ключ подписи приложения — app:settings:write. Издатель имеет их в учётных данных пользователя Cursor; приложение не может запросить их для себя.
В таблице перечислены области доступа, которые приложение запрашивает при установке. Чтобы узнать, какая область доступа требуется для отдельной операции, прочитайте её расширение x-origin-scopes в спецификации OpenAPI. Это расширение охватывает все операции, включая области доступа app, installation и namespace, которые входят в состав самих учётных данных, а не предоставляются разрешением при установке. Операция, все области доступа которой входят в состав учётных данных, помечается в расширении как ambient: true: запрашивать для неё ничего не нужно — достаточно предъявить нужные учётные данные.
Зеркалированные репозитории
Установка использует все доступные ей области доступа для нативного репозитория Origin и стабильного исходящего зеркала. Для репозитория в любом другом состоянии зеркала доступны только две области доступа:
repository:metadata:readrepository:contents:read
Все остальные области доступа возвращают 403 для этого репозитория независимо от того, что одобрил администратор рабочей области. Через REST API по-прежнему доступны чтение репозитория и содержимого, сравнение коммитов и синхронизация зеркала, а Origin отклоняет pull requests, ревью, комментарии, проверки, наборы правил и любые операции записи. Через Git по HTTPS по-прежнему работают clone, fetch, pull и скачивание LFS, а Origin отклоняет push и загрузку LFS.
Вывести репозиторий из этого состояния может только операция с учётными данными пользователя — установке это не под силу: Transition Repo Mirror меняет направление зеркалирования, Force Repo Mirror Cutover выполняет переключение на вышестоящий источник без отправки расходящихся refs обратно, а Detach Repo Mirror окончательно отключает зеркало.
Объект mirror репозитория не показывает, разрешена ли запись. Зеркало в процессе перехода может сообщать mirror.status как outbound и при этом оставаться доступным только для чтения, поэтому считайте 403 источником истины, а не ориентируйтесь на mirror.status.
Ограничение частоты запросов
В Origin API для каждого принципала действует общий балльный лимит, обновляемый в скользящем одноминутном окне. Для каждого типа аутентифицированного принципала установлен свой лимит:
| Принципал | Лимит по умолчанию |
|---|---|
| Токен доступа установки | 3 000 баллов в минуту |
| App JWT | 6 000 баллов в минуту |
| Пользователь Cursor или сервисный аккаунт | 600 баллов в минуту |
Перед запуском обработчика каждая конечная точка списывает из этого лимита фиксированное количество баллов. Ошибки аутентификации и авторизации не расходуют баллы.
| Стоимость | Операции |
|---|---|
| 0 | Получить сведения об ограничении частоты запросов. Только статус; баллы не расходуются. |
| 1 | Большинство конечных точек чтения, а также Создать токен доступа установки |
| 5 | Обычные операции записи, а также следующие более ресурсоёмкие операции чтения: Получить коммит, Получить список файлов коммита, Получить список файлов сравнения, Получить список файлов pull request, Получить tarball репозитория и Поиск по содержимому |
| 10 | Создать приложение, Create Repo, Создать коммит из файлов, Объединить pull request, Проверить возможность объединения pull request, Transition Repo Mirror и Force Repo Mirror Cutover |
Cursor может увеличить поминутный лимит для отдельных приложений партнёров по дизайну. Свяжитесь с Cursor, если вашей интеграции требуется более высокий лимит.
Заголовки ответа
Тарифицируемые ответы и Получить сведения об ограничении частоты запросов включают:
| Заголовок | Описание |
|---|---|
X-RateLimit-Limit | Количество баллов, доступных в текущем окне для данного принципала |
X-RateLimit-Remaining | Количество баллов, оставшихся в текущем окне |
X-RateLimit-Used | Количество баллов, израсходованных в текущем окне |
X-RateLimit-Reset | Метка времени Unix (в секундах UTC), когда окно сбрасывается |
X-RateLimit-Resource | Всегда core для общего бюджета публичного API |
X-RateLimit-Reset указывает на полное 60-секундное окно, отсчитываемое с момента ответа. Окно счётчика начинается с первого тарифицируемого запроса в серии, а не на границе календарной минуты.
Превышение лимита
Если запрос превышает лимит, API возвращает ответ HTTP 429 со следующими данными:
Retry-After: количество секунд ожидания перед повторной попыткой (60)- Те же заголовки
X-RateLimit-*, при этом значениеX-RateLimit-Remainingравно0
{ "code": 8, "message": "Rate limit exceeded: 3000 points per minute for this installation. Retry after 60s.", "details": []}Перед повторной попыткой дождитесь времени, указанного в Retry-After, или наступления X-RateLimit-Reset. Если несколько вызывающих сторон используют один токен установки, применяйте экспоненциальную задержку с джиттером.
Проверка оставшейся квоты
Вызовите Получить сведения об ограничении частоты запросов, чтобы узнать текущий лимит, не расходуя баллы. Тело ответа соответствует заголовкам X-RateLimit-* для общего ресурса core.
Общие соглашения
Пагинация
Конечные точки с поддержкой пагинации принимают:
pageSize: по умолчанию — 30, максимум — 100.pageToken: непрозрачный токен, возвращённый предыдущей страницей. Не анализируйте и не формируйте его самостоятельно.
В ответах используются поле коллекции для конкретного ресурса и nextPageToken. Оно пусто, если следующей страницы нет. В ответах на публичные запросы списков общее количество не указывается. Токены страниц привязаны к исходному ресурсу и фильтрам. При изменении фильтров начните пагинацию заново. Недопустимые, несовпадающие или непустые токены, не соответствующие запросу, возвращают 400.
Ошибки
Для ошибок используется тело в стиле Google RPC:
{ "code": 5, "message": "resource not found", "details": []}Распространённые коды состояния HTTP: 400, 401, 403, 404, 429, 500 и 503. Некоторые операции с базой данных Git также возвращают 409 при конфликтах состояния репозитория. См. Ограничения частоты запросов для заголовков 429 и поведения при повторных попытках.
Используйте код состояния HTTP и code для обработки ошибок. message предназначено для разработчиков.
404 не позволяет отличить несуществующий ресурс от ресурса, к которому ваше приложение не может получить доступ. Интерпретируйте его как "недоступен для этой установки", а не как доказательство отсутствия ресурса.
details содержит типизированные записи: сведения о нарушениях полей google.rpc.BadRequest при недопустимом аргументе и запись google.rpc.RequestInfo при каждой ошибке. Origin может в любой момент добавлять типы сведений, поэтому игнорируйте записи, которые ваша интеграция не распознаёт.
Каждый ответ с ошибкой содержит идентификатор запроса дважды: в заголовке ответа X-Request-ID и в записи google.rpc.RequestInfo в details. Origin возвращает отправленный вами x-request-id или генерирует его, если вы его не отправили. Запись RequestInfo присутствует даже если message содержит непрозрачную внутреннюю ошибку, поэтому при обращении в Cursor по поводу неудачного вызова укажите идентификатор запроса.
Несопоставленные пути в /v1/origin и запросы, использующие неверный метод для известного пути, возвращают это же тело вместо общей ошибки маршрутизатора. Сообщение указывает метод и путь и никогда не возвращает строку запроса.
Пути репозитория
В путях, ограниченных репозиторием, слаг владельца и имя репозитория указываются в формате {ownerSlug}/{repoName}. Оба сегмента обрабатываются без учёта регистра, поэтому к репозиторию можно обратиться при любом регистре. В ответах возвращаются сохранённые имя и слаг, а не указанный вами регистр; URL Git по HTTPS обрабатываются так же. Сравнивайте имена репозиториев без учёта регистра, а канонический вариант написания берите из Получить репозиторий.
Каждый путь, ограниченный репозиторием, также принимает стабильный идентификатор репозитория вместо этой пары: укажите _ в качестве слага владельца и идентификатор в качестве имени репозитория, например GET /v1/origin/repos/_/REPO_ID. Идентификатор берите из поля id в Получить репозиторий. Зарезервированный символ _ нельзя использовать в качестве слага владельца, поэтому эти две формы никогда не пересекаются. В запросе Connect или JSON задайте для ownerSlug значение _, а для name — идентификатор.
Форма с идентификатором сохраняется после переименования, поэтому это стабильный способ обратиться к репозиторию. Сам по себе идентификатор не предоставляет никаких прав: после того как Origin сопоставит идентификатор с репозиторием, вашему приложению всё равно нужна та же область действия для этого репозитория. Идентификатор, к которому ваше приложение не имеет доступа, возвращает то же тело 404, что и несуществующий идентификатор, поэтому ответ никогда не подтверждает существование репозитория. Некорректный идентификатор возвращает 400. Create Repo принимает только слаг владельца и отклоняет _.
Ссылки на ресурсы
Снимки ресурсов содержат актуальные значения полей ресурса. В контексте контейнера используются компактные ссылки вместо дублирования полных ресурсов:
RepositoryReferenceуказывает на репозиторий.PullRequestReferenceуказывает на pull request и содержит ссылку на его репозиторий.ThreadReferenceуказывает на тред, содержащий комментарий к pull request.OriginActorуказывает на публичного инициатора как на один из вариантов:user,appилиserviceAccount. Присутствует ровно один вариант; считывайте identity из этого варианта.
Текущие ограничения
- Получение списка репозиториев в пространстве имён и создание репозиториев не поддерживаются Partner API. Репозитории можно находить через установку.
- Сравнение коммитов возвращает сводные данные, а не встроенный список коммитов. У изменённых файлов есть собственная конечная точка с пагинацией: Список файлов сравнения.
- К тредам можно обращаться только для их разрешения. Конечная точка для прямого получения списка тредов отсутствует; читайте их из содержащихся в них комментариев.
- Вебхуки push не содержат полного списка коммитов.
- Слияние pull request поддерживается для нативных репозиториев Origin. Зеркальные репозитории отклоняются.
- Зеркальный репозиторий доступен только для чтения для установки, пока не станет стабильным исходящим зеркалом. См. Зеркальные репозитории.
Контрольный список реализации
- Храните приватный ключ Ed25519 в менеджере секретов и выполняйте ротацию ключей осознанно. См. Создание ключа подписи приложения.
- Проверяйте подтверждение установки в колбэках установки и считывайте идентификатор установки и
stateиз его утверждений. - Используйте краткоживущие JWT приложения и выпускайте токены установки непосредственно перед использованием.
- Для API с областью действия в пределах репозитория, записи check-run и Git HTTPS используйте токены установки, а не JWT приложения.
- Запрашивайте минимально необходимые области доступа и доступ к репозиторию.
- Считайте токены страниц непрозрачными и перезапускайте пагинацию при изменении фильтров.
- Поддерживайте значения
keyпроверок стабильными и понятными. Для каждой повторной попытки используйте новый неизменяемыйexternalId, а для обновлений — возрастающие значенияexternalUpdatedAt. - Проверяйте подписи вебхука по сырому телу запроса до его разбора.
- Дедуплицируйте доставки по
webhook-idи обрабатывайте их асинхронно после возврата2xx. - Игнорируйте неизвестные поля JSON для прямой совместимости.
- Учитывайте заголовки
Retry-AfterиX-RateLimit-*. Используйте Получить ограничение частоты запросов, чтобы отслеживать оставшиеся баллы, не расходуя их.
Справочник конечных точек
Полные схемы компонентов доступны в спецификации OpenAPI. В документе в качестве сервера указан https://api.cursor.com, определена схема безопасности HTTP Bearer bearerAuth, а для каждой операции перечислены коды ответов, которые она может вернуть, а также пример запроса и ответа. Кроме того, каждая операция содержит расширение x-origin-scopes: в scopes указан scope, необходимый для операции, а в tokenTypes — типы credential, которые она принимает. Параметры пути имеют те же имена, что используются в URL: ownerSlug и repoName. У каждой операции есть уникальный operationId; если одна операция обслуживает две формы URL, идентификатор второй формы получает суффикс _2, например OriginService_GetRepoTarball_2.
Во фрагментах JSON показаны значения-заполнители, соответствующие схемам. Описания полей ответа отражают схему OpenAPI и текущий контракт платформы.
Приложения и установки
Получить лимит запросов
/v1/origin/rate_limitВозвращает текущую информацию о лимите запросов к публичному API для аутентифицированного принципала.
Запрос к этой конечной точке не расходует баллы лимита запросов. Ответ содержит общий поминутный лимит баллов, используемый другими конечными точками публичного API для этого принципала. См. ограничение частоты запросов.
Поля ответа
resources object
resources.core object
resources.core.limit integer
resources.core.remaining integer
resources.core.reset integer
resources.core.used integer
rate object
resources.core. В новых клиентах используйте resources.core.curl --request GET \ --url 'https://api.cursor.com/v1/origin/rate_limit' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "resources": { "core": { "limit": 6000, "remaining": 5994, "reset": 1785682800, "used": 6 } }, "rate": { "limit": 6000, "remaining": 5994, "reset": 1785682800, "used": 6 }}Получить данные аутентифицированного приложения
/v1/origin/appВозвращает метаданные аутентифицированного приложения.
Поля ответа
id строка
displayName строка
webhookUrl строка
events массив
createdAt строка
updatedAt строка
installationRedirectUris массив
namespaceSlug строка
description строка
websiteUrl строка
defaultScopes массив
curl --request GET \ --url 'https://api.cursor.com/v1/origin/app' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "id": "app_01k2ja2000e0080000000000a1", "displayName": "CI Status Bot", "webhookUrl": "https://ci.acme.dev/webhooks/origin", "events": [ "pull_request.created", "pull_request.merged" ], "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "installationRedirectUris": [ "https://ci.acme.dev/origin/setup" ], "namespaceSlug": "acme", "description": "Posts CI status on pull requests.", "websiteUrl": "https://ci.acme.dev", "defaultScopes": [ "repository:contents:read", "repository:pull_requests:read" ]}Список установок приложения
/v1/origin/app/installationsВозвращает список установок аутентифицированного приложения.
Параметры запроса
pageSize целое число
pageToken строка
next_page_token предыдущего ответа. Пуст для первой страницы.Поля ответа
installations массив
installations[].id строка
installations[].appId строка
installations[].target object
installations[].target.slug строка
installations[].target.id строка
installations[].target.type строка
team, user. Пропускается, если неизвестно.installations[].createdAt строка
installations[].updatedAt строка
installations[].repoSelectionMode строка
installations[].scopes массив
installations[].installedBy object
installations[].installedBy.id строка
user_.installations[].installedBy.email строка
installations[].installedBy.displayName строка
installations[].installedBy.handle строка
@. Присутствует только пока этот профиль общедоступен; в противном случае отсутствует.installations[].suspendedAt строка
installations[].deletedAt строка
installation.deleted; удалённая установка больше не разрешается через API, поэтому эта конечная точка её никогда не возвращает.nextPageToken строка
curl --request GET \ --url 'https://api.cursor.com/v1/origin/app/installations' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "installations": [ { "id": "inst_01k2ja2000e0080000000000b2", "appId": "app_01k2ja2000e0080000000000a1", "target": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" }, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "repoSelectionMode": "selected", "scopes": [ "repository:contents:read", "repository:pull_requests:read" ] } ]}Получить установку приложения
/v1/origin/app/installations/{installationId}Возвращает сведения об одной установке для аутентифицированного приложения.
repoSelectionMode имеет значение all или selected.
Параметры пути
installationId строка Обязательно
Поля ответа
id строка
appId строка
target object
target.slug строка
target.id строка
target.type строка
team, user. Пропускается, если неизвестно.createdAt строка
updatedAt строка
repoSelectionMode строка
scopes массив
installedBy object
installedBy.id строка
user_.installedBy.email строка
installedBy.displayName строка
installedBy.handle строка
@. Указан только пока этот профиль общедоступен; в противном случае отсутствует.suspendedAt строка
deletedAt строка
installation.deleted; удалённая установка больше не разрешается через API, поэтому эта конечная точка никогда её не возвращает.curl --request GET \ --url 'https://api.cursor.com/v1/origin/app/installations/INSTALLATION_ID' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "id": "inst_01k2ja2000e0080000000000b2", "appId": "app_01k2ja2000e0080000000000a1", "target": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" }, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "repoSelectionMode": "selected", "scopes": [ "repository:contents:read", "repository:pull_requests:read" ]}Удалить установку приложения
/v1/origin/app/installations/{installationId}Удаляет установку, принадлежащую аутентифицированному приложению, и предотвращает выпуск новых токенов установки. Уже выпущенные краткоживущие токены могут оставаться действительными до истечения срока действия (не более 15 минут). Тело ответа пустое.
Параметры пути
installationId строка Обязательно
Поля ответа
Успешные запросы не возвращают тело ответа.
curl --request DELETE \ --url 'https://api.cursor.com/v1/origin/app/installations/INSTALLATION_ID' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Ответ:
204 No ContentСоздать токен доступа установки
/v1/origin/app/installations/{installationId}/access_tokensСоздаёт токен доступа установки для аутентифицированного приложения.
Требуется аутентификация с помощью JWT, подписанного приложением, как в GetAuthenticatedApp. Токен ограничен указанной установкой, которая должна принадлежать аутентифицированному приложению. Вызывающая сторона может ограничить токен подмножеством разрешённых областей доступа установки и доступных репозиториев.
В repositoryIds можно указать зеркальный репозиторий. Полученный токен содержит области доступа установки, а Origin по-прежнему применяет ограничение зеркала к каждому запросу: см. Зеркальные репозитории.
Параметры пути
installationId строка Обязательно
Тело запроса
scopes массив
repositoryIds массив
Поля ответа
token строка
expiresAt строка
curl --request POST \ --url 'https://api.cursor.com/v1/origin/app/installations/INSTALLATION_ID/access_tokens' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "scopes": [ "repository:contents:read", "repository:pull_requests:read" ], "repositoryIds": [ "repo_01k2ja2000e0080000000000q4" ]}'Структура ответа:
{ "token": "oit_2v8xkq4m1c7p9t3w5y0z6r4b", "expiresAt": "2026-08-01T10:30:00Z"}Список репозиториев установки приложения
/v1/origin/installation/reposВозвращает список репозиториев, доступных аутентифицированной установке приложения.
Требуется токен доступа установки (oit_), выпущенный методом CreateInstallationAccessToken.
Партнёры обнаруживают свои репозитории через эту конечную точку. Элементы списка — это краткие сводки репозиториев; используйте Get Repo для получения полных временных меток. Get Repo включает поле cloneUrl, доступное только для вывода.
Результаты включают зеркалированные репозитории. Зеркало доступно только для чтения, пока не станет стабильным исходящим (outbound) зеркалом: см. Зеркалированные репозитории.
Параметры запроса
pageSize целое число
pageToken строка
next_page_token предыдущего ответа. Пуст для первой страницы.Поля ответа
repositories массив
repositories[].id строка
repositories[].name строка
repositories[].fullName строка
repositories[].owner object
repositories[].owner.slug строка
repositories[].owner.id строка
repositories[].owner.type строка
team, user. Пропускается, если неизвестно.repositories[].defaultBranch строка
repositories[].mirror object
repositories[].mirror.source строка
github.repositories[].mirror.sourceId строка
repositories[].mirror.status строка
inbound, outbound.repositories[].visibility строка
internal, private.repositories[].allowMergeCommit boolean
repositories[].allowSquashMerge boolean
repositories[].deleteBranchOnMerge boolean
nextPageToken строка
repoSelectionMode строка
curl --request GET \ --url 'https://api.cursor.com/v1/origin/installation/repos' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "repositories": [ { "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-02T14:45:00Z", "pushedAt": "2026-08-02T14:45:00Z", "cloneUrl": "https://origin.cursor.com/git/acme/rocket.git" } ], "repoSelectionMode": "selected"}Список доставок вебхуков
/v1/origin/app/webhook/deliveriesПеречисляет доставки вебхуков для аутентифицированного приложения, от новых к старым.
Доставка — это одно событие, предназначенное для одного приложения; её идентификатор — значение заголовка webhook-id, которое видит получатель. delivered=false — предикат восстановления: он выбирает все доставки, которые ни разу не получили ответ 2xx, включая доставки, у которых во время сбоя закончились попытки повторной отправки.
Доставки можно перечислять в течение семи дней после их создания и только пока у вашего приложения есть активная установка в пространстве имён доставки. События жизненного цикла, ориентированные на приложение, такие как installation.deleted, остаются видимыми после удаления установки, которое они описывают.
Параметры запроса
delivered логический
delivered_at. delivered=false — предикат восстановления: он вычисляется на стороне сервера, поэтому не может пропустить доставку, у которой во время сбоя исчерпалась лестница повторных попыток, как это может произойти с заданным вызывающей стороной временным окном.eventType строка
pull_request.created.installationId строка
WebhookDelivery.installation.id).createdAfter строка
createdBefore строка
pageSize целое число
pageToken строка
next_page_token предыдущего ответа. Пуст для первой страницы.Поля ответа
deliveries массив
deliveries[].id строка
webhook-id, которое видит получатель; используйте его как ключ идемпотентности.deliveries[].event object
deliveries[].event.id строка
deliveries[].event.type строка
deliveries[].installation object
id — текущая активная установка для целевого владельца; не задано, если такой нет (возможно только для событий жизненного цикла, ориентированных на приложение, после деинсталляции).deliveries[].installation.id строка
deliveries[].installation.target object
deliveries[].installation.target.slug строка
deliveries[].installation.target.id строка
deliveries[].installation.target.type строка
team, user. Пропускается, если неизвестно.deliveries[].createdAt строка
deliveries[].deliveredAt строка
deliveries[].lastAttempt object
deliveries[].lastAttempt.id строка
deliveries[].lastAttempt.deliveryId строка
deliveries[].lastAttempt.trigger строка
automatic, manual.deliveries[].lastAttempt.responseStatusCode целое число
deliveries[].lastAttempt.latencyMs целое число
deliveries[].lastAttempt.errorMessage строка
deliveries[].lastAttempt.attemptedAt строка
nextPageToken строка
curl --request GET \ --url 'https://api.cursor.com/v1/origin/app/webhook/deliveries' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "deliveries": [ { "id": "whd_01k2ja2000e0080000000000j9", "event": { "id": "evt_01k2ja2000e0080000000000r5", "type": "pull_request.created" }, "installation": { "id": "inst_01k2ja2000e0080000000000b2", "target": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "createdAt": "2026-08-01T09:30:00Z", "deliveredAt": "2026-08-02T14:45:05Z", "lastAttempt": { "id": "wha_01k2ja2000e0080000000000k0", "deliveryId": "whd_01k2ja2000e0080000000000j9", "trigger": "automatic", "responseStatusCode": 200, "latencyMs": 182, "attemptedAt": "2026-08-02T14:45:05Z" } } ]}Пакетная повторная доставка вебхука
/v1/origin/app/webhook/deliveries:batchRedeliverЗапрашивает у Origin повторную отправку доставок.
Запрос означает «обеспечить отправку каждой из них», а не «добавить ещё одну отправку». Он возвращает по одному результату для каждого уникального входного значения, а не завершает весь пакет ошибкой из-за некорректной записи, поэтому один просроченный ID не может заблокировать остальную страницу восстановления. 202 означает, что отправки поставлены в очередь; сама доставка выполняется асинхронно, поэтому отслеживайте результаты через Список доставок вебхука.
Тело запроса
deliveryIds массив Обязательно
pageSize в Список доставок вебхука. Дубликаты удаляются с сохранением порядка первого появления. Пустой список или более 100 уникальных записей возвращает InvalidArgument (HTTP 400).Поля ответа
results массив
results[].deliveryId строка
results[].outcome строка
queued, когда создана отправка; already_in_flight, когда отправка уже выполняется; и not_found в остальных случаях. already_in_flight означает успех, а не ошибку. not_found охватывает неизвестные ID, ID старше семидневного срока хранения и пространства имён, в которых ваше приложение больше не установлено.curl --request POST \ --url 'https://api.cursor.com/v1/origin/app/webhook/deliveries:batchRedeliver' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "deliveryIds": [ "whd_01k2ja2000e0080000000000j9" ]}'Структура ответа:
{ "results": [ { "deliveryId": "whd_01k2ja2000e0080000000000j9", "outcome": "queued" } ]}Ping вебхук
/v1/origin/app/webhook/pingsОтправляет тестовую доставку на URL вебхука аутентифицированного приложения и сообщает, какой ответ вернул получатель.
Используйте для проверки получателя при настройке приложения, не дожидаясь реального события. Требуется аутентификация с помощью JWT, подписанного приложением, как для Получить данные аутентифицированного приложения.
Получатель видит формат продакшена: те же заголовки и подпись v1ed, которую можно проверить с помощью ключей подписи, значение webhook-event-type — ping, а полезная нагрузка содержит имя приложения. Ping не относится ни к одной установке, поэтому заголовок webhook-installation-id и поле installationId в обёртке отсутствуют.
Origin отправляет ping один раз синхронно и сообщает результат в ответе. Повторных попыток нет, и ping не является доменным событием: он никогда не появляется в Списке доставок вебхука и не может быть отправлен повторно. Сбой на стороне получателя указывается в ответе, а не возвращается как ошибка. Для приложения без настроенного URL вебхука возвращается FailedPrecondition (HTTP 400).
Тело запроса
Запрос не принимает полей. Отправьте пустой JSON-объект.
Поля ответа
deliveryId строка
webhook-id тестовой доставки, совпадающий с заголовком, который получил получатель.eventId строка
event.id.delivered boolean
true, если получатель ответил со статусом 2xx до истечения тайм-аута доставки. Поле присутствует всегда.responseStatusCode integer
0, если ответ не пришёл из-за сбоя подключения или истечения тайм-аута. Поле присутствует всегда.curl --request POST \ --url 'https://api.cursor.com/v1/origin/app/webhook/pings' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{}'Структура ответа:
{ "deliveryId": "whd_01k2ja2000e0080000000000j9", "eventId": "evt_01k2ja2000e0080000000000r5", "delivered": true, "responseStatusCode": 200}Получить приложение
/v1/origin/apps/{appId}Возвращает одно приложение по его идентификатору. Это операция чтения для управления, предназначенная для издателей приложения; Получить данные аутентифицированного приложения — аналогичная операция чтения собственных данных по JWT-credential самого приложения.
Path Parameters
appId string обязательный
app_.Response Fields
id string
app_.displayName string
webhookUrl string
events array
createdAt string
updatedAt string
installationRedirectUris array
namespaceSlug string
description string
websiteUrl string
defaultScopes array
curl --request GET \ --url 'https://api.cursor.com/v1/origin/apps/{appId}' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "id": "app_01k2ja2000e0080000000000a1", "displayName": "CI Status Bot", "webhookUrl": "https://ci.acme.dev/webhooks/origin", "events": [ "pull_request.created", "pull_request.merged" ], "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "installationRedirectUris": [ "https://ci.acme.dev/origin/setup" ], "namespaceSlug": "acme", "description": "Posts CI status on pull requests.", "websiteUrl": "https://ci.acme.dev", "defaultScopes": [ "repository:contents:read", "repository:pull_requests:read" ]}Обновление приложения
/v1/origin/apps/{appId}Обновляет настройки приложения. Пропущенные поля остаются без изменений; необходимо передать хотя бы одно изменяемое поле. Сброс webhookUrl с помощью пустой строки отключает исходящую доставку webhook и отменяет ожидающие доставки приложения; если задать URL снова, отменённые доставки не возобновятся.
Параметры пути
appId строка Обязательный
app_.Тело запроса
displayName строка
webhookUrl строка
events object
events.events array
description строка
websiteUrl строка
installationRedirectUris object
installationRedirectUris.installationRedirectUris массив
defaultScopes object
defaultScopes.scopes массив
Поля ответа
id строка
app_.displayName строка
webhookUrl строка
events array
createdAt строка
updatedAt строка
installationRedirectUris массив
namespaceSlug строка
description строка
websiteUrl строка
defaultScopes массив
curl --request PATCH \ --url 'https://api.cursor.com/v1/origin/apps/APP_ID' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "webhookUrl": "https://ci.acme.dev/webhooks/origin-v2", "events": { "events": [ "pull_request.created", "pull_request.merged", "repository.pushed" ] }}'Структура ответа:
{ "id": "app_01k2ja2000e0080000000000a1", "displayName": "CI Status Bot", "webhookUrl": "https://ci.acme.dev/webhooks/origin-v2", "events": [ "pull_request.created", "pull_request.merged", "repository.pushed" ], "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "installationRedirectUris": [ "https://ci.acme.dev/origin/setup" ], "namespaceSlug": "acme", "description": "Posts CI status on pull requests.", "websiteUrl": "https://ci.acme.dev", "defaultScopes": [ "repository:contents:read", "repository:pull_requests:read" ]}Добавление ключа подписи приложения
/v1/origin/apps/{appId}/signing_keysДобавляет ключ подписи в приложение. У приложения может быть лишь ограниченное количество активных ключей подписи; при попытке добавить ключ сверх лимита возвращается FailedPrecondition (HTTP 400) — до тех пор, пока не будет отозван другой ключ. Для уже зарегистрированного ключа возвращается AlreadyExists (HTTP 409 Conflict).
параметры пути
appId строка обязательный
app_.тело запроса
publicKey строка обязательный
поля ответа
kid строка
kid и для отзыва ключа.createdAt строка
curl --request POST \ --url 'https://api.cursor.com/v1/origin/apps/APP_ID/signing_keys' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "publicKey": "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAq9zTf3hL6wXe1cVj0bYs5mKR8uDnG2oAaPp4NiEkKlM=\n-----END PUBLIC KEY-----"}'Структура ответа:
{ "kid": "3q2xW9dK5fJm8vB1nY6cT0aZrQpLh4eGkVsN7uMxOdI", "createdAt": "2026-08-02T14:45:00Z"}Отзыв ключа подписи приложения
/v1/origin/apps/{appId}/signing_keys/{kid}Отзывает ключ подписи приложения по его key ID. App JWT, подписанные отозванным ключом, перестают проходить аутентификацию. Последний активный ключ подписи отозвать нельзя — такой запрос возвращает FailedPrecondition (HTTP 400). Тело ответа пустое.
параметры пути
appId строка обязательный
app_.kid строка обязательный
поля ответа
При успешном запросе тело ответа отсутствует.
curl --request DELETE \ --url 'https://api.cursor.com/v1/origin/apps/{appId}/signing_keys/{kid}' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Response:
204 No ContentСписок приложений пространства имён
/v1/origin/namespaces/{namespaceSlug}/appsВозвращает список приложений, принадлежащих пространству имён, начиная с самых новых. В ответах передаются только метаданные для отображения; чтобы получить конфигурацию вебхука конкретного приложения, используйте Get App.
параметры пути
namespaceSlug строка обязательный
Query Parameters
pageSize integer
pageToken строка
next_page_token предыдущего ответа. Для первой страницы — пустая строка.поля ответа
apps массив
apps[].id строка
app_.apps[].displayName строка
apps[].description строка
nextPageToken строка
curl --request GET \ --url 'https://api.cursor.com/v1/origin/namespaces/{namespaceSlug}/apps' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "apps": [ { "id": "app_01k2ja2000e0080000000000a1", "displayName": "CI Status Bot", "description": "Posts CI status on pull requests." }, { "id": "app_01k2ja2000e0080000000000a2", "displayName": "Deploy Bot", "description": "" } ], "nextPageToken": ""}Создать приложение
/v1/origin/namespaces/{namespaceSlug}/appsСоздаёт приложение, принадлежащее пространству имён. Приложения создаются приватными. Сгенерируйте пару ключей Ed25519 локально и отправьте только открытый ключ; Origin сохраняет его для проверки JWT приложения. Некорректные URL вебхуков, типы событий, URI перенаправления или области действия приводят к возврату InvalidArgument (HTTP 400).
Параметры пути
namespaceSlug строка Обязательный
Тело запроса
displayName строка Обязательный
publicKey строка Обязательный
webhookUrl строка
events array
description строка
websiteUrl строка
installationRedirectUris массив
defaultScopes массив
repository:contents:read. При установке области доступа по-прежнему можно указать явно.Поля ответа
id строка
app_.displayName строка
webhookUrl строка
events array
createdAt строка
updatedAt строка
installationRedirectUris массив
namespaceSlug строка
description строка
websiteUrl строка
defaultScopes массив
curl --request POST \ --url 'https://api.cursor.com/v1/origin/namespaces/NAMESPACE_SLUG/apps' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "displayName": "CI Status Bot", "publicKey": "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEAv7wFoV1bC9yKq3nZ8dQmXh5uJb2tR4sEwG6aP0iN8kY=\n-----END PUBLIC KEY-----", "webhookUrl": "https://ci.acme.dev/webhooks/origin", "events": [ "pull_request.created", "pull_request.merged" ], "description": "Posts CI status on pull requests.", "websiteUrl": "https://ci.acme.dev", "installationRedirectUris": [ "https://ci.acme.dev/origin/setup" ], "defaultScopes": [ "repository:contents:read", "repository:pull_requests:read" ]}'Структура ответа:
{ "id": "app_01k2ja2000e0080000000000a1", "displayName": "CI Status Bot", "webhookUrl": "https://ci.acme.dev/webhooks/origin", "events": [ "pull_request.created", "pull_request.merged" ], "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-01T09:30:00Z", "installationRedirectUris": [ "https://ci.acme.dev/origin/setup" ], "namespaceSlug": "acme", "description": "Posts CI status on pull requests.", "websiteUrl": "https://ci.acme.dev", "defaultScopes": [ "repository:contents:read", "repository:pull_requests:read" ]}Репозитории
cloneUrl — URL для клонирования по HTTPS, доступный только для вывода. Получить репозиторий включает cloneUrl.
Партнёры находят свои репозитории через Список репозиториев установки приложения. Получение списка репозиториев в пространстве имён и их создание не входят в Partner API.
Список репозиториев
/v1/origin/repos/{ownerSlug}Возвращает список репозиториев, принадлежащих сущности-владельцу.
Параметры пути
ownerSlug строка Обязательно
Параметры запроса
pageSize целое число
pageToken строка
next_page_token предыдущего ответа. Пуст для первой страницы.filter строка
Поля ответа
repositories массив
repositories[].id строка
repositories[].name строка
repositories[].fullName строка
repositories[].owner object
repositories[].owner.slug строка
repositories[].owner.id строка
repositories[].owner.type строка
team, user. Пропускается, если неизвестно.repositories[].defaultBranch строка
repositories[].createdAt строка
repositories[].updatedAt строка
repositories[].pushedAt строка
repositories[].cloneUrl строка
repositories[].mirror объект
repositories[].mirror.source строка
github.repositories[].mirror.sourceId строка
repositories[].mirror.status строка
inbound, outbound.repositories[].visibility строка
internal, private.repositories[].allowMergeCommit логическое значение
repositories[].allowSquashMerge boolean
repositories[].deleteBranchOnMerge логическое значение
nextPageToken строка
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "repositories": [ { "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-02T14:45:00Z", "pushedAt": "2026-08-02T14:45:00Z", "cloneUrl": "https://origin.cursor.com/git/acme/rocket.git" } ]}Получить репозиторий
/v1/origin/repos/{ownerSlug}/{repoName}Возвращает один репозиторий по его идентификатору (owner_id, name).
cloneUrl — это URL для клонирования по HTTPS, доступный только для вывода. Операция «Получить репозиторий» включает cloneUrl.
Параметры пути
ownerSlug строка Обязательно
repoName строка Обязательно
Поля ответа
id строка
name строка
fullName строка
owner object
owner.slug строка
owner.id строка
owner.type строка
team, user. Пропускается, если неизвестно.defaultBranch строка
createdAt строка
updatedAt строка
pushedAt строка
cloneUrl строка
mirror object
mirror.source строка
github.mirror.sourceId строка
mirror.status строка
inbound, outbound.visibility строка
internal, private.allowMergeCommit boolean
allowSquashMerge boolean
deleteBranchOnMerge логическое значение
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "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-02T14:45:00Z", "pushedAt": "2026-08-02T14:45:00Z", "cloneUrl": "https://origin.cursor.com/git/acme/rocket.git"}Update Repo
/v1/origin/repos/{ownerSlug}/{repoName}Обновляет настройки репозитория. Неуказанные поля остаются без изменений; необходимо указать хотя бы одно поле, доступное для задания.
Настройки применяются независимыми группами в фиксированном порядке: ветка по умолчанию, автоматическое удаление head-ветки, видимость, затем методы слияния. Обновление неатомарно для разных групп. Если группа отклонена, все предшествующие ей группы уже применены и остаются применёнными. Исправьте отклонённую группу и повторите попытку, чтобы получить запрошенное состояние. Ответ содержит репозиторий в состоянии после применения последней группы.
Запрос, в котором не задано ни одного поля, возвращает InvalidArgument (HTTP 400). Параллельное изменение ветки по умолчанию возвращает 409 Conflict.
Параметры пути
ownerSlug string Обязательный
repoName string Обязательный
Тело запроса
defaultBranch string
FailedPrecondition (HTTP 400).allowMergeCommit boolean
allowSquashMerge, при этом хотя бы одно из двух значений должно быть true. Если передать одно без другого, вернётся InvalidArgument (HTTP 400).allowSquashMerge boolean
allowMergeCommit, и по крайней мере один из этих двух должен быть true. Отправка одного без другого возвращает InvalidArgument (HTTP 400).deleteBranchOnMerge boolean
FailedPrecondition (HTTP 400).visibility string
internal, private. Не указывайте его, чтобы оставить видимость без изменений.Поля ответа
id строка
name строка
fullName строка
owner object
owner.slug string
owner.id string
owner.type string
team, user. Опускается, если тип неизвестен.defaultBranch string
createdAt string
updatedAt string
pushedAt string
cloneUrl string
mirror object
mirror.source строка
github.mirror.sourceId string
mirror.status строка
inbound, outbound.visibility string
internal, private.allowMergeCommit boolean
allowSquashMerge boolean
deleteBranchOnMerge boolean
curl --request PATCH \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "defaultBranch": "main", "allowMergeCommit": false, "allowSquashMerge": true, "deleteBranchOnMerge": true, "visibility": "private"}'Структура ответа:
{ "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-02T14:45:00Z", "pushedAt": "2026-08-02T14:45:00Z", "cloneUrl": "https://origin.cursor.com/git/acme/rocket.git", "visibility": "private", "allowMergeCommit": false, "allowSquashMerge": true, "deleteBranchOnMerge": true}Создать репозиторий
/v1/origin/repos/{ownerSlug}Создаёт репозиторий, принадлежащий владельцу.
На момент запроса владелец должен иметь право записывать в Origin. Владелец‑пользователь должен иметь тарифный план Pro, Pro Student, Pro+, Ultra или Start. Владелец‑команда должен иметь активный платный командный тарифный план, не находиться в Privacy Mode (Legacy) и не иметь Origin отключённым администратором команды. Для неподходящего владельца возвращается FailedPrecondition (HTTP 400). Чтение существующих репозиториев это требование не затрагивает.
Имена репозиториев занимаются без учёта регистра. Имя, которое отличается от уже существующего у владельца репозитория только регистром, будет отклонено, поэтому widgets и Widgets не могут существовать в одном пространстве имён. Переданное вами имя хранится в том виде, в котором вы его отправили.
Первый push в новый репозиторий может переназначить его ветку по умолчанию. Если этот push только создаёт ветки и ни одна из них не совпадает с сохранённой веткой по умолчанию репозитория, Origin устанавливает ветку по умолчанию на созданную ветку, либо на main или master, если push создаёт несколько веток и одно из этих имён присутствует среди них. В остальных случаях ветка по умолчанию остаётся без изменений. Текущее значение можно узнать через Получить репозиторий.
Параметры пути
ownerSlug строка Обязательно
Тело запроса
name строка Обязательно
defaultBranch строка
Поля ответа
id строка
name строка
fullName строка
owner object
owner.slug строка
owner.id строка
owner.type строка
team, user. Пропускается, если неизвестно.defaultBranch строка
createdAt строка
updatedAt строка
pushedAt строка
cloneUrl строка
mirror object
mirror.source строка
github.mirror.sourceId строка
mirror.status строка
inbound, outbound.visibility строка
internal, private.allowMergeCommit логическое значение
allowSquashMerge логическое значение
deleteBranchOnMerge логическое
curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "name": "rocket", "defaultBranch": "main"}'Структура ответа:
{ "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-02T14:45:00Z", "pushedAt": "2026-08-02T14:45:00Z", "cloneUrl": "https://origin.cursor.com/git/acme/rocket.git"}Список веток
/v1/origin/repos/{ownerSlug}/{repoName}/branchesВозвращает ветки репозитория и их последние коммиты в порядке возрастания имён с пагинацией по page_size и page_token.
Параметры пути
ownerSlug строка Обязательно
repoName строка Обязательно
Параметры запроса
pageSize целое число
pageToken строка
next_page_token предыдущего ответа. Для первой страницы оставьте пустым. Кодирует смещение страницы, поэтому при передаче токена страницы значение page_size в последующем запросе игнорируется.Поля ответа
branches массив
branches[].name строка
branches[].commit object
branches[].commit.sha строка
nextPageToken строка
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/branches' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "branches": [ { "name": "main", "commit": { "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4" } } ]}Получить tar-архив репозитория
/v1/origin/repos/{ownerSlug}/{repoName}/tarball/{ref}Скачивает сжатый gzip tar-архив дерева репозитория по ссылке ref.
Origin связывает архив с репозиторием и коммитом, в который разрешается ref. Первый запрос для заданного коммита возвращает 200 с Content-Type: application/gzip и передаёт архив потоком в теле ответа. Последующие запросы для того же коммита возвращают 302 с пустым телом и подписанным URL для скачивания в Location, действующим 15 минут; перейдите по перенаправлению, чтобы получить данные. Файлы архива располагаются в корне tar-архива, без дополнительного каталога. Пустой репозиторий возвращает ABORTED (HTTP 409 Conflict), а Git-ссылка, которая не разрешается, — 404.
Передавайте Git-ссылку как параметр запроса вместо сегмента пути, если она содержит "/": GET /v1/origin/repos/{ownerSlug}/{repoName}/tarball?ref=refs/heads/main. Не указывайте её, чтобы архивировать ветку репозитория по умолчанию.
Параметры пути
ownerSlug строка обязательно
repoName строка обязательно
ref строка обязательно
refs/heads/... или refs/tags/... либо символьная ссылка HEAD. Не является glob-шаблоном или revspec, поэтому <rev>~3 отклоняется. Пустое значение использует ветку репозитория по умолчанию.Поля ответа
sha строка
downloadUrl строка
Location ответа 302.curl --request GET --location --output repo.tar.gz \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/tarball/HEAD' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "downloadUrl": "https://artifacts.origin.cursor.com/tarballs/0192f7a4-6c1e-7b3a-9f21-3d54c9a7e6b0/9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4.tar.gz?Expires=1767225600&Signature=EXAMPLE&Key-Pair-Id=KEXAMPLE123", "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4"}Синхронизация зеркала
/v1/origin/repos/{ownerSlug}/{repoName}:syncMirrorСинхронизирует одну Git-ссылку зеркального репозитория с вышестоящим источником. Возвращает HTTP 200, когда цель синхронизации достигнута, или HTTP 202, если синхронизация ещё ожидается. wait=false (по умолчанию) запускает синхронизацию и обычно возвращает 202; 200 возвращается сразу, если sha уже доступен из ref. wait=true блокирует выполнение, пока цель не будет достигнута или не истечёт лимит ожидания (~2 минуты); в этом случае также возвращается 202, а синхронизация продолжается в фоновом режиме. Репозитории, не синхронизируемые с вышестоящим источником, отклоняются.
Параметры пути
ownerSlug строка Обязательный
repoName строка Обязательный
Тело запроса
ref строка Обязательный
refs/ и содержать имя ссылки после этого префикса, например refs/heads/main или refs/tags/v1. Короткие имена, такие как main, отклоняются с INVALID_ARGUMENT.wait boolean
sha строка
ref. Если значение задано и доступно из ref, вызов завершается раньше, не дожидаясь завершения других операций с зеркалом. Другие значения отклоняются с INVALID_ARGUMENT.Поля ответа
synced boolean
200, когда true, и 202, когда false.curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME:syncMirror' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "ref": "refs/heads/main", "wait": true}'Структура ответа:
{ "synced": true}Конечные точки перехода зеркал описаны в Origin Migration API. Синхронизация зеркала остаётся на этой странице.
Отключить зеркало репозитория
См. Отключить зеркало репозитория.
Получение задачи перехода зеркала
См. Получение задачи перехода зеркала.
Получение активной задачи перехода зеркала
См. Получение активной задачи перехода зеркала.
Force Repo Mirror Cutover
См. Force Repo Mirror Cutover.
Transition Repo Mirror
Проверки
- При первом вызове upsert набор создаётся автоматически.
- Обязательные проверки сопоставляются с устанавливающим приложением, а также с
keyнабора и, при необходимости,keyзапуска.nameиспользуется только для отображения и не участвует в сопоставлении. - Сохраняйте значения
keyнеизменными между попытками и понятными пользователям, так как на них основана конфигурация обязательных проверок. - Повторно используйте
externalIdдля обновления попытки — при этом её предыдущий результат удаляется; для повторной попытки используйте новыйexternalId, чтобы предыдущая попытка сохранилась в истории. - Используйте
checkRun.outputдля результатов, понятных человеку:title: краткий заголовок результата, до 255 символов.summary: основная сводка в Markdown, до 65 535 байт UTF-8.text: расширенные сведения в Markdown, до 65 535 байт UTF-8.
- Используйте
detailsUrlдля ссылки на внешнюю страницу результатов провайдера.
Отправка запуска проверки
/v1/origin/repos/{ownerSlug}/{repoName}/check-runsВыполняет вставку или обновление (upsert) набора проверок и запуска проверки с использованием токена доступа установки с правом repository:checks:write. Операция записи приписывается приложению, которому принадлежит аутентифицированная установка. Повторный вызов с теми же (repo, head_sha, suite.key, check.key) обновляет существующий запуск проверки на месте, а не создаёт дубликат.
Этот endpoint атомарно разрешает или создаёт попытку набора (suite attempt) и выполняет upsert одной попытки запуска (run attempt). Поле externalUpdatedAt упорядочивает обновления для одной и той же идентичности запуска; устаревшие повторные попытки (retries) не могут перезаписать более новое состояние.
deadlineAt задаёт необязательный крайний срок для запуска. Origin сохраняет его, возвращает при чтении и очищает, как только запуск достигает состояния completed. Крайний срок более чем на 24 часа в будущем отклоняется с ошибкой InvalidArgument (HTTP 400), а не усекается.
Когда крайний срок проходит для запуска, который всё ещё имеет статус in_progress, Origin самостоятельно завершает запуск с заключением timed_out и отправляет событие repository.check_run.completed. Истечение проверяется периодически, а не с помощью отдельного таймера для каждого запуска, поэтому запуск может ненадолго оставаться после крайнего срока, прежде чем Origin его закроет. Запуск со статусом queued никогда не истекает, как и запуск без поля deadlineAt. Если вы самостоятельно завершите запуск до крайнего срока, это снимет срок. Origin оставляет поле externalUpdatedAt запуска без изменений при тайм-ауте, поэтому более позднее завершение от вашего провайдера всё ещё может перезаписать заключение timed_out.
Параметры пути
ownerSlug string Обязательно
repoName строка Обязательно
Тело запроса
headSha строка Обязательно
checkSuite объект Обязательно
checkSuite.key string Обязательно
checkSuite.name string Обязательно
checkSuite.detailsUrl string
checkSuite.externalId string Обязательно
checkRun object Обязательно
checkRun.key string Обязательно
checkRun.name string Обязательно
checkRun.status string Обязательно
CHECK_RUN_LIFECYCLE_STATUS_UNSPECIFIED, queued, in_progress, completed. В схеме также указано значение rerequested, которое задаёт только Origin при повторном запросе; запрос с этим значением возвращает InvalidArgument (HTTP 400).checkRun.conclusion string
status == completed. Допустимые значения: CHECK_RUN_CONCLUSION_UNSPECIFIED, success, failure, neutral, cancelled, skipped, timed_out, action_required, stale.checkRun.externalUpdatedAt строка Обязательно
checkRun.startedAt string
checkRun.completedAt string
checkRun.detailsUrl строка
checkRun.externalId string Обязательно
checkRun.output object
checkRun.output.title string
checkRun.output.summary string
checkRun.output.text string
checkRun.deadlineAt string
InvalidArgument (HTTP 400), а не корректируются. Не указывайте его при создании, чтобы не устанавливать крайний срок; не указывайте при обновлении, чтобы оставить сохранённый крайний срок без изменений.checkRun.isRerequestable булево значение
true обязывает ваше приложение подписаться на repository.check_run.rerequested и отвечать на каждую доставку, публикуя новый запуск для того же head SHA и key: либо новый запуск с новым externalId, сохраняющий предыдущую попытку в истории, либо обновление повторно запрошенного запуска с тем же externalId, обновляющее его на месте. Пока такая новая публикация не поступит, повторно запрошенный запуск отображается как ожидающий в последнем состоянии проверок коммита, поэтому обязательная проверка блокирует слияние, а pull request показывает, что запуск ожидает повторного выполнения; объявление возможности повторного запроса без ответа оставляет проверку в подвешенном состоянии. Origin не проверяет наличие подписки при вашей публикации. Не указывайте это поле, чтобы сохранить сохранённое значение, которое для нового запуска равно false; отправьте false, чтобы отозвать объявление.Поля ответа
checkSuite object
checkSuite.id string
checkSuite.repository object
checkSuite.repository.id string
checkSuite.repository.name string
checkSuite.repository.owner object
checkSuite.repository.owner.slug строка
checkSuite.repository.owner.id string
checkSuite.repository.owner.type строка
team, user. Пропускается, если неизвестно.checkSuite.sha string
checkSuite.key string
checkSuite.name string
checkSuite.detailsUrl string
checkSuite.createdAt строка
checkSuite.updatedAt строка
checkSuite.externalId string
checkSuite.actor object
checkSuite.actor.user object
checkSuite.actor.user.id string
checkSuite.actor.user.email string
checkSuite.actor.user.displayName строка
checkSuite.actor.user.handle string
@. Присутствует только пока профиль публично видим; в противном случае отсутствует.checkSuite.actor.app object
checkSuite.actor.app.id string
checkSuite.actor.app.displayName строка
checkSuite.actor.serviceAccount object
checkSuite.actor.serviceAccount.id string
checkRun object
checkRun.id string
checkRun.repository object
checkRun.repository.id string
checkRun.repository.name string
checkRun.repository.owner object
checkRun.repository.owner.slug строка
checkRun.repository.owner.id string
checkRun.repository.owner.type строка
team, user. Пропускается, если неизвестно.checkRun.checkSuite object
checkRun.checkSuite.id строка
checkRun.sha string
checkRun.key string
checkRun.name строка
checkRun.status string
checkRun.conclusion string
status равен completed.checkRun.detailsUrl строка
checkRun.externalUpdatedAt string
checkRun.startedAt string
checkRun.completedAt string
checkRun.createdAt string
checkRun.updatedAt string
checkRun.externalId строка
checkRun.actor object
checkRun.actor.user object
checkRun.actor.user.id string
checkRun.actor.user.email string
checkRun.actor.user.displayName string
checkRun.actor.user.handle string
@. Присутствует только пока профиль публично видим; в противном случае отсутствует.checkRun.actor.app object
checkRun.actor.app.id string
checkRun.actor.app.displayName строка
checkRun.actor.serviceAccount object
checkRun.actor.serviceAccount.id string
checkRun.output object
checkRun.output.title string
checkRun.output.summary string
checkRun.output.text string
checkRun.deadlineAt string
checkRun.isRerequestable логическое
checkRun.rerequestedAt string
status имеет значение rerequested, запуск остаётся в последнем состоянии проверок коммита и помечается как ожидающий, а conclusion и отметки времени по-прежнему отражают вытесненный результат, поэтому обязательная проверка блокирует слияние, пока приложение не ответит.checkRun.rerequestedBy object
actor. Присутствует, когда задано rerequestedAt, и сбрасывается вместе с ним.curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/check-runs' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "checkSuite": { "key": "ci-8842", "name": "CI", "detailsUrl": "https://ci.acme.dev/runs/8842", "externalId": "build-8842" }, "checkRun": { "key": "ci-8842-unit-tests", "name": "unit-tests", "status": "completed", "conclusion": "success", "externalUpdatedAt": "2026-08-02T14:44:30Z", "startedAt": "2026-08-02T14:40:00Z", "completedAt": "2026-08-02T14:44:30Z", "detailsUrl": "https://ci.acme.dev/runs/8842", "externalId": "run-8842", "output": { "title": "Unit tests", "summary": "128 tests passed.", "text": "All suites green." } }}'Структура ответа:
{ "checkSuite": { "id": "crg_01k2ja2000e0080000000000h8", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "key": "ci-8842", "name": "CI", "detailsUrl": "https://ci.acme.dev/runs/8842", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "externalId": "build-8842", "actor": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } } }, "checkRun": { "id": "cr_01k2ja2000e0080000000000g7", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "checkSuite": { "id": "crg_01k2ja2000e0080000000000h8" }, "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "key": "ci-8842-unit-tests", "name": "unit-tests", "status": "completed", "conclusion": "success", "detailsUrl": "https://ci.acme.dev/runs/8842", "externalUpdatedAt": "2026-08-02T14:44:30Z", "startedAt": "2026-08-02T14:40:00Z", "completedAt": "2026-08-02T14:44:30Z", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "externalId": "run-8842", "actor": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "output": { "title": "Unit tests", "summary": "128 tests passed.", "text": "All suites green." } }}Пакетное добавление/обновление запусков проверок
/v1/origin/repos/{ownerSlug}/{repoName}/check-runs:batchUpsertАтомарно вставляет или обновляет несколько запусков проверок, принадлежащих одному набору. Запрос принимает не более 10 запусков и отклоняет дублирующиеся идентификаторы (external_id, key). Каждый запуск фиксируется, либо весь запрос откатывается.
Каждый запуск принимает тот же необязательный параметр deadlineAt, что и Post Check Run.
Параметры пути
ownerSlug string Обязательно
repoName string Обязательно
Тело запроса
headSha строка Обязательно
checkSuite object Обязательный
checkSuite.key string Обязательно
checkSuite.name string Обязательно
checkSuite.detailsUrl string
checkSuite.externalId string Обязательно
checkRuns массив Обязательно
(external_id, key).checkRuns[0].key string Обязательно
checkRuns[0].name строка Обязательно
checkRuns[0].status string Обязательно
CHECK_RUN_LIFECYCLE_STATUS_UNSPECIFIED, queued, in_progress, completed. В схеме также указано rerequested, которое задаёт только Origin при повторном запросе; запрос с этим значением возвращает InvalidArgument (HTTP 400).checkRuns[0].conclusion string
status == completed. Допустимые значения: CHECK_RUN_CONCLUSION_UNSPECIFIED, success, failure, neutral, cancelled, skipped, timed_out, action_required, stale.checkRuns[0].externalUpdatedAt string Обязательно
checkRuns[0].startedAt string
checkRuns[0].completedAt строка
checkRuns[0].detailsUrl string
checkRuns[0].externalId string Обязательно
checkRuns[0].output object
checkRuns[0].output.title string
checkRuns[0].output.summary string
checkRuns[0].output.text string
checkRuns[0].deadlineAt string
InvalidArgument (HTTP 400), а не корректируются. Не указывайте его при создании, чтобы не устанавливать крайний срок; не указывайте его при обновлении, чтобы сохранить ранее сохранённый срок без изменений.checkRuns[0].isRerequestable boolean
true обязывает ваше приложение подписаться на repository.check_run.rerequested и в ответ на каждую доставку публиковать новый запуск для того же head SHA и того же key: либо новый запуск с новым externalId, при этом старая попытка сохраняется в истории, либо обновление повторно запрошенного запуска с тем же externalId, что обновляет его на месте. Пока такая новая публикация не поступит, повторно запрошенный запуск отображается как ожидающий в последнем состоянии проверок коммита, поэтому требуемая проверка блокирует слияние, а pull request показывает запуск как ожидающий повторного запуска; объявление возможности повторного запроса без ответа оставляет проверку в подвешенном состоянии. Origin не проверяет наличие подписки при публикации. Пропустите это поле, чтобы сохранить хранимое значение, которое для нового запуска равно false; отправьте false, чтобы отозвать это объявление.Поля ответа
checkSuite object
checkSuite.id string
checkSuite.repository object
checkSuite.repository.id string
checkSuite.repository.name string
checkSuite.repository.owner object
checkSuite.repository.owner.slug строка
checkSuite.repository.owner.id string
checkSuite.repository.owner.type string
team, user. Опускается, если неизвестно.checkSuite.sha строка
checkSuite.key string
checkSuite.name строка
checkSuite.detailsUrl string
checkSuite.createdAt string
checkSuite.updatedAt string
checkSuite.externalId строка
checkSuite.actor object
checkSuite.actor.user object
checkSuite.actor.user.id string
checkSuite.actor.user.email string
checkSuite.actor.user.displayName string
checkSuite.actor.user.handle string
@. Присутствует, только пока этот профиль общедоступен; в остальных случаях опускается.checkSuite.actor.app object
checkSuite.actor.app.id string
checkSuite.actor.app.displayName string
checkSuite.actor.serviceAccount object
checkSuite.actor.serviceAccount.id string
checkRuns массив
checkRuns[].id строка
checkRuns[].repository object
checkRuns[].repository.id string
checkRuns[].repository.name string
checkRuns[].repository.owner object
checkRuns[].repository.owner.slug string
checkRuns[].repository.owner.id string
checkRuns[].repository.owner.type строка
team, user. Опускается, если неизвестно.checkRuns[].checkSuite object
checkRuns[].checkSuite.id строка
checkRuns[].sha строка
checkRuns[].key строка
checkRuns[].name string
checkRuns[].status string
checkRuns[].conclusion string
status равен completed.checkRuns[].detailsUrl string
checkRuns[].externalUpdatedAt string
checkRuns[].startedAt string
checkRuns[].completedAt строка
checkRuns[].createdAt string
checkRuns[].updatedAt string
checkRuns[].externalId string
checkRuns[].actor object
checkRuns[].actor.user object
checkRuns[].actor.user.id строка
checkRuns[].actor.user.email string
checkRuns[].actor.user.displayName строка
checkRuns[].actor.user.handle строка
@. Присутствует, только пока этот профиль общедоступен; в остальных случаях опускается.checkRuns[].actor.app object
checkRuns[].actor.app.id string
checkRuns[].actor.app.displayName string
checkRuns[].actor.serviceAccount object
checkRuns[].actor.serviceAccount.id string
checkRuns[].output object
checkRuns[].output.title string
checkRuns[].output.summary string
checkRuns[].output.text string
checkRuns[].deadlineAt string
checkRuns[].isRerequestable boolean
checkRuns[].rerequestedAt string
status имеет значение rerequested, запуск остаётся в последнем состоянии проверки коммита и отображается как ожидающий, при этом conclusion и временные отметки по-прежнему содержат заменённый результат, поэтому обязательная проверка блокирует слияние, пока приложение не ответит.checkRuns[].rerequestedBy object
actor. Присутствует, когда задано rerequestedAt, и сбрасывается вместе с ним.curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/check-runs:batchUpsert' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "checkSuite": { "key": "ci-8842", "name": "CI", "detailsUrl": "https://ci.acme.dev/runs/8842", "externalId": "build-8842" }, "checkRuns": [ { "key": "ci-8842-unit-tests", "name": "unit-tests", "status": "completed", "conclusion": "success", "externalUpdatedAt": "2026-08-02T14:44:30Z", "startedAt": "2026-08-02T14:40:00Z", "completedAt": "2026-08-02T14:44:30Z", "detailsUrl": "https://ci.acme.dev/runs/8842", "externalId": "run-8842", "output": { "title": "Unit tests", "summary": "128 tests passed.", "text": "All suites green." } } ]}'Структура ответа:
{ "checkSuite": { "id": "crg_01k2ja2000e0080000000000h8", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "key": "ci-8842", "name": "CI", "detailsUrl": "https://ci.acme.dev/runs/8842", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "externalId": "build-8842", "actor": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } } }, "checkRuns": [ { "id": "cr_01k2ja2000e0080000000000g7", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "checkSuite": { "id": "crg_01k2ja2000e0080000000000h8" }, "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "key": "ci-8842-unit-tests", "name": "unit-tests", "status": "completed", "conclusion": "success", "detailsUrl": "https://ci.acme.dev/runs/8842", "externalUpdatedAt": "2026-08-02T14:44:30Z", "startedAt": "2026-08-02T14:40:00Z", "completedAt": "2026-08-02T14:44:30Z", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "externalId": "run-8842", "actor": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "output": { "title": "Unit tests", "summary": "128 tests passed.", "text": "All suites green." } } ]}Получить запуск проверки
/v1/origin/repos/{ownerSlug}/{repoName}/check-runs/{checkRunId}Возвращает один запуск проверки по присвоенному сервером идентификатору (cr_...).
Параметры пути
ownerSlug string Обязательно
repoName строка Обязательно
checkRunId string Обязательное
cr_...).Поля ответа
id строка
repository объект
repository.id строка
repository.name строка
repository.owner object
repository.owner.slug string
repository.owner.id строка
repository.owner.type строка
team, user. Пропускается, если неизвестно.checkSuite object
checkSuite.id string
sha string
key строка
name string
status string
conclusion string
status равен completed.detailsUrl string
externalUpdatedAt string
startedAt строка
completedAt string
createdAt string
updatedAt string
externalId строка
actor object
actor.user object
actor.user.id строка
actor.user.email строка
actor.user.displayName строка
actor.user.handle строка
@. Указывается только пока профиль публично видим; в противном случае отсутствует.actor.app object
actor.app.id строка
actor.app.displayName строка
actor.serviceAccount object
actor.serviceAccount.id строка
output object
output.title string
output.summary string
output.text string
deadlineAt строка
isRerequestable boolean
rerequestedAt строка
status имеет значение rerequested, а запуск остаётся в последнем состоянии проверок коммита и отображается как ожидающий; при этом conclusion и временные метки по-прежнему содержат устаревший результат, поэтому обязательная проверка блокирует слияние, пока приложение не ответит.rerequestedBy object
actor. Присутствует, когда задано rerequestedAt, и сбрасывается вместе с ним.curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/check-runs/CHECK_RUN_ID' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "id": "cr_01k2ja2000e0080000000000g7", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "checkSuite": { "id": "crg_01k2ja2000e0080000000000h8" }, "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "key": "ci-8842-unit-tests", "name": "unit-tests", "status": "completed", "conclusion": "success", "detailsUrl": "https://ci.acme.dev/runs/8842", "externalUpdatedAt": "2026-08-02T14:44:30Z", "startedAt": "2026-08-02T14:40:00Z", "completedAt": "2026-08-02T14:44:30Z", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "externalId": "run-8842", "actor": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "output": { "title": "Unit tests", "summary": "128 tests passed.", "text": "All suites green." }}Список аннотаций запуска проверки
/v1/origin/repos/{ownerSlug}/{repoName}/check-runs/{checkRunId}/annotationsВозвращает список аннотаций check run в порядке возрастания ID.
Идентификаторы аннотаций можно сортировать по времени, поэтому порядок идентификаторов по возрастанию соответствует порядку создания. Токен страницы фиксирует размер страницы и область действия для оставшейся последовательности, поэтому после его отправки параметр pageSize игнорируется.
Параметры пути
ownerSlug string Обязательный
repoName string Обязательное
checkRunId string Обязательно
Параметры запроса
pageSize целое число
pageToken string
nextPageToken предыдущего ответа. Для первой страницы не указывайте.Поля ответа
annotations массив
annotations[].id string
annotations[].checkRunId string
annotations[].annotationLevel string
notice, warning, failure.annotations[].message string
annotations[].title string
annotations[].rawDetails string
annotations[].createdAt string
annotations[].updatedAt string
annotations[].location object
annotations[].location.path string
annotations[].location.startLine целое число
annotations[].location.endLine целое число
annotations[].location.columns object
annotations[].location.columns.startColumn целое число
annotations[].location.columns.endColumn целое число
nextPageToken string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/check-runs/CHECK_RUN_ID/annotations' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "annotations": [ { "id": "cra_01k2ja2000e0080000000000v1", "checkRunId": "cr_01k2ja2000e0080000000000g7", "annotationLevel": "warning", "message": "Deprecated API usage; migrate to the v2 client.", "title": "Deprecated API", "createdAt": "2026-08-02T14:45:00Z", "updatedAt": "2026-08-02T14:45:00Z", "location": { "path": "src/telemetry.ts", "startLine": 42, "endLine": 42 } } ]}Создать аннотации для проверки выполнения
/v1/origin/repos/{ownerSlug}/{repoName}/check-runs/{checkRunId}/annotationsДобавляет от 1 до 25 аннотаций к запуску проверки одной атомарной пакетной операцией.
Один check run содержит не более 100 аннотаций. Пакет, из‑за которого этот лимит будет превышен, отклоняется с ошибкой ResourceExhausted (HTTP 429), и ничего не записывается; пакет вне диапазона от 1 до 25 отклоняется с ошибкой InvalidArgument (HTTP 400). Операция только добавляет данные и не является идемпотентной, поэтому повторная попытка после неясного сбоя транспорта может привести к добавлению дубликатов и расходованию квоты. Одинаковое содержимое допускается.
Параметры пути
ownerSlug string Обязательное
repoName string Обязательное
checkRunId string Обязательный
Тело запроса
annotations array Обязательное
annotations[].annotationLevel string Обязательное поле
notice, warning, failure.annotations[].message string Обязательное
annotations[].title string
annotations[].rawDetails string
annotations[].location object
annotations[].location.path string Обязательный
annotations[].location.startLine integer Обязательно
annotations[].location.endLine integer Обязательное
startLine.annotations[].location.columns object
startLine и endLine находятся в одной и той же строке, и оба столбца должны быть переданы вместе.annotations[].location.columns.startColumn целое число
annotations[].location.columns.endColumn целое число
startColumn.Поля ответа
annotations array
annotations[].id string
annotations[].checkRunId string
annotations[].annotationLevel string
notice, warning, failure.annotations[].message string
annotations[].title string
annotations[].rawDetails string
annotations[].createdAt string
annotations[].updatedAt string
annotations[].location object
annotations[].location.path string
annotations[].location.startLine integer
annotations[].location.endLine целое число
annotations[].location.columns object
annotations[].location.columns.startColumn целое число
annotations[].location.columns.endColumn целое число
curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/check-runs/CHECK_RUN_ID/annotations' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "annotations": [ { "annotationLevel": "warning", "message": "Deprecated API usage; migrate to the v2 client.", "title": "Deprecated API", "location": { "path": "src/telemetry.ts", "startLine": 42, "endLine": 42 } } ]}'Структура ответа:
{ "annotations": [ { "id": "cra_01k2ja2000e0080000000000v1", "checkRunId": "cr_01k2ja2000e0080000000000g7", "annotationLevel": "warning", "message": "Deprecated API usage; migrate to the v2 client.", "title": "Deprecated API", "createdAt": "2026-08-02T14:45:00Z", "updatedAt": "2026-08-02T14:45:00Z", "location": { "path": "src/telemetry.ts", "startLine": 42, "endLine": 42 } } ]}Повторный запрос запуска проверки
/v1/origin/repos/{ownerSlug}/{repoName}/check-runs/{checkRunId}/rerequestЗапрашивает у приложения, сообщавшего о запуске проверки, его повторный запуск. Origin фиксирует запрос для этого запуска в поле rerequestedAt и уведомляет приложение-владельца событием repository.check_run.rerequested. Приложение отвечает публикацией нового запуска для того же head SHA и key — либо создаёт новый запуск, либо обновляет существующий; это очищает rerequestedAt и сохраняет опубликованный статус. Пока запрос остаётся незавершённым, status запуска имеет значение rerequested; его conclusion и временные метки по-прежнему описывают предыдущую попытку. Вызов возвращает запуск с установленным rerequestedAt и status rerequested.
Запуск должен быть в состоянии completed, иметь isRerequestable, быть текущей попыткой для своего key и находиться на текущей head-ветке открытого pull request. В остальных случаях возвращается FailedPrecondition (HTTP 400).
Для каждого запуска может быть активен только один повторный запрос. Повторный запрос при установленном rerequestedAt возвращает AlreadyExists (HTTP 409 Conflict), а после ответа приложения-владельца запуск снова становится доступен для повторного запроса. Любой субъект с правом repository:contents:write может повторно запросить любой такой запуск независимо от того, какое приложение о нём сообщило. Если checkRunId неизвестен или принадлежит другому репозиторию, возвращается 404.
Параметры пути
ownerSlug string Обязательно
repoName строка Обязательно
checkRunId string Обязательно
cr_...).Тело запроса
Запрос не содержит полей. Отправьте пустой JSON object.
Поля ответа
id строка
repository объект
repository.id строка
repository.name строка
repository.owner object
repository.owner.slug string
repository.owner.id строка
repository.owner.type строка
team, user. Пропускается, если неизвестно.checkSuite object
checkSuite.id string
sha string
key строка
name string
status string
conclusion string
status равен completed.detailsUrl string
externalUpdatedAt string
startedAt строка
completedAt string
createdAt string
updatedAt string
externalId строка
actor object
actor.user object
actor.user.id строка
actor.user.email строка
actor.user.displayName строка
actor.user.handle строка
@. Присутствует только пока профиль публично видим; в противном случае отсутствует.actor.app object
actor.app.id строка
actor.app.displayName строка
actor.serviceAccount object
actor.serviceAccount.id строка
output object
output.title string
output.summary string
output.text string
deadlineAt строка
isRerequestable boolean
rerequestedAt строка
status равен rerequested, запуск остаётся в последнем состоянии проверок коммита и читается как ожидающий, а conclusion и временные метки по-прежнему содержат замещённый результат, поэтому обязательная проверка блокирует слияние до ответа приложения.rerequestedBy object
actor. Присутствует всегда, когда задано rerequestedAt, и сбрасывается вместе с ним.curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/check-runs/CHECK_RUN_ID/rerequest' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{}'Структура ответа:
{ "id": "cr_01k2ja2000e0080000000000g7", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "checkSuite": { "id": "crg_01k2ja2000e0080000000000h8" }, "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "key": "ci-8842-unit-tests", "name": "unit-tests", "status": "rerequested", "conclusion": "failure", "detailsUrl": "https://ci.acme.dev/runs/8842", "externalUpdatedAt": "2026-08-02T14:44:30Z", "startedAt": "2026-08-02T14:40:00Z", "completedAt": "2026-08-02T14:44:30Z", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T15:02:10Z", "externalId": "run-8842", "actor": { "app": { "id": "app_01k2ja2000e0080000000000a1", "displayName": "Acme CI" } }, "output": { "title": "Unit tests", "summary": "3 of 128 tests failed." }, "isRerequestable": true, "rerequestedAt": "2026-08-02T15:02:10Z", "rerequestedBy": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }}Получить набор проверок
/v1/origin/repos/{ownerSlug}/{repoName}/check-suites/{checkSuiteId}Возвращает метаданные набора проверок по идентификатору, назначенному сервером (crg_...). Не включает запуски проверок; для получения запусков этого набора используйте ListCheckRunsForSuite.
Параметры пути
ownerSlug string Обязательное
repoName string Обязательно
checkSuiteId строка Обязательно
crg_...).Поля ответа
id string
repository object
repository.id строка
repository.name string
repository.owner object
repository.owner.slug string
repository.owner.id string
repository.owner.type string
team, user. Оставляется пустым, если неизвестно.sha строка
key string
name строка
detailsUrl string
createdAt string
updatedAt string
externalId string
actor object
actor.user object
actor.user.id string
actor.user.email string
actor.user.displayName string
actor.user.handle string
@. Присутствует только пока профиль виден публично; в противном случае отсутствует.actor.app object
actor.app.id строка
actor.app.displayName string
actor.serviceAccount object
actor.serviceAccount.id string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/check-suites/CHECK_SUITE_ID' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "id": "crg_01k2ja2000e0080000000000h8", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "key": "ci-8842", "name": "CI", "detailsUrl": "https://ci.acme.dev/runs/8842", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "externalId": "build-8842", "actor": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }}Список запусков проверок для набора
/v1/origin/repos/{ownerSlug}/{repoName}/check-suites/{checkSuiteId}/check-runsПеречисляет текущие запуски проверок набора. Если ключ запуска был указан в наборе более одного раза, возвращается только последняя попытка для этого ключа; замещённые попытки опускаются. Запуск, запрошенный повторно, остаётся в перечислении и отображается как ожидающий: поле status имеет значение rerequested, поле rerequestedAt задано, а его замещённые conclusion и отметки времени остаются без изменений, пока владеющее им приложение не ответит. Просмотреть замещённую попытку по её идентификатору можно с помощью Получить запуск проверки. Поддерживается постраничная навигация.
Параметры пути
ownerSlug string Обязательно
repoName string Обязательно
checkSuiteId string Обязательно
crg_...).Параметры запроса
pageSize integer
pageToken строка
next_page_token предыдущего ответа. Для первой страницы — пустой. Кодирует идентификатор последнего просмотренного check-run в пределах этого набора (suite), поэтому при передаче токена параметр page_size в последующем запросе игнорируется.Поля ответа
checkRuns массив
checkRuns[].id string
checkRuns[].repository объект
checkRuns[].repository.id string
checkRuns[].repository.name string
checkRuns[].repository.owner object
checkRuns[].repository.owner.slug строка
checkRuns[].repository.owner.id string
checkRuns[].repository.owner.type string
team, user. Пропускается, если неизвестно.checkRuns[].checkSuite object
checkRuns[].checkSuite.id строка
checkRuns[].sha строка
checkRuns[].key string
checkRuns[].name строка
checkRuns[].status строка
checkRuns[].conclusion string
status равен completed.checkRuns[].detailsUrl строка
checkRuns[].externalUpdatedAt строка
checkRuns[].startedAt строка
checkRuns[].completedAt строка
checkRuns[].createdAt string
checkRuns[].updatedAt строка
checkRuns[].externalId string
checkRuns[].actor object
checkRuns[].actor.user object
checkRuns[].actor.user.id string
checkRuns[].actor.user.email string
checkRuns[].actor.user.displayName string
checkRuns[].actor.user.handle строка
@. Отображается только тогда, когда профиль публично доступен; в противном случае опускается.checkRuns[].actor.app object
checkRuns[].actor.app.id строка
checkRuns[].actor.app.displayName строка
checkRuns[].actor.serviceAccount object
checkRuns[].actor.serviceAccount.id string
checkRuns[].output object
checkRuns[].output.title строка
checkRuns[].output.summary string
checkRuns[].output.text string
checkRuns[].deadlineAt строка
checkRuns[].isRerequestable логическое
checkRuns[].rerequestedAt string
status имеет значение rerequested, запуск остаётся в последнем состоянии проверок коммита и отображается как ожидающий, при этом conclusion и тайминги по‑прежнему содержат устаревший результат, поэтому обязательная проверка блокирует слияние, пока приложение не ответит.checkRuns[].rerequestedBy object
actor. Присутствует, когда установлено rerequestedAt, и очищается вместе с ним.nextPageToken строка
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/check-suites/CHECK_SUITE_ID/check-runs' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "checkRuns": [ { "id": "cr_01k2ja2000e0080000000000g7", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "checkSuite": { "id": "crg_01k2ja2000e0080000000000h8" }, "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "key": "ci-8842-unit-tests", "name": "unit-tests", "status": "completed", "conclusion": "success", "detailsUrl": "https://ci.acme.dev/runs/8842", "externalUpdatedAt": "2026-08-02T14:44:30Z", "startedAt": "2026-08-02T14:40:00Z", "completedAt": "2026-08-02T14:44:30Z", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "externalId": "run-8842", "actor": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "output": { "title": "Unit tests", "summary": "128 tests passed.", "text": "All suites green." } } ]}Список запусков проверок для коммита
/v1/origin/repos/{ownerSlug}/{repoName}/commits/{sha}/check-runsПеречисляет текущие запуски проверок для коммита по всем наборам: только запуски, принадлежащие последней попытке каждого набора, и внутри каждого набора — только последнюю попытку для каждого ключа запуска. Заменённые попытки опущены. Повторно запрошенный запуск остаётся в списке и отображается как ожидающий, при этом status равен rerequested, задано rerequestedAt, а его заменённые conclusion и временные метки остаются без изменений, пока приложение-владелец не ответит. Получить заменённую попытку по её собственному идентификатору можно с помощью Get Check Run. Опционально фильтруется по имени проверки и статусу. Поддерживается постраничная навигация.
Фильтры применяются к свернутому набору, поэтому запуск соответствует по статусу его последней попытки, и фильтр никогда не возвращает вытесненную попытку. Токены страниц содержат фильтры, при которых они были созданы, поэтому токен, воспроизведённый с другими фильтрами, отклоняется; при изменении фильтра начните пагинацию заново.
Параметры пути
ownerSlug string Обязательно
repoName string Обязательно
sha string Обязательно
Параметры запроса
pageSize целое число
pageToken строка
next_page_token предыдущего ответа. Для первой страницы — пустой. Кодирует идентификатор последнего увиденного check-run, привязанный к этому коммиту и к приведённым ниже фильтрам; поэтому при наличии токена параметр page_size в последующем запросе игнорируется, а повторное использование токена с другими фильтрами возвращает ошибку InvalidArgument (HTTP 400).checkName string
checkRuns[].name. Оставьте пустым, чтобы перечислить запуски с любым именем.status string
queued, in_progress, completed, rerequested. Любое другое значение возвращает InvalidArgument (HTTP 400). Опустите, чтобы получить список запусков в любом статусе.Поля ответа
checkRuns массив
checkRuns[].id string
checkRuns[].repository object
checkRuns[].repository.id string
checkRuns[].repository.name string
checkRuns[].repository.owner object
checkRuns[].repository.owner.slug string
checkRuns[].repository.owner.id string
checkRuns[].repository.owner.type строка
team, user. Пропускается, если неизвестно.checkRuns[].checkSuite object
checkRuns[].checkSuite.id string
checkRuns[].sha string
checkRuns[].key string
checkRuns[].name string
checkRuns[].status string
checkRuns[].conclusion string
status равен completed.checkRuns[].detailsUrl string
checkRuns[].externalUpdatedAt string
checkRuns[].startedAt string
checkRuns[].completedAt string
checkRuns[].createdAt string
checkRuns[].updatedAt string
checkRuns[].externalId string
checkRuns[].actor object
checkRuns[].actor.user object
checkRuns[].actor.user.id string
checkRuns[].actor.user.email строка
checkRuns[].actor.user.displayName string
checkRuns[].actor.user.handle string
@. Показывается только пока профиль общедоступен; в противном случае отсутствует.checkRuns[].actor.app object
checkRuns[].actor.app.id строка
checkRuns[].actor.app.displayName string
checkRuns[].actor.serviceAccount object
checkRuns[].actor.serviceAccount.id строка
checkRuns[].output object
checkRuns[].output.title string
checkRuns[].output.summary строка
checkRuns[].output.text строка
checkRuns[].deadlineAt string
checkRuns[].isRerequestable boolean
checkRuns[].rerequestedAt string
status равен rerequested, а запуск остаётся в последнем состоянии проверок коммита и отображается как ожидающий, при этом conclusion и временные метки всё ещё содержат вытесненный результат, поэтому требуемая проверка блокирует слияние до ответа приложения.checkRuns[].rerequestedBy object
actor. Присутствует, когда задано rerequestedAt, и сбрасывается вместе с ним.nextPageToken строка
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/commits/SHA/check-runs' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "checkRuns": [ { "id": "cr_01k2ja2000e0080000000000g7", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "checkSuite": { "id": "crg_01k2ja2000e0080000000000h8" }, "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "key": "ci-8842-unit-tests", "name": "unit-tests", "status": "completed", "conclusion": "success", "detailsUrl": "https://ci.acme.dev/runs/8842", "externalUpdatedAt": "2026-08-02T14:44:30Z", "startedAt": "2026-08-02T14:40:00Z", "completedAt": "2026-08-02T14:44:30Z", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "externalId": "run-8842", "actor": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "output": { "title": "Unit tests", "summary": "128 tests passed.", "text": "All suites green." } } ]}Список наборов проверок для коммита
/v1/origin/repos/{ownerSlug}/{repoName}/commits/{sha}/check-suitesВозвращает список наборов проверок для коммита. Возвращается только последняя попытка каждого набора — по каждому отчитывающемуся субъекту и ключу набора; замещённые попытки не включаются. Замещённую попытку можно прочитать по её собственному идентификатору через Get Check Suite. Возвращает только метаданные набора (без вложенных запусков). Поддерживает пагинацию.
Параметры пути
ownerSlug string Обязательное
repoName строка Обязательно
sha string Обязательно
Параметры запроса
pageSize integer
pageToken строка
next_page_token предыдущего ответа. Для первой страницы пустой. Кодирует идентификатор последнего встреченного check-suite, относящийся к этому коммиту, поэтому при наличии токена параметр page_size в последующем запросе игнорируется.Поля ответа
checkSuites массив
checkSuites[].id string
checkSuites[].repository object
checkSuites[].repository.id string
checkSuites[].repository.name string
checkSuites[].repository.owner object
checkSuites[].repository.owner.slug строка
checkSuites[].repository.owner.id string
checkSuites[].repository.owner.type string
team, user. Не указывается, если неизвестно.checkSuites[].sha строка
checkSuites[].key string
checkSuites[].name строка
checkSuites[].detailsUrl string
checkSuites[].createdAt string
checkSuites[].updatedAt string
checkSuites[].externalId строка
checkSuites[].actor object
checkSuites[].actor.user object
checkSuites[].actor.user.id строка
checkSuites[].actor.user.email string
checkSuites[].actor.user.displayName string
checkSuites[].actor.user.handle string
@. Присутствует только когда профиль общедоступен; в противном случае отсутствует.checkSuites[].actor.app object
checkSuites[].actor.app.id string
checkSuites[].actor.app.displayName string
checkSuites[].actor.serviceAccount object
checkSuites[].actor.serviceAccount.id string
nextPageToken строка
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/commits/SHA/check-suites' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "checkSuites": [ { "id": "crg_01k2ja2000e0080000000000h8", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "key": "ci-8842", "name": "CI", "detailsUrl": "https://ci.acme.dev/runs/8842", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "externalId": "build-8842", "actor": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } } } ]}Коммиты и содержимое
Коммит отделяет метаданные Git-объекта в commit от связей репозитория верхнего уровня. В ответах со списками отсутствует stats; Get Commit включает сводную stats для всего коммита. Изменённые файлы возвращаются только в поддерживающей пагинацию коллекции List Commit Files. author и committer — это Git-идентификаторы, записанные в коммите, а не объекты пользователей Origin.
Сравнение содержит только сводную информацию: в него никогда не включаются списки коммитов или диффы файлов. status имеет строго одно из значений: identical, ahead, behind или diverged; aheadBy и behindBy — это количество коммитов. baseCommit, headCommit и mergeBaseCommit используют сокращённое представление коммита (без stats и файлов).
Список коммитов
/v1/origin/repos/{ownerSlug}/{repoName}/commitsПеречисляет коммиты в ветке или начиная с указанной ссылки.
В результатах списка отсутствует stats. Используйте Get Commit для получения сводной статистики и List Commit Files для постраничного получения диффа файлов.
Параметры пути
ownerSlug строка Обязательно
repoName строка Обязательно
Параметры запроса
sha строка
HEAD), с которой начинать перечисление. Пустое значение означает ветку по умолчанию репозитория.pageSize целое число
pageToken строка
next_page_token предыдущего ответа. Для первой страницы пуст. Кодирует начальный ref и страницу, поэтому при наличии токена значения sha/page_size в последующем запросе игнорируются.Поля ответа
commits массив
commits[].sha строка
commits[].commit object
commits[].commit.author object
commits[].commit.author.name строка
commits[].commit.author.email строка
commits[].commit.author.date строка
commits[].commit.committer object
commits[].commit.committer.name строка
commits[].commit.committer.email строка
commits[].commit.committer.date строка
commits[].commit.message строка
commits[].commit.tree object
commits[].commit.tree.sha строка
commits[].parents массив
commits[].parents[].sha строка
nextPageToken строка
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/commits' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "commits": [ { "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "commit": { "author": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "committer": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "message": "Add launch telemetry", "tree": { "sha": "a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b8" } }, "parents": [ { "sha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" } ], "stats": { "additions": 128, "deletions": 46, "total": 174 } } ]}Получить коммит
/v1/origin/repos/{ownerSlug}/{repoName}/commits/{sha}Возвращает один коммит по SHA или ссылке (ref) с агрегированной статистикой всего коммита stats. Изменённые файлы не включены; используйте Список файлов коммита.
author и committer — это идентичности Git, записанные в коммите, а не объекты пользователей Origin.
Параметры пути
ownerSlug строка Обязательно
repoName строка Обязательно
sha строка Обязательно
HEAD) коммита для получения.Поля ответа
sha строка
commit object
commit.author object
commit.author.name строка
commit.author.email строка
commit.author.date строка
commit.committer object
commit.committer.name строка
commit.committer.email строка
commit.committer.date строка
commit.message строка
commit.tree object
commit.tree.sha строка
parents массив
parents[].sha строка
stats object
stats.additions целое число
stats.deletions целое число
stats.total целое число
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/commits/SHA' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "commit": { "author": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "committer": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "message": "Add launch telemetry", "tree": { "sha": "a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b8" } }, "parents": [ { "sha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" } ], "stats": { "additions": 128, "deletions": 46, "total": 174 }}Список файлов коммита
/v1/origin/repos/{ownerSlug}/{repoName}/commits/{sha}/filesВозвращает список файлов, изменённых коммитом.
sha может быть SHA коммита, веткой, тегом или символической ссылкой, например HEAD. По умолчанию возвращаются 30 файлов, максимум — 100. Токен страницы фиксирует разрешённый коммит, размер страницы и курсор по файлам; в последующих запросах sha и pageSize должны совпадать с токеном. Для каждого файла указываются filename, status, additions, deletions, changes, patch и previousFilename, если файл был переименован или скопирован. Для бинарных файлов patch пуст.
Параметры пути
ownerSlug строка Обязательно
repoName строка Обязательно
sha строка Обязательно
HEAD) коммита, файлы которого нужно перечислить.Параметры запроса
pageSize integer
pageToken строка
next_page_token предыдущего ответа. Пуст для первой страницы. Токен фиксирует выбранный коммит, размер страницы и позицию курсора файла, поэтому параметры sha и page_size в последующем запросе должны соответствовать токену.Поля ответа
files массив
files[].filename строка
files[].status строка
files[].additions integer
files[].deletions integer
files[].changes integer
files[].patch строка
files[].previousFilename строка
nextPageToken строка
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/commits/SHA/files' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "files": [ { "filename": "src/telemetry.ts", "status": "modified", "additions": 6, "deletions": 3, "changes": 9, "patch": "@@ -12,6 +12,9 @@\n import { ignite } from \"./ignition\";\n+import { emitLaunchTelemetry } from \"./telemetry\";\n" } ]}Сравнение коммитов
/v1/origin/repos/{ownerSlug}/{repoName}/compare/{basehead}Сравнивает коммиты, refs или теги относительно их базы слияния. basehead имеет вид "{base}...{head}"; refs, содержащие "/", должны указываться по их SHA.
base и head могут быть SHA, веткой, тегом или символической ссылкой, такой как HEAD. Ответ — непагинированная сводка: status принимает значения identical, ahead, behind или diverged; три объекта коммита являются разреженными и не содержат stats и файлов. Поля totalCommits, вложенные commits и files не возвращаются. Для несвязанных историй возвращается 404.
Параметры пути
ownerSlug строка Обязательно
repoName строка Обязательно
basehead строка Обязательно
"{base}...{head}", где любая из ревизий может быть SHA, веткой, тегом или символической ссылкой (например, HEAD).Поля ответа
status строка
aheadBy целое число
behindBy целое число
baseCommit object
baseCommit.sha строка
baseCommit.commit object
baseCommit.commit.author object
baseCommit.commit.author.name строка
baseCommit.commit.author.email строка
baseCommit.commit.author.date строка
baseCommit.commit.committer object
baseCommit.commit.committer.name строка
baseCommit.commit.committer.email строка
baseCommit.commit.committer.date строка
baseCommit.commit.message строка
baseCommit.commit.tree object
baseCommit.commit.tree.sha строка
baseCommit.parents массив
baseCommit.parents[].sha строка
headCommit object
headCommit.sha строка
headCommit.commit object
headCommit.commit.author object
headCommit.commit.author.name строка
headCommit.commit.author.email строка
headCommit.commit.author.date строка
headCommit.commit.committer object
headCommit.commit.committer.name строка
headCommit.commit.committer.email строка
headCommit.commit.committer.date строка
headCommit.commit.message строка
headCommit.commit.tree объект
headCommit.commit.tree.sha строка
headCommit.parents массив
headCommit.parents[].sha строка
mergeBaseCommit object
mergeBaseCommit.sha строка
mergeBaseCommit.commit object
mergeBaseCommit.commit.author object
mergeBaseCommit.commit.author.name строка
mergeBaseCommit.commit.author.email строка
mergeBaseCommit.commit.author.date строка
mergeBaseCommit.commit.committer object
mergeBaseCommit.commit.committer.name строка
mergeBaseCommit.commit.committer.email строка
mergeBaseCommit.commit.committer.date строка
mergeBaseCommit.commit.message строка
mergeBaseCommit.commit.tree object
mergeBaseCommit.commit.tree.sha строка
mergeBaseCommit.parents массив
mergeBaseCommit.parents[].sha строка
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/compare/BASE...HEAD' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "status": "ahead", "aheadBy": 2, "behindBy": 0, "baseCommit": { "sha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8", "commit": { "author": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "committer": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "message": "Add launch telemetry", "tree": { "sha": "a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b8" } }, "parents": [ { "sha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" } ], "stats": { "additions": 128, "deletions": 46, "total": 174 } }, "headCommit": { "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "commit": { "author": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "committer": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "message": "Add launch telemetry", "tree": { "sha": "a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b8" } }, "parents": [ { "sha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" } ], "stats": { "additions": 128, "deletions": 46, "total": 174 } }, "mergeBaseCommit": { "sha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8", "commit": { "author": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "committer": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "message": "Add launch telemetry", "tree": { "sha": "a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b8" } }, "parents": [ { "sha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" } ], "stats": { "additions": 128, "deletions": 46, "total": 174 } }}Список файлов для сравнения
/v1/origin/repos/{ownerSlug}/{repoName}/compare/{basehead}/filesВозвращает список файлов, изменённых при сравнении: дифф head с базой слияния base и head.
basehead — это "{base}...{head}"; для ссылок (refs), содержащих "/", необходимо использовать их SHA. Список файлов всегда соответствует сводке из Compare Commits, поэтому при сравнении identical или behind возвращается пустой список, а для несвязанных историй возвращается 404. По умолчанию возвращается 30 файлов, максимум — 100. Для каждого файла присутствуют те же поля, что и в List Commit Files.
Параметры пути
ownerSlug строка Обязательно
repoName строка Обязательно
basehead строка Обязательно
"{base}...{head}", где каждая из ревизий может быть SHA, веткой, тегом или символической ссылкой, например HEAD.Параметры запроса
pageSize integer
pageToken строка
next_page_token предыдущего ответа. Пуст для первой страницы. Токен привязан к разрешённому сравнению, размеру страницы и положению курсора файла, поэтому параметры basehead и page_size в последующем запросе должны совпадать с токеном. Origin повторно разрешает сравнение на каждой странице; если его коммиты с момента выдачи токена переместились, запрос возвращает InvalidArgument (HTTP 400), и перечисление необходимо начать заново с первой страницы.Поля ответа
files массив
files[].filename строка
files[].status строка
files[].additions целое число
files[].deletions integer
files[].changes integer
files[].patch строка
files[].previousFilename строка
nextPageToken строка
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/compare/BASE...HEAD/files' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "files": [ { "filename": "src/telemetry.ts", "status": "modified", "additions": 6, "deletions": 3, "changes": 9, "patch": "@@ -12,6 +12,9 @@\n import { ignite } from \"./ignition\";\n+import { emitLaunchTelemetry } from \"./telemetry\";\n" } ]}Получить содержимое
/v1/origin/repos/{ownerSlug}/{repoName}/contentsВозвращает содержимое файла или каталога для указанной Git-ссылки. Путь к файлу передаётся в параметре запроса path (поддерживаются вложенные пути); не указывайте его или оставьте пустым, чтобы получить содержимое корневого каталога репозитория. Файлы размером более 1 МиБ (после декодирования) отклоняются с ошибкой FailedPrecondition (HTTP 400).
Файлы содержат данные в кодировке base64. Каталоги содержат непосредственные дочерние элементы в entries. Записи каталога — это сокращённые дочерние элементы, содержащие type, name, path, sha и size; чтобы прочитать содержимое дочернего элемента, получите его по пути.
Параметры пути
ownerSlug строка Обязательный
repoName строка Обязательный
Параметры запроса
path строка
ref строка
HEAD), содержимое которых нужно прочитать. При пустом значении используется ветка репозитория по умолчанию.Поля ответа
type строка
encoding строка
size строка
name строка
path строка
sha строка
content строка
entries массив
type, name, path, sha и size; чтобы прочитать содержимое дочернего элемента, получите его по пути.curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/contents' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "type": "file", "encoding": "base64", "size": "312", "name": "telemetry.ts", "path": "src/telemetry.ts", "sha": "c9d8e7f6a5b4c3d2e1f0a9b8c7d6e5f4a3b2c1d0", "content": "Y29uc29sZS5sb2coImxhdW5jaCIpOwo="}Пакетное получение содержимого
/v1/origin/repos/{ownerSlug}/{repoName}/contents:batchGetВозвращает содержимое нескольких явно указанных путей в заданном ref одним запросом. Для каждого запрошенного пути возвращается результат с указанием, найден ли он; найденный путь имеет ту же структуру Content, что и в GetContents (файлы — в base64, каталоги — с непосредственными entries, символические ссылки — как файлы). Пути сопоставляются точно, без glob-выражений или шаблонов; можно запросить не более 20 путей, дубликаты удаляются. Результаты ответа сохраняют порядок первого появления в запросе. Один файл, превышающий ограничение в 1 МиБ, установленное для Get Contents, приводит к ошибке всего пакета FailedPrecondition (HTTP 400). Используется POST, поскольку список путей передаётся в теле запроса.
Параметры пути
ownerSlug строка Обязательно
repoName строка Обязательно
Тело запроса
paths массив Обязательно
ref строка
HEAD), из которых читать. Пустое значение означает ветку по умолчанию репозитория.Поля ответа
results массив
results[].path строка
results[].found логическое значение
results[].content object
results[].content.type строка
results[].content.encoding строка
results[].content.size строка
results[].content.name строка
results[].content.path строка
results[].content.sha строка
results[].content.content строка
results[].content.entries массив
resolvedCommitSha строка
curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/contents:batchGet' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "paths": [ "src/telemetry.ts" ], "ref": "main"}'Структура ответа:
{ "results": [ { "path": "src/telemetry.ts", "found": true, "content": { "type": "file", "encoding": "base64", "size": "312", "name": "telemetry.ts", "path": "src/telemetry.ts", "sha": "c9d8e7f6a5b4c3d2e1f0a9b8c7d6e5f4a3b2c1d0", "content": "Y29uc29sZS5sb2coImxhdW5jaCIpOwo=" } } ], "resolvedCommitSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4"}Поиск по содержимому
/v1/origin/repos/{ownerSlug}/{repoName}:grepВыполняет поиск по тексту файлов репозитория на указанной Git-ссылке и возвращает совпавшие строки, а также запрошенные строки окружающего контекста. Поиск построчный: шаблон никогда не совпадает через перенос строки, и каждая возвращаемая запись — это одна строка. Репозиторий сканируется при каждом запросе, поэтому пагинация и курсор не используются; ответ считается полным, только если limitHit равно false. Пустой репозиторий без Git-ссылок возвращает пустой список совпадений и limitHit false. Используется POST, поскольку параметры поиска передаются в теле запроса.
Параметры пути
ownerSlug string Обязательный
repoName строка Обязательный
Тело запроса
ref строка
HEAD) для поиска. Если пусто, используется ветка по умолчанию для репозитория.query string Обязательный
literal. Пробелы значимы и учитываются при поиске. Пустой шаблон возвращает InvalidArgument (HTTP 400). Максимальный размер в UTF-8: 4096 байт.literal boolean
query как точный текст, а не как регулярное выражение.caseInsensitive boolean
wholeWord boolean
contextBefore integer
contextAfter integer
filterPath строка
includes массив
/ соответствует на любой глубине, * соответствует внутри одного сегмента пути, а ** — через несколько сегментов. Если указано хотя бы одно включение (include), путь, не соответствующий ни одному из них, не ищется. Не более 20 записей. Максимальный размер шаблона в UTF-8: 4096 байт.excludes массив
includes. Исключение имеет приоритет над включением, и исключение каталога исключает всё, что находится внутри него. Не более 20 записей. Максимальный размер шаблона в UTF-8: 4096 байт.maxResults integer
Поля ответа
matches массив
matches[].path строка
matches[].lineNumber integer
matches[].line строка
matches[].kind строка
match, context.matches[].submatches массив
line. Для строки контекста всегда пусто. Если limitHit равно true, последняя совпавшая строка может содержать лишь часть своих совпадений. Диапазоны, полностью выходящие за пределы line, опускаются, а диапазоны, частично выходящие за line, обрезаются до оставшихся байтов.matches[].submatches[].start integer
matches[].submatches[].end integer
limitHit boolean
maxResults. Сузьте query, filterPath или списки glob, чтобы выполнить поиск по меньшему набору файлов.curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME:grep' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "ref": "main", "query": "emitLaunchTelemetry\\(", "contextBefore": 1, "contextAfter": 1, "includes": [ "*.ts" ], "excludes": [ "**/node_modules/**" ], "maxResults": 50}'{ "matches": [ { "path": "src/telemetry.ts", "lineNumber": 11, "line": "export function emitLaunchTelemetry(stage: string): void {", "kind": "match", "submatches": [ { "start": 16, "end": 37 } ] }, { "path": "src/telemetry.ts", "lineNumber": 12, "line": " console.log(\"launch\", stage);", "kind": "context", "submatches": [] } ], "limitHit": false}Данные Git
Низкоуровневые Git-object. Для чтения требуется repository:contents:read, а для пустого репозитория возвращается 409. Create Commit From Files и Create Git Ref записывают Git-object и требуют repository:contents:write.
Получить blob
/v1/origin/repos/{ownerSlug}/{repoName}/git/blobs/{sha}Возвращает Git-object blob по SHA. По умолчанию возвращается JSON, где content содержит данные в base64 с MIME-переносами. Чтобы получить необработанные байты blob, передайте в REST-запросе Accept: application/vnd.origin.raw+json (или application/vnd.origin.raw). Blob размером более 4 МиБ в декодированном виде отклоняются; для файлов большего размера клонируйте репозиторий по Git HTTPS. Для пустых репозиториев возвращается ошибка 409 Conflict.
Параметры пути
ownerSlug строка обязательный
repoName строка обязательный
sha строка обязательный
Поля ответа
sha строка
size целое число
encoding строка
content строка
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/git/blobs/SHA' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "sha": "c9d8e7f6a5b4c3d2e1f0a9b8c7d6e5f4a3b2c1d0", "size": 312, "encoding": "base64", "content": "Y29uc29sZS5sb2coImxhdW5jaCIpOwo="}Получить Git-коммит
/v1/origin/repos/{ownerSlug}/{repoName}/git/commits/{sha}Возвращает объект коммита Git по SHA (или разрешимой ревизии). Это низкоуровневое представление коммита в Git Database (плоская структура author/message/tree), а не ресурс более высокого уровня GetCommit по пути /commits/{sha}. В sha можно передать SHA коммита, ветку, тег или символическую ссылку, например HEAD. Для пустых репозиториев возвращается ошибка 409 Conflict.
Параметры пути
ownerSlug строка Обязательно
repoName строка Обязательно
sha строка Обязательно
HEAD.Поля ответа
sha строка
author object
author.name строка
author.email строка
author.date строка
committer object
committer.name строка
committer.email строка
committer.date строка
message строка
tree object
tree.sha строка
parents массив
parents[].sha строка
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/git/commits/SHA' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "author": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "committer": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "message": "Add launch telemetry", "tree": { "sha": "a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b8" }, "parents": [ { "sha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" } ]}Создать коммит из файлов
/v1/origin/repos/{ownerSlug}/{repoName}/git/commits:createFromFilesСоздаёт коммит в ветке на основе inline-изменений файлов и переводит ветку на него.
Изменения применяются к дереву на expectedHeadSha, который становится родителем нового коммита. Если ветка сместилась или не существует, набор изменений не меняет дерево, удаляется путь, которого нет в дереве, запись блокируется набором правил push либо содержимое репозитория зеркалируется с другого хоста — во всех этих случаях возвращается FailedPrecondition (HTTP 400).
Один запрос может содержать не более 1000 изменений файлов, 8 МиБ на файл и 32 МиБ содержимого суммарно. При превышении лимита, повторении пути или отправке некорректного поля возвращается InvalidArgument (HTTP 400), а в нарушениях полей google.rpc.BadRequest указывается проблемная запись files[i].
Ветка должна уже существовать. Сначала создайте её с помощью Create Git Ref, а затем делайте в неё коммиты.
Параметры пути
ownerSlug string Обязательный
repoName string Обязательный
Тело запроса
targetBranch string Обязательный
<branch>, heads/<branch> или refs/heads/<branch>. Ветка должна уже существовать. HEAD отклоняется в любом написании.expectedHeadSha string Обязательный
message string Обязательно
author object Обязательный
author.name string Обязательное
author.email string Обязательный
committer object
author.committer.name string
committer.committer.email string
committer.files массив Обязательный
files[].path string Обязательно
/, например docs/changelog.md.files[].content string
files[].encoding. Создаёт файл или заменяет его содержимое. Задайте ровно одно из полей: files[].content или files[].delete.files[].delete boolean
true. Задайте ровно одно из полей: files[].content или files[].delete.files[].encoding string
files[].content. Допустимые значения: utf-8 (по умолчанию), base64. Игнорируется при удалении.files[].mode string
files[].content. Допустимые значения: file (по умолчанию), executable, symlink — в этом случае содержимое задаёт цель ссылки. Игнорируется при удалении.Поля ответа
sha string
treeSha string
previousHeadSha string
curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/git/commits:createFromFiles' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "targetBranch": "feature/login", "expectedHeadSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "message": "Add login telemetry", "author": { "name": "Jane Doe", "email": "[email protected]" }, "files": [ { "path": "src/login/telemetry.ts", "content": "export const LOGIN_EVENT = 1;" }, { "path": "assets/login.png", "content": "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==", "encoding": "base64" }, { "path": "src/login/legacy.ts", "delete": true } ]}'Структура ответа:
{ "sha": "5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7c6d", "treeSha": "a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b8", "previousHeadSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4"}Получить Git-ссылку
/v1/origin/repos/{ownerSlug}/{repoName}/git/ref/{ref}Возвращает одну Git-ссылку по имени. ref обычно имеет вид heads/<branch> или tags/<tag> (с префиксом refs/ или без него), либо символьную ссылку HEAD. Поддерживается только точное совпадение; для поиска по префиксу используйте ListMatchingGitRefs. Для пустых репозиторев возвращается ошибка 409 Conflict.
Параметры пути
ownerSlug строка Обязательный
repoName строка Обязательный
ref строка Обязательный
heads/<branch> или tags/<tag>; префикс refs/ принимается и нормализуется. Также принимается символьная ссылка HEAD (возвращается как ref: "HEAD" с последним коммитом). Выполняется точное сопоставление по полному имени Git-ссылки.Поля ответа
ref строка
object object
object.type имеет значение "tag", а object.sha — SHA объекта тега.object.sha строка
object.type строка
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/git/ref/REF' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "ref": "refs/heads/main", "object": { "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "type": "commit" }}Создание Git-ссылки
/v1/origin/repos/{ownerSlug}/{repoName}/git/refsСоздаёт ссылку на ветку, указывающую на существующий коммит.
Создавать можно только ссылки на ветки. Тег, любое другое пространство имён ссылок, а также sha, не являющийся полным шестнадцатеричным SHA коммита в репозитории, приводят к ошибке InvalidArgument (HTTP 400). Создание ветки, которая уже указывает на sha, завершается успешно и возвращает существующую ссылку; если ветка существует и указывает на другой коммит, возвращается AlreadyExists (HTTP 409 Conflict). Если создание блокируется набором правил push либо выполняется в репозитории, содержимое которого зеркалируется с другого хоста, возвращается FailedPrecondition (HTTP 400).
Path Parameters
ownerSlug string Обязательный
repoName string Обязательный
Request Body
ref string Обязательный
refs/heads/<branch> или heads/<branch>.sha string Обязательный
Response Fields
ref string
object object
object.type равен "commit".object.sha string
object.type string
curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/git/refs' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "ref": "refs/heads/feature/login", "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4"}'Структура ответа:
{ "ref": "refs/heads/feature/login", "object": { "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "type": "commit" }}Список Git-ссылок по префиксу
/v1/origin/repos/{ownerSlug}/{repoName}/git/matching-refsВозвращает список Git-ссылок, имена которых начинаются с указанного префикса. REST-ответы разворачиваются в JSON-массив (через response_body). Завершающий слеш в ref сохраняется (heads/ → refs/heads/). Символьная ссылка HEAD сопоставляется точно (она не входит в refs/). Для пустых репозиториев возвращается ошибка 409 Conflict.
Параметры пути
ownerSlug строка Обязательный
repoName строка Обязательный
Параметры запроса
ref строка
heads/<prefix> или tags/<prefix>; префикс refs/ принимается и нормализуется. Если значение пустое, выводятся все Git-ссылки (REST-привязка без завершающего сегмента пути).Поля ответа
Ответ представляет собой массив. Каждый элемент содержит:
ref строка
object object
object.type имеет значение "tag", а object.sha — SHA объекта тега.object.sha строка
object.type строка
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/git/matching-refs' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "refs": [ { "ref": "refs/heads/main", "object": { "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "type": "commit" } } ]}Список Git-ссылок, соответствующих пути
/v1/origin/repos/{ownerSlug}/{repoName}/git/matching-refs/{ref}Возвращает Git-ссылки, имена которых начинаются с указанного префикса. REST-ответы разворачиваются в JSON-массив (через response_body). Завершающий слеш в ref сохраняется (heads/ → refs/heads/). Символьная ссылка HEAD сопоставляется строго (она не находится в refs/). Для пустых репозиториев возвращается ошибка 409 Conflict.
Параметры пути
ownerSlug строка Обязательный
repoName строка Обязательный
ref строка Обязательный
heads/<prefix> или tags/<prefix>; префикс refs/ принимается и нормализуется. Пустое значение возвращает все Git-ссылки (REST-привязка без завершающего сегмента пути).Поля ответа
Ответ представляет собой массив. Каждый элемент содержит:
ref строка
object object
object.type имеет значение "tag", а object.sha — SHA объекта тега.object.sha строка
object.type строка
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/git/matching-refs/REF' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "refs": [ { "ref": "refs/heads/main", "object": { "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "type": "commit" } } ]}Получить тег
/v1/origin/repos/{ownerSlug}/{repoName}/git/tags/{sha}Возвращает объект аннотированного Git-тега по SHA. Облегчённые теги не являются объектами тегов и возвращают NotFound. Для пустых репозиториев возвращается 409 Conflict.
Параметры пути
ownerSlug string Обязательный
repoName string Обязательный
sha string Обязательный
Поля ответа
sha string
tag string
message string
tagger object
tagger.name string
tagger.email string
tagger.date string
object object
object.sha string
object.type string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/git/tags/SHA' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "sha": "e1f0a9b8c7d6e5f4a3b2c1d0e9f8a7b6c5d4e3f2", "tag": "v1.2.0", "message": "Release v1.2.0", "tagger": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "object": { "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "type": "commit" }}Получить дерево
/v1/origin/repos/{ownerSlug}/{repoName}/git/trees/{sha}Возвращает объект дерева Git по SHA или разрешимой ревизии. sha принимает SHA дерева, SHA коммита, ветку, тег или символическую ссылку, такую как HEAD. Установите recursive=true (или 1), чтобы обойти всё дерево; если не указывать этот параметр или передать любое другое значение, будут перечислены только непосредственные элементы. Рекурсивные списки усекаются после 100 000 записей или 7 МиБ и устанавливают truncated=true. Пустые репозитории возвращают 409 Conflict.
Параметры пути
ownerSlug string Обязательный
repoName string Обязательно
sha string Обязательный
HEAD.Параметры запроса
recursive boolean
true, возвращается полный рекурсивный обход дерева. Значения параметра запроса true и 1 включают рекурсию; если не указывать параметр или передать любое другое значение (включая false и 0), будут перечислены только непосредственные потомки.Поля ответа
sha string
tree array
tree[].path string
tree[].mode string
tree[].type string
tree[].sha string
tree[].size integer
int32 гарантирует, что REST JSON возвращает число; отдельные blob размером более 2 ГиБ не представимы.truncated boolean
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/git/trees/SHA' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "sha": "a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b8", "tree": [ { "path": "src/telemetry.ts", "mode": "100644", "type": "blob", "sha": "c9d8e7f6a5b4c3d2e1f0a9b8c7d6e5f4a3b2c1d0", "size": 312 } ], "truncated": false}Grants
Grant связывает один principal с одним repository или одним owner и одним правом доступа. Эти конечные точки читают, задают и удаляют grants, назначенные непосредственно на resource, — благодаря этому изменения доступа можно описывать скриптами и проверять так же, как код. Операции write используют те же проверки, что и Codebase permissions UI, и записывают те же audit events repository.access_changed и namespace.access_changed. О видах principal, двух уровнях прав доступа и о том, как grants уровня owner взаимодействуют с grants уровня repository, читайте в разделе Origin Grants API.
Список разрешений репозитория
/v1/origin/repos/{ownerSlug}/{repoName}/grantsВозвращает список пользователей, групп и групп владеющей команды, обладающих правом доступа, выданным непосредственно на репозиторий. Права доступа, унаследованные от владельца репозитория, не включаются.
Параметры пути
ownerSlug строка Обязательный
repoName строка Обязательный
Параметры запроса
pageSize integer
pageToken.pageToken строка
next_page_token предыдущего ответа. Для первой страницы оставьте пустым.Поля ответа
grants массив
pageSize grants.grants[].user object
user, group или teamGroup.grants[].user.id строка
user_.grants[].user.email строка
grants[].user.displayName строка
grants[].user.handle строка
@. Передаётся только в том случае, если профиль общедоступен; в остальных случаях отсутствует.grants[].group object
grants[].group.id строка
grp_.grants[].teamGroup object
grants[].teamGroup.kind строка
members, admins.grants[].permission строка
read, write, admin, custom. Значение custom указывает на пользовательскую политику, которую Upsert Repository Grant не принимает.repository object
nextPageToken строка
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/{ownerSlug}/{repoName}/grants' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "grants": [ { "group": { "id": "grp_01k2ja2000e0080000000000n2" }, "permission": "admin" }, { "teamGroup": { "kind": "admins" }, "permission": "admin" }, { "teamGroup": { "kind": "members" }, "permission": "write" }, { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" }, "permission": "read" } ], "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "nextPageToken": ""}Upsert repository grant
/v1/origin/repos/{ownerSlug}/{repoName}/grantsЗадаёт право доступа, которым пользователь, группа или группа владеющей команды обладает непосредственно в репозитории, заменяя любое право доступа, ранее выданное этому principal напрямую. Повторная выдача права доступа, которое у principal уже есть, завершается успешно и ничего не меняет. Пользователь должен быть активным участником команды или организации владельца репозитория, а группа — активной группой этой организации; иначе запрос возвращает FailedPrecondition (HTTP 400).
Параметры пути
ownerSlug строка Обязательный
repoName строка Обязательный
Тело запроса
user object
user, group или teamGroup.user.id строка
user_.user.email строка
user.displayName строка
user.handle строка
@. Присутствует, только пока профиль общедоступен; в остальных случаях опускается.group object
group.id строка
grp_.teamGroup object
teamGroup.kind строка
members, admins.permission строка Обязательное
read, write, admin. Значение custom возвращает InvalidArgument (HTTP 400); пользовательские политики выходят за рамки этого API.Поля ответа
user object
user, group или teamGroup.user.id строка
user_.user.email строка
user.displayName строка
user.handle строка
@. Возвращается, только пока профиль общедоступен; в остальных случаях опускается.group object
group.id строка
grp_.teamGroup object
teamGroup.kind строка
members, admins.permission строка
curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/grants' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "user": { "id": "user_01k2ja2000e0080000000000c3" }, "permission": "write"}'Response shape:
{ "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" }, "permission": "write"}Удаление права доступа к репозиторию
/v1/origin/repos/{ownerSlug}/{repoName}/grantsУдаляет право доступа, выданное пользователю, группе или группе команды-владельца непосредственно на репозиторий. Права, унаследованные от владельца репозитория, не затрагиваются, поэтому для группы команды-владельца применяется значение по умолчанию с уровня владельца. Попытка удалить право доступа, которым principal не обладает напрямую, завершается успешно и ничего не меняет. Тело ответа пустое.
Path Parameters
ownerSlug строка обязательный
repoName строка обязательный
Request Body
user object
user, group или teamGroup.user.id строка
user_.user.email строка
user.displayName строка
user.handle строка
@. Присутствует, только пока этот профиль виден публично; в остальных случаях опускается.group object
group.id строка
grp_.teamGroup object
teamGroup.kind строка
members, admins.Response Fields
При успешных запросах тело ответа отсутствует.
curl --request DELETE \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/grants' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "group": { "id": "grp_01k2ja2000e0080000000000n2" }}'Ответ:
204 No ContentСписок разрешений пространства имён
/v1/origin/owners/{ownerSlug}/grantsВозвращает список тех, кому предоставлен доступ к владельцу: пользователей, группы, а также встроенные группы admin и member владеющей команды. Каждый грант несёт разрешение, которое он даёт для каждого репозитория этого владельца. Гранты, выданные на отдельные репозитории, не включаются; их можно получить через List Repository Grants.
Параметры пути
ownerSlug строка Обязательный
Query Parameters
pageSize integer
pageToken.pageToken строка
next_page_token предыдущего ответа. Для первой страницы оставьте пустым.Поля ответа
grants массив
pageSize.grants[].user object
user, group или teamGroup.grants[].user.id строка
user_.grants[].user.email строка
grants[].user.displayName строка
grants[].user.handle строка
@. Присутствует, только пока профиль общедоступен; в остальных случаях опускается.grants[].group object
grants[].group.id строка
grp_.grants[].teamGroup object
grants[].teamGroup.kind строка
members, admins.grants[].permission строка
PERMISSION_READ, PERMISSION_CONTRIBUTOR, PERMISSION_WRITE, PERMISSION_ADMIN, PERMISSION_CUSTOM. Значение PERMISSION_CUSTOM означает custom policy, которую Upsert Namespace Grant не принимает.nextPageToken строка
curl --request GET \ --url 'https://api.cursor.com/v1/origin/owners/{ownerSlug}/grants' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "grants": [ { "group": { "id": "grp_01k2ja2000e0080000000000n2" }, "permission": "PERMISSION_ADMIN" }, { "teamGroup": { "kind": "admins" }, "permission": "PERMISSION_ADMIN" }, { "teamGroup": { "kind": "members" }, "permission": "PERMISSION_CONTRIBUTOR" }, { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" }, "permission": "PERMISSION_WRITE" } ], "nextPageToken": ""}Upsert-обновление гранта пространства имён
/v1/origin/owners/{ownerSlug}/grantsЗадаёт право доступа, которым пользователь, группа или группа владеющей команды напрямую обладает на owner, заменяя право доступа, ранее выданное этому principal напрямую. Повторная выдача права доступа, которое principal уже имеет, завершается успешно и ничего не меняет. Запрос возвращает FailedPrecondition (HTTP 400), если пользователь не является активным участником владеющей команды или её организации, если группа не является активной группой этой организации либо если запись оставит owner без администратора.
Параметры пути
ownerSlug строка Обязательный
Тело запроса
user object
user, group или teamGroup.user.id строка
user_.user.email строка
user.displayName строка
user.handle строка
@. Передаётся, только пока профиль общедоступен; в остальных случаях не передаётся.group object
group.id строка
grp_.teamGroup object
teamGroup.kind строка
members, admins.permission строка Обязательное
PERMISSION_READ, PERMISSION_CONTRIBUTOR, PERMISSION_WRITE, PERMISSION_ADMIN. Значения PERMISSION_READ, PERMISSION_CONTRIBUTOR и PERMISSION_WRITE задают соответствующий уровень доступа к внутренним репозиториям владельца, а PERMISSION_ADMIN даёт права на администрирование самого владельца. PERMISSION_CUSTOM возвращает InvalidArgument (HTTP 400).Поля ответа
user object
user, group или teamGroup.user.id строка
user_.user.email строка
user.displayName строка
user.handle строка
@. Присутствует, только пока профиль общедоступен; в остальных случаях не возвращается.group object
group.id строка
grp_.teamGroup object
teamGroup.kind строка
members, admins.permission строка
curl --request POST \ --url 'https://api.cursor.com/v1/origin/owners/OWNER_SLUG/grants' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "user": { "id": "user_01k2ja2000e0080000000000c3" }, "permission": "PERMISSION_WRITE"}'Структура ответа:
{ "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" }, "permission": "PERMISSION_WRITE"}Удаление права доступа к пространству имён
/v1/origin/owners/{ownerSlug}/grantsУдаляет право доступа, которым пользователь, группа или группа владеющей команды обладает непосредственно на уровне owner. Права доступа для репозитория не затрагиваются. Удаление права доступа, которым principal не обладает напрямую, завершается успешно и ничего не меняет, а удаление, после которого у owner не останется ни одного администратора, возвращает FailedPrecondition (HTTP 400). Тело ответа пустое.
Параметры пути
ownerSlug строка обязательный
Тело запроса
user object
user, group или teamGroup.user.id строка
user_.user.email строка
user.displayName строка
user.handle строка
@. Присутствует, только пока профиль виден публично; в остальных случаях отсутствует.group object
group.id строка
grp_.teamGroup object
teamGroup.kind строка
members, admins.Поля ответа
При успешном запросе тело ответа отсутствует.
curl --request DELETE \ --url 'https://api.cursor.com/v1/origin/owners/OWNER_SLUG/grants' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "group": { "id": "grp_01k2ja2000e0080000000000n2" }}'Ответ:
204 No ContentМетки
Определение метки принадлежит одному репозиторию и идентифицируется по имени. Назначение меток pull request — отдельная операция; см. Назначение меток pull request.
Список меток
/v1/origin/repos/{ownerSlug}/{repoName}/labelsВозвращает список меток, определённых в репозитории, отсортированный по имени.
Токены страниц привязаны к репозиторию, для которого они были выпущены. Повторное использование токена для другого репозитория, как и любой другой некорректный токен, приводит к ошибке InvalidArgument (HTTP 400).
Параметры пути
ownerSlug строка Обязательный
repoName строка Обязательный
Параметры запроса
pageSize целое число
pageToken строка
nextPageToken предыдущего ответа. Для первой страницы не указывайте.Поля ответа
labels array
labels[].id строка
labels[].name строка
labels[].color строка
#.labels[].description строка
nextPageToken строка
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/labels' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "labels": [ { "id": "lbl_01k2ja2000e0080000000000m1", "name": "bug", "color": "d73a4a", "description": "Something isn't working" } ]}Создать метку
/v1/origin/repos/{ownerSlug}/{repoName}/labelsСоздаёт метку в репозитории.
Если это имя уже используется другой меткой в репозитории, возвращается AlreadyExists (HTTP 409 Conflict). Если color содержит не шесть шестнадцатеричных символов, name длиннее 50 символов или description длиннее 255 символов, возвращается InvalidArgument (HTTP 400).
Параметры пути
ownerSlug строка Обязательный
repoName строка Обязательный
Тело запроса
name строка Обязательный
color строка Обязательный
#. Заглавные буквы во входных данных сохраняются в нижнем регистре.description строка
Поля ответа
id строка
name строка
color строка
#.description строка
curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/labels' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "name": "bug", "color": "d73a4a", "description": "Something isn'\''t working"}'Структура ответа:
{ "id": "lbl_01k2ja2000e0080000000000m1", "name": "bug", "color": "d73a4a", "description": "Something isn't working"}Получить метку
/v1/origin/repos/{ownerSlug}/{repoName}/labels/{labelName}Возвращает метку репозитория по имени.
Если имя неизвестно, возвращается 404. Если labelName пуст, возвращается InvalidArgument (HTTP 400).
Параметры пути
ownerSlug строка Обязательный
repoName строка Обязательный
labelName строка Обязательный
Поля ответа
id строка
name строка
color строка
#.description строка
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/labels/LABEL_NAME' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "id": "lbl_01k2ja2000e0080000000000m1", "name": "bug", "color": "d73a4a", "description": "Something isn't working"}Удаление метки
/v1/origin/repos/{ownerSlug}/{repoName}/labels/{labelName}Удаляет метку репозитория по имени. Тело ответа пустое.
При удалении метка также удаляется из всех pull request, которым она была назначена. Для неизвестного имени возвращается 404. Если labelName пуст, возвращается InvalidArgument (HTTP 400).
Параметры пути
ownerSlug строка Обязательно
repoName строка Обязательно
labelName строка Обязательно
Поля ответа
При успешном запросе тело ответа отсутствует.
curl --request DELETE \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/labels/LABEL_NAME' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Ответ:
204 No ContentОбновить метку
/v1/origin/repos/{ownerSlug}/{repoName}/labels/{labelName}Обновляет метку репозитория, указанную по её текущему имени.
Пропущенные поля остаются без изменений. Если не указано ни одно из трёх полей, запрос возвращает метку в текущем состоянии. Попытка переименовать метку в имя, уже используемое другой меткой, возвращает AlreadyExists (HTTP 409 Conflict). Если labelName неизвестен, возвращается 404.
Параметры пути
ownerSlug строка Обязательный
repoName строка Обязательный
labelName строка Обязательный
Тело запроса
name строка
color строка
#. Не указывайте, чтобы не изменять.description строка
Поля ответа
id строка
name строка
color строка
#.description строка
curl --request PATCH \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/labels/LABEL_NAME' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "color": "b60205"}'Структура ответа:
{ "id": "lbl_01k2ja2000e0080000000000m1", "name": "bug", "color": "b60205", "description": "Something isn't working"}Pull requests
Закрытые или смерженные pull request могут дополнительно включать closedAt, mergedAt и mergeCommitSha. Считайте head.ref и base.ref непрозрачными строками Git-ссылок Origin: это могут быть короткие имена веток или полные значения refs/heads/….
verdict ревью принимает значения approve, request_changes или comment. submittedAt отсутствует у неотправленного черновика ревью. dismissal отсутствует, пока вердикт активен. Отклонённые ревью остаются видимыми в списках ревью. Ревью, автоматически заменённые более новым решением, содержат сообщение, сгенерированное сервером.
Комментарии содержат ссылку на thread для группировки. При ответе запросы на создание комментария по-прежнему принимают скалярный параметр команды threadId. Разрешите или повторно откройте тред с помощью Обновление треда pull request.
Список пул-реквестов
/v1/origin/repos/{ownerSlug}/{repoName}/pullsВозвращает список pull request в репозитории с возможностью фильтрации по head-ветке, base-ветке, автору, диапазону времени создания и состоянию. Для каждого pull request указаны назначенные ему метки.
Результаты сортируются по порядку создания или по времени последнего обновления, выбираемому с помощью sortBy — сначала самые новые. Установите direction=asc для обратного порядка. Токены страниц встраивают информацию о сортировке и фильтрах, при которых они были созданы, поэтому токен, воспроизведённый с другой сортировкой или набором фильтров, отклоняется; при изменении любого из них перезапустите пагинацию.
Параметры пути
ownerSlug string Обязательно
repoName string Обязательно
Параметры запроса
head string
state string
open (по умолчанию), closed, merged, all. closed охватывает все pull request, которые больше не открыты, включая влитые; merged ограничивает выборку только влитыми. При любом другом значении возвращается InvalidArgument (HTTP 400).pageSize целое число
pageToken string
nextPageToken предыдущего ответа. Не указывайте его для первой страницы.author string
pullRequests[].author.user.id, pullRequests[].author.app.id или pullRequests[].author.serviceAccount.id (user_…, app_… или sa_…), либо точный адрес электронной почты пользователя. Сопоставление адресов электронной почты нечувствительно к регистру. У приложений и сервисных аккаунтов нет почтового адреса, поэтому таким образом можно выбрать только авторов-пользователей. Для автора без pull request'ов возвращается пустой список, как и в случае, если адрес электронной почты не соответствует ровно одному пользователю. Любое другое значение, включая общий идентификатор origin-cursor-managed-actor, возвращает InvalidArgument (HTTP 400).base string
main) или полностью квалифицированный ref (refs/heads/main). Оставьте пустым, чтобы вывести список по всем базам.direction string
sortBy. По умолчанию используется "desc": при sortBy=created сначала возвращаются недавно созданные, а при sortBy=updated — недавно обновлённые. "asc" меняет порядок на обратный. При любом другом значении возвращается InvalidArgument (HTTP 400).since string
2026-08-01T00:00:00Z. Возвращаются только pull request, созданные в этот момент или позже. Некорректная метка времени возвращает InvalidArgument (HTTP 400).until string
since. Возвращаются только pull request'ы, созданные в этот момент или ранее. Некорректная метка времени возвращает InvalidArgument (HTTP 400).sortBy строка
created (порядок создания, значение по умолчанию) или updated (время последнего обновления). При любом другом значении возвращается InvalidArgument (HTTP 400).Поля ответа
pullRequests массив
pullRequests[].id string
pullRequests[].number строка
pullRequests[].state string
pullRequests[].draft логическое значение
pullRequests[].merged boolean
pullRequests[].title string
pullRequests[].body string
pullRequests[].head object
pullRequests[].head.ref строка
pullRequests[].head.sha строка
pullRequests[].base object
pullRequests[].base.ref строка
pullRequests[].base.sha string
pullRequests[].author object
pullRequests[].author.user object
pullRequests[].author.user.id string
pullRequests[].author.user.email string
pullRequests[].author.user.displayName string
pullRequests[].author.user.handle string
@. Указывается только пока профиль общедоступен; в противном случае отсутствует.pullRequests[].author.app object
pullRequests[].author.app.id string
pullRequests[].author.app.displayName string
pullRequests[].author.serviceAccount object
pullRequests[].author.serviceAccount.id string
pullRequests[].createdAt string
pullRequests[].updatedAt string
pullRequests[].closedAt string
pullRequests[].mergedAt string
pullRequests[].mergeCommitSha string
pullRequests[].additions целое число
pullRequests[].deletions целое число
pullRequests[].changedFiles целое число
pullRequests[].labels массив
pullRequests[].labels[].id string
pullRequests[].labels[].name строка
pullRequests[].labels[].color string
#.pullRequests[].labels[].description string
pullRequests[].version object
pullRequests[].version.number строка
pullRequests[].version.headSha строка
pullRequests[].version.baseSha string
pullRequests[].version.createdAt string
nextPageToken string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "pullRequests": [ { "id": "pr_01k2ja2000e0080000000000d4", "number": "17", "state": "open", "draft": false, "merged": false, "title": "Add launch telemetry", "body": "Adds structured launch telemetry to the ignition path.", "head": { "ref": "add-telemetry", "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4" }, "base": { "ref": "main", "sha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" }, "author": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "additions": 128, "deletions": 46, "changedFiles": 5, "labels": [ { "id": "lbl_01k2ja2000e0080000000000m1", "name": "bug", "color": "d73a4a", "description": "Something isn't working" } ], "version": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8", "createdAt": "2026-08-01T09:30:00Z" } } ]}Получить Pull Request
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}Возвращает один pull request вместе с назначенными ему метками.
Закрытые или объединённые pull request'ы могут дополнительно включать closedAt, mergedAt и mergeCommitSha. Рассматривайте head.ref и base.ref как непрозрачные строки ref Origin; это могут быть короткие имена веток или полностью квалифицированные значения refs/heads/….
Параметры пути
ownerSlug string Обязательно
repoName string Обязательно
pullNumber string Обязательно
Поля ответа
id строка
number string
state string
draft boolean
merged boolean
title string
body string
head object
head.ref string
head.sha string
base object
base.ref string
base.sha string
author object
author.user object
author.user.id строка
author.user.email строка
author.user.displayName строка
author.user.handle строка
@. Присутствует только пока профиль общедоступен; в противном случае отсутствует.author.app object
author.app.id строка
author.app.displayName строка
author.serviceAccount object
author.serviceAccount.id string
createdAt string
updatedAt строка
closedAt строка
mergedAt string
mergeCommitSha string
additions целое число
deletions целое число
changedFiles целое число
labels массив
labels[].id строка
labels[].name строка
labels[].color строка
#.labels[].description строка
version object
version.number string
version.headSha строка
version.baseSha строка
version.createdAt string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "id": "pr_01k2ja2000e0080000000000d4", "number": "17", "state": "open", "draft": false, "merged": false, "title": "Add launch telemetry", "body": "Adds structured launch telemetry to the ignition path.", "head": { "ref": "add-telemetry", "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4" }, "base": { "ref": "main", "sha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" }, "author": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "additions": 128, "deletions": 46, "changedFiles": 5, "labels": [ { "id": "lbl_01k2ja2000e0080000000000m1", "name": "bug", "color": "d73a4a", "description": "Something isn't working" } ], "version": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8", "createdAt": "2026-08-01T09:30:00Z" }}Создать запрос на перенос (Pull Request)
/v1/origin/repos/{ownerSlug}/{repoName}/pullsСоздаёт pull request из head в base.
Необязательный параметр parent_pull_number помещает это изменение в стек поверх другого открытого или черновикового pull request в том же репозитории.
Если title длиннее 256 символов или body длиннее 65 536 символов, возвращается InvalidArgument (HTTP 400). Оба ограничения учитывают кодовые точки Unicode.
Если у head нет общей истории с base, возвращается InvalidArgument (HTTP 400) и ничего не создаётся. Если позже push приведёт к тому, что head открытого pull request перестанет иметь общую историю с его base, Origin закроет pull request и отправит pull_request.closed; последующий связанный push не откроет его снова.
Параметры пути
ownerSlug string Обязательно
repoName string Обязательно
Тело запроса
title string Обязательно
body строка
head string Обязательно
base string Обязательно
InvalidArgument (HTTP 400).draft boolean
parentPullNumber string
Поля ответа
id строка
number string
state строка
draft boolean
merged boolean
title строка
body строка
head object
head.ref строка
head.sha string
base object
base.ref строка
base.sha строка
author object
author.user object
author.user.id string
author.user.email string
author.user.displayName string
author.user.handle string
@. Присутствует только, пока этот профиль публично видим; в противном случае отсутствует.author.app object
author.app.id string
author.app.displayName string
author.serviceAccount object
author.serviceAccount.id строка
createdAt string
updatedAt строка
closedAt строка
mergedAt строка
mergeCommitSha string
additions целое число
deletions целое число
changedFiles целое число
labels массив
labels[].id строка
labels[].name string
labels[].color string
#.labels[].description строка
version object
version.number строка
version.headSha строка
version.baseSha string
version.createdAt строка
curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "title": "Add launch telemetry", "body": "Adds structured launch telemetry to the ignition path.", "head": "add-telemetry", "base": "main", "draft": false}'Структура ответа:
{ "id": "pr_01k2ja2000e0080000000000d4", "number": "17", "state": "open", "draft": false, "merged": false, "title": "Add launch telemetry", "body": "Adds structured launch telemetry to the ignition path.", "head": { "ref": "add-telemetry", "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4" }, "base": { "ref": "main", "sha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" }, "author": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "additions": 128, "deletions": 46, "changedFiles": 5, "labels": [ { "id": "lbl_01k2ja2000e0080000000000m1", "name": "bug", "color": "d73a4a", "description": "Something isn't working" } ], "version": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8", "createdAt": "2026-08-01T09:30:00Z" }}Обновить pull request
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}Обновляет заголовок, описание, базовую ветку и/или состояние жизненного цикла pull request'а.
Пропущенные поля остаются без изменений. Переданные поля применяются в следующем порядке: metadata, затем reopen/draft/ready-for-review, затем base, затем close. Операция close выполняется последней, поэтому смена целевой ветки в том же запросе всё ещё может увидеть открытое изменение; reopen выполняется до base, поэтому для закрытого pull request можно сменить целевую ветку. Если один из последующих шагов завершится ошибкой, предыдущие шаги уже могут быть применены.
Если длина title больше 256 символов или длина body больше 65 536 символов, возвращается InvalidArgument (HTTP 400). Оба ограничения считаются в кодовых точках Unicode.
Параметры пути
ownerSlug string Обязательно
repoName string Обязательно
pullNumber string Обязательное
Тело запроса
title string
body string
state строка
"open" или "closed". "closed" закрывает pull request. "open" без draft: true переводит его в состояние готовности к ревью, в том числе публикует существующий черновик. Состояние Merged нельзя изменить. Используйте MergePullRequest.draft boolean
true помечает pull request как черновик; false — как готовый к ревью (и повторно открывает его, если он закрыт). Игнорируется, когда state равно "closed".base строка
InvalidArgument (HTTP 400).Поля ответа
id string
number string
state строка
draft boolean
merged boolean
title string
body string
head объект
head.ref строка
head.sha string
base object
base.ref строка
base.sha string
author object
author.user object
author.user.id string
author.user.email string
author.user.displayName string
author.user.handle string
@. Присутствует, только пока этот профиль публично доступен; в остальных случаях отсутствует.author.app object
author.app.id string
author.app.displayName string
author.serviceAccount object
author.serviceAccount.id строка
createdAt string
updatedAt string
closedAt строка
mergedAt string
mergeCommitSha string
additions целое число
deletions целое число
changedFiles целое число
labels массив
labels[].id string
labels[].name string
labels[].color string
#.labels[].description строка
version object
version.number строка
version.headSha строка
version.baseSha string
version.createdAt string
curl --request PATCH \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "title": "Add launch telemetry", "body": "Adds structured launch telemetry to the ignition path.", "state": "open", "draft": false, "base": "main"}'Структура ответа:
{ "id": "pr_01k2ja2000e0080000000000d4", "number": "17", "state": "open", "draft": false, "merged": false, "title": "Add launch telemetry", "body": "Adds structured launch telemetry to the ignition path.", "head": { "ref": "add-telemetry", "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4" }, "base": { "ref": "main", "sha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" }, "author": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "additions": 128, "deletions": 46, "changedFiles": 5, "labels": [ { "id": "lbl_01k2ja2000e0080000000000m1", "name": "bug", "color": "d73a4a", "description": "Something isn't working" } ], "version": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8", "createdAt": "2026-08-01T09:30:00Z" }}Список комментариев к pull request
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/commentsПеречисляет все комментарии к pull request в хронологическом порядке, при необходимости ограничивая выборку окном по времени создания. Каждый комментарий содержит полный тред: идентификатор, привязку к диффу и статус разрешения. Группируйте плоский ответ по thread.id без дополнительного запроса.
Токены страниц содержат фильтры, с которыми они были выпущены, поэтому токен, повторно использованный с другими фильтрами, будет отклонён; при изменении фильтра начните пагинацию заново.
Параметры пути
ownerSlug string Обязательно
repoName string Обязательно
pullNumber string Обязательно
Параметры запроса
pageSize целое число
pageToken строка
nextPageToken предыдущего ответа. Для первой страницы не указывайте.since string
2026-08-01T00:00:00Z. Возвращаются только комментарии, созданные в этот момент или позже. При некорректной метке времени возвращается InvalidArgument (HTTP 400).until string
since. Возвращаются только комментарии, созданные в этот момент или ранее. При неверном формате метки времени возвращается ошибка InvalidArgument (HTTP 400).threadIds массив
InvalidArgument (HTTP 400).Поля ответа
comments массив
comments[].id string
comments[].thread object
comments[].thread.id string
comments[].thread.version object
comments[].thread.version.number строка
comments[].thread.version.headSha строка
comments[].thread.version.baseSha строка
comments[].thread.version.createdAt string
comments[].thread.path строка
comments[].thread.side строка
left, right. Не задано для веток общего обсуждения.comments[].thread.startLine целое число
side. 0 — для веток уровня файла и общих обсуждений.comments[].thread.endLine целое число
0, если якорь состоит из одной строки или не имеет диапазона строк.comments[].thread.resolvedAt string
comments[].thread.createdAt string
comments[].thread.updatedAt строка
comments[].body string
comments[].author object
comments[].author.user object
comments[].author.user.id строка
comments[].author.user.email string
comments[].author.user.displayName строка
comments[].author.user.handle string
@. Присутствует только пока профиль общедоступен; в противном случае отсутствует.comments[].author.app object
comments[].author.app.id строка
comments[].author.app.displayName строка
comments[].author.serviceAccount object
comments[].author.serviceAccount.id строка
comments[].createdAt string
comments[].updatedAt строка
pullRequest object
pullRequest.id строка
pullRequest.number строка
pullRequest.repository объект
pullRequest.repository.id string
pullRequest.repository.name string
pullRequest.repository.owner object
pullRequest.repository.owner.slug строка
pullRequest.repository.owner.id строка
pullRequest.repository.owner.type строка
team, user. Не указывается, если неизвестно.nextPageToken string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/comments' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "comments": [ { "id": "cmt_01k2ja2000e0080000000000e5", "thread": { "id": "cth_01k2ja2000e0080000000000s6", "version": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8", "createdAt": "2026-08-01T09:30:00Z" }, "path": "src/telemetry/retry.ts", "side": "right", "startLine": 42, "endLine": 45, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z" }, "body": "Should the retry budget be configurable?", "author": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z" } ], "pullRequest": { "id": "pr_01k2ja2000e0080000000000d4", "number": "17", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } } }}Получить комментарий к pull request
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/comments/{commentId}Возвращает один комментарий к pull request по его стабильному идентификатору Origin. Комментарий за пределами авторизованного репозитория или комментарий из ожидающего рассмотрения ревью, недоступный вызывающей стороне, возвращает 404.
Параметры пути
ownerSlug string Обязательный
repoName string Обязательно
commentId string Обязательно
Поля ответа
id string
thread object
thread.id string
thread.version object
thread.version.number string
thread.version.headSha string
thread.version.baseSha string
thread.version.createdAt string
thread.path string
thread.side string
left, right. Не задано для тредов общего обсуждения.thread.startLine integer
side. 0 — для тредов на уровне файла и общего обсуждения.thread.endLine integer
0, если якорь — одна строка или не имеет диапазона строк.thread.resolvedAt string
thread.createdAt string
thread.updatedAt string
body string
author object
author.user object
author.user.id string
author.user.email string
author.user.displayName string
author.user.handle string
@. Указывается только пока этот профиль публично виден; иначе не указывается.author.app object
author.app.id string
author.app.displayName string
author.serviceAccount object
author.serviceAccount.id string
createdAt string
updatedAt string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/comments/COMMENT_ID' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "id": "cmt_01k2ja2000e0080000000000e5", "thread": { "id": "cth_01k2ja2000e0080000000000s6", "version": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8", "createdAt": "2026-08-01T09:30:00Z" }, "path": "src/telemetry/retry.ts", "side": "right", "startLine": 42, "endLine": 45, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z" }, "body": "Should the retry budget be configurable?", "author": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z"}Создать комментарий к pull request
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/commentsСоздаёт комментарий к Origin pull request. Комментарий относится ровно к одному из четырёх вариантов: threadId отвечает в существующем треде — как для общего обсуждения, так и для inline; inline создаёт новый тред, привязанный к диапазону строк в диффе версии pull request; file создаёт новый тред для всего файла в этом диффе; если не указано ни одно из них, создаётся новый тред общего обсуждения. Тела длиной более 65 536 символов отклоняются с ошибкой InvalidArgument (HTTP 400).
Привязка inline должна ссылаться на дифф версии. path должен быть частью этого диффа, и на указанной side должно быть содержимое, поэтому привязка left к добавленному файлу или right к удалённому файлу отклоняется с ошибкой InvalidArgument (HTTP 400). Любая строка изменённого файла может быть якорем, и диапазон не ограничен хунками диффа. Диапазон должен укладываться в файл на привязанной стороне: left читается на base-коммите, а right — на head; диапазон, выходящий за последнюю строку, отклоняется с ошибкой InvalidArgument (HTTP 400). Origin никогда не переходит на комментарий общего обсуждения, когда якорь недействителен.
Якорь file содержит только путь. Origin определяет сторону по типу изменения файла: для удалённого файла — base-версию, в остальных случаях — head-версию, и возвращает её в thread.side. Для удаления отправляйте путь удалённого файла, для любого другого изменения — путь из head-версии. Путь, выходящий за пределы диффа, отклоняется с ошибкой InvalidArgument (HTTP 400), как и исходный путь переименованного файла до переименования.
Параметры пути
ownerSlug строка Обязательно
repoName string Обязательно
pullNumber строка Обязательно
Тело запроса
body string Обязательно
threadId string
versionNumber.inline object
threadId.inline.path строка Обязательно
inline.side string Обязательно
left — для базовой версии файла, right — для head-версии.inline.startLine целое число Обязательно
inline.endLine целое число
startLine. Не указывать для однострочного якоря.file object
threadId или inline.file.path string Обязательно
versionNumber string
0 или отсутствие значения означает последнюю версию на момент вызова. Имеет значение только для новых тредов.Поля ответа
id string
thread object
thread.id string
thread.version object
thread.version.number строка
thread.version.headSha string
thread.version.baseSha строка
thread.version.createdAt string
thread.path строка
thread.side string
left, right. Не задано для тредов общего обсуждения.thread.startLine целое число
side. 0 — для тредов на уровне файла и общего обсуждения.thread.endLine целое число
0, если якорь находится в одной строке или не имеет диапазона строк.thread.resolvedAt строка
thread.createdAt string
thread.updatedAt строка
body string
author object
author.user object
author.user.id string
author.user.email string
author.user.displayName string
author.user.handle строка
@. Указывается только когда профиль общедоступен; в противном случае опускается.author.app object
author.app.id string
author.app.displayName string
author.serviceAccount object
author.serviceAccount.id string
createdAt string
updatedAt string
curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/comments' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "body": "Should the retry budget be configurable?"}'Структура ответа:
{ "id": "cmt_01k2ja2000e0080000000000e5", "thread": { "id": "cth_01k2ja2000e0080000000000s6", "version": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8", "createdAt": "2026-08-01T09:30:00Z" }, "path": "src/telemetry/retry.ts", "side": "right", "startLine": 42, "endLine": 45, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z" }, "body": "Should the retry budget be configurable?", "author": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z"}Обновить комментарий к pull request
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/comments/{commentId}Обновляет комментарий к pull request по его стабильному идентификатору Origin.
Заменяет текст комментария. Комментарий должен принадлежать репозиторию, указанному в пути, быть видимым для вызывающего и быть создан этим же вызывающим. Комментарии из другого репозитория и скрытые комментарии в статусе ожидания ревью возвращают 404; видимый комментарий, принадлежащий другому участнику, возвращает 403. Тела длиной более 65 536 символов отклоняются с ошибкой InvalidArgument (HTTP 400).
Параметры пути
ownerSlug строка Обязательно
repoName string Обязательно
commentId string Обязательно
Тело запроса
body string Обязательно
Поля ответа
id string
thread object
thread.id string
thread.version object
thread.version.number string
thread.version.headSha строка
thread.version.baseSha string
thread.version.createdAt строка
thread.path строка
thread.side строка
left, right. Не задано для тредов общего обсуждения.thread.startLine целое число
side. 0 — для тредов на уровне файла и общих обсуждений.thread.endLine целое число
0, если привязка состоит из одной строки или не имеет диапазона строк.thread.resolvedAt строка
thread.createdAt string
thread.updatedAt string
body string
author object
author.user object
author.user.id string
author.user.email string
author.user.displayName string
author.user.handle строка
@. Указывается только пока профиль общедоступен; в противном случае отсутствует.author.app object
author.app.id string
author.app.displayName string
author.serviceAccount object
author.serviceAccount.id string
createdAt string
updatedAt string
curl --request PATCH \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/comments/COMMENT_ID' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "body": "Should the retry budget be configurable?"}'Структура ответа:
{ "id": "cmt_01k2ja2000e0080000000000e5", "thread": { "id": "cth_01k2ja2000e0080000000000s6", "version": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8", "createdAt": "2026-08-01T09:30:00Z" }, "path": "src/telemetry/retry.ts", "side": "right", "startLine": 42, "endLine": 45, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z" }, "body": "Should the retry budget be configurable?", "author": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z"}Обновление треда Pull Request
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/threads/{threadId}Разрешает или повторно открывает поток комментариев запроса на вытягивание и возвращает его обновлённое состояние. Попытка разрешить уже разрешённый поток или повторно открыть уже открытый не выполняет никаких действий.
Тред должен принадлежать репозиторию, указанному в пути; для треда, хранящегося в другом репозитории, возвращается 404. Отвечать в разрешённом треде с помощью Create Pull Request Comment разрешено — это не открывает его заново.
Параметры пути
ownerSlug string Обязательное
repoName string Обязательное
threadId string Обязательный
Тело запроса
resolved boolean Обязательное
true закрывает тред; false снова открывает его.Поля ответа
id string
version object
version.number string
version.headSha строка
version.baseSha string
version.createdAt string
path string
side string
left, right. Не задаётся для тредов общего обсуждения.startLine целое число
side. 0 — для тредов уровня файла и общих обсуждений.endLine целое число
0, если якорь указывает на одну строку или не задаёт диапазон строк.resolvedAt string
createdAt string
updatedAt string
curl --request PATCH \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/threads/THREAD_ID' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "resolved": true}'Структура ответа:
{ "id": "cth_01k2ja2000e0080000000000s6", "version": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8", "createdAt": "2026-08-01T09:30:00Z" }, "path": "src/telemetry/retry.ts", "side": "right", "startLine": 42, "endLine": 45, "resolvedAt": "2026-08-03T10:00:00Z", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-03T10:00:00Z"}Список коммитов в pull request
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/commitsВозвращает список коммитов в pull request.
Возвращает коммиты pull request в виде упрощённых объектов Commit (без stats). По умолчанию возвращается 30 результатов, максимум — 100, при этом всего доступно не более 250 коммитов. Токен страницы фиксирует версию pull request, размер страницы и курсор коммитов; в последующих запросах pageSize должен совпадать со значением в токене, а токен, который больше не соответствует текущим head или base, возвращает 400.
Параметры пути
ownerSlug string Обязательно
repoName string Обязательно
pullNumber string Обязательно
Параметры запроса
pageSize целое число
pageToken string
next_page_token предыдущего ответа. Пустой для первой страницы. Токен привязан к репозиторию, версии pull request, размеру страницы и смещению коммита.Поля ответа
commits массив
commits[].sha string
commits[].commit object
commits[].commit.author object
commits[].commit.author.name string
commits[].commit.author.email string
commits[].commit.author.date string
commits[].commit.committer object
commits[].commit.committer.name string
commits[].commit.committer.email string
commits[].commit.committer.date string
commits[].commit.message string
commits[].commit.tree object
commits[].commit.tree.sha string
commits[].parents массив
commits[].parents[].sha string
nextPageToken string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/commits' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "commits": [ { "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "commit": { "author": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "committer": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "message": "Add launch telemetry", "tree": { "sha": "a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b8" } }, "parents": [ { "sha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" } ], "stats": { "additions": 128, "deletions": 46, "total": 174 } } ]}Список файлов pull request
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/filesВозвращает список файлов, изменённых в pull request.
Возвращает имя файла, статус, количество строк, патч и необязательное предыдущее имя файла. По умолчанию возвращается 30 файлов, максимум — 100. Токен страницы фиксирует версию pull request, размер страницы и курсор файла; в последующих запросах pageSize должен совпадать с токеном, а токен, который больше не соответствует текущей head-ветке или base-ветке, возвращает 400.
Параметры пути
ownerSlug string Обязательное
repoName string Обязательно
pullNumber string Обязательное
Параметры запроса
pageSize integer
pageToken string
next_page_token предыдущего ответа. Для первой страницы пуст. Токен привязан к репозиторию, версии pull request, размеру страницы и курсору изменённых файлов.Поля ответа
files массив
files[].filename string
files[].status string
files[].additions integer
files[].deletions integer
files[].changes integer
files[].patch string
files[].previousFilename string
nextPageToken string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/files' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "files": [ { "filename": "src/telemetry.ts", "status": "modified", "additions": 6, "deletions": 3, "changes": 9, "patch": "@@ -12,6 +12,9 @@\n import { ignite } from \"./ignition\";\n+import { emitLaunchTelemetry } from \"./telemetry\";\n" } ]}Список меток pull request
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/labelsВозвращает все метки, назначенные pull request, отсортированные по имени.
Ответ содержит полный список назначенных меток, а не его страницу, поэтому эта конечная точка не принимает параметры пагинации. Pull request может иметь не более 100 меток. Если pull request не найден, возвращается 404.
Параметры пути
ownerSlug string Обязательный
repoName string Обязательный
pullNumber string Обязательный
Поля ответа
labels array
labels[].id string
labels[].name string
labels[].color string
#.labels[].description string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/labels' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "labels": [ { "id": "lbl_01k2ja2000e0080000000000m1", "name": "bug", "color": "d73a4a", "description": "Something isn't working" } ]}Задать метки pull request
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/labelsЗаменяет все метки pull request указанными метками.
Пустой список удаляет все назначенные метки. Метки должны уже существовать в репозитории; неизвестное имя метки или неизвестный pull request возвращает 404. К pull request можно назначить не более 100 меток, поэтому при указании более 100 возвращается FailedPrecondition (HTTP 400). В ответе возвращается список меток, назначенных после замены, отсортированный по имени.
Параметры пути
ownerSlug string Обязательный
repoName string Обязательный
pullNumber string Обязательный
Тело запроса
labels array
Поля ответа
labels array
id, name, color и description.curl --request PUT \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/labels' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "labels": [ "bug" ]}'Структура ответа:
{ "labels": [ { "id": "lbl_01k2ja2000e0080000000000m1", "name": "bug", "color": "d73a4a", "description": "Something isn't working" } ]}Добавление меток к pull request
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/labelsДобавляет к pull request существующие метки репозитория.
Метки, уже назначенные pull request, сохраняются. Метки должны уже существовать в репозитории; при неизвестном имени или неизвестном pull request возвращается 404. В запросе необходимо указать от 1 до 100 меток, а pull request может иметь в общей сложности не более 100 меток, поэтому запрос, который превысит этот лимит, вернёт FailedPrecondition (HTTP 400). Ответ содержит только указанные вами метки, а не полный набор меток pull request; чтобы получить полный набор, используйте Список меток pull request.
Параметры пути
ownerSlug string Обязательный
repoName string Обязательный
pullNumber string Обязательный
Тело запроса
labels array Обязательный
Поля ответа
labels array
id, name, color и description.curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/labels' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "labels": [ "bug" ]}'Структура ответа:
{ "labels": [ { "id": "lbl_01k2ja2000e0080000000000m1", "name": "bug", "color": "d73a4a", "description": "Something isn't working" } ]}Удалить все метки pull request
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/labelsУдаляет все метки у pull request.
Запрос выполняется успешно, если у pull request нет меток. Если pull request не найден, возвращается 404. Тело ответа пустое.
Параметры пути
ownerSlug string Обязательный
repoName string Обязательный
pullNumber string Обязательный
Поля ответа
При успешном запросе тело ответа отсутствует.
curl --request DELETE \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/labels' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Ответ:
204 No ContentУдалить метку pull request
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/labels/{labelName}Удаляет метку из pull request.
Если метка не назначена pull request, как и если pull request не существует, возвращается 404. В ответе перечислены оставшиеся метки pull request, отсортированные по имени.
Параметры пути
ownerSlug string Обязательный
repoName string Обязательный
pullNumber string Обязательный
labelName string Обязательный
Поля ответа
labels array
id, name, color и description.curl --request DELETE \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/labels/LABEL_NAME' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "labels": [ { "id": "lbl_01k2ja2000e0080000000000m1", "name": "bug", "color": "d73a4a", "description": "Something isn't working" } ]}Слияние Pull Request
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/mergeВыполняет слияние pull request в базовую ветку.
Для pull request в stack выполняет merge всего префикса от root до target, заканчивающегося на этом номере. а не только этого pull request. Поддерживается только для нативных репозиториев Origin; зеркалируемые репозитории отклоняются.
Параметры пути
ownerSlug string Обязательный
repoName string Обязательное
pullNumber string Обязательно
Тело запроса
expectedHeadSha строка
ABORTED (HTTP 409 Conflict) и ничего не сливается. Значения, не являющиеся полным SHA коммита, отклоняются с кодом InvalidArgument (HTTP 400). Опустите параметр, чтобы слить то, что является текущим head. Не проверяется, если pull request уже слит — в этом случае возвращается идемпотентный успешный ответ.mergeMethod строка
merge — создаёт merge-коммит, и squash — создаёт один squash-коммит. Метод, который репозиторий не разрешает, отклоняется с ошибкой FailedPrecondition (HTTP 400), а любое другое значение — с InvalidArgument (HTTP 400). Пропустите этот параметр, чтобы использовать значение по умолчанию для репозитория: merge-коммит, если репозиторий его разрешает, иначе squash; squash также применяется, если base-ветка требует линейной истории.Поля ответа
mergeCommitSha string
mergedPullNumbers массив
pullRequest object
pullRequest.id строка
pullRequest.number строка
pullRequest.state строка
pullRequest.draft boolean
pullRequest.merged boolean
pullRequest.title string
pullRequest.body string
pullRequest.head object
pullRequest.head.ref string
pullRequest.head.sha строка
pullRequest.base object
pullRequest.base.ref строка
pullRequest.base.sha строка
pullRequest.author object
pullRequest.author.user object
pullRequest.author.user.id строка
pullRequest.author.user.email string
pullRequest.author.user.displayName строка
pullRequest.author.user.handle строка
@. Присутствует только когда профиль общедоступен; в противном случае отсутствует.pullRequest.author.app object
pullRequest.author.app.id строка
pullRequest.author.app.displayName строка
pullRequest.author.serviceAccount object
pullRequest.author.serviceAccount.id string
pullRequest.createdAt string
pullRequest.updatedAt string
pullRequest.closedAt строка
pullRequest.mergedAt string
pullRequest.mergeCommitSha string
pullRequest.additions целое число
pullRequest.deletions целое число
pullRequest.changedFiles целое число
pullRequest.labels массив
pullRequest.labels[].id string
pullRequest.labels[].name строка
pullRequest.labels[].color string
#.pullRequest.labels[].description string
pullRequest.version object
pullRequest.version.number string
pullRequest.version.headSha string
pullRequest.version.baseSha строка
pullRequest.version.createdAt строка
curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/merge' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "expectedHeadSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "mergeMethod": "squash"}'Структура ответа:
{ "mergeCommitSha": "5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7c6d", "mergedPullNumbers": [ "17" ], "pullRequest": { "id": "pr_01k2ja2000e0080000000000d4", "number": "17", "state": "closed", "draft": false, "merged": true, "title": "Add launch telemetry", "body": "Adds structured launch telemetry to the ignition path.", "head": { "ref": "add-telemetry", "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4" }, "base": { "ref": "main", "sha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" }, "author": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "closedAt": "2026-08-03T10:15:00Z", "mergedAt": "2026-08-03T10:15:00Z", "mergeCommitSha": "5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7c6d", "additions": 128, "deletions": 46, "changedFiles": 5, "labels": [ { "id": "lbl_01k2ja2000e0080000000000m1", "name": "bug", "color": "d73a4a", "description": "Something isn't working" } ], "version": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8", "createdAt": "2026-08-01T09:30:00Z" } }}Получение сведений о возможности слияния pull request
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/mergeabilityВозвращает, можно ли объединить pull request и, если нельзя — какие условия этому препятствуют. Вердикт оценивается по тем же условиям, которые применяет Merge Pull Request, поэтому вердикт mergeable означает, что объединение для той же ветки head должно завершиться успешно. Для составного (stacked) pull request вердикт охватывает все pull request от корня стека до текущего, и каждый блокер указывает, к какому pull request он относится.
Для stack, содержащего в сумме более 200 pull request, включая уже смерженных предшественников, возвращается FailedPrecondition (HTTP 400).
Эта операция находится в предварительном просмотре, и её структура может измениться, пока контракт уточняется. Декодируйте ответы, допуская неизвестные поля и неизвестные значения перечислений; считайте нераспознанный verdict как blocked и отображайте blockers[].message, если не распознаёте blockers[].kind.
Параметры пути
ownerSlug строка Обязательный
repoName строка Обязательный
pullNumber строка Обязательный
Параметры запроса
expectedHeadSha строка
Aborted (HTTP 409 Conflict) вместо результата. Значение, которое не является полным SHA коммита, возвращает InvalidArgument (HTTP 400).Поля ответа
pullRequest object
pullRequest.id строка
pullRequest.number строка
pullRequest.repository object
pullRequest.repository.id строка
pullRequest.repository.name строка
pullRequest.repository.owner object
pullRequest.repository.owner.slug строка
pullRequest.repository.owner.id строка
pullRequest.repository.owner.type строка
team, user. Пропускается, если неизвестно.verdict строка
evaluatedPullRequests. Допустимые значения: mergeable — слияние pullRequest приводит к слиянию всех pull request — и blocked. Нераспознанное значение считайте blocked.blockers массив
verdict равен mergeable. Не более одного blocker на pull request для каждого вида, кроме required_checks — по одному на каждый state, а также rule_failure и ruleset_error — по одному на каждое отдельное message.blockers[].pullRequest object
evaluatedPullRequests, к которому относится этот блокировщик. Содержит те же поля, что и pullRequest.blockers[].kind строка
draft, closed, merged, merge_conflict, required_checks, required_approvals, codeowner_approval, behind_base, needs_restack, restack_pending, conflict_check_pending, invalid_stack, ruleset_error, rule_failure. Новые виды добавляются со временем; блокер, вид которого появился позже вашей версии клиента, декодируется с незаданным kind, но по-прежнему блокирует.blockers[].message строка
kind не распознано.blockers[].requiredChecks object
required_checks.blockers[].requiredChecks.state строка
missing, pending, failing, action_required.blockers[].requiredChecks.checks массив
blockers[].requiredChecks.checks[].name строка
blockers[].requiredChecks.checks[].owner object
actor, что и у actor при запуске проверки.blockers[].requiredChecks.checks[].checkRun object
headSha, соответствующий этому требованию, в виде ссылки. Опускается, если ни один не был зарегистрирован — это состояние missing. Содержит только id, name и checkSuite.id, поскольку для чтения этой операции достаточно repository:pull_requests:read, тогда как для статуса, заключения, выходных данных и URL с подробностями запуска требуется repository:checks:read; их можно получить через Получить запуск проверки.blockers[].requiredApprovals object
required_approvals.blockers[].requiredApprovals.requiredCount integer
blockers[].requiredApprovals.approvedCount integer
blockers[].codeownerApproval object
codeowner_approval.blockers[].codeownerApproval.requirements массив
blockers[].codeownerApproval.requirements[].owners массив
blockers[].codeownerApproval.requirements[].paths массив
blockers[].mergeConflict object
merge_conflict.blockers[].mergeConflict.conflictedPaths массив
blockers[].mergeConflict.truncated логическое значение
blockers[].mergeConflict.inheritedFromDownstack boolean
blockers[].stackShape object
invalid_stack.blockers[].stackShape.reason строка
partially_merged, cycle, missing_parent, cross_repository_parent, base_branch_missing.blockers[].stackShape.relatedPullRequests массив
pullRequest.evaluatedPullRequests массив
pullRequest: сначала root стека, последним — сам pullRequest. Предшествующие изменения, уже прошедшие merge, относятся к history и не перечисляются. Для pull request'а вне стека — ровно один element. Каждый содержит те же fields, что и pullRequest.headSha строка
pullRequest, прошедший оценку.baseRef строка
baseSha строка
baseRef на момент evaluatedAt. Последующий пуш в baseRef может изменить вердикт. Пусто, если базовую ветку не удалось определить, например при некорректном стеке.evaluatedAt строка
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/mergeability' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'{ "pullRequest": { "id": "pr_01k2ja2000e0080000000000d4", "number": "17", "repository": { "id": "repo_01k2ja2000e0080000000000a1", "name": "launch-control", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000b2" } } }, "verdict": "blocked", "blockers": [ { "pullRequest": { "id": "pr_01k2ja2000e0080000000000d4", "number": "17", "repository": { "id": "repo_01k2ja2000e0080000000000a1", "name": "launch-control", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000b2" } } }, "kind": "required_approvals", "message": "Количество одобряющих ревью: 0; требуется: 1. Запросите ревью и дождитесь необходимого одобрения.", "requiredApprovals": { "requiredCount": 1, "approvedCount": 0 } }, { "pullRequest": { "id": "pr_01k2ja2000e0080000000000d4", "number": "17", "repository": { "id": "repo_01k2ja2000e0080000000000a1", "name": "launch-control", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000b2" } } }, "kind": "required_checks", "message": "Обязательные проверки статуса ещё выполняются. Дождитесь завершения проверок или исправьте неуспешные проверки.", "requiredChecks": { "state": "pending", "checks": [ { "name": "ci / build", "owner": { "app": { "id": "app_01k2ja2000e0080000000000e5", "displayName": "Launch CI" } }, "checkRun": { "id": "cr_01k2ja2000e0080000000000f6", "name": "ci / build", "checkSuite": { "id": "crg_01k2ja2000e0080000000000f7" } } } ] } } ], "evaluatedPullRequests": [ { "id": "pr_01k2ja2000e0080000000000d4", "number": "17", "repository": { "id": "repo_01k2ja2000e0080000000000a1", "name": "launch-control", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000b2" } } } ], "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseRef": "main", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8", "evaluatedAt": "2026-08-02T14:45:00Z"}Список запрошенных ревьюеров pull request
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/requested_reviewersВозвращает пользователей и группы, у которых сейчас запрошено ревью pull request.
Прямой запрос снимается, когда этот пользователь отправляет ревью, а запрос к группе — когда ревью отправляет любой текущий участник группы. Неотправленные черновики ревью оставляют запрос в ожидании, а повторный запрос ревью после отправки возвращает ревьюера в этот список. Группы без читаемого публичного идентификатора не включаются.
Параметры пути
ownerSlug string Обязательный
repoName string Обязательный
pullNumber string Обязательный
Поля ответа
users array
users[].id string
user_…) в том же формате, который использует API организации.users[].email string
users[].displayName string
users[].handle string
@. Присутствует только пока этот профиль виден публично; иначе не включается.groups array
groups[].id string
grp_…).curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/requested_reviewers' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "users": [ { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } ], "groups": [ { "id": "grp_01k2ja2000e0080000000000n2" } ]}Запрос ревьюеров pull request
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/requested_reviewersЗапрашивает ревью у указанных пользователей и групп по pull request и возвращает ревьюеров, запрошенных этим вызовом.
Идентификаторы сопоставляются с кандидатами в ревьюеры репозитория по публичному идентификатору, электронной почте пользователя или слагу группы. Отображаемые имена не сопоставляются. Неизвестный или неоднозначный идентификатор возвращает ошибку InvalidArgument (HTTP 400) с указанием этого идентификатора, и требуется как минимум одна непустая запись в полях users или groups.
Повторный запрос уже запрошенного ревьюера обновляет отметку времени запроса, поэтому ревьюер, уже отправивший ревью, снова становится ожидающим. Если ревьюер не является кандидатом для репозитория, возвращается PermissionDenied (HTTP 403).
Параметры пути
ownerSlug string Обязательное
repoName string Обязательное
pullNumber string Обязательное
Тело запроса
users array
user_… или адресу электронной почты.groups array
grp_…, квалифицированному слагу группы или слагу группы.Поля ответа
users array
users[].id string
user_…), тот же формат, который использует API организации.users[].email string
users[].displayName string
users[].handle string
@. Указывается только пока профиль общедоступен; в противном случае опускается.groups array
groups[].id string
grp_…).curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/requested_reviewers' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "users": [ "user_01k2ja2000e0080000000000c3" ], "groups": [ "grp_01k2ja2000e0080000000000n2" ]}'Структура ответа:
{ "users": [ { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } ], "groups": [ { "id": "grp_01k2ja2000e0080000000000n2" } ]}Удаление запрошенных ревьюеров pull request
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/requested_reviewersОтменяет запросы на ревью для указанных пользователей и групп в pull request. Тело ответа пустое.
Идентификаторы сопоставляются с кандидатами в ревьюеры репозитория по публичному идентификатору, email пользователя или слагу группы. Отображаемые имена не сопоставляются. Неизвестный или неоднозначный идентификатор приводит к ошибке InvalidArgument (HTTP 400) с указанием этого идентификатора; в полях users и groups должна быть хотя бы одна непустая запись.
Удаление пользователя или группы, у которых ревью не запрошено, ничего не меняет. Идентификатор, который больше не является кандидатом в ревьюеры, всё равно принимается, если это стабильный публичный идентификатор (user_… или grp_…), поэтому ревьюера, покинувшего репозиторий, можно удалить.
Параметры пути
ownerSlug string Обязательный
repoName string Обязательный
pullNumber string Обязательный
Тело запроса
users array
user_… или email.groups array
grp_…, полному слагу группы или слагу группы.Поля ответа
Успешные запросы не возвращают тело ответа.
curl --request DELETE \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/requested_reviewers' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "users": [ "user_01k2ja2000e0080000000000c3" ], "groups": [ "grp_01k2ja2000e0080000000000n2" ]}'Ответ:
204 No ContentСписок ревью pull request
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/reviewsВозвращает отправленные ревью для pull request, отсортированные по submitted_at в порядке возрастания. Незавершённые ревью не включаются.
Параметры пути
ownerSlug string Обязательно
repoName string Обязательно
pullNumber string Обязательное
Параметры запроса
pageSize целое число
pageToken строка
nextPageToken предыдущего ответа. Не указывайте его для первой страницы.Поля ответа
reviews массив
reviews[].id string
reviews[].author object
reviews[].author.user object
reviews[].author.user.id string
reviews[].author.user.email string
reviews[].author.user.displayName string
reviews[].author.user.handle string
@. Присутствует только пока профиль общедоступен; в противном случае отсутствует.reviews[].author.app object
reviews[].author.app.id строка
reviews[].author.app.displayName string
reviews[].author.serviceAccount object
reviews[].author.serviceAccount.id string
reviews[].verdict string
reviews[].body string
reviews[].submittedAt string
reviews[].pullRequestVersion object
reviews[].pullRequestVersion.number строка
reviews[].pullRequestVersion.headSha строка
reviews[].pullRequestVersion.baseSha string
reviews[].pullRequestVersion.createdAt строка
reviews[].dismissal object
reviews[].dismissal.dismissedBy object
reviews[].dismissal.dismissedBy.user object
reviews[].dismissal.dismissedBy.user.id строка
reviews[].dismissal.dismissedBy.user.email string
reviews[].dismissal.dismissedBy.user.displayName строка
reviews[].dismissal.dismissedBy.user.handle string
@. Указывается только если профиль общедоступен; в противном случае отсутствует.reviews[].dismissal.dismissedBy.app object
reviews[].dismissal.dismissedBy.app.id string
reviews[].dismissal.dismissedBy.app.displayName string
reviews[].dismissal.dismissedBy.serviceAccount object
reviews[].dismissal.dismissedBy.serviceAccount.id string
reviews[].dismissal.dismissedAt string
reviews[].dismissal.message string
pullRequest object
pullRequest.id строка
pullRequest.number строка
pullRequest.repository объект
pullRequest.repository.id string
pullRequest.repository.name строка
pullRequest.repository.owner object
pullRequest.repository.owner.slug string
pullRequest.repository.owner.id строка
pullRequest.repository.owner.type строка
team, user. Не указывается, если неизвестно.nextPageToken string
curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/reviews' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "reviews": [ { "id": "rev_01k2ja2000e0080000000000f6", "author": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "verdict": "approve", "body": "Approving. The telemetry schema matches the spec.", "submittedAt": "2026-08-02T15:00:00Z", "pullRequestVersion": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8", "createdAt": "2026-08-01T09:30:00Z" } } ], "pullRequest": { "id": "pr_01k2ja2000e0080000000000d4", "number": "17", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } } }}Создать обзор Pull Request
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/reviewsСоздаёт и отправляет ревью pull request, при необходимости вместе с комментариями одним атомарным запросом. Для каждого комментария доступны те же варианты привязки, что и в Создать комментарий к Pull Request: comments[].inline для диапазона строк, comments[].file для всего файла, comments[].threadId для ответа или ни один из них для общего обсуждения.
Ревью отправляется сразу. Новое ревью approve или request_changes заменяет предыдущее активное решение вызывающего для того же pull request, которое при этом отклоняется. Авторы pull request не могут approve собственный pull request. Операция завершается с ошибкой FAILED_PRECONDITION, если у вызывающего есть неотправленное черновое ревью для этого pull request.
Если задан параметр comments, каждый якорь проверяется по диффу проверяемой версии перед записью, с использованием той же проверки в диффе, что и в Create Pull Request Comment. Если один комментарий не проходит проверку, весь запрос завершается с ошибкой InvalidArgument (HTTP 400) и ничего не публикуется. Комментарии становятся видимыми атомарно вместе с обзором: ни один комментарий или событие не наблюдаемы до отправки обзора, а затем каждый комментарий генерирует собственный webhook pull_request.comment.created наряду с событием обзора.
Операция не содержит ключа идемпотентности, поэтому повторная попытка после неоднозначного сбоя транспорта может создать второе ревью. Перед повторной попыткой вызовите Список ревью pull request.
Параметры пути
ownerSlug string Обязательно
repoName string Обязательное
pullNumber string Обязательно
Тело запроса
verdict string Обязательно
PULL_REQUEST_REVIEW_VERDICT_UNSPECIFIED, approve, request_changes, comment.body строка
versionNumber строка
PullRequestVersion.number). Оставьте пустым, чтобы просмотреть последнюю версию на момент вызова. Комментарии привязаны к той же версии.comments массив
comments[].body строка Обязательно
comments[].inline object
inline в Создать комментарий к Pull Request. Нельзя сочетать с comments[].threadId.comments[].inline.path строка Обязательно
comments[].inline.side string Обязательно
left для базовой версии файла, right для версии head.comments[].inline.startLine целое число Обязательно
side. Диапазон не должен выходить за пределы этого файла.comments[].inline.endLine целое число
startLine. Не указывайте для якоря, занимающего одну строку.comments[].threadId строка
comments[].inline, comments[].file и это поле, чтобы открыть новый общий тред обсуждения.comments[].file object
file в Создать комментарий к Pull Request. Нельзя сочетать с comments[].inline или comments[].threadId.comments[].file.path строка Обязательно
Поля ответа
id string
author object
author.user object
author.user.id строка
author.user.email string
author.user.displayName строка
author.user.handle строка
@. Присутствует только тогда, когда профиль общедоступен; в противном случае отсутствует.author.app object
author.app.id строка
author.app.displayName string
author.serviceAccount object
author.serviceAccount.id строка
verdict string
body строка
submittedAt строка
pullRequestVersion object
pullRequestVersion.number строка
pullRequestVersion.headSha string
pullRequestVersion.baseSha string
pullRequestVersion.createdAt строка
dismissal object
dismissal.dismissedBy object
dismissal.dismissedBy.user object
dismissal.dismissedBy.user.id строка
dismissal.dismissedBy.user.email строка
dismissal.dismissedBy.user.displayName строка
dismissal.dismissedBy.user.handle строка
@. Присутствует только тогда, когда профиль общедоступен; в противном случае отсутствует.dismissal.dismissedBy.app object
dismissal.dismissedBy.app.id строка
dismissal.dismissedBy.app.displayName строка
dismissal.dismissedBy.serviceAccount object
dismissal.dismissedBy.serviceAccount.id строка
dismissal.dismissedAt строка
dismissal.message строка
curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/reviews' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "verdict": "approve", "body": "Approving. The telemetry schema matches the spec.", "versionNumber": "3"}'Структура ответа:
{ "id": "rev_01k2ja2000e0080000000000f6", "author": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "verdict": "approve", "body": "Approving. The telemetry schema matches the spec.", "submittedAt": "2026-08-02T15:00:00Z", "pullRequestVersion": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8", "createdAt": "2026-08-01T09:30:00Z" }}Обновить обзор pull request
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/reviews/{reviewId}Обновляет текст ревью. Обновить его может только автор ревью; остальные вызывающие стороны получают PERMISSION_DENIED. Если ревью не относится к указанному pull request, возвращается NOT_FOUND.
Неотправленные черновые обзоры также можно обновлять; у ответа черновика нет submitted_at.
Параметры пути
ownerSlug string Обязательно
repoName string Обязательно
pullNumber строка Обязательно
reviewId string Обязательное
Тело запроса
body string Обязательно
Поля ответа
id строка
author object
author.user object
author.user.id string
author.user.email string
author.user.displayName строка
author.user.handle string
@. Присутствует только пока профиль общедоступен; в противном случае отсутствует.author.app object
author.app.id string
author.app.displayName строка
author.serviceAccount object
author.serviceAccount.id строка
verdict строка
body string
submittedAt строка
pullRequestVersion object
pullRequestVersion.number строка
pullRequestVersion.headSha string
pullRequestVersion.baseSha строка
pullRequestVersion.createdAt string
dismissal object
dismissal.dismissedBy object
dismissal.dismissedBy.user object
dismissal.dismissedBy.user.id строка
dismissal.dismissedBy.user.email строка
dismissal.dismissedBy.user.displayName строка
dismissal.dismissedBy.user.handle string
@. Отображается только пока профиль общедоступен; в противном случае отсутствует.dismissal.dismissedBy.app object
dismissal.dismissedBy.app.id строка
dismissal.dismissedBy.app.displayName string
dismissal.dismissedBy.serviceAccount object
dismissal.dismissedBy.serviceAccount.id string
dismissal.dismissedAt строка
dismissal.message строка
curl --request PATCH \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/reviews/REVIEW_ID' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "body": "Approving. The telemetry schema matches the spec."}'Структура ответа:
{ "id": "rev_01k2ja2000e0080000000000f6", "author": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "verdict": "approve", "body": "Одобрено. Схема телеметрии соответствует спецификации.", "submittedAt": "2026-08-02T15:00:00Z", "pullRequestVersion": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8", "createdAt": "2026-08-01T09:30:00Z" }}Отклонить обзор запроса на внесение изменений
/v1/origin/repos/{ownerSlug}/{repoName}/pulls/{pullNumber}/reviews/{reviewId}/dismissalsОтменяет отправленное ревью, чтобы его вердикт больше не учитывался при определении состояния ревью pull request'а. Само ревью сохраняется и продолжает отображаться в ListPullRequestReviews с установленным полем dismissal.
Чтобы отклонить ревью, необязательно быть его автором; достаточно права доступа на запись в ревью pull request репозитория.
Отменить можно только ревью типов approve и request_changes, и только один раз: ревью типа comment, неотправленное черновое ревью или уже отменённое ревью возвращает FAILED_PRECONDITION, а повторный вызов оставляет первую отмену в силе. Ревью, которое не принадлежит указанному pull request, возвращает NOT_FOUND.
Параметры пути
ownerSlug string Обязательно
repoName string Обязательно
pullNumber string Обязательно
reviewId string Обязательное
Тело запроса
message string Обязательно
Поля ответа
id строка
author object
author.user object
author.user.id строка
author.user.email string
author.user.displayName string
author.user.handle строка
@. Присутствует только пока профиль общедоступен; в противном случае отсутствует.author.app object
author.app.id строка
author.app.displayName string
author.serviceAccount object
author.serviceAccount.id string
verdict строка
body string
submittedAt строка
pullRequestVersion object
pullRequestVersion.number строка
pullRequestVersion.headSha string
pullRequestVersion.baseSha string
pullRequestVersion.createdAt строка
dismissal object
dismissal.dismissedBy object
dismissal.dismissedBy.user object
dismissal.dismissedBy.user.id string
dismissal.dismissedBy.user.email строка
dismissal.dismissedBy.user.displayName строка
dismissal.dismissedBy.user.handle string
@. Присутствует, только пока профиль общедоступен; в противном случае отсутствует.dismissal.dismissedBy.app object
dismissal.dismissedBy.app.id строка
dismissal.dismissedBy.app.displayName строка
dismissal.dismissedBy.serviceAccount object
dismissal.dismissedBy.serviceAccount.id строка
dismissal.dismissedAt строка
dismissal.message строка
curl --request PUT \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/pulls/PULL_NUMBER/reviews/REVIEW_ID/dismissals' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "message": "Superseded by a newer review."}'Структура ответа:
{ "id": "rev_01k2ja2000e0080000000000f6", "author": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "verdict": "approve", "body": "Approving. The telemetry schema matches the spec.", "submittedAt": "2026-08-02T15:00:00Z", "pullRequestVersion": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8", "createdAt": "2026-08-01T09:30:00Z" }, "dismissal": { "dismissedBy": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "dismissedAt": "2026-08-02T15:00:00Z", "message": "Superseded by a newer review." }}Наборы правил
Список наборов правил
/v1/origin/repos/{ownerSlug}/{repoName}/rulesetsВозвращает список всех наборов правил, настроенных для репозитория.
Наборы правил для каждого репозитория имеют ограниченный размер, поэтому полный список возвращается в одном ответе, а этот endpoint не поддерживает разбивку на страницы. repository указывается один раз и описывает репозиторий, общий для всех наборов правил в ответе.
Параметры пути
ownerSlug string Обязательное поле
repoName string Обязательное
Поля ответа
rulesets массив
rulesets[].id string
rulesets[].name string
rulesets[].description строка
rulesets[].enforcement string
active, evaluate, disabled.rulesets[].kind строка
merge_branch, push_branch, push_tag, push_repository.rulesets[].includedRefNames массив
~ALL и ~DEFAULT_BRANCH.rulesets[].excludedRefNames массив
rulesets[].includedRefNames.rulesets[].rules массив
rulesets[].rules[].id string
rulesets[].rules[].ruleType string
pull_request, require_status_checks, require_branch_up_to_date, deletion или non_fast_forward.rulesets[].rules[].parameters object
rulesets[].rules[].ruleType.rulesets[].bypassActors массив
rulesets[].bypassActors[].id string
rulesets[].bypassActors[].bypassMode string
always, pull_request_only.rulesets[].bypassActors[].user object
user, team, app или originRole.rulesets[].bypassActors[].user.id string
rulesets[].bypassActors[].team object
rulesets[].bypassActors[].team.organizationPublicId строка
rulesets[].bypassActors[].team.groupPublicId string
rulesets[].bypassActors[].app object
rulesets[].bypassActors[].app.id string
app_.rulesets[].bypassActors[].originRole object
rulesets[].bypassActors[].originRole.role string
namespace_admin, repository_admin, repository_write.repository object
repository.id string
repository.name string
repository.owner object
repository.owner.slug строка
repository.owner.id string
repository.owner.type строка
team, user. Не указывается, если неизвестно.curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/rulesets' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "rulesets": [ { "id": "rs_01k2ja2000e0080000000000t7", "name": "require-review", "description": "Require an approving review before merging to main.", "enforcement": "active", "kind": "merge_branch", "includedRefNames": [ "refs/heads/main" ], "rules": [ { "id": "rsr_01k2ja2000e0080000000000v8", "ruleType": "pull_request", "parameters": { "requiredApprovingReviewCount": 1 } } ], "bypassActors": [ { "id": "rsba_01k2ja2000e0080000000000w9", "bypassMode": "always", "user": { "id": "act_01k2ja2000e0080000000000x0" } } ] } ], "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }}Создать набор правил
/v1/origin/repos/{ownerSlug}/{repoName}/rulesetsСоздаёт набор правил для репозитория.
Ответ содержит сохранённый набор правил, включая идентификаторы, которые Origin присваивает каждому правилу и субъекту обхода. Пустое поле name отклоняется с ошибкой InvalidArgument (HTTP 400).
Параметры пути
ownerSlug string Обязательное
repoName string Обязательно
Тело запроса
name string Обязательно
description строка
enforcement string Обязательно
active, evaluate, disabled.kind string Обязательный
merge_branch, push_branch, push_tag, push_repository.includedRefNames массив
~ALL и ~DEFAULT_BRANCH. Значения с количеством записей более 64 отклоняются с ошибкой InvalidArgument (HTTP 400).excludedRefNames массив
includedRefNames.rules массив
ruleType и необязательное поле parameters; Origin присваивает каждому правилу id. Значения с более чем 20 записями отклоняются с ошибкой InvalidArgument (HTTP 400).bypassActors массив
bypassMode и ровно одно из: user, team, app или originRole; Origin присваивает id каждому актору. Значения с более чем 15 записями отклоняются с ошибкой InvalidArgument (HTTP 400).Поля ответа
id строка
name строка
description строка
enforcement строка
active, evaluate, disabled.kind строка
merge_branch, push_branch, push_tag, push_repository.includedRefNames массив
~ALL и ~DEFAULT_BRANCH.excludedRefNames массив
includedRefNames.rules массив
rules[].id строка
rules[].ruleType string
pull_request, require_status_checks, require_branch_up_to_date, deletion или non_fast_forward.rules[].parameters object
rules[].ruleType.bypassActors массив
bypassActors[].id string
bypassActors[].bypassMode string
always, pull_request_only.bypassActors[].user object
user, team, app или originRole.bypassActors[].user.id string
bypassActors[].team object
bypassActors[].team.organizationPublicId string
bypassActors[].team.groupPublicId string
bypassActors[].app object
bypassActors[].app.id string
app_.bypassActors[].originRole object
bypassActors[].originRole.role строка
namespace_admin, repository_admin, repository_write.curl --request POST \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/rulesets' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "name": "require-review", "description": "Require an approving review before merging to main.", "enforcement": "active", "kind": "merge_branch", "includedRefNames": [ "refs/heads/main" ], "rules": [ { "ruleType": "pull_request", "parameters": { "requiredApprovingReviewCount": 1 } } ], "bypassActors": [ { "bypassMode": "always", "user": { "id": "act_01k2ja2000e0080000000000x0" } } ]}'Структура ответа:
{ "id": "rs_01k2ja2000e0080000000000t7", "name": "require-review", "description": "Require an approving review before merging to main.", "enforcement": "active", "kind": "merge_branch", "includedRefNames": [ "refs/heads/main" ], "rules": [ { "id": "rsr_01k2ja2000e0080000000000v8", "ruleType": "pull_request", "parameters": { "requiredApprovingReviewCount": 1 } } ], "bypassActors": [ { "id": "rsba_01k2ja2000e0080000000000w9", "bypassMode": "always", "user": { "id": "act_01k2ja2000e0080000000000x0" } } ]}Получить набор правил
/v1/origin/repos/{ownerSlug}/{repoName}/rulesets/{rulesetId}Возвращает набор правил репозитория по его постоянному идентификатору Origin.
И неизвестный репозиторий, и неизвестный набор правил возвращают 404; сообщение позволяет их различить.
Параметры пути
ownerSlug string Обязательное поле
repoName string Обязательный
rulesetId string Обязательно
Поля ответа
id строка
name string
description строка
enforcement строка
active, evaluate, disabled.kind string
merge_branch, push_branch, push_tag, push_repository.includedRefNames массив
~ALL и ~DEFAULT_BRANCH.excludedRefNames массив
includedRefNames.rules массив
rules[].id string
rules[].ruleType string
pull_request, require_status_checks, require_branch_up_to_date, deletion или non_fast_forward.rules[].parameters object
rules[].ruleType.bypassActors массив
bypassActors[].id строка
bypassActors[].bypassMode string
always, pull_request_only.bypassActors[].user object
user, team, app или originRole.bypassActors[].user.id string
bypassActors[].team object
bypassActors[].team.organizationPublicId строка
bypassActors[].team.groupPublicId string
bypassActors[].app object
bypassActors[].app.id string
app_.bypassActors[].originRole object
bypassActors[].originRole.role string
namespace_admin, repository_admin, repository_write.curl --request GET \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/rulesets/RULESET_ID' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Структура ответа:
{ "id": "rs_01k2ja2000e0080000000000t7", "name": "require-review", "description": "Require an approving review before merging to main.", "enforcement": "active", "kind": "merge_branch", "includedRefNames": [ "refs/heads/main" ], "rules": [ { "id": "rsr_01k2ja2000e0080000000000v8", "ruleType": "pull_request", "parameters": { "requiredApprovingReviewCount": 1 } } ], "bypassActors": [ { "id": "rsba_01k2ja2000e0080000000000w9", "bypassMode": "always", "user": { "id": "act_01k2ja2000e0080000000000x0" } } ]}Обновить набор правил
/v1/origin/repos/{ownerSlug}/{repoName}/rulesets/{rulesetId}Обновляет существующий набор правил репозитория.
Запрос заменяет всю конфигурацию набора правил. rules и bypassActors заменяются целиком, а не объединяются, и Origin присваивает сохранённым записям новые идентификаторы, поэтому отправьте все правила и субъекты обхода, которые вы хотите сохранить.
Параметры пути
ownerSlug строка Обязательное поле
repoName строка Обязательный
rulesetId string Обязательно
Тело запроса
name string Обязательное
description строка
enforcement string Обязательно
active, evaluate, disabled.kind string Обязательное
merge_branch, push_branch, push_tag, push_repository.includedRefNames массив
~ALL и ~DEFAULT_BRANCH. Значения с более чем 64 записями отклоняются с ошибкой InvalidArgument (HTTP 400).excludedRefNames массив
includedRefNames.rules массив
ruleType и необязательные parameters; Origin присваивает каждому правилу id. Значения при количестве записей более 20 отклоняются с ошибкой InvalidArgument (HTTP 400).bypassActors массив
bypassMode и ровно одно из полей: user, team, app или originRole; Origin присваивает id каждому субъекту. Значения, превышающие 15 записей, отклоняются с ошибкой InvalidArgument (HTTP 400).Поля ответа
id строка
name строка
description строка
enforcement строка
active, evaluate, disabled.kind строка
merge_branch, push_branch, push_tag, push_repository.includedRefNames массив
~ALL и ~DEFAULT_BRANCH.excludedRefNames массив
includedRefNames.rules массив
rules[].id string
rules[].ruleType строка
pull_request, require_status_checks, require_branch_up_to_date, deletion или non_fast_forward.rules[].parameters object
rules[].ruleType.bypassActors массив
bypassActors[].id string
bypassActors[].bypassMode string
always, pull_request_only.bypassActors[].user object
user, team, app или originRole.bypassActors[].user.id string
bypassActors[].team object
bypassActors[].team.organizationPublicId строка
bypassActors[].team.groupPublicId string
bypassActors[].app object
bypassActors[].app.id string
app_.bypassActors[].originRole object
bypassActors[].originRole.role string
namespace_admin, repository_admin, repository_write.curl --request PUT \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/rulesets/RULESET_ID' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN' \ --header 'Content-Type: application/json' \ --data '{ "name": "require-review", "description": "Require an approving review before merging to main.", "enforcement": "active", "kind": "merge_branch", "includedRefNames": [ "refs/heads/main" ], "rules": [ { "ruleType": "pull_request", "parameters": { "requiredApprovingReviewCount": 1 } } ], "bypassActors": [ { "bypassMode": "always", "user": { "id": "act_01k2ja2000e0080000000000x0" } } ]}'Структура ответа:
{ "id": "rs_01k2ja2000e0080000000000t7", "name": "require-review", "description": "Require an approving review before merging to main.", "enforcement": "active", "kind": "merge_branch", "includedRefNames": [ "refs/heads/main" ], "rules": [ { "id": "rsr_01k2ja2000e0080000000000v8", "ruleType": "pull_request", "parameters": { "requiredApprovingReviewCount": 1 } } ], "bypassActors": [ { "id": "rsba_01k2ja2000e0080000000000w9", "bypassMode": "always", "user": { "id": "act_01k2ja2000e0080000000x0" } } ]}Удалить набор правил
/v1/origin/repos/{ownerSlug}/{repoName}/rulesets/{rulesetId}Удаляет набор правил репозитория по его стабильному идентификатору Origin. Тело ответа пустое.
И неизвестный репозиторий, и неизвестный набор правил возвращают 404; различить их позволяет сообщение. Набор правил из другого репозитория считается неизвестным. Пустой rulesetId возвращает InvalidArgument (HTTP 400).
Параметры пути
ownerSlug string обязательный
repoName string обязательный
rulesetId string обязательный
Поля ответа
При успешном запросе тело ответа отсутствует.
curl --request DELETE \ --url 'https://api.cursor.com/v1/origin/repos/OWNER_SLUG/REPO_NAME/rulesets/RULESET_ID' \ --header 'Authorization: Bearer YOUR_ORIGIN_TOKEN'Ответ:
204 No ContentВебхуки
Origin отправляет подписанные HTTP-запросы POST на зарегистрированный HTTPS URL вебхука приложения с content-type: application/json.
Доставка гарантируется как минимум один раз. Устраняйте дубликаты повторных попыток по webhook-id, надёжно принимайте запрос, быстро возвращайте 2xx и обрабатывайте событие асинхронно.
Origin повторяет попытки при транспортных ошибках, ответах 429 и 5xx — всего до семи попыток. Задержки между повторными попытками: 5 секунд, 30 секунд, 1 минута, 2 минуты, 4 минуты и 8 минут. Другие ответы 4xx считаются окончательными.
Чтобы убедиться, что получатель работает до поступления первого реального события, вызовите Проверить вебхук.
Origin доставляет события для зеркалированных репозиториев, а полезные нагрузки событий установки указывают их в массивах выбранных репозиториев. Доставка не расширяет возможности вызовов установки: см. Зеркалированные репозитории.
Заголовки
| Заголовок | Описание |
|---|---|
content-type | application/json |
user-agent | Cursor-Origin-Webhook/1.0 |
webhook-id | Стабильный идентификатор доставки и ключ идемпотентности. |
webhook-timestamp | Метка времени Unix, включённая в подпись. |
webhook-signature | v1ed,BASE64_SIGNATURE |
webhook-event-type | Слаг события для маршрутизации. |
webhook-event-id | Идентификатор исходного события Origin, дублируемый из подписанного тела. |
webhook-app-id | Идентификатор целевого приложения. |
webhook-installation-id | Идентификатор целевой установки. |
Заголовки маршрутизации предназначены для удобства. После проверки подписи источником истины считается тело.
Проверка подписи
Используйте сырое тело запроса до его обработки. Сформируйте:
lowercaseHex(SHA-256("<webhook-id>.<webhook-timestamp>.<raw-request-body>"))Проверьте подпись Ed25519 для UTF-8-байтов этого шестнадцатеричного дайджеста по активному ключу Origin JWKS. Отклоняйте временные метки, отличающиеся от текущего времени более чем на пять минут.
import { createHash, createPublicKey, verify, type JsonWebKeyInput,} from "node:crypto";export async function verifyOriginWebhook( body: Buffer, headers: Record<string, string | undefined>): Promise<boolean> { const id = headers["webhook-id"]; const timestamp = Number(headers["webhook-timestamp"]); const signature = headers["webhook-signature"] ?.split(/\s+/) .find((value) => value.startsWith("v1ed,")); const now = Math.floor(Date.now() / 1000); if ( !id || !signature || !Number.isInteger(timestamp) || Math.abs(now - timestamp) > 300 ) { return false; } const digest = createHash("sha256") .update(`${id}.${timestamp}.`) .update(body) .digest("hex"); // В продакшене кэшируйте этот ответ. const { keys } = await fetch( "https://api.cursor.com/v1/origin/keys" ).then((response) => response.json()) as { keys: JsonWebKeyInput[]; }; return keys.some((jwk) => { try { return verify( null, Buffer.from(digest), createPublicKey({ key: jwk, format: "jwk" }), Buffer.from(signature.slice(5), "base64") ); } catch { return false; } });}Обёртка доставки
Каждый запрос содержит полезную нагрузку события и идентификаторы доставки, приложения и установки:
{ "deliveryId": "whd_01...", "appId": "app_01...", "installationId": "i_01...", "event": { "id": "evt_01...", "type": "pull_request.comment.created", "eventTime": "2026-07-01T10:03:00Z", "payload": {} }}deliveryId не меняется при повторных попытках. event.id идентифицирует исходное событие домена.
Восстановление
Используйте JWT приложения для запроса GET /app/webhook/deliveries. Фильтруйте по статусу доставки, типу события, установке, временному диапазону или токену страницы. delivered=false возвращает все доставки, которые получатель ещё ни разу не подтвердил ответом 2xx. Доставки остаются доступными для просмотра в течение семи дней, поэтому восстановление нужно выполнить в этот срок.
Используйте POST /app/webhook/deliveries:batchRedeliver, чтобы поставить в очередь повторную отправку до 100 идентификаторов доставок. Операция удаляет повторяющиеся идентификаторы и возвращает результат для каждой доставки.
Владелец может приостановить доставку вебхуков приложения в его настройках, а Origin может сделать это самостоятельно: приложение, получатель которого не справился как минимум с 20 раундами доставки в течение 72-часового окна, при отсутствии успешных доставок в этом окне и при сбоях, затрагивающих более одного пространства имён установщика, отключается автоматически. В любом случае доставка останавливается, пока владелец её не возобновит, запросы на повторную отправку возвращают FailedPrecondition (HTTP 400) и ничего не ставится в очередь, а API не предоставляет поля для приостановленного состояния — поэтому считайте сигналом именно FailedPrecondition при повторной отправке. Сброс webhookUrl приложения через Update App действует сильнее: он полностью отменяет ожидающие доставки, и повторная установка URL их не вернёт.
Справочник по вебхукам
Все события, которые доставляет Origin, и полезная нагрузка каждого события с описанием каждого поля. О механике подписки, заголовках, проверке подписи, обёртке доставки и повторных попытках см. Вебхуки.
События
| Событие | Доставляется, когда |
|---|---|
repository.created | Репозиторий создаётся. |
repository.deleted | Репозиторий удаляется. |
repository.pushed | При push изменяется одна или несколько Git-ссылок. |
repository.metadata.updated | Изменяется ветка по умолчанию репозитория. |
pull_request.created | Открывается pull request. |
pull_request.head_ref.pushed | Продвигается head-ветка pull request. |
pull_request.base_ref.updated | Изменяется базовая Git-ссылка или определённый базовый коммит. |
pull_request.metadata.updated | Изменяется заголовок или описание. |
pull_request.closed | Pull request закрывается без слияния, в том числе когда Origin закрывает его, поскольку после push его head-ветка не имеет общей истории с base-веткой. |
pull_request.merged | Pull request сливается. |
pull_request.reopened | Закрытый pull request открывается снова. |
pull_request.published | Черновик становится открытым pull request. |
pull_request.comment.created | Создаётся видимый комментарий к pull request. |
pull_request.review.submitted | Ревью отправляется с любым вердиктом. |
pull_request.review.dismissed | Отправленное ревью отклоняется явно или заменяется другим. |
pull_request.reviewer.added | Запрашивается ревьюер. |
pull_request.reviewer.removed | Ревьюер удаляется. |
pull_request.reviewer.rerequested | Ревьюер запрашивается повторно. |
repository.check_run.created | Создаётся запуск проверки. |
repository.check_run.completed | Запуск проверки завершается. |
repository.check_run.rerequested | Завершённый запуск проверки запрашивается повторно. Доставляется только приложению, которому принадлежит запуск. |
installation.created | Приложение устанавливается. |
installation.updated | Изменяются области доступа, выбор репозитория или slug пространства имён владельца. |
installation.suspended | Установка приостанавливается. |
installation.unsuspended | Приостановленная установка восстанавливается. |
installation.deleted | Приложение удаляется. |
Структура полезной нагрузки каждого события описана поле за полем в разделе Полезная нагрузка событий.
Пять событий installation.* направляются самому приложению, а не подписке репозитория. Origin всегда отправляет их, поэтому они не отображаются в списке событий, доступных для выбора в приложении. Все остальные события в этой таблице — подписки на уровне репозитория.
Origin не отправляет repository.pushed для репозитория, зеркалированного из GitHub. Эти push принадлежат GitHub, и он отправляет собственные push-вебхуки, поэтому доставка от Origin была бы дублированием. Push в нативные репозитории Origin и в исходящие зеркала доставляются как обычно, а состояние зеркала не влияет ни на какие другие события. repository.deleted отправляется для репозитория, зеркалированного из GitHub: остановка синхронизации удаляет только репозиторий на стороне Cursor, и GitHub ничего для него не отправляет.
Event payloads
Обёртка каждого события содержит его полезную нагрузку в виде object в поле payload. События с одинаковой структурой относятся к одному семейству полезной нагрузки; для каждого семейства ниже описаны доставляющие его события, его поля и пример полезной нагрузки, сгенерированный из спецификация OpenAPI.
Репозиторий создан
repository.createdПоля payload
repository object
repository.id string
repository.name string Обязательное
repository.fullName string
repository.owner object
repository.owner.slug string
repository.owner.id string
repository.owner.type string
team или user. Доступно только для вывода; не задано, если значение неизвестно. Одно из: team, user.repository.defaultBranch string
repository.createdAt string
repository.updatedAt string
repository.pushedAt string
repository.cloneUrl string
repository.mirror object
repository.mirror.source string
github.repository.mirror.sourceId string
repository.mirror.status string
inbound, outbound.repository.visibility string
internal или private. Одно из значений: internal, private.repository.allowMergeCommit boolean
repository.allowSquashMerge boolean
repository.deleteBranchOnMerge boolean
Пример event.payload:
{ "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-01T09:30:00Z", "cloneUrl": "https://origin.cursor.com/git/acme/rocket.git" }}Репозиторий удалён
repository.deletedПоля полезной нагрузки
repository object
repository.id string
repository.name string
repository.owner object
repository.owner.slug string
repository.owner.id string
repository.owner.type string
team или user. Доступно только для вывода; не задано, если неизвестно. Одно из значений: team, user.deletedAt string
Пример event.payload:
{ "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "deletedAt": "2026-08-03T08:15:00Z"}Отправка в репозиторий
repository.pushedОдин атомарный push, который может обновить несколько Git-ссылок. Массив commits отсутствует; каждое обновление Git-ссылки содержит только метаданные tip, предоставляемые по мере возможности.
Поля payload
repository object
repository.id string
repository.name string
repository.owner object
repository.owner.slug string
repository.owner.id string
repository.owner.type string
team или user. Только для вывода; не задано, если неизвестно. Одно из значений: team, user.refUpdates массив
refUpdates[].ref string
refs/heads/main или refs/tags/v3.14.1.refUpdates[].before string
ref до push. Состоит из одних нулей (0000000000000000000000000000000000000000), если Git-ссылка была только что создана.refUpdates[].after string
ref после push. Содержит только нули (0000000000000000000000000000000000000000), если Git-ссылка была удалена.refUpdates[].created boolean
refUpdates[].deleted boolean
refUpdates[].forced логическое значение
refUpdates[].headCommit object
refUpdates[].headCommit.sha string
refUpdates[].headCommit.author object
refUpdates[].headCommit.author.name string
refUpdates[].headCommit.author.email string
refUpdates[].headCommit.author.date string
refUpdates[].headCommit.committer object
refUpdates[].headCommit.committer.name string
refUpdates[].headCommit.committer.email string
refUpdates[].headCommit.committer.date string
refUpdates[].headCommit.message string
pushedAt string
pusher object
pusher.user object
pusher.user.id string
pusher.user.email string Обязательный
pusher.user.displayName string
pusher.user.handle string
pusher.app object
pusher.app.id string
pusher.app.displayName string
pusher.serviceAccount object
pusher.serviceAccount.id string
refUpdatesCount integer
Пример event.payload:
{ "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "refUpdates": [ { "ref": "refs/heads/add-telemetry", "before": "5c8d7e6f5a4b3c2d1e0f9a8b7c6d5e4f3a2b1c0d", "after": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "created": false, "deleted": false, "forced": false, "headCommit": { "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "author": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "committer": { "name": "Jane Doe", "email": "[email protected]", "date": "2026-08-01T09:30:00Z" }, "message": "Add launch telemetry" } } ], "pushedAt": "2026-08-02T14:45:00Z", "pusher": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "refUpdatesCount": 1}Метаданные репозитория обновлены
repository.metadata.updatedСодержит полный снимок репозитория без delta и без актора, выполнившего обновление. Чтобы узнать, что изменилось, сравните последовательные снимки или повторно запросите репозиторий.
Поля payload
repository object
repository.id string
repository.name string Обязательное
repository.fullName string
repository.owner object
repository.owner.slug string
repository.owner.id string
repository.owner.type string
team или user. Только для вывода; не задано, если значение неизвестно. Одно из: team, user.repository.defaultBranch string
repository.createdAt string
repository.updatedAt string
repository.pushedAt string
repository.cloneUrl string
repository.mirror object
repository.mirror.source string
github.repository.mirror.sourceId string
repository.mirror.status string
inbound, outbound.repository.visibility string
internal или private. Одно из значений: internal, private.repository.allowMergeCommit boolean
repository.allowSquashMerge boolean
repository.deleteBranchOnMerge boolean
Пример event.payload:
{ "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "fullName": "acme/rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" }, "defaultBranch": "release", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-03T08:15:00Z", "cloneUrl": "https://origin.cursor.com/git/acme/rocket.git", "pushedAt": "2026-08-02T14:45:00Z" }}События pull request
pull_request.createdpull_request.publishedpull_request.reopenedpull_request.closedpull_request.mergedpull_request.metadata.updatedpull_request.head_ref.pushedpull_request.base_ref.updatedИзменение жизненного цикла pull request. Действие жизненного цикла передаётся в event.type обёртки; отдельного поля действия нет.
Поля payload
pullRequest object
GetPullRequest.pullRequest.id string
pullRequest.number string
pullRequest.state string
pullRequest.draft boolean
pullRequest.merged boolean
pullRequest.title string
pullRequest.body string
pullRequest.head object
pullRequest.head.ref string
pullRequest.head.sha string
pullRequest.base object
pullRequest.base.ref строка
pullRequest.base.sha string
pullRequest.author object
pullRequest.author.user object
pullRequest.author.user.id string
pullRequest.author.user.email string Обязательное
pullRequest.author.user.displayName string
pullRequest.author.user.handle string
pullRequest.author.app object
pullRequest.author.app.id string
pullRequest.author.app.displayName string
pullRequest.author.serviceAccount object
pullRequest.author.serviceAccount.id string
pullRequest.createdAt string
pullRequest.updatedAt string
pullRequest.closedAt string
pullRequest.mergedAt string
pullRequest.mergeCommitSha string
pullRequest.additions integer
pullRequest.deletions целое число
pullRequest.changedFiles integer
pullRequest.version object
pullRequest.version.number string
pullRequest.version.headSha string
pullRequest.version.baseSha string
pullRequest.version.createdAt string
repository object
repository.id string
repository.name string
repository.owner object
repository.owner.slug string
repository.owner.id string
repository.owner.type string
team или user. Доступно только для вывода; не задано, если неизвестно. Одно из значений: team, user.Пример event.payload:
{ "pullRequest": { "id": "pr_01k2ja2000e0080000000000d4", "number": "17", "state": "open", "draft": false, "merged": false, "title": "Add launch telemetry", "body": "Adds structured launch telemetry to the ignition path.", "head": { "ref": "add-telemetry", "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4" }, "base": { "ref": "main", "sha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8" }, "author": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "additions": 128, "deletions": 46, "changedFiles": 5, "version": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8", "createdAt": "2026-08-01T09:30:00Z" } }, "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }}Комментарий к pull request
pull_request.comment.createdКомментарий, созданный в pull request. Комментарии, добавленные в рамках ревью, отправляются в момент публикации ревью — по одному событию на каждый комментарий.
Поля payload
pullRequest object
pullRequest.id string
pullRequest.number строка
pullRequest.repository object
pullRequest.repository.id string
pullRequest.repository.name string
pullRequest.repository.owner object
pullRequest.repository.owner.slug string
pullRequest.repository.owner.id string
pullRequest.repository.owner.type string
team или user. Только для вывода; не задано, если неизвестно. Одно из значений: team, user.comment object
comment.thread.id. Состояние разрешения треда в событие не входит — получить его можно через GetPullRequestComment.comment.id string
comment.thread object
comment.thread.id string
comment.thread.version object
PullRequestReview.pull_request_version).comment.thread.version.number string
comment.thread.version.headSha string
comment.thread.version.baseSha строка
comment.thread.version.createdAt string
comment.thread.path string
comment.thread.side string
left, right.comment.thread.startLine целое число
side. 0 для тредов уровня файла и тредов общего обсуждения.comment.thread.endLine integer
comment.thread.resolvedAt string
comment.thread.createdAt string
comment.thread.updatedAt string
comment.body string
comment.author object
comment.author.user object
comment.author.user.id string
comment.author.user.email string Обязательный
comment.author.user.displayName строка
comment.author.user.handle string
comment.author.app object
comment.author.app.id строка
comment.author.app.displayName строка
comment.author.serviceAccount object
comment.author.serviceAccount.id string
comment.createdAt string
comment.updatedAt string
Пример event.payload:
{ "pullRequest": { "id": "pr_01k2ja2000e0080000000000d4", "number": "17", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } } }, "comment": { "id": "cmt_01k2ja2000e0080000000000e5", "thread": { "id": "cth_01k2ja2000e0080000000000s6", "version": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8", "createdAt": "2026-08-01T09:30:00Z" }, "path": "src/telemetry/retry.ts", "side": "right", "startLine": 42, "endLine": 45, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z" }, "body": "Should the retry budget be configurable?", "author": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z" }}События ревью pull request
pull_request.review.submittedpull_request.review.dismissedПоля payload
pullRequest object
pullRequest.id string
pullRequest.number строка
pullRequest.repository object
pullRequest.repository.id string
pullRequest.repository.name string
pullRequest.repository.owner object
pullRequest.repository.owner.slug string
pullRequest.repository.owner.id string
pullRequest.repository.owner.type string
team или user. Только для вывода; не задано, если значение неизвестно. Одно из значений: team, user.review object
review.dismissal.review.id string
review.author object
review.author.user object
review.author.user.id string
review.author.user.email string Обязательное
review.author.user.displayName string
review.author.user.handle string
review.author.app object
review.author.app.id string
review.author.app.displayName string
review.author.serviceAccount object
review.author.serviceAccount.id string
review.verdict string
approve, request_changes, comment.review.body string
review.submittedAt string
review.pullRequestVersion object
review.pullRequestVersion.number string
review.pullRequestVersion.headSha string
review.pullRequestVersion.baseSha string
review.pullRequestVersion.createdAt string
review.dismissal object
review.dismissal.dismissedBy object
review.dismissal.dismissedBy.user object
review.dismissal.dismissedBy.user.id string
review.dismissal.dismissedBy.user.email string Обязательный
review.dismissal.dismissedBy.user.displayName string
review.dismissal.dismissedBy.user.handle string
review.dismissal.dismissedBy.app object
review.dismissal.dismissedBy.app.id string
review.dismissal.dismissedBy.app.displayName string
review.dismissal.dismissedBy.serviceAccount object
review.dismissal.dismissedBy.serviceAccount.id string
review.dismissal.dismissedAt string
review.dismissal.message string
Пример event.payload:
{ "pullRequest": { "id": "pr_01k2ja2000e0080000000000d4", "number": "17", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } } }, "review": { "id": "rev_01k2ja2000e0080000000000f6", "author": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "verdict": "approve", "body": "Approving. The telemetry schema matches the spec.", "submittedAt": "2026-08-02T15:00:00Z", "pullRequestVersion": { "number": "3", "headSha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "baseSha": "3b1f9c2d8a7e6f5049c8b7a6d5e4f3a2b1c0d9e8", "createdAt": "2026-08-01T09:30:00Z" } }}События ревьюера pull request
pull_request.reviewer.addedpull_request.reviewer.removedpull_request.reviewer.rerequestedИзменение списка запрошенных ревьюеров pull request. Текущий набор ожидающих ревьюеров можно получить через ListPullRequestRequestedReviewers.
Поля payload
pullRequest object
pullRequest.id string
pullRequest.number строка
pullRequest.repository object
pullRequest.repository.id string
pullRequest.repository.name string
pullRequest.repository.owner object
pullRequest.repository.owner.slug string
pullRequest.repository.owner.id string
pullRequest.repository.owner.type string
team или user. Доступно только для вывода; не задано, если значение неизвестно. Одно из: team, user.reviewer object
reviewer.user object
reviewer.user.id string
reviewer.user.email string Обязательное
reviewer.user.displayName string
reviewer.user.handle string
reviewer.group object
grp_…). Пока содержит только id.reviewer.group.id string
createdVia string
manual, codeowners.createdBy object
createdBy.user object
createdBy.user.id string
createdBy.user.email string Обязательный
createdBy.user.displayName string
createdBy.user.handle string
createdBy.app object
createdBy.app.id string
createdBy.app.displayName string
createdBy.serviceAccount object
createdBy.serviceAccount.id string
createdAt string
Пример event.payload:
{ "pullRequest": { "id": "pr_01k2ja2000e0080000000000d4", "number": "17", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } } }, "reviewer": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "createdVia": "codeowners", "createdAt": "2026-08-02T14:45:00Z"}События проверочных запусков
repository.check_run.createdrepository.check_run.completedЗафиксированный снимок для события жизненного цикла check-run в Origin.
Поля полезной нагрузки
repository object
repository.id string
repository.name string
repository.owner object
repository.owner.slug string
repository.owner.id string
repository.owner.type string
team или user. Только для вывода; не устанавливается, если неизвестно. Одно из: team, user.checkSuite object
checkSuite.id string
checkSuite.repository object
checkSuite.repository.id string
checkSuite.repository.name string
checkSuite.repository.owner object
checkSuite.repository.owner.slug string
checkSuite.repository.owner.id string
checkSuite.repository.owner.type string
team или user. Только для вывода; не устанавливается, если неизвестно. Одно из: team, user.checkSuite.sha string
checkSuite.key строка
checkSuite.name string
checkSuite.detailsUrl string
checkSuite.createdAt string
checkSuite.updatedAt string
checkSuite.externalId строка
checkSuite.actor object
checkSuite.actor.user object
checkSuite.actor.user.id string
checkSuite.actor.user.email string Обязательно
checkSuite.actor.user.displayName string
checkSuite.actor.user.handle string
checkSuite.actor.app object
checkSuite.actor.app.id string
checkSuite.actor.app.displayName string
checkSuite.actor.serviceAccount object
checkSuite.actor.serviceAccount.id string
checkRun object
checkRun.id string
checkRun.repository object
checkRun.repository.id string
checkRun.repository.name string
checkRun.repository.owner object
checkRun.repository.owner.slug строка
checkRun.repository.owner.id string
checkRun.repository.owner.type string
team или user. Только для вывода; не устанавливается, если неизвестно. Одно из: team, user.checkRun.checkSuite object
checkRun.checkSuite.id string
checkRun.sha string
checkRun.key string
checkRun.name string
checkRun.status string
rerequested — завершённый запуск, повторное выполнение которого было запрошено, но владеющее приложение ещё не ответило: для читателей он в состоянии ожидания (отображается как queued), при этом conclusion и временные метки по-прежнему описывают вытесненную попытку. Устанавливается только Origin при повторном запросе (RerequestCheckRun); приложения не могут его публиковать. Одно из: queued, in_progress, completed, rerequested.checkRun.conclusion string
status имеет значение completed или rerequested. Для запуска со статусом rerequested это решение вытесненной попытки: считайте запуск ожидающим и читайте conclusion только когда status == completed. Одно из: success, failure, neutral, cancelled, skipped, timed_out, action_required, stale.checkRun.detailsUrl string
checkRun.externalUpdatedAt string
checkRun.startedAt string
checkRun.completedAt string
checkRun.createdAt string
checkRun.updatedAt string
checkRun.externalId string
CheckRunInput.external_id: рекомендуется по одному на выполнение).checkRun.actor object
checkRun.actor.user object
checkRun.actor.user.id string
checkRun.actor.user.email string Обязательное
checkRun.actor.user.displayName string
checkRun.actor.user.handle string
checkRun.actor.app object
checkRun.actor.app.id string
checkRun.actor.app.displayName string
checkRun.actor.serviceAccount object
checkRun.actor.serviceAccount.id string
checkRun.output object
checkRun.output.title string
checkRun.output.summary string
checkRun.output.text string
checkRun.deadlineAt string
checkRun.isRerequestable boolean
CheckRunInput.is_rerequestable).checkRun.rerequestedAt string
status имеет значение rerequested, а запуск остаётся в состоянии ожидания CI коммита (conclusion и тайминги — устаревшие результаты); владеющее приложение отвечает, опубликовав запуск, на который оно ссылается, объявив is_rerequestable — это может быть новый запуск с тем же key или обновление этого запуска (что очищает это поле) — после чего запуск можно снова запросить. Метка времени в формате RFC 3339.checkRun.rerequestedBy object
rerequested_at; сбрасывается вместе с ним, когда отвечает владеющее приложение.checkRun.rerequestedBy.user object
checkRun.rerequestedBy.user.id string
checkRun.rerequestedBy.user.email string Обязательно
checkRun.rerequestedBy.user.displayName string
checkRun.rerequestedBy.user.handle string
checkRun.rerequestedBy.app object
checkRun.rerequestedBy.app.id string
checkRun.rerequestedBy.app.displayName string
checkRun.rerequestedBy.serviceAccount object
checkRun.rerequestedBy.serviceAccount.id string
actor object
actor.user object
actor.user.id string
actor.user.email string Обязательное
actor.user.displayName string
actor.user.handle string
actor.app object
actor.app.id string
actor.app.displayName string
actor.serviceAccount object
actor.serviceAccount.id string
Пример event.payload:
{ "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "checkSuite": { "id": "crg_01k2ja2000e0080000000000h8", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "key": "ci-8842", "name": "CI", "detailsUrl": "https://ci.acme.dev/runs/8842", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "externalId": "build-8842", "actor": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } } }, "checkRun": { "id": "cr_01k2ja2000e0080000000000g7", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "checkSuite": { "id": "crg_01k2ja2000e0080000000000h8" }, "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "key": "ci-8842-unit-tests", "name": "unit-tests", "status": "completed", "conclusion": "success", "detailsUrl": "https://ci.acme.dev/runs/8842", "externalUpdatedAt": "2026-08-02T14:44:30Z", "startedAt": "2026-08-02T14:40:00Z", "completedAt": "2026-08-02T14:44:30Z", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "externalId": "run-8842", "actor": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "output": { "title": "Unit tests", "summary": "128 tests passed.", "text": "All suites green." } }, "actor": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }}Повторный запрос проверки выполнения
repository.check_run.rerequestedPayload вебхука repository.check_run.rerequested доставляется только приложению, которому принадлежит check run. В ответ опубликуйте новый run для того же SHA коммита head и того же key — либо новый run (новый external_id), либо обновление повторно запрошенного run. Зафиксированный run имеет status: rerequested (его conclusion и тайминги являются замененным результатом), пока ответная публикация не сбросит rerequested_at. Каждый принятый повторный запрос порождает одно событие, и после ответа run можно запросить повторно снова, поэтому дедупликацию повторных отправок выполняйте только по идентификатору события; в check_run.rerequested_at хранится непогашенная отметка. Payload не содержит контекста pull request (check runs привязываются к (repository, sha)): потребителю, которому нужен pull request, следует определить его по check_run.sha через собственное сопоставление head-веток либо через ListPullRequests с фильтром по той head branch, которую он собирал.
Поля полезной нагрузки
repository object
repository.id string
repository.name string
repository.owner object
repository.owner.slug string
repository.owner.id string
repository.owner.type string
team или user. Только для вывода; не задаётся, если неизвестно. Одно из: team, user.checkSuite object
checkSuite.id string
checkSuite.repository object
checkSuite.repository.id string
checkSuite.repository.name string
checkSuite.repository.owner object
checkSuite.repository.owner.slug string
checkSuite.repository.owner.id string
checkSuite.repository.owner.type string
team или user. Только для вывода; не устанавливается, если неизвестно. Одна из: team, user.checkSuite.sha string
checkSuite.key строка
checkSuite.name string
checkSuite.detailsUrl string
checkSuite.createdAt string
checkSuite.updatedAt string
checkSuite.externalId строка
checkSuite.actor object
checkSuite.actor.user object
checkSuite.actor.user.id string
checkSuite.actor.user.email string Обязательно
checkSuite.actor.user.displayName string
checkSuite.actor.user.handle string
checkSuite.actor.app object
checkSuite.actor.app.id string
checkSuite.actor.app.displayName string
checkSuite.actor.serviceAccount object
checkSuite.actor.serviceAccount.id string
checkRun object
status: rerequested): отметка времени сохраняется в check_run.rerequested_at, а инициатор запроса — в check_run.rerequested_by.checkRun.id string
checkRun.repository object
checkRun.repository.id string
checkRun.repository.name string
checkRun.repository.owner object
checkRun.repository.owner.slug строка
checkRun.repository.owner.id string
checkRun.repository.owner.type string
team или user. Только для вывода; не задаётся, если неизвестно. Одно из: team, user.checkRun.checkSuite object
checkRun.checkSuite.id string
checkRun.sha string
checkRun.key string
checkRun.name string
checkRun.status string
rerequested — это завершённый run, повторный запуск которого был запрошен, но владеющее приложение на него ещё не ответило: для читателей он считается ожидающим (отображайте его как queued), при этом conclusion и тайминги по-прежнему описывают вытесненную попытку. Задаётся только Origin при повторном запросе (RerequestCheckRun); приложения не могут его публиковать. Одно из: queued, in_progress, completed, rerequested.checkRun.conclusion string
status равен completed или rerequested. Для повторно запрошенного запуска это вердикт вытесненной попытки: рассматривайте запуск как ожидающий и читайте conclusion только когда status == completed. Одно из: success, failure, neutral, cancelled, skipped, timed_out, action_required, stale.checkRun.detailsUrl string
checkRun.externalUpdatedAt string
checkRun.startedAt string
checkRun.completedAt string
checkRun.createdAt string
checkRun.updatedAt string
checkRun.externalId string
CheckRunInput.external_id: рекомендуется по одному на выполнение).checkRun.actor object
checkRun.actor.user object
checkRun.actor.user.id string
checkRun.actor.user.email string Обязательное
checkRun.actor.user.displayName string
checkRun.actor.user.handle string
checkRun.actor.app object
checkRun.actor.app.id string
checkRun.actor.app.displayName string
checkRun.actor.serviceAccount object
checkRun.actor.serviceAccount.id string
checkRun.output object
checkRun.output.title string
checkRun.output.summary string
checkRun.output.text string
checkRun.deadlineAt string
checkRun.isRerequestable boolean
CheckRunInput.is_rerequestable).checkRun.rerequestedAt string
status равен rerequested, а run остаётся в состоянии CI коммита как ожидающий (conclusion и временные метки содержат вытесненный результат); владеющее приложение отвечает, публикуя run, к которому оно обязалось, объявив is_rerequestable, — новый run с тем же key либо обновление этого run (что сбрасывает данное поле), — после чего run можно запросить повторно. Метка времени в формате RFC 3339.checkRun.rerequestedBy object
rerequested_at; сбрасывается вместе с ним, когда отвечающее приложение отвечает.checkRun.rerequestedBy.user object
checkRun.rerequestedBy.user.id string
checkRun.rerequestedBy.user.email string Обязательное
checkRun.rerequestedBy.user.displayName string
checkRun.rerequestedBy.user.handle string
checkRun.rerequestedBy.app object
checkRun.rerequestedBy.app.id string
checkRun.rerequestedBy.app.displayName string
checkRun.rerequestedBy.serviceAccount object
checkRun.rerequestedBy.serviceAccount.id string
Пример event.payload:
{ "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "checkSuite": { "id": "crg_01k2ja2000e0080000000000h8", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "key": "ci-8842", "name": "CI", "detailsUrl": "https://ci.acme.dev/runs/8842", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T15:10:00Z", "externalId": "build-8842", "actor": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } } }, "checkRun": { "id": "cr_01k2ja2000e0080000000000g7", "repository": { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } }, "checkSuite": { "id": "crg_01k2ja2000e0080000000000h8" }, "sha": "9a41f0c3d2b8e7f6a5c4d3e2f1b0a9c8d7e6f5a4", "key": "ci-8842-unit-tests", "name": "unit-tests", "status": "rerequested", "conclusion": "failure", "detailsUrl": "https://ci.acme.dev/runs/8842", "externalUpdatedAt": "2026-08-02T14:44:30Z", "startedAt": "2026-08-02T14:40:00Z", "completedAt": "2026-08-02T14:44:30Z", "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T15:10:00Z", "externalId": "run-8842", "actor": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "output": { "title": "Unit tests", "summary": "1 of 129 tests failed.", "text": "FAIL telemetry.spec.ts > flushes queued events on shutdown" }, "isRerequestable": true, "rerequestedAt": "2026-08-02T15:10:00Z", "rerequestedBy": { "user": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } } }}Установка создана
installation.createdПоля payload
installation object
installation.id string
installation.appId string
app.id в payload.installation.target object
installation.target.slug string
installation.target.id string
installation.target.type string
team или user. Доступно только для вывода; не задано, если значение неизвестно. Одно из: team, user.installation.repoSelectionMode string
all, selected.installation.repositories array
installation.repositories[].id string
installation.repositories[].name string
installation.repositories[].owner object
installation.repositories[].owner.slug string
installation.repositories[].owner.id string
installation.repositories[].owner.type строка
team или user. Доступно только для вывода; не задано, если значение неизвестно. Одно из: team, user.installation.scopes array
installation.repositoriesCount integer
installation.createdAt string
installation.updatedAt string
installation.deletedAt string
installation.suspendedAt string
installation.installedBy object
installation.installedBy.id string
installation.installedBy.email string Обязательное
installation.installedBy.displayName string
installation.installedBy.handle string
app object
app.id string
app.displayName string
Пример event.payload:
{ "installation": { "id": "inst_01k2ja2000e0080000000000b2", "appId": "app_01k2ja2000e0080000000000a1", "target": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" }, "repoSelectionMode": "selected", "repositories": [ { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } } ], "scopes": [ "repository:contents:read", "repository:pull_requests:read" ], "repositoriesCount": 1, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-01T09:30:00Z", "installedBy": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "app": { "id": "app_01k2ja2000e0080000000000a1", "displayName": "CI Status Bot" }}Установка обновлена
installation.updatedПоля payload
installation object
installation.id string
installation.appId string
app.id в payload.installation.target object
installation.target.slug string
installation.target.id string
installation.target.type string
team или user. Доступно только для вывода; не задано, если значение неизвестно. Одно из: team, user.installation.repoSelectionMode string
all, selected.installation.repositories array
installation.repositories[].id string
installation.repositories[].name string
installation.repositories[].owner object
installation.repositories[].owner.slug string
installation.repositories[].owner.id string
installation.repositories[].owner.type строка
team или user. Доступно только для вывода; не задано, если значение неизвестно. Одно из: team, user.installation.scopes массив
installation.repositoriesCount integer
installation.createdAt string
installation.updatedAt string
installation.deletedAt string
installation.suspendedAt string
installation.installedBy object
installation.installedBy.id string
installation.installedBy.email string Обязательное
installation.installedBy.displayName string
installation.installedBy.handle string
app object
app.id string
app.displayName string
Пример event.payload:
{ "installation": { "id": "inst_01k2ja2000e0080000000000b2", "appId": "app_01k2ja2000e0080000000000a1", "target": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" }, "repoSelectionMode": "selected", "repositories": [ { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } } ], "scopes": [ "repository:contents:read", "repository:pull_requests:read" ], "repositoriesCount": 1, "createdAt": "2026-08-01T09:30:00Z", "updatedAt": "2026-08-02T14:45:00Z", "installedBy": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "app": { "id": "app_01k2ja2000e0080000000000a1", "displayName": "CI Status Bot" }}Установка приостановлена
installation.suspendedПоля payload
installation object
installation.id string
installation.appId string
app.id в payload.installation.target object
installation.target.slug string
installation.target.id string
installation.target.type string
team или user. Доступно только для вывода; не задано, если значение неизвестно. Одно из: team, user.installation.repoSelectionMode string
all, selected.installation.repositories array
installation.repositories[].id string
installation.repositories[].name string
installation.repositories[].owner object
installation.repositories[].owner.slug string
installation.repositories[].owner.id string
installation.repositories[].owner.type строка
team или user. Доступно только для вывода; не задано, если значение неизвестно. Одно из: team, user.installation.scopes массив
installation.repositoriesCount integer
installation.createdAt string
installation.updatedAt string
installation.deletedAt string
installation.suspendedAt string
installation.installedBy object
installation.installedBy.id string
installation.installedBy.email string Обязательное
installation.installedBy.displayName string
installation.installedBy.handle string
app object
app.id string
app.displayName string
Пример event.payload:
{ "installation": { "id": "inst_01k2ja2000e0080000000000b2", "appId": "app_01k2ja2000e0080000000000a1", "target": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" }, "repoSelectionMode": "selected", "repositories": [ { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } } ], "scopes": [ "repository:contents:read", "repository:pull_requests:read" ], "repositoriesCount": 1, "createdAt": "2026-08-01T09:30:00Z", "installedBy": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" }, "suspendedAt": "2026-08-03T08:15:00Z" }, "app": { "id": "app_01k2ja2000e0080000000000a1", "displayName": "CI Status Bot" }}Установка возобновлена
installation.unsuspendedПоля payload
installation object
installation.id string
installation.appId string
app.id в payload.installation.target object
installation.target.slug string
installation.target.id string
installation.target.type string
team или user. Доступно только для вывода; не задано, если значение неизвестно. Одно из: team, user.installation.repoSelectionMode string
all, selected.installation.repositories array
installation.repositories[].id string
installation.repositories[].name string
installation.repositories[].owner object
installation.repositories[].owner.slug string
installation.repositories[].owner.id string
installation.repositories[].owner.type строка
team или user. Доступно только для вывода; не задано, если значение неизвестно. Одно из: team, user.installation.scopes массив
installation.repositoriesCount integer
installation.createdAt string
installation.updatedAt string
installation.deletedAt string
installation.suspendedAt string
installation.installedBy object
installation.installedBy.id string
installation.installedBy.email string Обязательное
installation.installedBy.displayName string
installation.installedBy.handle string
app object
app.id string
app.displayName string
Пример event.payload:
{ "installation": { "id": "inst_01k2ja2000e0080000000000b2", "appId": "app_01k2ja2000e0080000000000a1", "target": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" }, "repoSelectionMode": "selected", "repositories": [ { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } } ], "scopes": [ "repository:contents:read", "repository:pull_requests:read" ], "repositoriesCount": 1, "createdAt": "2026-08-01T09:30:00Z", "installedBy": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" } }, "app": { "id": "app_01k2ja2000e0080000000000a1", "displayName": "CI Status Bot" }}Установка удалена
installation.deletedПоля payload
installation object
installation.id string
installation.appId string
app.id в payload.installation.target object
installation.target.slug string
installation.target.id string
installation.target.type string
team или user. Доступно только для вывода; не задано, если значение неизвестно. Одно из: team, user.installation.repoSelectionMode string
all, selected.installation.repositories array
installation.repositories[].id string
installation.repositories[].name string
installation.repositories[].owner object
installation.repositories[].owner.slug string
installation.repositories[].owner.id string
installation.repositories[].owner.type строка
team или user. Доступно только для вывода; не задано, если значение неизвестно. Одно из: team, user.installation.scopes array
installation.repositoriesCount integer
installation.createdAt string
installation.updatedAt string
installation.deletedAt string
installation.suspendedAt string
installation.installedBy object
installation.installedBy.id string
installation.installedBy.email string Обязательное
installation.installedBy.displayName string
installation.installedBy.handle string
app object
app.id string
app.displayName string
Пример event.payload:
{ "installation": { "id": "inst_01k2ja2000e0080000000000b2", "appId": "app_01k2ja2000e0080000000000a1", "target": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" }, "repoSelectionMode": "selected", "repositories": [ { "id": "repo_01k2ja2000e0080000000000q4", "name": "rocket", "owner": { "slug": "acme", "id": "ns_01k2ja2000e0080000000000p3", "type": "team" } } ], "scopes": [ "repository:contents:read", "repository:pull_requests:read" ], "repositoriesCount": 1, "createdAt": "2026-08-01T09:30:00Z", "installedBy": { "id": "user_01k2ja2000e0080000000000c3", "email": "[email protected]" }, "deletedAt": "2026-08-03T08:15:00Z" }, "app": { "id": "app_01k2ja2000e0080000000000a1", "displayName": "CI Status Bot" }}