G

geoprimitives · Marine Depth

by geoprimitives

GETBase

$0.005

per call · USD Coin on Base

Give it a latitude and longitude and it answers with what the nautical chart says about the water there: the depth range of the charted depth area containing the position, the nearest charted sounding and how far away it is, and the chart's own zone of confidence for that area. Parameters go in the query string: this is a GET, there is no body. NOT FOR NAVIGATION, stated first because it is a condition of using the source. This is derived from NOAA Electronic Navigational Charts and redistributed; it is not an official NOAA ENC and does not meet federal chart carriage regulations under 33 CFR 164 or SOLAS chapter V, which only charts from NOAA or a certified NOAA ENC distributor do. Every response repeats this under `disclaimer`. NOAA and NOAA ENC are registered trademarks of NOAA, which does not endorse this service. COVERAGE is 65 NOAA ENC cells of usage bands 3, 4 and 5 over five working areas of southeast and southcentral Alaska: Sitka Sound; Kasaan Bay and Clarence Strait; Metlakatla, Ketchikan and Revillagigedo Channel; Juneau, Gastineau Channel and Lynn Canal; and Cordova with eastern Prince William Sound. It is not statewide, it is not the whole coast, and the small-scale cells that would make it look wider were deliberately left out. The coverage check reads the coordinate, so it runs in the handler after payment rather than in front of the 402: a position off the charts is quoted like any other and then refused with outside_coverage. A refusal does not settle and nothing is charged, but it costs a signature and a round trip, so check the coverage first. Every response repeats it under `coverage`. NOTHING IS INTERPOLATED, and that is the difference between this and GET /v1/elevation. Terrain is a continuous surface and sampling it between pixels is legitimate; a chart is a set of assertions a hydrographer made, and averaging two of them invents a depth nobody surveyed. So `depthAreaMinimum` is DRVAL1 of the charted depth area the position falls inside, the shoalest depth that area is guaranteed to hold, and `nearestSounding` is a real charted sounding with the geodesic distance to it. The two routinely disagree and are meant to: a sounding is a measurement at a point and the area is a guarantee over a region. The guarantee is the number to navigate a plan by; the sounding tells you how the area was arrived at. WHICH CHART ANSWERS: ENC cells overlap on purpose, so a position in Sitka sits on a 1:12,000 harbour cell, a 1:45,000 approach cell and a 1:180,000 coastal cell at once, and they do not agree because the smaller scales generalise. The largest-scale cell covering the position wins outright, usage band first and then compilation scale, which is the rule an ECDIS follows. The response names the cell, its band, its scale, its edition and its NOAA issue date, and lists any cell it consulted first that charted no depth area there. SURVEY QUALITY is on every answer as the chart's CATZOC zone of confidence, with the position and depth accuracy that zone implies, and the survey start and end dates when the chart gives them. Read it before you trust a depth. NOAA's own warning applies to all of it: much of the depth information on NOAA charts is from surveys conducted before 1940 and the shoreline is more than 20 years old. Zone A1 is a modern full-coverage survey; zone D or U means the chart is telling you it does not know. DATUMS: depths are metres below Mean Lower Low Water, which is the US chart datum, so a real depth at a real moment is this number plus the tide. Heights on the same charts are above Mean High Water. Positions are WGS 84. Reproject with POST /v1/transform if you are in State Plane or NAD27; the datum shift matters here, since a NAD27 Alaskan position is over a hundred metres from its WGS 84 one. VINTAGE: the charts are a snapshot taken on 2026-05-02. NOAA reissues ENCs weekly for Notice to Mariners and this store does not follow them, so a cell here can be behind NOAA's current edition. The cell edition, update number and issue date that answered are in `source` for exactly that comparison. REFUSALS that cost nothing: a position with no charted depth area is `no_depth_area`, which means land, a drying area the chart gives no depth for, or a gap between cells, and it is refused rather than answered with null. A position off the charts is `outside_coverage`. A chart object that cannot be read is a 503, not a guess. For what is in the way rather than how deep it is, use GET /v1/marine/hazards, which returns charted rocks, obstructions and wrecks within a radius.

Endpoint

GET https://api.geoprimitives.dev/v1/marine/depth

766

Calls / 30d

4

Unique payers / 30d

Sep 10

Last called

exact

Payment scheme

Call this service

TypeScript · @x402/fetch
import { wrapFetchWithPayment } from "@x402/fetch";
import { privateKeyToAccount } from "viem/accounts";

const account = privateKeyToAccount(process.env.PRIVATE_KEY);
const fetchWithPay = wrapFetchWithPayment(fetch, account);

const res = await fetchWithPay("https://api.geoprimitives.dev/v1/marine/depth", {
  method: "GET",
});
const data = await res.json();
cURL
curl -X GET \
  "https://api.geoprimitives.dev/v1/marine/depth?lat=57.0405&lon=-135.3421" \
  -H "X-PAYMENT: <signed x402 payment>"

Example response

{
  "chart": {
    "band": "harbour",
    "cell": "US5AK2NE",
    "cellsConsulted": [
      "US5AK2NE"
    ],
    "edition": 3,
    "issued": "20260302",
    "scale": 12000,
    "update": 0
  },
  "coverage": {
    "areas": [
      "Sitka Sound",
      "Kasaan Bay and Clarence Strait",
      "Metlakatla, Ketchikan and Revillagigedo Channel",
      "Juneau, Gastineau Channel and Lynn Canal",
      "Cordova and eastern Prince William Sound"
    ],
    "bands": [
      "coastal (band 3)",
      "approach (band 4)",
      "harbour (band 5)"
    ],
    "cells": 65,
    "classes": [
      "SOUNDG",
      "DEPARE",
      "DRGARE",
      "UWTROC",
      "OBSTRN",
      "WRECKS",
      "M_QUAL"
    ],
    "reason": "The charts are the 65 NOAA ENC cells of usage bands 3 to 5 that cover five working areas of southeast and southcentral Alaska. This is not statewide and it is not the whole coast. The coverage check reads the coordinate, so it runs in the handler and after payment, not in front of the 402: a position off the charts is quoted like any other and then refused with outside_coverage. A refusal does not settle, so nothing is charged, but it costs a signature and a round trip. Check the coverage against this list first.",
    "region": "Southeast and southcentral Alaska, 65 NOAA ENC cells"
  },
  "depthAreaMaximum": 36.5,
  "depthAreaMinimum": 18.2,
  "disclaimer": {
    "notForNavigation": true,
    "origin": "https://www.charts.noaa.gov/ENCs/",
    "statement": "Derived from NOAA ENC data and redistributed. This is NOT an official NOAA ENC and does NOT meet federal chart carriage regulations under 33 CFR 164 or SOLAS chapter V; only charts from NOAA or a certified NOAA ENC distributor do. Do not navigate on this answer.",
    "surveyAge": "NOAA's own warning, repeated because it governs how much any of this is worth: much of the depth information on NOAA charts comes from surveys conducted before 1940 and the shoreline is more than 20 years old. The zone of confidence in every depth answer is the chart's own assessment of that, per area.",
    "trademark": "NOAA and NOAA ENC are registered trademarks of the National Oceanic and Atmospheric Administration, which does not endorse this service.",
    "vintage": "Chart data as held on 2026-05-02. NOAA reissues ENCs weekly for Notice to Mariners and this snapshot does not track them; the cell edition and issue date that answered are in \"source\" so you can compare against NOAA's own catalog."
  },
  "interpolation": "none. depthAreaMinimum is DRVAL1 of the charted depth area containing the position, and nearestSounding is a real charted sounding with the distance to it. Nothing between them is invented.",
  "nearestSounding": {
    "depth": 20.1,
    "distanceMetres": 5.88,
    "lat": 57.0405259,
    "lon": -135.3420156
  },
  "notes": [],
  "query": {
    "lat": 57.0405,
    "lon": -135.3421
  },
  "soundingDatum": "Mean Lower Low Water",
  "source": {
    "cell": "US5AK2NE",
    "cellBand": "harbour",
    "cellEdition": 3,
    "cellIssued": "20260302",
    "cellScale": 12000,
    "cellUpdate": 0,
    "dataset": "NOAA Electronic Navigational Charts, S-57 edition 3.1",
    "horizontalDatum": "WGS 84",
    "publisher": "NOAA Office of Coast Survey (IHO S-62 producer code 550)",
    "release": "20260502",
    "rights": "Public domain (US government work, 17 U.S.C. 105). NOAA ENC is a registered trademark of NOAA.",
    "soundingDatum": "Mean Lower Low Water",
    "units": "metres",
    "url": "https://www.charts.noaa.gov/ENCs/"
  },
  "surveyQuality": {
    "depthAccuracy": "0.50 m + 1% depth; full area search, all significant seafloor features detected",
    "positionAccuracy": "5 m + 5% depth",
    "positionAccuracyMetres": null,
    "soundingAccuracyMetres": null,
    "surveyEnd": "20020510",
    "surveyStart": "20020429",
    "zoneOfConfidence": "A1"
  },
  "tilesRead": 1,
  "units": "metres"
}

Payment details

Pay to0x76a51b5dd3729950b3b60c17f19252d221968fce
AssetUSD Coin · 0x833589fcd6edb6e08f4c7c32d4f71b54bda02913
NetworksBase
Schemesexact

Is this your API?

Pin it to the top of Other and the homepage with a featured placement.

Get featured →

More from geoprimitives & similar services

G

geoprimitives · US Geographies

api.geoprimitives.dev

Give it a longitude and latitude inside the United States and it answers with the Census FIPS codes for that point: the 2-digit state code, the 5-digit county GEOID, and the GEOID of the congressional district. Parameters go in the query string: this is a GET, there is no body. The codes are the product and the names are a courtesy. A county GEOID is the join key to essentially every geography-keyed federal dataset -- the American Community Survey, BLS Local Area Unemployment Statistics, BEA regional accounts, CDC WONDER, HUD, USDA, FEMA -- and the state code is its first two digits, so one call gives you both keys already in the form those tables expect. County GEOID is also the first five digits of a tract GEOID (11 digits) and of a block group GEOID (12), so it is the prefix you would filter a tract-level extract down with. COVERAGE, stated up front because the shortfall is the point: this endpoint answers state, county and congressional district, and it does NOT answer tract, block group, place or ZCTA. That is a size limit, not an oversight, and it was measured rather than guessed. A national compacted H3 index of tracts is 3196 KiB gzipped and of block groups 5335 KiB, at a resolution already too coarse for either; the whole Worker has 3 MiB compressed to spend and most of that was gone before this route existed. Those four tiers need an object store behind the Worker and will arrive with one. Every response repeats this under `coverage`, so an agent never has to infer it from a missing field. In the meantime geocoding.geo.census.gov answers all seven tiers, free, authoritative, at the cost of a round trip and a dependency. VINTAGE: TIGER/Line 2025, congressional districts for the 119th Congress. It is on every response under `vintage` and it matters more here than almost anywhere else in this catalog, because TIGER is re-cut annually and districts move with redistricting, so a stale district code is a wrong answer a caller cannot detect from the outside. Nothing here self-updates; a new vintage means a rebuild. The data is a work of the United States government and is in the public domain (17 U.S.C. 105) -- no attribution clause and no redistribution terms. ACCURACY, and this is the part to read before you trust a code. The boundaries themselves are full-resolution TIGER, the same geometry the Census Geocoder answers from, not a simplified copy. What is approximate is the lookup: the polygons are indexed as compacted H3 cells at resolution 7, about 1.22 km across, so a point within roughly 610 m of a boundary may be attributed to the neighbour. County equivalents and districts too small to describe at that resolution -- Falls Church city, the other Virginia independent cities, the congressional districts inside New York City -- carry a second index at resolution 9, about 87 m, and `boundaryAccuracyMetres` says which one answered you. Because a 610 m index is only useful if you know when not to trust it, every response carries `boundaryUncertain.county` and `boundaryUncertain.congressionalDistrict`. They are true when a neighbouring cell resolves to a different code, which means the boundary is close enough that the index cannot settle which side you are on. Measured against geocoding.geo.census.gov on 650 coordinates: on 400 population-weighted points the county code was right 389 times and the district code 383, and every one of the 11 and 17 disagreements was flagged; on 250 points drawn deliberately 100 m to 1500 m from a county line the county code was right 183 times, and every one of the 67 wrong county codes and 25 wrong district codes was flagged. Across all 650 it never returned a wrong code with the flag clear. It is generous in the other direction -- it flagged 74 of the 400 correct-heavy sample -- so treat `true` as "verify this one if it matters" rather than as "this is wrong". Outside the United States the answer is `found: false` with null codes and a paid 200, because "this coordinate is not in the US" is the answer you asked for. County polygons include their legal water area out to the three-mile limit and across the Great Lakes, so harbours, piers and lake coordinates resolve normally and only genuinely foreign or high-seas points fall out. Coverage is the 50 states, DC, Puerto Rico, American Samoa, Guam, the Northern Mariana Islands and the US Virgin Islands. A small amount of water is inside a county but inside no congressional district, which TIGER publishes as a real polygon; that answers with a district whose number is null rather than with a guess. Longitude and latitude are checked against EPSG:4326 bounds before anything else touches them, because H3 silently normalises an out-of-range latitude into a real but wrong cell rather than refusing it. Reproject with POST /v1/transform first if you are not already in WGS 84. TIGER publishes in NAD83, which this reads as WGS 84; the two differ by under two metres, which is a fortieth of the index's own resolution.

GETBaseOther
$0.01 / call4 calls / 30d
G

geoprimitives · Timezone

api.geoprimitives.dev

Give it a longitude and latitude and it answers with the IANA timezone identifier (America/New_York), the UTC offset in force there right now, whether daylight saving is currently in effect and by how much, the local wall-clock time, and the zone's standard offset. Pass an optional ISO 8601 `at` instant to ask about any moment between 1900 and 2100 instead of now, which is what you want when scheduling something months out across a DST boundary. Parameters go in the query string: this is a GET, there is no body. Two halves, with different vintages, and the difference matters. The offset and the DST rules come from the runtime's own timezone database and are current: a rule change reaches this endpoint when Cloudflare updates ICU, with no redeploy here. The *boundaries* come from tz_world (efele.net), CC0 1.0 and derived from VMAP0, a public-domain US government product. That map was frozen at tzdb 2016d in May 2016, and this catalog sells public-domain and permissively-licensed data only, which is why it is used rather than the current OpenStreetMap-derived alternative. What the vintage costs, measured against IANA's own coordinates for all 312 zones in zone1970.tab rather than estimated: 293 agree. Of the 19 that do not, 7 are Antarctic research stations, which this map does not cover at all and which fall back to the open-water rule; 7 more return a different identifier for the identical offset and DST all year (Australia/Brisbane for Australia/Lindeman, America/Regina for America/Swift_Current, and five like them), so the time is right and only the name is old. That leaves four regions where the answer is up to one hour wrong because the zone was split after 2016: Chilean Magallanes and Aysen (answered as America/Santiago rather than America/Punta_Arenas or America/Coyhaique), the Mexican border municipalities around Ciudad Juarez, Saratov Oblast in Russia, and the weeks each spring when Asia/Hebron and Asia/Jerusalem change on different dates. If you query inside one of those, do not trust this endpoint. Boundary precision is a separate question from vintage. The map is indexed as compacted H3 cells at resolution 6, whose half-width is about 1.6 km, chosen to match VMAP0's own stated positional accuracy of roughly 2 km rather than to flatter the index. So a point within a couple of kilometres of a zone border may be attributed to the neighbour, and no amount of the source's precision would fix that because the source does not have it. Away from a border the answer is exact. Every answer says where it came from under `source`. `boundary` means the point is inside a mapped timezone polygon and is the answer you are paying for. `coastal` means it is over water or on land this map does not cover, and the identifier is the nearest zone within about 60 km -- correct for a harbour or a coastal city whose coordinate falls just offshore, and not a boundary result. `nautical` means open water more than about 60 km from mapped land, answered with the tz database's own rule for international waters, meridians 15 degrees apart; it is not the time kept aboard any vessel and it ignores territorial waters. Longitude and latitude are checked against EPSG:4326 bounds before anything else touches them, because H3 silently normalises an out-of-range latitude into a real but wrong cell rather than refusing it. Reproject with POST /v1/transform first if you are not already in WGS 84. The DST flag is decided on offsets rather than on the tz database's own isdst bit, so Europe/Dublin reads as daylight saving in summer like everywhere else, and it is measured over a window either side of the instant so that a zone which changes its standard offset mid-year -- Asia/Almaty in 2024 -- is not mistaken for one on daylight saving.

GETBaseOther
$0.005 / call4 calls / 30d
G

geoprimitives · Hello

api.geoprimitives.dev

Echo endpoint. Returns the name you send, the network the payment settled on, and the price you paid. Use it to prove your x402 client works end to end -- discover, read the 402, sign, retry, get a body -- before you spend anything on a real endpoint. It is the cheapest route in the catalog and it computes nothing, so a failure here is a payment problem and never a geospatial one. Do not use it for anything else: it has no geospatial behaviour at all. It is priced at exactly what it costs us to settle one onchain transaction, so the whole of what you pay here goes to the facilitator and none of it to us. That is deliberate: this route is worth having only because it is genuinely paid, since a free echo would prove nothing about whether your client can pay.

POSTBaseSocial & Community
$0.001 / call3 calls / 30d