API / grep-origin-contents-via-api

API

Grep Origin Contents via the API

Search the text of a repository's files at a ref with POST https://api.cursor.com/v1/origin/repos/{ownerSlug}/{repoName}:grep. Official reference: Origin API and changelog (OpenAPI OriginService_GrepContents).

Origin is in Early Beta and subject to change. Authenticate with an installation access token (oit_…) or a user access token that carries repository:contents:read. Availability: Early Beta per the API overview.

The body requires query. By default query is a regular expression; set literal to true to match exact text. The search is line-oriented: a pattern never matches across a line break, and each returned entry is one line. There is no pagination; the response is complete only when limitHit is false.

Cost: 5 points against the principal budget (heavier read, same tier as Get Commit and Get Repo Tarball).

Path parameters

Param Required Meaning
ownerSlug yes Owning entity's unique slug
repoName yes Repo name, unique to the owner

Request body

Field Required Meaning
query yes Pattern to search. Empty is rejected (400). Max UTF-8 size: 4096 bytes
ref no Commit, branch, tag, or symbolic ref such as HEAD. Empty uses the default branch
literal no When true, treat query as exact text instead of a regex
caseInsensitive no Applied only when literal is true; ignored for regex (use a leading (?i) in query)
wholeWord no Applied only when literal is true; ignored for regex (use \b around the pattern)
contextBefore no Lines of context before each match; values above 10 reduce to 10
contextAfter no Lines of context after each match; values above 10 reduce to 10
filterPath no Restrict to this file or directory relative to the repo root
includes no Glob allowlist (at most 20). Case-insensitive; * is one segment; ** crosses segments
excludes no Glob denylist (at most 20). An exclude beats an include
maxResults no Cap on matching occurrences. 0 or omit defaults to 1000; values above 1000 reduce to 1000. Context lines do not count
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 '{
  "query": "(?i)launch",
  "ref": "HEAD",
  "includes": ["**/*.ts"],
  "excludes": ["**/node_modules/**"],
  "contextBefore": 1,
  "contextAfter": 1,
  "maxResults": 100
}'

Literal whole-word example:

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 '{
  "query": "launch",
  "literal": true,
  "caseInsensitive": true,
  "wholeWord": true
}'

Response

200 returns matches (order of files and lines is unspecified) and limitHit.

Each entry is a GrepContentsMatch:

Field Meaning
path Path relative to the repository root
lineNumber One-based line number
line Line text without its trailing terminator
kind match or context
submatches Byte ranges inside line (start inclusive, end exclusive). Always empty on context lines
{
  "matches": [
    {
      "path": "src/cli.ts",
      "lineNumber": 42,
      "line": "  await launchAgent(opts);",
      "kind": "match",
      "submatches": [
        {
          "start": 8,
          "end": 14
        }
      ]
    }
  ],
  "limitHit": false
}

An empty repository (no refs) returns no matches and limitHit false. When limitHit is true, narrow query, filterPath, or the glob lists. Base URL: https://api.cursor.com/v1/origin.