Unearth Atlas Unearth Insights Unearth Agents Pricing Data Catalog API Docs Log in Talk to Sales

API reference

JSON over HTTPS. Available on the Pro plan and above.

Overview

The Unearth AI API exposes the same site-selection logic that powers our mapping tool, programmatically. Query a circle of demand and supply infrastructure, get a deduplicated list with operators, distances, and a 0–100 opportunity score.

Base URL: https://api.unearth-ai.com

API version: v1 (current). Versioned via the URL path.

MCP server

The fastest way to use Unearth from an LLM-driven agent (Claude Desktop, Cursor, Cline, your custom agent): install the Model Context Protocol server. One config line and the agent gets seven Unearth tools as first-class function calls.

{
    "mcpServers": {
        "unearth": {
            "command": "npx",
            "args":    ["-y", "@unearth-ai/mcp"],
            "env":     { "UNEARTH_API_KEY": "unearth_pro_…" }
        }
    }
}

Full setup at /agents. Source at github.com/unearth-ai/mcp.

For OpenAI / Gemini / function-calling-style agents, we also publish a ready-to-use tool spec at /api/tools-openai.json.

JavaScript SDK

Optional one-file ES module that wraps every endpoint with helper methods. Works in browsers, Node 18+, Deno, and Bun. ~1KB minified, no dependencies.

import { UnearthClient } from 'https://unearth-ai.com/assets/sdk/unearth.js';

const u = new UnearthClient({ apiKey: process.env.UNEARTH_API_KEY });
const result = await u.search({ lat: 37.77, lng: -122.41, radiusKm: 10, datasets: 'coworking' });
console.log(result.opportunity, result.total_in_radius);

Errors throw with status, code, hint, and rateLimitResetEpoch properties so you can build retry/backoff logic without re-parsing the response.

Authentication

All authenticated endpoints expect a Bearer token in the Authorization header. Provision a key by completing checkout on the pricing page; the key is shown once on welcome.html after payment.

Authorization: Bearer unearth_pro_a1b2c3d4e5f6…

Treat your API key like a password. Store it in an environment variable, not in source control. If a key is exposed, manage it via the billing portal and contact support to rotate.

Rate limits

Limits are per calendar month, reset at 00:00 UTC on the first of the month. Every authenticated response includes the current period's usage:

{
  "meta": {
    "rate_limit": { "used": 247, "limit": 10000, "period": "month" }
  }
}
  • Starter: 1,000 requests / month
  • Pro: 10,000 requests / month
  • Enterprise: negotiated volume

Exceeding the cap returns 429 rate_limit_exceeded. Need higher? Talk to us.

Errors

Errors return a JSON body with an error string and (sometimes) a hint:

{ "error": "invalid_lat_lng" }
StatusCodeMeaning
400invalid_lat_lngMissing or non-numeric coordinates.
400lat_lng_out_of_rangeOutside ±90° / ±180°.
400invalid_radius_kmMust be between 0 and 200.
400unknown_datasetsOne or more dataset IDs are not recognised. Check Dataset IDs.
401missing_api_keyNo Authorization header.
401invalid_api_keyToken is unknown or revoked.
429rate_limit_exceededMonthly cap reached. Upgrade or wait until next period.
503stripe_not_configuredBilling endpoints aren't ready yet (pre-launch).

Health check

GET/v1/healthNo auth
$ curl https://api.unearth-ai.com/v1/health
{ "ok": true, "ts": "2026-04-27T10:00:00.000Z" }

List datasets

GET/v1/datasetsNo auth

Returns the dataset IDs you can pass to /v1/search, plus their role (supply or demand) and whether they're temporarily deferred.

$ curl https://api.unearth-ai.com/v1/datasets
{
  "datasets": [
    { "id": "ev-charger",   "role": "supply", "deferred": false },
    { "id": "data-centers", "role": "demand", "deferred": false },
    { "id": "coworking",    "role": "demand", "deferred": false },
    { "id": "coliving",     "role": "demand", "deferred": false },
    { "id": "self-storage", "role": "demand", "deferred": false },
    { "id": "solar-farm",   "role": "demand", "deferred": false }
  ]
}

Sample queries

Try a query right now without an API key — the /v1/datasets/<id>/sample endpoint returns the first records of any dataset. For full radius queries you'll need a Pro key.

GET/v1/searchAuth required

Find every record across one or more datasets that falls inside a circle, score the opportunity, and return the top operators.

Query parameters

ParamTypeDescription
latrequirednumberCenter latitude, -90 to 90.
lngrequirednumberCenter longitude, -180 to 180.
radius_kmnumberSearch radius in kilometres. Default 10. Max 200.
datasetsstringComma-separated dataset IDs. Defaults to all non-deferred.

Example

curl -H "Authorization: Bearer $UNEARTH_API_KEY" \
  "https://api.unearth-ai.com/v1/search?lat=37.77&lng=-122.41&radius_km=10&datasets=coworking,data-centers"

Response

{
  "query":            { "lat": 37.77, "lng": -122.41, "radius_km": 10, "datasets": ["coworking","data-centers"] },
  "deferred_datasets": [],
  "total_in_radius":   84,
  "supply_count":      0,
  "demand_count":      84,
  "opportunity":       0,
  "area_km2":          314.2,
  "density_per_100km2": 26.7,
  "top_operators": [
    { "name": "WeWork", "count": 9 },
    { "name": "Industrious", "count": 4 }
  ],
  "by_dataset": {
    "coworking":    { "count": 76, "records": [ /* … */ ] },
    "data-centers": { "count": 8,  "records": [ /* … */ ] }
  },
  "meta": {
    "api_version":  "1.0",
    "generated_at": "2026-04-27T10:00:00.000Z",
    "rate_limit":   { "used": 247, "limit": 10000, "period": "month" },
    "attribution": { /* see below */ }
  }
}

Record fields (in by_dataset.<id>.records[])

FieldTypeDescription
idstringSource-stable identifier.
namestringDisplay name of the facility / operator.
operatorstringOperator (parent company / brand) if known.
lat, lngnumberGeographic coordinates (WGS84).
city, countrystringResolved location.
distance_kmnumberGreat-circle distance from the query center.

Usage

GET/v1/usageAuth required

Returns this month's consumption plus 12 months of history (oldest-first, ready to chart).

{
  "plan": "pro",
  "rate_limit": { "used": 247, "limit": 10000, "remaining": 9753, "period": "2026-04" },
  "history": [
    { "period": "2025-05", "requests": 0 },
    { "period": "2025-06", "requests": 0 },
    /* … */
    { "period": "2026-04", "requests": 247 }
  ],
  "created_at": "2026-04-12T15:32:11.000Z"
}

Key introspection

GET/v1/keys/meAuth required

Returns the calling key's fingerprint, plan, monthly limit, and (when available) email and Stripe customer ID. Useful for verifying which key the client is presenting without round-tripping through the dashboard. The full key is never returned.

$ curl -H "Authorization: Bearer $UNEARTH_API_KEY" \
       https://api.unearth-ai.com/v1/keys/me
{
  "fingerprint": "unearth_…a3f6",
  "plan": "pro",
  "rate_limit_per_month": 10000,
  "email": "ada@example.com",
  "created_at": "2026-04-12T15:32:11.000Z",
  "stripe_customer_id": "cus_xyz"
}

Key rotation

POST/v1/keys/rotateAuth required

Generates a new API key tied to the same subscription and revokes the old one. The old key stops working immediately — save the new one before closing the response. The dev-mode key (when used) cannot be rotated.

$ curl -X POST -H "Authorization: Bearer $UNEARTH_API_KEY" \
       https://api.unearth-ai.com/v1/keys/rotate
{
  "api_key":    "unearth_pro_b7c9…ef21",
  "fingerprint": "unearth_…ef21",
  "plan":       "pro",
  "rotated_at": "2026-04-29T19:22:08.103Z",
  "notice":     "Save this key now — it will not be shown again. The previous key is revoked."
}

Rate-limit response headers

Every successful authenticated response carries X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset (Unix epoch seconds at the start of next month, UTC). Surface these to your users for backoff logic — same convention as GitHub's API.

Billing portal

POST/v1/billing-portalAuth required

Returns a one-time URL to the Stripe-hosted billing portal where customers can update payment method, change plan, or cancel.

curl -X POST -H "Authorization: Bearer $UNEARTH_API_KEY" \
  https://api.unearth-ai.com/v1/billing-portal
# → { "url": "https://billing.stripe.com/p/session/…" }

Redirect the user to response.url; Stripe returns them to https://unearth-ai.com/pricing.html when they're done.

Dataset IDs

IDRoleSource
ev-chargersupplyOpen Charge Map (CC BY-SA 4.0) + OSM (ODbL). Stratified sample of 5k records — full dataset (177k+) ships on Enterprise.
data-centersdemandOSM (ODbL) + Unearth Data Intelligence.
coworkingdemandOpenStreetMap (ODbL).
colivingdemandOpenStreetMap (ODbL).
self-storagedemandOpenStreetMap (ODbL).
solar-farmdemandOpenStreetMap (ODbL).

Attribution

API responses include a meta.attribution object naming each source and its license. When you display, redistribute, or build on top of records, please credit the underlying sources:

Full posture, including share-alike triggers and Derivative-Database boundaries: LICENSES.md.