Docs
How a delivery is shaped.
The conventions every delivery follows: request filters, the response envelope, no-data answers, bulk file layout and the agent endpoint. Hosts and keys are issued in your scope; none is published here.
- Status
- Available on request
- Public endpoint
- None today
- Formats
- JSON, Parquet, CSV, JSONL
- Agents
- MCP endpoint
The response envelope
Every API and agent response wraps the rows in the same envelope, so a caller can tell what it got and how old it is without reading the rows.
| Field | Meaning |
|---|---|
dataset | wells, permits, units, production, well-production or county-index |
query | The filters as we read them |
as_of | When the view was built and the source update date of the rows |
coverage | Whether the state or county is in the view, out of it, or not offered |
provenance | The lakehouse view and the upstream feed each row came from |
data | The rows, with the fields agreed in your scope |
next_cursor | Opaque cursor for the next page, or null |
Worked examples with real rows: wells, permits, units, production and the join, county index (synthetic).
Filters
stateasND, andcountywith its state suffixapi10for wells, permits, units and the join;permit_number;unit_idupdated_since(date): rows changed upstream on or after the date, for incremental loadsoperator,formation,spud_fromandspud_towhere the dataset carries themcursorandlimitfor paging
Authentication is a key sent as a bearer token, issued per scope and per agent. Keys are never shown on this site.
No-data answers
An empty answer says why. not_in_view means we hold that state but found no row; out_of_coverage means we hold no rows for that state; not_offered means the area is held back.
{
"dataset": "wells",
"query": {
"api10": "4200000000"
},
"coverage": {
"state": "TX",
"status": "not_in_view"
},
"data": [],
"note": "No row in the view. The view is not a full copy of the upstream feed; absence here is not proof the well does not exist."
}{
"dataset": "county-index",
"query": {
"county": "HELD COUNTY (TX)"
},
"coverage": {
"state": "TX",
"status": "not_offered"
},
"data": []
}Incremental loads
Each dataset has one primary key: CompletionId for wells, Permitid for permits, unit_id for units, EntityId for production headers, RecordId for the county index. The first drop is a full snapshot. When your scope includes change feeds, they are set up this way: later drops carry only rows changed upstream since the last drop, each with an _op column: upsert or delete. A delete row carries the key and the date it left the view. Merge on the key. A fresh full snapshot is available whenever you want to reconcile.
Over the API, the updated_since filter is set up to return changed rows, including deletes, in the same shape.
Field conventions
- Dates are calendar dates (
YYYY-MM-DD) with no time zone. View build times are UTC timestamps. - Missing values are null; nothing is filled in. Any field can be null except the primary key.
- Numbers are passed as the source gives them; depths and lengths in feet, liquids in barrels, gas in mcf.
- Coordinates are decimal degrees as the source supplies them. The datum per state is stated in your scope.
- List fields (parties, API lists, land descriptions) are arrays in JSON and Parquet, and JSON strings in CSV.
- Column names keep the source names except where a character breaks loaders:
API10/UWIbecomesapi10_uwi.
Bulk files
One file set per dataset and state, partitioned as dataset/state=XX/, in Parquet (default), CSV or JSONL; unit outlines also as GeoParquet or GeoJSON. Each drop comes with a manifest listing every file, its row count and a SHA-256 checksum, and the view build date. Delivery to a bucket or SFTP location you name, or a signed download link.
{
"dataset": "wells",
"state": "ND",
"drop_type": "full or changes",
"changes_since": null,
"view_built": "2026-10-07T07:22:59Z",
"files": [
{
"path": "wells/state=ND/part-0000.parquet",
"rows": "<count>",
"sha256": "<checksum>"
}
],
"row_count_total": "<count>",
"fields": [
"API10",
"WellName",
"..."
]
}Agent endpoint
For AI agents, the same datasets sit behind an MCP server. Tools: coverage (which states and datasets we hold), get_well, get_permits, get_unit, get_production, search_index (county index, scoped counties only). Each call returns the envelope above.
Use is metered per request and billed on the terms in your scope. Each agent gets its own key, so usage is reported per agent.
{
"mcpServers": {
"landman-technology": {
"url": "https://<host given in your scope>/mcp",
"headers": {
"Authorization": "Bearer <key issued to you>"
}
}
}
}Limits
- Rate limits are set per key in the scope.
- Sweeping requests that walk a county record by record are refused; ask for a bulk file instead.
- Fields with personal contact data (permit contact names and phone numbers) are not delivered.
- Responses are research data. They carry no title opinion and no legal conclusion.