Skip to main content
API · v1

The context layer for your GitHub org

One API turns your whole GitHub organization into structured, LLM-ready context — ownership, dependency graph, contributor expertise, PR & review context, semantic retrieval, and activity. Call it directly, or connect the official MCP server and any agent gets it as native tools.

Getting started

Overview

Every endpoint is scoped to your organization, derived from your API key and GitHub App install — you never pass an org id. Read endpoints return pre-computed, relationship-aware context; webhooks push updates to you in real time.

Value
Base URLhttps://eos.dev/api/v1
AuthBearer API key (eos_…)
FormatJSON · { data, meta }
VersioningX-EOS-API-Version: 1 (additive only)
Getting started

Quickstart

Three steps from zero to your first context call:

1. Install the EOS GitHub App on the repos you want context for — every surface is scoped to what the App can see. 2. Create an API key in Settings → API (pick the scopes you need). 3. Call the API:

curl "https://eos.dev/api/v1/context/ownership?repo=acme/app&path=services/auth" \
  -H "Authorization: Bearer eos_your_key_here"

Or with the TypeScript SDK:

import { EosClient } from "@eos-ai/sdk";

const eos = new EosClient({ apiKey: process.env.EOS_API_KEY });
const { data } = await eos.context.ownership({ repo: "acme/app", path: "services/auth" });
console.log(data[0].handle, data[0].score); // "alex.kim" 912.4
Getting started

Authentication & scopes

Pass your key as a Bearer token on every request. Any org member can create a key from Settings → API in the console; manage, rotate and revoke them there. A key is scoped to the organization it was minted for and only grants the scopes you select — pick the least it needs.

Keys & the GitHub App. Context is only available for repositories the EOS GitHub App can see. A key inherits that install’s scope — it can read context for those repos and nothing else. Install or adjust repository access from the console at any time.

Authorization: Bearer eos_xxxxxxxxxxxxxxxxxxxxxxxx
ScopeGrants
read:contextAll context surfaces: ownership & expertise, architecture & dependency graph, contributors, PR & review context, and activity/hotspots.
read:searchRetrieval over your org's own history (POST /context/search) — LLM-ready chunks with citations.
read:sqlRead-only SQL over your workspace's own data (POST /context/query) — the curated api.* views.

The console authenticates by session cookie instead of a key; both resolve to the same org-scoped access.

Getting started

Limits & usage

The unit is one context request (one API call or one MCP tool call). Every plan gets the full API surface — tiers gate volume, not endpoints. Two limits apply in parallel: a short-window rate limit (hour + day) that protects the service, and a monthly quota. Every response carries both, so a client (or an agent) can pace itself:

X-RateLimit-Limit: 100          # daily request cap for your plan
X-RateLimit-Remaining: 98
X-RateLimit-Reset: 34200        # seconds until the daily window resets (midnight UTC)
X-EOS-Quota-Limit: 5000         # monthly context-request quota
X-EOS-Quota-Used: 1287
X-EOS-Quota-Remaining: 3713
X-EOS-Quota-Warning: 80         # only present at 80% / 100% of the monthly quota

Requests allowed per plan:

PlanPer hourPer dayPer month
Free601005,000
Starter2001,000Unlimited
Pro2,00010,000Unlimited
EnterpriseUnlimitedUnlimitedUnlimited

The Free tier includes the full API surface and the MCP server. Semantic retrieval and synthesis are powered internally by Claude — folded into pricing, never a separate credit SKU. Exceeding a limit returns 429 with a Retry-After header; the daily limit resets at midnight UTC and the hourly at the top of the hour.

Getting started

Responses & errors

Successful responses use a { data, meta } envelope. data is the surface’s result (an array for list surfaces, an object for the graph); meta carries result counts, timestamps, and per-surface context. For data freshness, call /context/freshness.

{
  "data": [ /* … the surface's result … */ ],
  "meta": { "total": 2, "generated_at": "2026-07-30T12:00:00Z" }
}

Errors return { error, code }. Branch on code (stable), not the message:

codeMeaning
invalid_requestA query/body parameter failed validation (HTTP 400).
unauthorizedMissing or invalid API key (HTTP 401).
forbidden_scopeThe key lacks the scope the endpoint requires (HTTP 403).
plan_upgrade_requiredThe endpoint requires a higher plan than the key's workspace has (HTTP 403).
rate_limitedRate limit or monthly quota exceeded — see Retry-After (HTTP 429).
not_foundThe requested resource doesn't exist (HTTP 404).
internalUnexpected server error (HTTP 500).
Context surfaces

Ownership & expertise

Who owns or knows any file, module, or system — computed from real contribution history, not CODEOWNERS. The answer to “who should review this?” and “who knows auth?”

GET/context/ownershipread:contextFree+
Who owns or knows a file, module, or directory — from real contribution history. Pass repo + path; returns ranked owners with a knowledge-concentration (bus-factor) signal. 'Who should review this?' 'Who knows auth?'
GET /api/v1/context/ownership?repo=acme/app&path=services/auth

{
  "data": [
    { "handle": "alex.kim", "score": 912.4, "commits": 312, "recent_commits": 41,
      "files_touched": 18, "lines_changed": 8730, "last_committed": "2026-07-28T09:12:00Z" },
    { "handle": "ren.park", "score": 104.2, "commits": 47, "recent_commits": 3,
      "files_touched": 9, "lines_changed": 1210, "last_committed": "2026-05-02T14:03:00Z" }
  ],
  "meta": {
    "repo": "acme/app", "path": "services/auth", "total": 2, "weighting": "recency_churn",
    "knowledge_concentration": { "top_owner": "alex.kim", "top_owner_share": 0.898, "single_owner_risk": true }
  }
}
Context surfaces

Architecture & dependency graph

A structural map of the org — repos, modules, inter-file dependencies, and coupling (files that change together). The same graph your agents retrieve and the console visualizes.

GET/context/graphread:contextStarter+
Structural map of repos, modules, and inter-file dependencies across the org.
GET/context/graph/couplingread:contextStarter+
Logical coupling — files that change together, derived from co-change history.
GET/context/graph/importsread:contextStarter+
Static import dependency graph — real 'A imports B' edges parsed from source (JS/TS), rolled up to modules.
GET /api/v1/context/graph?repo=acme/app

{
  "data": {
    "nodes": [
      { "id": "services/auth", "commits": 210, "file_count": 34 },
      { "id": "lib/db",        "commits": 168, "file_count": 22 }
    ],
    "edges": [
      { "source": "services/auth", "target": "lib/db", "shared_commits": 41 }
    ]
  },
  "meta": { "plan": "pro", "repo": "acme/app", "node_count": 2, "edge_count": 1,
    "module_total": 2, "truncated": false, "generated_at": "2026-07-30T12:00:00Z" }
}
Context surfaces

Contributor context

Per-person expertise areas, activity footprint, and review history — so an agent can route work to the right human.

GET/context/contributorsread:contextFree+
Per-person expertise areas, activity footprint, and review history.
GET/context/contributors/{handle}read:contextFree+
One contributor's expertise map and where they are most active.
GET /api/v1/context/contributors/alex.kim

{
  "data": {
    "handle": "alex.kim",
    "period_days": 180, "merged_prs": 63, "open_prs": 2,
    "avg_cycle_time_hours": 18.4, "lines_changed": 24100,
    "expertise": [
      { "repo": "acme/api", "commits": 312 },
      { "repo": "acme/app", "commits": 96 }
    ],
    "recent_prs": [
      { "title": "Rotate refresh tokens", "repo": "acme/api", "merged_at": "2026-07-27T14:03:00Z" }
    ]
  }
}
Context surfaces

PR & review context

The review graph: who reviews what, turnaround, and related past PRs — plus scored reviewer suggestions with citations.

GET/context/pullsread:contextFree+
The review graph: who reviews what, turnaround, and related past PRs.
GET/context/pulls/{number}/reviewersread:contextFree+
Suggested reviewers for a PR, scored by expertise, recency and availability — with citations.
GET /api/v1/context/pulls/482/reviewers?repo=acme/api

{
  "data": {
    "pr": { "repo": "acme/api", "number": 482, "title": "Add rate limiting", "author": "dan" },
    "suggested_reviewers": [
      { "github_handle": "sam.lee", "display_name": "Sam Lee", "score": 0.82,
        "reason": "5 PRs merged in this repo, no open PRs, 4 merged in the last 30d",
        "signals": { "repo_prs": 5, "wip": 0, "merged_30d": 4 } }
    ],
    "primary": "sam.lee"
  },
  "meta": { "plan": "pro", "count": 1 }
}
Context surfaces

Activity & hotspots

Where change is concentrated right now — hotspots, churn, and what's moving across the org.

GET/context/activityread:contextStarter+
Where change is concentrated right now — hotspots, churn, and what's moving.
GET /api/v1/context/activity?repo=acme/app&days=7

{
  "data": [
    { "path": "services/auth/session.ts", "file": "session.ts", "module": "services/auth",
      "commits": 23, "author_count": 4, "intensity": "high",
      "summary": "session.ts changed 23× by 4 authors in the last 7d" }
  ],
  "meta": { "plan": "pro", "repo": "acme/app", "period_days": 7, "count": 1,
    "file_count": 991, "truncated": false, "generated_at": "2026-07-30T12:00:00Z" }
}
Context surfaces

SQL query

Run read-only SQL over your own workspace data — pull requests, commits, repos, developers, Linear issues, and CI runs — when the fixed endpoints don't match the exact shape you need. Every view is already scoped to your workspace; there's no workspace_id to pass or filter on. Pro plan and up.

Only a single SELECT (or WITH … SELECT) is allowed. Results are capped at limit rows (default 1000) and queries time out at ~8s. Call GET /context/query/schema for the exact views and columns. Pass "format": "csv" to get a CSV download instead of JSON (row count and truncation are returned in the X-EOS-Row-Count / X-EOS-Truncated headers). Hit the row cap? Page with keyset in your SQL — e.g. … where id > $last order by id limit 1000.

POST/context/queryread:sqlPro+
Run read-only SQL over your own data — PRs, commits, repos, developers, Linear issues, CI runs — scoped to your workspace. JSON or CSV.
GET/context/query/schemaread:sqlPro+
The queryable views and their columns, so you (or an LLM) know what SQL you can write.
POST /api/v1/context/query
{ "sql": "select repo, count(*) as prs from pull_requests where state = 'merged' group by 1 order by 2 desc", "limit": 100 }

{
  "data": [
    { "repo": "acme/api", "prs": 128 },
    { "repo": "acme/web", "prs": 74 }
  ],
  "meta": { "plan": "pro", "row_count": 2, "truncated": false, "limit": 100,
    "generated_at": "2026-08-03T12:00:00Z" }
}
Realtime & tooling

Webhooks

Subscribe an https endpoint and EOS pushes events as they happen — so your agents always call fresh context without polling. Manage subscriptions in Settings → API (Pro+). The signing secret is shown once.

EventFires when
context.updatedAny context surface for a path was recomputed after a change.
ownership.changedThe owner or backup owner of a file or module changed.
graph.changedDependencies or coupling for a module changed.
contributor.updatedA contributor's expertise or activity footprint shifted.
pull.reviewed / pull.mergedA pull request was reviewed or merged.
reindex.completedA repository finished (re)indexing — its context is now fresh.

Each delivery is a signed POST. Verify X-EOS-Signature (HMAC-SHA256 of the raw body) before trusting it:

import { createHmac, timingSafeEqual } from "node:crypto";

function verify(rawBody, header, secret) {
  const expected = "sha256=" + createHmac("sha256", secret).update(rawBody).digest("hex");
  const a = Buffer.from(header), b = Buffer.from(expected);
  return a.length === b.length && timingSafeEqual(a, b);
}

Payloads carry a stable id (the idempotency key), api_version, and are retried up to 3× with backoff.

Realtime & tooling

SDK

The TypeScript SDK wraps every context surface with types. Install @eos-ai/sdk:

import { EosClient } from "@eos-ai/sdk";
const eos = new EosClient({ apiKey: process.env.EOS_API_KEY });

await eos.context.ownership({ repo: "acme/api", path: "services/auth" });
await eos.context.graph({ repo: "acme/api" });
await eos.context.contributor("alex.kim");
await eos.context.reviewers(482, { repo: "acme/api" });
await eos.context.search({ query: "how does auth refresh work" });
Realtime & tooling

MCP — for AI agents

Run the official EOS MCP server so any MCP-compatible agent (Claude Desktop, Cursor, Windsurf) gets your org as native tools — zero glue code. It exposes get_ownership, get_graph, get_contributors, suggest_reviewers, search_context and more.

{
  "mcpServers": {
    "eos": {
      "command": "npx",
      "args": ["-y", "@eos-ai/mcp-server"],
      "env": { "EOS_API_KEY": "eos_your_key_here" }
    }
  }
}

Looking for the raw machine-readable spec? The full OpenAPI document is at /api/docs.