API / create-origin-app-via-api

API

Create an Origin App via the API

Register a new Origin App owned by a namespace with POST https://api.cursor.com/v1/origin/namespaces/{namespaceSlug}/apps. Official reference: Origin API → Create App.

Origin is in Early Beta and subject to change. Authenticate with a Cursor user access token that carries namespace:apps:create. An app JWT cannot create apps for itself. Availability: Early Beta per the API overview.

Generate an Ed25519 key pair locally and send only the PEM SPKI public key. Origin stores that public key to verify the app's JWTs. Keep the private key in a secrets manager. Apps are created private.

The namespace owner must be eligible to write to Origin when you call Create App (same bar as Create Repo). A user owner needs Pro, Pro Student, Pro+, Ultra, or Start. A team owner needs an active paid team plan, must not be on Privacy Mode (Legacy), and must not have Origin turned off by a team admin. Origin checks the namespace owner's eligibility, not the calling user's. An ineligible owner returns FailedPrecondition (HTTP 400).

Invalid webhook URLs, event types, redirect URIs, or scopes return InvalidArgument (HTTP 400). Cost: 10 points against the user principal budget.

Path parameters

Param Required Meaning
namespaceSlug yes Slug of the namespace that will own the app

Request body

Field Required Meaning
displayName yes Human-facing app name; must not be empty
publicKey yes PEM SPKI Ed25519 public key
webhookUrl no Absolute HTTPS webhook URL; empty means no deliveries
events no Webhook event slugs from the Origin events catalog
description no Short description
websiteUrl no Absolute HTTPS publisher site
installationRedirectUris no Exact HTTPS install callback allowlist (no fragment)
defaultScopes no Default scopes offered at install (e.g. repository:contents:read)
openssl genpkey -algorithm ED25519 -out origin-app-private.pem
openssl pkey -in origin-app-private.pem -pubout -out origin-app-public.pem
curl --request POST \
  --url 'https://api.cursor.com/v1/origin/namespaces/NAMESPACE_SLUG/apps' \
  --header 'Authorization: Bearer YOUR_USER_ACCESS_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"
  ]
}'

Response

The body returns the created app: id (prefixed app_), displayName, webhookUrl, events, createdAt, updatedAt, installationRedirectUris, namespaceSlug, description, websiteUrl, and defaultScopes.

Store id. Use it as the JWT iss / kid when signing app JWTs, and as client_id on the install URL. Manage settings later with Get App and Update App; rotate keys with Add App Signing Key and Revoke App Signing Key.

For interactive or scripted user calls, prefer origin api after origin auth login (or CURSOR_API_KEY) so the CLI exchanges a personal user API key for a short-lived user access token. Do not put a Cursor API key directly in the Origin Authorization header.

Base URL: https://api.cursor.com/v1/origin.