API Documentation

Most endpoints are free and return cached data. One endpoint — /api/solar/irradiance — supports x402 micropayments for premium live data. No API keys required.

Paid EndpointPremium

GET/api/solar/irradiance
Params

lat, lng

Price

$0.001 USDC

Session

30 min after payment

Free Tier (cached, up to 15 min old)

  • Current GHI & DNI (W/m²)
  • Cloud cover percentage
  • Hourly irradiance forecast
  • Sunrise & sunset times

Premium (live data)

  • All free tier fields
  • 7-day daily forecast
  • Temperature & wind speed
  • Thermal panel efficiency
  • Diffuse radiation (DHI)
  • Weather descriptions

Free EndpointsFree

EndpointDescription
/api/solar/building-insightsRoof analysis via Google Solar API
/api/solar/data-layersAnnual solar flux heatmap PNG
/api/geocode/searchForward/reverse geocoding
/api/weather/forecastsEnsemble weather (4 sources)
/api/weather/biasTemperature bias correction
/api/kalshi/marketsKalshi weather prediction markets

x402 Payment Flow

How a developer integrates with the paid endpoint, step by step.

Step 1 — Free request (no headers needed)

GET /api/solar/irradiance?lat=32.7&lng=-117.1

→ 200 OK — returns cached data (up to 15 min old)

Step 2 — Request premium, receive 402

GET /api/solar/irradiance?lat=32.7&lng=-117.1
Headers:
  X-Request-Premium: true
  X-Wallet-Address: 0xYourWalletAddress

→ 402 Payment Required
{
  "accepts": [
    {
      "scheme": "exact",
      "network": "base-sepolia",
      "maxAmountRequired": "1000",
      "resource": "/api/solar/irradiance?lat=32.7&lng=-117.1",
      "asset": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
      "payTo": "0xServerWalletAddress",
      "extra": { "name": "USDC", "version": "1" }
    }
  ]
}

Step 3 — Sign & retry with payment

Your wallet signs a USDC payment using the details from the 402 response. Retry the request with the signed payment in the x-payment header. The server verifies the payment via the x402 facilitator.

GET /api/solar/irradiance?lat=32.7&lng=-117.1
Headers:
  X-Request-Premium: true
  X-Wallet-Address: 0xYourWalletAddress
  x-payment: <signed-payment-payload>

→ 200 OK — returns premium live data
→ X-PAYMENT-RESPONSE header included

Step 4 — Session (30 minutes)

After a successful payment, the server returns a signed X-SESSION-TOKEN (and cookie). Subsequent requests using that token automatically receive premium data for 30 minutes — no further payments needed until session expiry. Wallet-address session lookup is supported as a legacy fallback.

Automatic handling with x402-fetch

The x402-fetch library wraps fetch to handle the 402 → sign → retry flow automatically:

import { wrapFetchWithPayment } from 'x402-fetch'

const paidFetch = wrapFetchWithPayment(fetch, signer)

const res = await paidFetch(
  '/api/solar/irradiance?lat=32.7&lng=-117.1',
  {
    headers: {
      'X-Request-Premium': 'true',
      'X-Wallet-Address': address
    }
  }
)

Response Examples

Free vs premium responses from /api/solar/irradiance. Premium-only fields are highlighted.

Free Response

{
  "success": true,
  "data": {
    "current": {
      "ghi": 542,
      "dni": 680,
      "cloudCover": 15,
      "isDay": true
    },
    "hourly": [
      { "time": "14:00", "ghi": 542,
        "dni": 680, "cloudCover": 15 }
    ],
    "daily": {
      "sunrise": "2025-01-15T06:48:00",
      "sunset": "2025-01-15T17:12:00"
    },
    "location": {
      "latitude": 32.7,
      "longitude": -117.1,
      "timezone": "America/Los_Angeles",
      "elevation": 20
    }
  },
  "cached": true,
  "premium": false,
  "timestamp": 1736956200000
}

Premium Response

{
  "success": true,
  "data": {
    "current": {
      "ghi": 542,
      "dni": 680,
      "cloudCover": 15,
      "isDay": true,
      "temperature": 22.4,
      "windSpeed": 3.1,
      "diffuseRadiation": 128,
      "thermalEfficiency": 98.9,
      "weatherDescription": "Mainly clear"
    },
    "hourly": [
      { "time": "14:00", "ghi": 542,
        "dni": 680, "cloudCover": 15,
        "diffuseRadiation": 128,
        "temperature": 22.4 }
    ],
    "daily": { ... },
    "forecast": [
      { "date": "2025-01-16",
        "radiationSum": 18.2,
        "estimatedKwh": 5.1,
        "weatherDescription": "Sunny" }
    ],
    "location": { ... }
  },
  "cached": false,
  "premium": true,
  "timestamp": 1736956200000
}

Supported Networks

Testnet (current): Base Sepolia (EVM, USDC), Solana Devnet

Mainnet (planned): Base, Solana

Rate Limits

/api/geocode/search: 1 request/second per IP (Nominatim upstream constraint)

Free tier solar: Served from cache — no meaningful rate limit

Premium sessions: Higher limits during 30-minute window