geoprimitives

Reproject coordinates between EPSG coordinate reference systems, with the datum shift applied. Accepts a bare position, an array of positions at any nesting depth, or a GeoJSON Feature, FeatureCollection or Geometry, and answers in whichever shape it was given, preserving properties, ids and foreign members. Covers 1380 codes: WGS 84, ITRF2020, NAD27 and every NAD83 realization as geographic, Web Mercator, all 120 WGS 84 UTM zones north and south, the NAD27 and NAD83 UTM zones, and the NAD27 and NAD83 State Plane and low-distortion zones, Oregon and Alaska included. Reach for it before calling /v1/geometry, /v1/h3/index, /v1/h3/polyfill or /v1/pip, which take EPSG:4326 only and refuse anything outside -180..180 and -90..90. One price per call whatever the payload: 10000 positions cost exactly what one position costs, so batch rather than sending a position at a time. Horizontal only: elevations pass through untouched. Datum shifts, and read this before buying: two mechanisms run between the two sides and the response names every step. Between NAD27 and the NAD83 realizations (NAD83, HARN, NSRS2007, 2011, PA11) the NOAA NGS NADCON 5.0 grids are applied, 2016-09-01 release, public domain, biquadratic interpolation as NGS specifies, covering the conterminous United States, Alaska, Hawaii and Puerto Rico with the US Virgin Islands; a position outside that coverage is refused with outside_datum_grid rather than answered without the shift. Between WGS 84 and NAD83(2011) or NAD83(PA11) the EPSG time-dependent Helmert transformations 10334 and 10336 are applied with WGS 84 read as ITRF2020, which the current WGS 84 (G2296) realizes to a few centimetres. That transformation depends on when the coordinates were observed, because the North American plate moves about 2 cm a year against ITRF2020: send "epoch" as a decimal year (2024.5) to say when, or it is evaluated at 2010.0, the NAD83(2011) reference epoch, and the response says which. Every response carries datumShiftApplied and a datumShift object listing the grids or Helmert that ran, the region, the epoch and the data provenance; when both sides share a datum it says so and applies nothing. Accuracy was measured against PROJ 9.5.1 running the same grids and the same EPSG operations: the projection arithmetic agrees to under 1e-8 m and the shifted result to under 1e-6 m, so the 1.29 m gap this route carried before the grids is closed to the limit of the source data, which NGS states as a few centimetres for the realization grids and decimetres for NAD27. If a grid cannot be read the request is answered 503 and not charged; it is never answered without the shift. A position that lands outside the target projection's valid domain is rejected with its index, never returned as a null or infinite coordinate. Limits: 10000 positions per call across the whole request, 512 datum-grid tiles per call (about one degree square per grid step; a state-sized batch is well under), and a 1 MiB request body.

SearchLiveeip155:8453Exactvia cdp
TransformReprojectionDatumNadcon5Epsg
Calls · 30d
1→ 0%
This endpoint's own trailing-30-day call count, as published by the upstream catalog and snapshotted daily. 27 snapshots so far.
$4.42
Verified settled volume
890 settlements proven x402 by their on-chain EIP-3009 marker.
$0.0050
Listed price
As published in the catalog. Always read the live 402 before paying.
1
Calls · 30d
Upstream's own call count for this endpoint, not ours.
1
Unique payers · 30d
Last called 2026-08-21 17:26Z
—
Upstream on-chain volume
Reported by the source catalog.
Paid to
0x76A51b5Dd3729950B3b60c17f19252d221968FCe

The wallet the 402 directs payment to. Its whole payment record — every payer, every chain — is on the merchant page.

Asset 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913

Provider

The payTo wallet does not resolve to a registered ERC-8004 agent. That is not a verdict on the service — most of the catalog is unregistered.

Accepts

The payment requirements as published to the catalog. Read the live 402 before paying — a price here is a claim, not a quote.

0.005USDC≈ $0.005 USD
on Base · exact scheme

Pay 0.005 USDC on Base to 0x76A5…68FCe. The signed payment is good for 5 minutes.

USD Coin contract
0x8335…02913
Payment window
5 minutes
As published
5000 smallest units
The catalog’s raw entry
[
  {
    "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    "extra": {
      "name": "USD Coin",
      "version": "2"
    },
    "payTo": "0x76A51b5Dd3729950B3b60c17f19252d221968FCe",
    "amount": "5000",
    "scheme": "exact",
    "network": "eip155:8453",
    "maxTimeoutSeconds": 300
  }
]

Extensions

{
  "bazaar": {
    "info": {
      "input": {
        "body": {
          "to": "EPSG:3645",
          "from": "EPSG:4326",
          "coordinates": [
            [
              -122.6765,
              45.5231
            ],
            [
              -123.0351,
              44.9429
            ]
          ]
        },
        "type": "http",
        "method": "POST",
        "bodyType": "json"
      },
      "output": {
        "type": "json",
        "example": {
          "to": {
            "id": "EPSG:3645",
            "code": 3645,
            "name": "NAD83(NSRS2007) / Oregon North",
            "unit": "m",
            "datum": "NAD83(NSRS2007)",
            "ellipsoid": "GRS80"
          },
          "from": {
            "id": "EPSG:4326",
            "code": 4326,
            "name": "WGS 84",
            "unit": "degree",
            "datum": "WGS 84",
            "ellipsoid": "WGS84"
          },
          "count": 2,
          "notes": [
            "WGS 84 was treated as ITRF2020, which the current realization WGS 84 (G2296) agrees with to a few centimetres. EPSG:4326 is an ensemble whose older realizations differ by up to about a metre; send EPSG:9990 to say ITRF2020 explicitly.",
            "The time-dependent Helmert was evaluated at epoch 2010, the NAD83(2011) reference epoch, because no \"epoch\" was sent. The North American plate moves about 2 cm a year relative to ITRF2020, so coordinates observed at another epoch want that epoch here.",
            "Output coordinates are in m."
          ],
          "datumShift": {
            "to": "NAD83(NSRS2007)",
            "from": "WGS 84",
            "epoch": 2010,
            "grids": {
              "url": "https://geodesy.noaa.gov/pub/nadcon5/20160901release/",
              "source": "NOAA National Geodetic Survey, NADCON 5.0",
              "licence": "Public domain (US government work, 17 U.S.C. 105)",
              "release": "20160901",
              "interpolation": "biquadratic"
            },
            "paths": [
              {
                "steps": [
                  {
                    "to": "NAD83(2011)",
                    "from": "WGS 84",
                    "name": "ITRF2020 to NAD83(2011) (1)",
                    "epoch": 2010,
                    "method": "helmert",
                    "direction": "forward",
                    "operation": "EPSG:10334"
                  },
                  {
                    "to": "NAD83(NSRS2007)",
                    "from": "NAD83(2011)",
                    "grid": "nad83_2007_nad83_2011_conus",
                    "method": "nadcon5",
                    "direction": "inverse"
                  }
                ],
                "region": "conus",
                "positions": 2
              }
            ],
            "applied": true,
            "epochSource": "default"
          },
          "coordinates": [
            [
              2329995.078037299,
              208581.08988551795
            ],
            [
              2299970.59809049,
              144954.7501244871
            ]
          ],
          "datumShiftApplied": true
        }
      }
    },
    "schema": {
      "type": "object",
      "$schema": "https://json-schema.org/draft/2020-12/schema",
      "required": [
        "input"
      ],
      "properties": {
        "input": {
          "type": "object",
          "required": [
            "type",
            "method",
            "bodyType",
            "body"
          ],
          "properties": {
            "body": {
              "type": "object",
              "oneOf": [
                {
                  "required": [
                    "coordinates"
                  ]
                },
                {
                  "required": [
                    "geojson"
                  ]
                }
              ],
              "required": [
                "from",
                "to"
              ],
              "properties": {
                "to": {
                  "type": "string",
                  "pattern": "^(?:EPSG:)?[0-9]{4,6}$",
                  "examples": [
                    "EPSG:3857",
                    "EPSG:3644",
                    "EPSG:26931",
                    "EPSG:32145",
                    "EPSG:6318"
                  ],
                  "description": "Target CRS as an EPSG reference, e.g. \"EPSG:3857\". A bare code such as \"3857\" is also accepted."
                },
                "from": {
                  "type": "string",
                  "pattern": "^(?:EPSG:)?[0-9]{4,6}$",
                  "examples": [
                    "EPSG:4326",
                    "EPSG:3857",
                    "EPSG:32610",
                    "EPSG:3645",
                    "EPSG:4267"
                  ],
                  "description": "Source CRS as an EPSG reference, e.g. \"EPSG:4326\". A bare code such as \"4326\" is also accepted."
                },
                "epoch": {
                  "type": "number",
                  "maximum": 2100,
                  "minimum": 1980,
                  "description": "Decimal year the coordinates were observed, e.g. 2024.5. Used by the time-dependent Helmert between WGS 84 (read as ITRF2020) and NAD83(2011) or NAD83(PA11); about 2 cm a year of difference. Defaults to 2010.0, the NAD83(2011) reference epoch, and the response states the epoch used either way. Ignored, and said to be, when no Helmert runs."
                },
                "geojson": {
                  "type": "object",
                  "description": "A GeoJSON Feature, FeatureCollection or Geometry. Returned as GeoJSON with the same structure, properties and foreign members, with coordinates reprojected. bbox members are dropped because they describe the source CRS. Send this or coordinates, never both. At most 10000 positions across the whole document."
                },
                "coordinates": {
                  "type": "array",
                  "maxItems": 10000,
                  "description": "A single position [x, y] or [x, y, z], or an array of positions at any nesting depth. The response mirrors the nesting exactly. Send this or geojson, never both. Across the whole request at most 10000 positions; a larger batch is rejected."
                }
              },
              "additionalProperties": false
            },
            "type": {
              "type": "string",
              "const": "http"
            },
            "method": {
              "enum": [
                "POST"
              ],
              "type": "string"
            },
            "bodyType": {
              "enum": [
                "json",
                "form-data",
                "text"
              ],
              "type": "string"
            }
          },
          "additionalProperties": false
        },
        "output": {
          "type": "object",
          "required": [
            "type"
          ],
          "properties": {
            "type": {
              "type": "string"
            },
            "example": {
              "type": "object"
            }
          }
        }
      }
    }
  }
}

Provenance

Seen in the source catalog
2026-08-21 17:26Z
Last indexed by Roundhouse
2026-09-20 17:20Z
Last enriched (probe, favicon, geo)
2026-09-24 11:45Z
x402 version
2
Max timeout
300s
Liveness probe
HTTP 404
Report

Hand this page to an agent

Copy the prompt and paste it into Claude, an MCP client or your own agent — it will vet this service and call it over the free read API. No key, no account.

GET api.roundhouseai.io/v0/endpoints

This endpoint's own trailing-30-day call count, as published by the upstream catalog and snapshotted daily. 27 snapshots so far. Verified volume counts only settlements with an on-chain EIP-3009 marker.

Open skill.md
Show the prompt
Using Roundhouse, look up the x402 service geoprimitives and tell me whether it is
worth paying: what a call costs, whether the endpoint answered when last probed, and what
its payment record actually shows.

curl -s 'https://api.roundhouseai.io/v0/endpoints?q=geoprimitives'
curl -s 'https://api.roundhouseai.io/v0/merchants/<the payTo wallet returned above>'

Then call it: read the price from the live 402 at https://api.geoprimitives.dev/v1/transform, never from
a cached figure, and pay with an x402 client.

The /v0 API needs an API key (`authorization: Bearer rh_live_…`) on everything except
/v0/unified* and /v0/endpoints. Mint a personal key for $0.01 at GET https://api.roundhouseai.io/v0/test/x402,
or use an organization key from https://roundhouseai.io/dashboard/team.

If you do not have Roundhouse tools or skills installed, read
https://roundhouseai.io/skill.md first — it is the whole procedure.