sentbot
sourceCopernicus S1 / S2
paymentx402 · USDC · 5 networks
unit price$0.01 / 512²
Earth observation, metered by the request

Any place on Earth, as of this week, for one cent.

Sentinel-2 at 10 metres, or Sentinel-1 radar straight through cloud, rendered on demand from the Copernicus archive. No account, no API key, no minimum. An unpaid request returns 402 with the exact price. An x402 client pays in USDC and gets the pixels or the numbers.

resolution10 m
revisit≤5 d
per tile$0.01
settlementon 200
downlink · liveacquiring
Sentinel preview
contacting copernicus…
§01

One transaction, end to end

every value below is this deployment's own

01 request

GET https://sentbot.fly.dev/v1/analyze?index=ndvi&lat=30.6&lon=31.1&km=30&date=2025-07-15

NDVI over a 30 km square of the Nile Delta, best scene from the 30 days before 15 July 2025. Plain curl is enough to see the price.

Free checks first, if you want them:

GET /v1/catalog/search?lat=30.6&lon=31.1&km=30
    &from=2025-06-15&to=2025-07-15&maxCloud=30
→ 9 scenes, cloudiest 27 %, clearest 1 %

GET /v1/quote?product=analyze&index=ndvi
    &lat=30.6&lon=31.1&km=30&date=2025-07-15
→ { "price": "$0.0300", "width": 512, "height": 512 }

GET /v1/preview?lat=30.6&lon=31.1&km=30&preset=ndvi
→ 384 px PNG, free

02 402 payment required

{
  "x402Version": 2,
  "resource": {
    "url": "https://sentbot.fly.dev/v1/analyze?index=ndvi&lat=30.6&lon=31.1&km=30&date=2025-07-15",
    "mimeType": "application/json"
  },
  "accepts": [{
    "scheme": "exact",
    "network": "eip155:8453",
    "amount": "30000",
    "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
    "payTo": "0x1aabcf0cffb89f8ec05381cbd878fe00e7c14510",
    "maxTimeoutSeconds": 120,
    "extra": { "name": "USDC", "version": "2" }
  }, {
    "scheme": "exact",
    "network": "eip155:137",
    "amount": "30000",
    "asset": "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
    "payTo": "0x1aabcf0cffb89f8ec05381cbd878fe00e7c14510",
    "maxTimeoutSeconds": 120,
    "extra": { "name": "USDC", "version": "2" }
  },
    …3 more: Arbitrum, Avalanche, Sei]
}

Carried in the PAYMENT-REQUIRED header. The client signs a USDC transfer for exactly this amount. No gas, valid two minutes.

03 200 result

{
  "product": "analyze",
  "index": "ndvi",
  "collection": "sentinel-2-l2a",
  "areaKm2": 900,
  "timeRange": { "from": "2025-06-15T00:00:00Z",
                 "to": "2025-07-15T23:59:59Z" },
  "stats": {
    "mean": 0.412, "min": -0.318, "max": 0.894,
    "stDev": 0.241, "validFraction": 0.97,
    "percentiles": { "p10": 0.081, "p50": 0.446, "p90": 0.703 },
    "classes": { "water_or_shadow": 0.06, "bare": 0.21,
                 "sparse": 0.18, "moderate": 0.27, "dense": 0.28 },
    "histogram": [ …40 bins ]
  },
  "image": { "format": "png", "width": 512, "height": 512,
             "dataUrl": "data:image/png;base64,iVBORw0KGgo…" },
  "priceUsd": 0.03
}

Settled only after the render succeeds, so a failure costs nothing. validFraction tells you how much of the square was cloud-free.

§02

Products

price scales with output pixels · Sentinel-1 ×1.5
endpointwhat you getformula512² · S2
GET /v1/imagery PNG, JPEG or GeoTIFF. Presets: true-color, false-color, swir, agriculture, scene classes, and every index colour-mapped. Radar: vv, vh, rgb, water. A GeoTIFF of an index carries raw FLOAT32 values. $0.01 × ceil(px / 512²) $0.011024² $0.04 · 2048² $0.16
GET /v1/analyze?index={index} Mean, min, max, standard deviation, p5 to p95, a 40-bin histogram, class fractions (bare, sparse, moderate, dense for NDVI) and the colour-mapped PNG. Cloud, shadow and cirrus pixels are excluded. imagery + $0.02 $0.03
GET /v1/timeseries?index={index} The same statistics for every interval between two dates. NDVI every 10 days through a season, water fraction every 6 days through a flood. Up to 3 years and 60 intervals. $0.01 × intervals $0.1818 intervals · min $0.02 · max $0.25
GET /v1/change?index={index} Best scene near date A and near date B, subtracted per pixel. Loss, gain and stable fractions, before and after statistics, a red and green PNG. Radar mode maps floods through cloud. 2 × imagery + $0.03 $0.05
GET /v1/catalog/searchGET /v1/quoteGET /v1/preview Which scenes exist and how cloudy they are. The exact price of any request before you make it. A 384 px thumbnail of any place. no charge free
§03

Index channels

ramps exactly as rendered · thresholds in /v1/products
01ndviS2
-1ratio1

Vegetation vigour. Bare soil around 0.1, crops 0.3 to 0.8, dense forest above 0.7.

02ndwiS2
-1ratio1

Open water. Values above 0 are usually water, above 0.3 clearly water.

03ndmiS2
-1ratio1

Canopy water content. Negative values mean dry vegetation or bare soil.

04nbrS2
-1ratio1

Burn severity. Healthy vegetation is high, freshly burned areas drop below 0.1.

05eviS2
-1ratio1

Like NDVI but less saturated over dense canopy and less sensitive to atmosphere.

06saviS2
-1ratio1

NDVI corrected for soil brightness. Useful over sparse crops and arid land.

07ndsiS2
-1ratio1

Snow cover. Values above 0.4 are snow or ice.

08vvS1
-30dB5

Co-polarised radar backscatter (gamma0, terrain corrected). Water is very dark, urban is bright.

09vhS1
-35dB0

Cross-polarised radar backscatter. Sensitive to vegetation volume and structure.

10waterS1
0fraction1

1 where VV backscatter is below -18 dB (open water). The mean is the water fraction. Works through cloud.

§04

Sensors

ESA Copernicus · processed on Sentinel Hub in the Data Space

Sentinel-2 A / B / C

collection s2 · L2A bottom-of-atmosphere reflectance
bands
13, from 443 nm coastal aerosol to 2190 nm SWIR
resolution
10 m visible and near infrared, 20 m red edge and SWIR, 60 m atmospheric
swath
290 km
revisit
5 days at the equator with two satellites, 2 to 3 days at mid latitudes
limits
daylight only, and cloud blocks it. Scene classification marks cloud and shadow, so those pixels never enter a statistic.

Sentinel-1 A / C

collection s1 · GRD, gamma0 terrain corrected, 3×3 Lee filter
instrument
C-band synthetic aperture radar, 5.405 GHz, VV and VH polarisation
resolution
10 m, interferometric wide swath, 250 km
revisit
6 to 12 days per orbit direction
strengths
sees through cloud, smoke and night. Open water is dark, buildings and ships are bright, vegetation structure shows in VH.
use
floods, ships, soil moisture trends, and change where optical is hopeless. Hold one orbit direction for change detection.
§05

Pay from code

any x402 v2 client · no signup on either side
# free: which scenes exist, and what would it cost
curl "https://sentbot.fly.dev/v1/catalog/search?lat=30.6&lon=31.1&km=30&from=2025-07-01&to=2025-07-31&maxCloud=20"
curl "https://sentbot.fly.dev/v1/quote?product=analyze&index=ndvi&lat=30.6&lon=31.1&km=30&date=2025-07-15"

# paid: with no payment header you get the 402 above
curl -i "https://sentbot.fly.dev/v1/analyze?index=ndvi&lat=30.6&lon=31.1&km=30&date=2025-07-15"

# operators: the admin key skips the paywall
curl -H "x-api-key: $ADMIN_API_KEY" "https://sentbot.fly.dev/v1/imagery?lat=25.118&lon=55.133&km=7&preset=true-color&width=1024" -o dubai.png
import { privateKeyToAccount } from "viem/accounts";
import { x402Client, wrapFetchWithPayment } from "@x402/fetch";
import { ExactEvmScheme } from "@x402/evm/exact/client";

const account = privateKeyToAccount(process.env.PRIVATE_KEY);
const client = new x402Client().register("eip155:*", new ExactEvmScheme(account)); // or "solana:*" with @x402/svm
const pay = wrapFetchWithPayment(fetch, client);

const res = await pay("https://sentbot.fly.dev/v1/analyze?index=ndvi&lat=30.6&lon=31.1&km=30&date=2025-07-15");
const a = await res.json();
console.log(a.stats.mean, a.stats.classes, a.stats.validFraction);
# pip install x402 eth-account httpx
from eth_account import Account
from x402.clients.httpx import x402HttpxClient

account = Account.from_key(PRIVATE_KEY)
async with x402HttpxClient(account=account) as client:
    r = await client.get("https://sentbot.fly.dev/v1/change?index=nbr",
                         params={"bbox": "-8.7,39.4,-8.5,39.55",
                                 "dateA": "2025-06-01", "dateB": "2025-08-20"})
    print(r.json()["difference"]["lossFraction"])
§06

Machine interface

discover, price and buy with no human in the loop
/llms.txtone-screen summary
/agent.mdfull guide: parameters, how to pay, how to read the numbers
/openapi.jsonOpenAPI 3.1, every parameter and schema
/.well-known/x402paid resources and starting prices
/v1/productsindices, ranges, class thresholds, limits
PAYMENT-REQUIREDeach 402 carries a bazaar discovery schema and a JSON quote
/v1/pricingthe pricing rules as data, including the multiplier in force
/healthliveness, plus which subsystems are configured