Drillr provides market data, SEC filings, and AI-generated analysis for informational purposes only. Third-party data is not guaranteed accurate. See Disclaimer.

Drillr External API — Developer Guide#

Access Drillr's AI-powered financial research and data feeds through MCP, REST API, or CLI.

Table of Contents#


Authentication#

Modern MCP clients can connect without an API key. Configure only the Streamable HTTP URL:

https://gateway.drillr.ai/mcp/data

On first connection the client opens Drillr in your browser. Sign in, review the client name, and approve access. Drillr issues that client its own revocable external credential; your browser session and the credential itself are never shown or copied into configuration.

OAuth credentials can call only the public /mcp/data surface. They use the same wallet, pricing, rate limits, usage reporting, and revoke controls as API keys. Manage authorized clients at https://drillr.ai/developer/keys.

REST and fallback clients: API key#

REST endpoints require an API key. API keys also remain supported for MCP clients that do not implement browser OAuth. Create one at https://drillr.ai/developer/keys; it is shown exactly once, so store it in a secret manager.

Pass the key with either header:

# Use either one, not both.
Authorization: Bearer drl_xxx

# Alternative header:
X-API-Key: drl_xxx

For agent-assisted setup, open https://drillr.ai/developer/agent and copy the setup prompt for your client into Codex or Claude Code. The install guide lives at https://drillr.ai/developer/mcp-install.md.


MCP Tools#

Connect to https://gateway.drillr.ai/mcp/data via MCP Streamable HTTP transport.

Eight data tools are exposed on this MCP server. Per-call pricing is listed in Pricing.

ToolPurpose
run_sqlRead-only PostgreSQL SELECT over financial + alternative-data tables
get_table_schemaColumn metadata for a specific table (use before crafting run_sql)
list_tablesBrowse altdata categories + their tables/columns
news_searchSemantic search over news, market events, and attributed claims, grouped into storylines
sec_report_listList SEC filings (10-K / 10-Q / 8-K / S-4 / JP EDINET) by company + date
sec_report_searchVector + keyword search inside SEC filing narrative
company_searchNL company / asset discovery — finds tickers matching a thematic prompt (e.g. "AI infra plays")
ticker_lookupResolve a company name / brand / ticker substring to canonical ticker(s) with history

Five-market company discovery#

company_search covers US, Japan, Hong Kong, China A-shares, and Korea. Its optional market argument accepts one lowercase value or a list drawn from us, jp, hk, cn, and kr. Omit market or pass [] to search all five markets; list order does not express priority.

{
  "query": "Hong Kong and China EV battery suppliers",
  "market": ["hk", "cn"]
}

The REST endpoint POST /api/v1/data/company_search uses the same request body. Existing clients that send a single value such as "market": "jp" remain valid.

Synchronous one-shot search is available as REST POST /api/v1/search — see REST API.

Typical MCP flow#

1. list_tables({ categories: ["Macro & Trade"] })
   → Discover available tables + their columns

2. get_table_schema({ table_name: "financial_statements" })
   → Column list before crafting a SQL query

3. run_sql({ sql: "SELECT ... FROM financial_statements WHERE ticker = 'AAPL' ..." })
   → Structured rows

4. sec_report_search({ ticker: "AAPL", query: "AI capex guidance" })
   → Relevant filing passages with citations

REST API#

Base URL: https://gateway.drillr.ai

All endpoints are rooted at /api/v1/ and require an API key.

MethodPathPurpose
POST/api/v1/searchSynchronous research agent (NL question → answer)
POST/api/v1/data/run_sqlREST mirror of MCP run_sql
GET/api/v1/data/get_table_schemaREST mirror of MCP get_table_schema
GET/api/v1/data/list_tablesREST mirror of MCP list_tables
POST/api/v1/data/news_searchREST mirror of MCP news_search
GET/api/v1/data/sec_report_listREST mirror of MCP sec_report_list
POST/api/v1/data/sec_report_searchREST mirror of MCP sec_report_search
POST/api/v1/data/company_searchREST mirror of MCP company_search
POST/api/v1/data/ticker_lookupREST mirror of MCP ticker_lookup

The /api/v1/data/* endpoints mirror the 9 MCP tools above 1:1 — same inputs, same outputs, same pricing. Use them when you'd rather call HTTP directly than wire up an MCP client.

The one shape difference: news_search over MCP returns Markdown (to fit the MCP host's token cap), while the REST endpoint returns the structured JSON envelope — storylines with their events, plus a parallel claims array.

Renamed and retired endpoints (2026-07-14)#

  • ticker_resolveticker_lookup. The MCP tool name changed immediately. The old REST path POST /api/v1/data/ticker_resolve still works as a deprecated alias for one release — migrate now, it will be removed.
  • signal_listnews_search. This one is a replacement, not an alias: GET /api/v1/data/signal_list and the MCP signal_list tool are gone, not deprecated. news_search covers the same feed with semantic retrieval and storyline grouping, but the parameters differ (ticker / theme / query / since / until instead of tickers / sector / from_date / to_date), and there is no sector filter.

POST /api/v1/search#

ParameterTypeRequiredDefaultDescription
questionstringYes-The question
contextstringNo-Additional context
session_idstringNo-Continue a previous session
streambooleanNotrueSSE streaming or JSON response

Streaming example:

curl -X POST https://gateway.drillr.ai/api/v1/search \
  -H "Authorization: Bearer drl_xxx" \
  -H "X-Drillr-Via: github" \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -d '{"question": "What is NVDA PE ratio?"}'

SSE events:

EventDescription
statusConnection established, includes session_id
tool_callAgent is calling a data source (user-friendly label)
text_deltaIncremental text content
doneComplete or failed. Payload: { status, session_id, sources, duration_ms, _credits: { charged, method }, error? }. _credits.charged is the string "0.0" on status: 'failed' (failed calls aren't billed).

Non-streaming JSON:

curl -X POST https://gateway.drillr.ai/api/v1/search \
  -H "Authorization: Bearer drl_xxx" \
  -H "X-Drillr-Via: github" \
  -H "Content-Type: application/json" \
  -d '{"question": "AAPL market cap?", "stream": false}'
{
  "data": {
    "text": "Apple's market cap is approximately $3.4 trillion...",
    "session_id": "uuid",
    "sources": [{ "tool": "Looking up company info (AAPL)", "ticker": "AAPL" }],
    "duration_ms": 12500,
  },
  "_credits": {
    "charged": "4.0",
    "method": "usage_based",
  },
}

/api/v1/search uses the same envelope as /api/v1/data/* — see the Response envelope section under Pricing for the full schema (success + error). _credits.balance_after is not returned on this endpoint; check the Usage page for the latest balance.

For per-tool input/output shapes of the /api/v1/data/* endpoints, the description fields on each MCP tool are the source of truth — call once with sample inputs to inspect the response.


CLI Tool#

A first-party drillr CLI is coming soon — it'll wrap the same authentication, search, and data tools available through MCP and REST. Until then, please use the MCP or REST channels above.


Pricing#

Drillr Data API calls are billed in credits (cr). Each billable call deducts credits from your account balance. You can view per-call deductions on the Usage page.

Pricing modes#

Fixedrun_sql / sec_report_list / sec_report_search / news_search charge a flat per-call rate (see the table below).

Usage-based — tools powered by an AI agent (the research agent, NL company discovery) are billed by actual work, so the per-call charge varies. Typical ranges are listed in the per-tool table below; responses surface the exact charge as _credits.charged and _credits.method: "usage_based".

Free — schema / navigation utilities are not billed.

Per-tool rates#

Tool / EndpointPer callMode
run_sql0.1 crFixed
sec_report_list0.1 crFixed
sec_report_search0.1 crFixed
news_search0.2 crFixed
company_searchtypical 3–5 crUsage-based
POST /api/v1/searchtypical 2–5 crUsage-based
get_table_schema0 crFree
list_tables0 crFree
ticker_lookup0 crFree

Notes#

  • Same tool, same price across surfaces. A run_sql call costs the same via MCP (/mcp/data) or REST (/api/v1/data/run_sql), and the same applies to every other data tool.
  • run_sql row cap by plan. Each query returns up to 100 rows on Free/Plus and up to 500 rows on Ultra/Enterprise. An explicit larger LIMIT is clamped to the cap; when a result is capped the response carries truncated: true and a notice.
  • Failed calls are not billed. Errors before tool execution (auth, validation, permission 403) don't deduct credits. Errors during execution (upstream timeout, etc.) are also not billed.
  • Balance + usage are surfaced on the Developer dashboard. /api/v1/search returns 402 Payment Required when your balance is too low. Keep your balance positive to avoid interrupted calls.

Response envelope#

All nine /api/v1/data/* endpoints use a uniform envelope so clients can write a single response parser and balance check across the surface.

Success (2xx):

{
  "data": {
    /* tool-specific payload — see each endpoint's schema in the OpenAPI spec */
  },
  "_credits": {
    "charged": "0.1", // 1-decimal cr string
    "method": "per_call", // per_call | usage_based | free
    "balance_after": "1842.0", // remaining credit balance, 1-decimal cr string
  },
}

_credits.charged and _credits.balance_after are 1-decimal credit strings (e.g. "0.1", "0.2", "499.9"), not numbers — per-call data tools cost fractional credits. Parse with parseFloat() if you need a number.

  • _credits.charged — credits deducted for this call as a 1-decimal cr string; "0.0" for free tools
  • _credits.method — billing mode:
    • per_call — fixed per-request charge
    • usage_based — variable charge, scales with the work done
    • free — no charge
  • _credits.balance_after — your credit balance after this call, as a 1-decimal cr string. Best-effort — may be omitted. For the authoritative balance, check the Usage page.

Error (4xx / 5xx):

{
  "error": {
    "code": "invalid_request", // stable machine-readable
    "message": "Missing required query param: ticker", // human-readable, not stable
    "retry_after_seconds": 30, // present on 429 only
    "limit": 8, // present on 429 concurrency-limit only
  },
}

Known error.code values: invalid_request, unauthenticated, forbidden, rate_limited. New codes may be added — treat unknown codes as opaque and fall back to error.message for the human detail.


Rate Limits#

LimitValue
Request rate30 / minute

Rate limits apply per OAuth credential or API key. 429 responses include retry_after_seconds. For balance-related failures see Pricing.


Platform Setup Examples#

Use browser OAuth whenever the client supports it. The MCP URL alone is enough; do not add an Authorization header or copy a key into the config.

Claude Code#

claude mcp add --scope user --transport http drillr-data \
  https://gateway.drillr.ai/mcp/data

From a human-operated terminal, run claude mcp login drillr-data and complete the browser flow. If Drillr first shows a sign-in page, sign in and then review the client name and click Allow. Start or restart Claude Code after login so the new user-scoped server is loaded into the conversation.

When a coding agent performs setup inside an already-open Claude Code conversation, its Bash tool has no terminal and that conversation does not hot-load a new user-scoped entry. The agent install contract uses a pseudo-terminal around the native login command, waits for its callback, and runs the free verification in a clean one-shot Claude Code process.

Codex CLI#

codex mcp add drillr-data --url https://gateway.drillr.ai/mcp/data

Current Codex versions may open the Drillr consent page and complete OAuth during add. If add reports a successful login, do not run another login command. Only when it finishes without authenticating, or when an existing entry needs authentication, run:

codex mcp login drillr-data

Claude Desktop#

{
  "mcpServers": {
    "drillr-data": {
      "type": "http",
      "url": "https://gateway.drillr.ai/mcp/data"
    }
  }
}

Restart Claude Desktop after saving the file, then approve Drillr in the browser when prompted.

API-key fallback: Hermes Agent#

Use this only when the installed Hermes/OpenClaw version does not support MCP OAuth. Create the key at https://drillr.ai/developer/keys and store it as a secret.

mcp_servers:
  drillr-data:
    url: 'https://gateway.drillr.ai/mcp/data'
    headers:
      Authorization: 'Bearer drl_xxx'
      X-Drillr-Via: 'github'
    timeout: 120

API-key fallback: OpenClaw#

{
  "mcp": {
    "servers": {
      "drillr-data": {
        "url": "https://gateway.drillr.ai/mcp/data",
        "headers": {
          "Authorization": "Bearer drl_xxx",
          "X-Drillr-Via": "github"
        }
      }
    }
  }
}

When your Hermes/OpenClaw build adds MCP OAuth login, remove the entire headers block and use its login command instead. Never configure OAuth and a static bearer header on the same server entry.


For AI Coding Agents#

Setup is one command per client, followed by a browser sign-in the user performs. The commands, the authorization step for each client, and troubleshooting are in the install guide at https://drillr.ai/developer/mcp-install.md.

Both Codex and Claude Code load MCP tools when a session starts, so a server added mid-session is absent from that session's tool list. That is expected: start a new session rather than reaching the server another way.

The copy-and-paste setup prompts are at https://drillr.ai/developer/agent.


Error Handling#

HTTP StatusMeaning
400Missing required parameter / malformed input
401Invalid or missing credentials
402Insufficient credits
403Credential doesn't have access to this endpoint
404Resource not found or inaccessible
429Rate limit exceeded (see retry_after_seconds)
502Upstream data source unavailable

Error-code strings in the response body:

CodeMeaning
unauthenticatedNo credentials provided
key_invalidAPI key not recognized
key_revokedAPI key was revoked (see revoked_at)
key_expiredAPI key has passed its expiry
insufficient_creditsBalance can't cover this call
invalid_queryQuery parameter validation failed
invalid_bodyRequest body validation failed
invalid_idMalformed UUID or similar
not_foundResource not found or inaccessible
upstream_errorDatabase or data-source call failed