Providers

Cursor Origin

Use pull requests on Cursor Origin, including stacked pull requests, reviews and check runs.

The Cursor Origin provider covers pull requests on Origin, including stacked pull requests, with their comments, reviews and check runs. It also covers repository contents and Origin App installations. Origin has no issues, discussions, releases or notifications.

DetailValue
Importforges/cursor-origin
FactoriescursorOrigin(), cursorOriginLite()
Authtoken, app
The Cursor Origin provider is experimental. It uses the alpha Origin API v1alpha1 (ORIGIN_API_VERSION), which can change. See Capabilities.

Authentication

The provider accepts a user access token or Origin App credentials:

import { cursorOrigin } from 'forges/cursor-origin'

const forge = cursorOrigin({
  auth: { type: 'token', token: process.env.CURSOR_AUTH_TOKEN! },
}).create()

const app = cursorOrigin({
  auth: {
    type: 'app',
    appId: 'app_01...',
    privateKey: process.env.ORIGIN_APP_PRIVATE_KEY!,
    installationId: 'i_01...',
  },
}).create()

A user access token is the value that the Origin CLI reads from CURSOR_AUTH_TOKEN. Personal Cursor API keys aren't Origin bearer tokens, and the provider doesn't accept them.

For app auth, privateKey is the app's Ed25519 private key in PKCS#8 PEM format. The provider signs an app JWT with it. With installationId, the provider mints installation tokens as it needs them. Without installationId, the provider authenticates as the app itself. In that case, installations.list() lists the app's installations, and installations.provider(installation) returns a provider for one installation.

Origin has no anonymous access, so auth is required.

Instance

The instance is origin.cursor.com, which is the host in clone URLs. baseUrl defaults to https://api.cursor.com, and the provider appends /v1/origin.

Stacked pull requests

For a pull request in a stack, thread.stack contains the stack ID and the parent pull request.

Merging

Origin supports the merge and squash methods only. If you don't pass method, merge() reads the repository settings. When exactly one method is allowed, it uses that method. When both are allowed, it throws MergeMethodRequiredError. whenChecksPass and message are unavailable.

Review comments

A comment anchored to a line in the diff is a review comment. Review comments appear in threads.events() as review_comment events, and threads.comments() doesn't return them. Origin doesn't link inline comments to the review that submitted them, so each review has comments: false.

Webhooks

Origin sends webhooks in the Standard Webhooks format, with these headers:

HeaderContent
webhook-idThe delivery ID
webhook-timestampThe time of the delivery, in seconds
webhook-signatureAn Ed25519 signature over the hex SHA-256 of <webhook-id>.<webhook-timestamp>.<body>

The provider verifies the signature against the public keys from the /keys endpoint, which it caches for ten minutes. It doesn't use webhookSecret. It rejects deliveries with a timestamp more than five minutes from the current time.

const forge = cursorOrigin({ auth }).create()

const events = await forge.webhooks.ingest({
  headers: request.headers,
  body: await request.text(),
})

installation.* deliveries become installation events. You register hooks in the app definition, so the webhooks management methods are unavailable.

Recording fixtures

CURSOR_AUTH_TOKEN=... FIXTURE_CURSOR_ORIGIN_REPO=owner/repo \
FIXTURE_CURSOR_ORIGIN_PULL=1 pnpm record-fixtures cursor-origin

Capabilities

Generated by pnpm capability-matrix; do not edit by hand.

CapabilitySupport
experimental✅
sources.poll❌
sources.webhook✅
sources.subscribe❌
repos.get✅
users.get❌
repos.listexperimental
repos.labels❌
repos.createLabel❌
repos.milestones❌
repos.collaborators❌
repos.permissionFor❌
repos.addCollaborator❌
repos.assignableUsers❌
repos.reviewerCandidates❌
threads.getPR
threads.listPR
threads.getMany✅
comments.listPR
comments.editPR (experimental)
comments.deletePR (experimental)
reactions.list❌
notifications.list❌
notifications.markRead❌
notifications.markDone❌
notifications.unsubscribe❌
notifications.markAllRead❌
notifications.markAllDone❌
notifications.unreadCount❌
writes.commentPR
writes.upsertCommentPR (emulated)
writes.closePR
writes.reopenPR
writes.createPR (experimental)
writes.updatePR (experimental)
writes.setLabelsPR (experimental)
writes.addLabels❌
writes.removeLabels❌
writes.setMilestone❌
writes.react❌
writes.setAssignees❌
writes.requestReviewPR (experimental)
writes.merge✅
writes.approveAndMerge✅
writes.transfer❌
writes.markDuplicate❌
subscriptions.get❌
subscriptions.set❌
installations❌
checks.threadPR
checks.listexperimental
checks.report❌
checks.rerun❌
ci.runs❌
ci.run❌
ci.jobs❌
ci.log❌
contents.fileexperimental
contents.treeexperimental
contents.branchesexperimental
contents.tagsexperimental
contents.resolveRefexperimental
contents.commitsexperimental
contents.commitexperimental
contents.compareexperimental
contents.threadFilesexperimental
contents.threadCommitsexperimental
reviews.list✅
reviews.createexperimental
reviews.submit❌
reviews.approveexperimental
reviews.resolveThreadexperimental
releases.list❌
releases.get❌
releases.latest❌
releases.getByTag❌
releases.downloadAsset❌
webhooks.list❌
webhooks.create❌
webhooks.update❌
webhooks.delete❌
webhooks.rotateSecret❌
webhooks.deliveries❌
webhooks.redeliver❌
search.threads❌
search.repos❌
search.commits❌
securityAlerts❌
eventKindsnative
authtoken, app
limitsunknown
Copyright © 2026