Skip to main content
API reference →
SQL · Context API · How-to

Query your entire GitHub org with SQL

August 17, 2026 · 6 min read

EOS indexes your entire GitHub organization — every pull request, commit, review, and CI run — into one model, and then hands it back to you as a database you can query with read-only SQL. One SELECT, one API call, rows back. No paginating the GitHub API, no recomputing per request, no rate limits.

Index once, query anything

The GitHub API is a firehose of raw events. Ask it something as ordinary as “how many PRs merged in under a day last month, by repo?” and you’re paginating thousands of objects, holding them in memory, and computing the answer yourself — against a 5,000-request-per-hour ceiling, on every run.

EOS already did that work. It continuously ingests the org and keeps a fresh, structured index. You don’t crawl anything — you send SQL to POST /v1/context/query and get the answer directly.

One request

Send a single SELECT and your API key. That’s the whole surface:

curl https://eos.dev/api/v1/context/query \
  -H "Authorization: Bearer $EOS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "sql": "select repo, count(*) as merged from pull_requests where state = '\''merged'\'' and merged_at > now() - interval '\''30 days'\'' group by repo order by merged desc",
    "limit": 100
  }'

A few rules keep it safe and simple: it’s read-only — a single SELECT (or WITH … SELECT), nothing else. Every view is already scoped to your workspace, so there’s no workspace_id to filter on and no way to reach another org’s data. Results are capped at limit rows (default and max 1,000), and queries time out at about eight seconds.

What you can query

The index is exposed as a handful of Postgres views — reference them bare (pull_requests) or qualified (api.pull_requests):

The exact, current shape — every view and column — is discoverable at GET /v1/context/query/schema, so an agent writing SQL can read the schema first.

Real queries

These run as-is against the views above.

Cycle time — median hours from open to merge, per repo:

select
  repo,
  round(percentile_cont(0.5) within group (
    order by extract(epoch from (merged_at - opened_at)) / 3600
  )::numeric, 1) as median_hours
from pull_requests
where state = 'merged'
  and merged_at > now() - interval '90 days'
group by repo
order by median_hours;

Review coverage — share of merged PRs that got at least one review:

select
  round(100.0 * avg((review_count > 0)::int), 1) as pct_reviewed
from pull_requests
where state = 'merged'
  and merged_at > now() - interval '30 days';

Load — top authors by merged PRs and total churn, last 30 days:

select
  author_handle,
  count(*) as merged,
  sum(lines_added + lines_removed) as churn
from pull_requests
where state = 'merged'
  and merged_at > now() - interval '30 days'
group by author_handle
order by merged desc
limit 10;

CI health — failure rate per workflow, last two weeks:

select
  workflow_name,
  count(*) as runs,
  round(100.0 * avg((conclusion = 'failure')::int), 1) as fail_pct
from ci_runs
where started_at > now() - interval '14 days'
group by workflow_name
order by fail_pct desc;

Why this beats the alternatives

Build any view on top

Because the answer comes back as plain rows, the query is the building block for anything: a weekly report a cron assembles every Friday, a panel in your own dashboard, or an agent that asks “who usually reviews changes like this?” before it routes a PR. You’re not consuming our dashboards — you’re querying the index underneath them and shaping the output however you need.

Read-only SQL is available on EOS’s paid plans, starting at Starter, $5/month. The free tier covers the REST and MCP surfaces — read the reference or grab a key to start.
Give your agents the context of your entire GitHub org.
Free tier: 5,000 context requests every month, no credit card.