
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.