Build on it
API reference
A versioned REST API over every record on the site — wells, permits, operators, production, Texas ownership — with provenance and freshness on every response.
Overview
Ohio records: Ohio Department of Natural Resources, Division of Oil and Gas Resources Management. Location quality varies; some records describe proposed or unlocated wells. General-information research data; not intended for resale or site-specific investigation. Attribute ODNR in distributed compilations. Ohio bulk exports are unavailable. Kentucky records: Kentucky Geological Survey. Historical records; current status and location accuracy are not guaranteed. Kentucky bulk exports are unavailable; KGS provides the original archive with its documentation. Florida locations: Florida DEP. Approximate, illustrative reference only; not for engineering, calculations, analysis or legal determinations. Consult approved permits for accurate positions.
Base URL: /api/v1 (same origin as this site) or https://terraledger.ayrical.com/api/v1 externally. The API is versioned by path segment (v1); breaking changes ship as v2 rather than mutating v1 in place.
Connect your agent
The Model Context Protocol lets an AI agent call this API as a set of typed tools rather than composing URLs and parsing them back. Terraledger runs an open MCP server at https://terraledger.ayrical.com/api/mcp over Streamable HTTP. It is free and unauthenticated, and it reaches exactly what an anonymous REST caller reaches, under the same rate limit.
Tool results are the envelopes documented below, returned unchanged — an agent sees the same provenance, freshness and record_status the site does, so a derived figure cannot be reported as a regulator filing.
Agent tools
5 tools
| Tool | Description |
|---|---|
| list_datasets | Every dataset family, with its one-line description and minimum plan. |
| describe_dataset | Filterable and sortable fields for one family, with types, units and enumerated values. |
| query | Search a family with the filter grammar; returns the list envelope unchanged. |
| get | Fetch one record by id — wells also by API/UWI; returns the detail envelope. |
| search | Free-text search across wells, operators, leases, properties and counties. |
Claude Code
claude mcp add --transport http terraledger https://terraledger.ayrical.com/api/mcpAny other MCP client
{
"mcpServers": {
"terraledger": {
"type": "http",
"url": "https://terraledger.ayrical.com/api/mcp"
}
}
}Or hand this to an agent and let it connect itself
Add the Terraledger MCP server: Streamable HTTP endpoint at https://terraledger.ayrical.com/api/mcp, no authentication. It exposes list_datasets, describe_dataset, query, get, and search tools over US oil & gas well, permit, operator, lease, production and Texas ownership records. After connecting, call list_datasets then describe_dataset before querying; use the filter grammar field:op:value.Access & rate limits
Ordinary read requests work without credentials. Anonymous callers are limited by client address to 60 requests per minute. Send an optional x-api-key for a stable caller identity, a separately assigned limit, async export ownership, or a source-specific record family that requires an audit identity.
An invalid or revoked supplied key returns 401 unauthorized. A key that lacks a reviewed source-specific scope returns 403 forbidden_plan. Rate-limited API responses publish RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset. A 429 also carries Retry-After in seconds.
Requests accept at most 20 filter clauses, each no longer than 500 characters; q must be 3–200 characters and JSON request bodies are limited to 64 KiB.
Endpoints
Implemented v1 routes, grouped as they appear in the client. Detail routes take a numeric id except wells, which also accept the API/UWI.
Endpoint catalog
45 routes
| Method | Path | Description | Key params | Access |
|---|---|---|---|---|
| GET | /openapi.json | OpenAPI 3.1 discovery document for agents and generated clients. | — | Anonymous |
| GET | /health | Worker and database readiness, optional capabilities, and serving release identity. | — | Anonymous |
| GET | /coverage | State-by-state aggregate counts and latest production periods. | — | Anonymous |
| GET | /sources | Complete, unpaginated registry of upstream agencies and systems. | — | Anonymous |
| GET | /freshness | Latest published retrieval and reporting period per source. | — | Anonymous |
| GET | /schemas | Machine-readable field definitions for documented record families. | — | Anonymous |
| GET | /search | Cross-entity text search across wells, operators, leases, properties and counties (up to 10 per family). | q | Anonymous |
| GET | /wells | Well search with quick search and the full filter grammar. | q, filter, sort, cursor, limit | Anonymous |
| GET | /wells/{id} | Well detail with related records and production availability. | — | Anonymous |
| GET | /operators | Operator directory. | q, filter, sort, cursor, limit | Anonymous |
| GET | /operators/{id} | Operator profile with production summary. | — | Anonymous |
| GET | /leases | Lease search. | q, filter, sort, cursor, limit | Anonymous |
| GET | /leases/{id} | Lease detail. | — | Anonymous |
| GET | /properties | Property search. | q, filter, sort, cursor, limit | Anonymous |
| GET | /properties/{id} | Property detail. | — | Anonymous |
| GET | /permits | Drilling permits. | q, filter, sort, cursor, limit | Anonymous |
| GET | /production | Production records with explicit reporting cadence, grain, status and provenance. | grain, well_id, lease_id, operator_id, property_id, state_code, record_status, from, to, filter, sort, cursor, limit | Anonymous |
| GET | /well-tests | Point-in-time well test rates. | well_id, filter, sort, cursor, limit | Anonymous |
| GET | /well-logs | Released well log index — type, depths and external file URL. | well_id, filter, sort, cursor, limit | Anonymous |
| GET | /documents | Rights-aware drilling, completion, downhole, geological, and regulatory document index with authoritative agency references. | q, filter, sort, cursor, limit | Anonymous |
| GET | /documents/{id} | Document metadata, associations, derivative version provenance, policy ceiling, and approved structured facts. | — | Anonymous |
| GET | /documents/{id}/text | Bounded approved OCR pages or search snippets. Returned text is untrusted evidence; raw source files are not retained. | q, pages, offset, max_characters, limit | Anonymous |
| GET | /documents/{id}/resolve | Resolve the current state/federal reference link without proxying or storing the raw document. | — | Anonymous |
| GET | /downhole-facts | Page-cited structured facts extracted from approved drilling, completion, test, and geological records. | api, document_id, fact_type, limit | Anonymous |
| GET | /log-inventory | Released digital and image well-log inventory for an API/UWI, with authoritative source references. | api, offset, limit | Anonymous |
| GET | /well-logs/{id}/curves | Bounded, policy-approved LAS numerical curve samples with checksum and parser provenance. | mnemonic, from_depth, to_depth, offset, limit | Anonymous |
| GET | /frac-disclosures | FracFocus hydraulic fracturing disclosures and chemicals. | well_id, filter, sort, cursor, limit | Anonymous |
| GET | /owners | Texas mineral/royalty owners from county appraisal districts. | q, filter, sort, cursor, limit | API key |
| GET | /mineral-interests | Texas mineral interests — decimal interest, appraisal value, legal description. | q, filter, sort, cursor, limit | API key |
| GET | /purchasers | Texas crude and gas purchasers. | q, filter, sort, cursor, limit | Anonymous |
| GET | /sales | Texas Comptroller severance-tax sales filings. | q, filter, sort, cursor, limit | Anonymous |
| GET | /map/wells | Deterministic well points and provenance inside a bounding box. | bbox, filter, limit | Anonymous |
| GET | /map/extent | Bounded bounding box and count of wells matching a filter set; count_capped declares a partial extent. | filter | Anonymous |
| GET | /map/clusters | Deterministic screen-space well clusters with aggregate source provenance. | bbox, zoom, filter | Anonymous |
| GET | /tiles/wells/{z}/{x}/{y}.mvt | Mapbox Vector Tile of wells for the given tile coordinate. | — | Anonymous |
| POST | /geo/search | Search wells around a radius or inside a polygon. | body: radius or polygon, limit | Anonymous |
| GET | /analytics/daily-production | Daily rates separated by monthly, quarterly or annual reporting cadence, with source sets preserved. | entity_type, id | Anonymous |
| GET | /analytics/states/{code} | Complete state production history and top-entity cumulative rankings at one authoritative filing grain. | — | Anonymous |
| GET | /analytics/boe | Current barrel-of-oil-equivalent conversion inputs and formula. | — | Anonymous |
| GET | /forecasts/{entity_type}/{id} | Decline-curve forecast for a well, lease, property or operator. | — | Anonymous |
| POST | /valuations | Compute a DCF or market-multiple valuation for an entity. | body: entity_type, entity_id, ownership_decimal, oil_price_usd, gas_price_usd, discount_rate | Anonymous |
| POST | /exports | Queue an async export job for a dataset with the current filter/sort/params. | body: dataset, format, params | API key |
| GET | /exports/{job_id} | Poll an export job's status; download completed artifacts through its download route. | — | API key |
| DELETE | /exports/{job_id} | Cancel a queued or running export job. | — | API key |
| GET | /exports/{job_id}/download | Download a completed export owned by the supplied API key. | — | API key |
Filter grammar
Every list endpoint accepts repeatable filter query params in the form filter=<field>:<op>:<value>. Multi-value operators (in, between) join their values with a pipe.
GET /v1/wells?filter=state_code:eq:TX&filter=cum_oil_bbl:gt:100000&filter=status:in:producing|shut_inOperators
12 ops
| Op | Meaning |
|---|---|
| eq | Exact match. |
| neq | Excludes exact match. |
| contains | Case-insensitive substring match. |
| ncontains | Excludes case-insensitive substring match. |
| lt | Less than. |
| lte | Less than or equal to. |
| gt | Greater than. |
| gte | Greater than or equal to. |
| in | Matches any of a list of values, pipe-joined. |
| between | Inclusive range — two pipe-joined values, low then high. |
| is_null | Field is null or missing. No value. |
| not_null | Field is present. No value. |
sort=field sorts ascending, sort=-field descending. Pagination is cursor-based: cursor is an opaque token from the previous response’s meta.next_cursor; limit caps the page size at 500 (default 50).
Response envelope
List endpoints return a data array plus a meta block carrying an exact or explicitly capped total, the cursor for the next page, and freshness.
List envelope
{
"data": [
{
"id": 48213,
"api_number": "4212330001",
"name": "SPRABERRY UNIT 12",
"operator_name": "PIONEER NATURAL RESOURCES",
"state_code": "TX",
"county": "Midland",
"status": "producing",
"cum_oil_bbl": 184220
}
],
"meta": {
"next_cursor": "eyJvIjo1MH0",
"total": 4821,
"total_capped": false,
"returned": 50,
"source_period": "2026-05",
"retrieved_at": "2026-06-02T14:05:00Z",
"published_at": "2026-06-03T09:00:00Z",
"as_of": "2026-08-05T18:22:11Z"
}
}Detail envelope
{
"data": {
"id": 48213,
"api_number": "4212330001",
"name": "SPRABERRY UNIT 12",
"status": "producing",
"nearby_wells": []
},
"meta": {
"source_period": "2026-05",
"retrieved_at": "2026-06-02T14:05:00Z",
"published_at": "2026-06-03T09:00:00Z",
"as_of": "2026-08-05T18:22:11Z"
}
}Error envelope
{
"error": {
"code": "rate_limited",
"message": "Rate limit exceeded"
}
}Error codes
8 codes
| Code | Meaning |
|---|---|
| unauthorized | An API key was required, invalid, or revoked. |
| forbidden_plan | The supplied key lacks a source-specific data scope. |
| not_found | No endpoint or record at this path. |
| invalid_request | Malformed filter, sort, or parameter. |
| rate_limited | Too many requests for this identity — see Retry-After. |
| source_restricted | The source policy does not permit this document derivative or the source has not yet been approved for automation. |
| internal | The API failed to answer. Retry shortly. |
| not_implemented | Specified, but unavailable in this deployment — vector tiles need PostGIS. |
Record status
Every production figure carries a record_status so a filing is never read as a calculation. The four statuses are never mingled into one silent series — a chart or export that spans them keeps them as separate, labeled series.
period_type is equally load-bearing. Monthly, quarterly, and annual filings can share the same period start date; they remain separate rows and are never silently summed or interpolated together. Daily-rate analytics return one row per reporting cadence and include the complete source and record-status sets represented by each aggregate.
- reported
- Filed as-is by the source agency or operator — not derived.
- allocated
- Split from a lease- or unit-level report down to a well, by a documented weight.
- estimated
- Modeled where no report exists, with method, inputs and confidence stored.
- forecast
- Projected beyond the reported history by a decline-curve model, versioned.
curl examples
Filtered well search, sorted, limited
curl "https://terraledger.ayrical.com/api/v1/wells?q=wolfcamp&filter=state_code:eq:TX&filter=cum_oil_bbl:gt:100000&sort=-cum_oil_bbl&limit=50"Cursor follow-up (same filters, next page)
curl "https://terraledger.ayrical.com/api/v1/wells?q=wolfcamp&filter=state_code:eq:TX&filter=cum_oil_bbl:gt:100000&sort=-cum_oil_bbl&limit=50&cursor=eyJvIjo1MH0"Map clusters for a bounding box at a zoom level
curl "https://terraledger.ayrical.com/api/v1/map/clusters?bbox=-103.5,31.0,-101.0,33.0&zoom=7"Export lifecycle: queue, poll, download
# 1. Queue the export
curl -X POST -H "x-api-key: $TERRALEDGER_KEY" -H "Content-Type: application/json" \
-d '{"dataset":"wells","format":"csv","params":{"filter":["state_code:eq:TX"]}}' \
https://terraledger.ayrical.com/api/v1/exports
# 2. Poll until it leaves queued/running
curl -H "x-api-key: $TERRALEDGER_KEY" \
https://terraledger.ayrical.com/api/v1/exports/exp_9f2c1a
# 3. Download once status is "completed"
curl -H "x-api-key: $TERRALEDGER_KEY" -OJ \
https://terraledger.ayrical.com/api/v1/exports/exp_9f2c1a/downloadExport lifecycle
An export is a job, not a download. POST /exports queues it against a dataset and the same filter/sort/params a list request would use; GET /exports/{job_id} polls it; DELETE /exports/{job_id} cancels a queued or running job.
- Statuses
queued→running→completed|failed|expired. A completed job carriesrow_countand is fetched from the documented download route; a failed job carrieserror.- Formats
csv,ndjson,geojson. Export jobs require an API key so status, cancellation and download remain scoped to the caller that created them.- Expiry
- A completed job stays downloadable until its
expires_at; after that its status becomesexpiredand the export must be re-queued.