DroneInfo

API documentation

The multi-source weather API.

REST endpoints over a normalised envelope. Per-source attribution on every reading. Honest unavailable when a field cannot be sourced.

Try it - no key required

Before you sign up, hit the public demo. It runs the real pipeline for a coordinate and returns the same shape as the authenticated /v1/weather/point - current conditions, radar nowcast, and per-source status - so you can judge the data honesty for yourself. Capped at 20 requests per hour per IP; for anything beyond that, get a free key.

curlbash
# No key, no signup. Same pipeline and response shape as the authenticated endpoint.
curl "https://api.droneinfo.app/v1/demo/weather/point?lat=59.3293&lon=18.0686"

The demo omits the hourly forecast and is rate-limited per IP rather than per key; every other field matches the authenticated response. It reads back X-RateLimit-Remaining-Hour so you can see the quota drain.

Quickstart

From signup to your first authenticated response in three steps.

  1. 01

    Create an account

    Sign up and verify your email. Free tier is forever, no card required.
  2. 02

    Generate an API key

    On /dashboard/keys, create a key and copy it. Keys are shown in plaintext exactly once; store it in your secret manager.
  3. 03

    Make a request

    curlbash
    curl -H "Authorization: Bearer di_live_..." \
      "https://api.droneinfo.app/v1/weather/point?lat=59.3293&lon=18.0686&country=SE"
    A 200 response includes X-RateLimit-Remaining-Month and X-RateLimit-Remaining-Burst headers so you can pace traffic.

Authentication

Every request must include a Bearer token in the Authorization header. Keys are 40 characters, prefixed with di_live_, and are linked to your account’s subscription tier. Lost a key? Revoke it and create a new one - keys are stored as one-way SHA-256 hashes, so they cannot be recovered.

Headerbash
Authorization: Bearer di_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  • Server-side only. Never embed a key in client JavaScript or mobile apps; proxy requests through your backend.
  • One key per environment. Use separate keys for staging and production so you can revoke without downtime.
  • Rotate freely. A new key activates instantly; revoke the old one when traffic has shifted.

Base URL & versioning

All endpoints live under https://api.droneinfo.app/v1. The v1 surface is stable: response fields will not be removed or have their types changed without a major version bump. New optional fields may appear at any time - your client should ignore unknown keys.

Endpoints

All endpoints accept GET. Parameter values are URL-encoded. Responses are JSON.

Current weather

Free tier

GET /v1/weather/point

Single-shot current weather for a coordinate. Safety-critical fields (wind, gust, precipitation, visibility) are pessimistically merged across providers; every snapshot carries the contributing provider in its `source` field.

ParameterTypeDefaultDescription
lat*number-Latitude in decimal degrees, WGS84. Range −90 to 90. Three-decimal precision is enough for the cache (~111 m).
lon*number-Longitude in decimal degrees, WGS84. Range −180 to 180.
countrystring-Optional ISO 3166-1 alpha-2. Hints at country-specific providers (national radar, airspace integrations, …). Outside coverage the api falls back to the country-agnostic baseline; an unknown code is never an error.
Requestbash
curl -H "Authorization: Bearer di_live_..." \
  "https://api.droneinfo.app/v1/weather/point?lat=59.3293&lon=18.0686"
Response (200)json
{
  "location": { "lat": 52.52, "lon": 13.405 },
  "current": {
    "location": { "lat": 52.52, "lon": 13.405 },
    "observedAt": "2026-05-06T19:15",
    "source": "forecast-model",
    "temperatureC": 10.7,
    "humidityPercent": 25,
    "windSpeed10mMs": 4,
    "windGust10mMs": 9.4,
    "windDirection10mDeg": 163,
    "windSpeed120mMs": 5.7,
    "windDirection120mDeg": 168,
    "precipitationMm": 0,
    "visibilityMeters": 24140,
    "pressureMslHpa": 1012.3,
    "windProfile": [
      { "altitudeM": 10,  "speedMs": 3.0,  "directionDeg": 250 },
      { "altitudeM": 120, "speedMs": 4.45, "directionDeg": 279 },
      { "altitudeM": 500, "speedMs": 6.02, "directionDeg": 301 }
    ]
  },
  "nowcast": {
    "location": { "lat": 52.52, "lon": 13.405 },
    "observedAt": "2026-05-06T19:15",
    "source": "dwd-radar",
    "precipitationMm": 0.12
  },
  "nowcastSource": "dwd-radar",
  "radarCoverage": "ok",
  "radarStatus": "available",
  "providerStatus": [
    { "source": "forecast-model",              "available": true, "lastSuccessAt": "2026-05-06T19:15:08Z" },
    { "source": "met-norway-locationforecast", "available": true, "lastSuccessAt": "2026-05-06T19:15:08Z" },
    { "source": "dwd-radar",                   "available": true, "lastSuccessAt": "2026-05-06T19:14:51Z" }
  ],
  "updatedAt": "2026-05-06T19:15:09.123Z"
}
  • All wind speeds are m/s (ICAO/EASA aviation standard).
  • Optional fields are omitted from the JSON when the upstream provider cannot supply them - treat any missing key as unknown, never silently zero.
  • `windProfile` carries the upper-air interpolation. Pro tier only.
  • `nowcast` is populated when a precipitation nowcast is available for the coordinate. `radarCoverage` is `"ok"` for real ground-based radar (regions where we operate a national adapter) or `"model-fallback"` for a global model nowcast; absent when no nowcast is available at all.
  • `providerStatus[]` lists every upstream queried for this response with its current health (independent of whether it contributed a field).

Hourly forecast

Free tier

GET /v1/weather/hourly

Hourly forecast for the next 24 hours on Free, up to 72 + pastHours backfill on Hobby and above. Same field shape as `weather/point` for each hour.

ParameterTypeDefaultDescription
lat*number-Latitude in decimal degrees, WGS84. Range −90 to 90. Three-decimal precision is enough for the cache (~111 m).
lon*number-Longitude in decimal degrees, WGS84. Range −180 to 180.
countrystring-Optional ISO 3166-1 alpha-2. Hints at country-specific providers (national radar, airspace integrations, …). Outside coverage the api falls back to the country-agnostic baseline; an unknown code is never an error.
hoursinteger24Number of forecast hours, 1-72. Capped at 24 on Free tier.
dayinteger0Day offset from today, 0-6. Combine with `hours` to walk a future day window.
pastHoursinteger0Backfill of past hours, 0-72. Hobby tier and above.
Requestbash
curl -H "Authorization: Bearer di_live_..." \
  "https://api.droneinfo.app/v1/weather/hourly?lat=59.3293&lon=18.0686"
Response (200)json
{
  "location": { "lat": 52.52, "lon": 13.405 },
  "hourly": [
    {
      "location": { "lat": 52.52, "lon": 13.405 },
      "forecastTime": "2026-05-06T20:00",
      "observedAt": "2026-05-06T20:00",
      "source": "forecast-model",
      "temperatureC": 9.4,
      "windSpeed10mMs": 3.7,
      "windGust10mMs": 8.6,
      "precipitationMm": 0,
      "visibilityMeters": 24140
    },
    {
      "location": { "lat": 52.52, "lon": 13.405 },
      "forecastTime": "2026-05-06T21:00",
      "observedAt": "2026-05-06T21:00",
      "source": "forecast-model",
      "temperatureC": 8.8,
      "windSpeed10mMs": 3.2,
      "windGust10mMs": 7.9,
      "precipitationMm": 0,
      "visibilityMeters": 24140
    }
  ],
  "dailyAstronomy": [
    { "sunriseIso": "2026-05-06T05:26", "sunsetIso": "2026-05-06T20:59" }
  ],
  "providerStatus": [
    { "source": "forecast-model",              "available": true },
    { "source": "met-norway-locationforecast", "available": true }
  ],
  "updatedAt": "2026-05-06T19:15:09.450Z"
}

Flight Score

Hobby tier and above

GET /v1/flight-score

Advisory 0-100 drone-flight score with conservative thresholds blending wind and gusts (including the 25-150 m altitude corridor), precipitation, visibility, temperature, and the geomagnetic Kp index. Returns reasons on every degraded field. Not legal permission to fly.

ParameterTypeDefaultDescription
lat*number-Latitude in decimal degrees, WGS84. Range −90 to 90. Three-decimal precision is enough for the cache (~111 m).
lon*number-Longitude in decimal degrees, WGS84. Range −180 to 180.
countrystring-Optional ISO 3166-1 alpha-2. Hints at country-specific providers (national radar, airspace integrations, …). Outside coverage the api falls back to the country-agnostic baseline; an unknown code is never an error.
Requestbash
curl -H "Authorization: Bearer di_live_..." \
  "https://api.droneinfo.app/v1/flight-score?lat=59.3293&lon=18.0686"
Response (200)json
{
  "status": "caution",
  "score": 85,
  "mode": "pro",
  "reasons": [
    {
      "type": "gust",
      "severity": "warning",
      "message": "Wind gusts 9.4 m/s are close to caution limit.",
      "value": 9.4,
      "unit": "m/s"
    }
  ],
  "calculatedAt": "2026-05-06T17:22:24.835Z",
  "legalNotice": "This is not a flight permission. Always check LFV Dronechart before flying.",
  "officialLinks": [
    { "title": "LFV Dronechart", "url": "https://dronechart.lfv.se/" },
    { "title": "Transportstyrelsen UAS guide", "url": "https://www.transportstyrelsen.se/en/aviation/aircraft/drones-unmanned-aircraft/guide-to-uas-operations-in-sweden/" },
    { "title": "EASA drone geo-zones", "url": "https://www.easa.europa.eu/en/light/topics/geo-zones-know-where-fly-your-drone" }
  ],
  "region": "se",
  "authorityName": "Transportstyrelsen / LFV"
}
  • `status` is one of `good` (≥70), `caution` (40-69), `bad` (<40), or `unknown` when a critical field is unavailable.
  • `mode` is `"pro"` when radar nowcast and the 25-150 m altitude wind corridor are factored into the verdict; `"free"` when the score uses only signals the free-tier UI surfaces.
  • `region` is the ISO 3166-1 alpha-2 country code when the `country` hint resolves to a known national authority, or `"generic"` otherwise. `legalNotice`, `officialLinks`, and `authorityName` reflect that resolution.
  • `authorityName` is the human-readable name of the national drone authority for the resolved region (e.g. `"FAA"`, `"Transportstyrelsen / LFV"`), or `null` for the generic fallback. The registry covers 30+ countries; outside it `officialLinks` falls back to the EASA geo-zones map.

Activity Score

Free tier

GET /v1/activity-score

Two-axis conditions assessment for a chosen activity (drone, paraglider, hang-glider, speedflying, kitesurf, windsurf, wing-foil). `safety` answers "is it safe?"; `quality` answers "is it worth going?" - the axes diverge for wind- and thermal-dependent sports. Per-axis reasons plus a data-confidence flag. Advisory only; not legal permission to fly.

ParameterTypeDefaultDescription
lat*number-Latitude in decimal degrees, WGS84. Range −90 to 90. Three-decimal precision is enough for the cache (~111 m).
lon*number-Longitude in decimal degrees, WGS84. Range −180 to 180.
activity*string-Activity id from GET /v1/activities (e.g. `drone`, `paraglider`, `kitesurf`). Case- and whitespace-insensitive. Unknown values return 400 UNKNOWN_ACTIVITY.
countrystring-Optional ISO 3166-1 alpha-2. Hints at country-specific providers (national radar, airspace integrations, …). Outside coverage the api falls back to the country-agnostic baseline; an unknown code is never an error.
shoreBearingDegnumber-Wind-water activities only: the compass bearing (0-360, 0=N) the wind blows FROM when purely offshore (the land side). Enables the offshore-wind safety check; without it a wind-water assessment stays `confidence: "partial"`.
Requestbash
curl -H "Authorization: Bearer di_live_..." \
  "https://api.droneinfo.app/v1/activity-score?lat=59.3293&lon=18.0686&activity=value"
Response (200)json
{
  "activity": "paraglider",
  "safety": { "score": 100, "status": "safe" },
  "quality": { "score": 15, "status": "flat" },
  "reasons": [
    {
      "axis": "quality",
      "metric": "thermals",
      "severity": "warning",
      "message": "Thermals weak (80 J/kg) - limited soaring.",
      "value": 80,
      "unit": "J/kg"
    }
  ],
  "confidence": "full",
  "calculatedAt": "2026-07-20T09:12:00.000Z",
  "tier": "pro",
  "legalNotice": "This is advisory only. Always check your local airspace authority before flying.",
  "officialLinks": [
    { "title": "EASA drone geo-zones", "url": "https://www.easa.europa.eu/en/light/topics/geo-zones-know-where-fly-your-drone" }
  ],
  "region": "generic",
  "authorityName": null
}
  • `safety.status` is one of `safe` / `caution` / `dangerous` / `unknown`; `quality.status` is one of `ideal` / `good` / `marginal` / `flat` / `unknown` (`flat` = not worth it, e.g. too light to ride).
  • For `drone` the two axes are identical (`quality` mirrors `safety`); for free-flight and wind-water activities they diverge - a calm day can be `safety: safe` yet `quality: flat`.
  • `confidence` is `full` / `partial` / `low` - `partial` when an activity's required inputs are missing (no thermal data for a paraglider, or no `shoreBearingDeg` for a wind-water sport). The engine never fabricates missing data.
  • Each reason carries an `axis` (`safety` or `quality`) and a `severity` (`info` / `warning` / `critical` / `blocking`; `blocking` zeroes the quality axis).
  • `region`, `legalNotice`, `officialLinks`, and `authorityName` follow the same country resolution as /v1/flight-score.

Activities

Free tier

GET /v1/activities

Lists the activities available to /v1/activity-score - use it to populate a selector or validate the `activity` param.

No query parameters.

Requestbash
curl -H "Authorization: Bearer di_live_..." \
  "https://api.droneinfo.app/v1/activities"
Response (200)json
{
  "activities": [
    { "id": "drone", "category": "aerial-powered", "label": "Drone" },
    { "id": "paraglider", "category": "free-flight", "label": "Paraglider" },
    { "id": "kitesurf", "category": "wind-water", "label": "Kitesurf" }
  ]
}
  • `category` is one of `aerial-powered` / `free-flight` / `wind-water` / `freefall`. The list grows over time - treat it as the source of truth for valid `activity` ids.

NOTAM / TFR

Hobby tier and above

GET /v1/notam/point

Drone-relevant airspace restrictions (currently US Temporary Flight Restrictions via the FAA) visible from the coordinate. Honest three-state status: `not_supported` outside integrated countries, `active` when something intersects, `ok` when coverage exists and nothing does. Advisory only - never a substitute for the official source.

ParameterTypeDefaultDescription
lat*number-Latitude in decimal degrees, WGS84. Range −90 to 90. Three-decimal precision is enough for the cache (~111 m).
lon*number-Longitude in decimal degrees, WGS84. Range −180 to 180.
countrystring-Optional ISO 3166-1 alpha-2. Hints at country-specific providers (national radar, airspace integrations, …). Outside coverage the api falls back to the country-agnostic baseline; an unknown code is never an error.
Requestbash
curl -H "Authorization: Bearer di_live_..." \
  "https://api.droneinfo.app/v1/notam/point?lat=59.3293&lon=18.0686"
Response (200)json
{
  "status": "active",
  "country": "us",
  "activeCount": 1,
  "notams": [
    {
      "id": "0/1234",
      "kind": "tfr",
      "severity": "critical",
      "summary": "Stadium TFR · Yankee Stadium",
      "description": "Flight restricted within 3 NM up to 3000 ft AGL during major sporting events.",
      "validFrom": "2026-05-06T22:00:00Z",
      "validUntil": "2026-05-07T03:00:00Z",
      "distanceKm": 4.2,
      "link": "https://tfr.faa.gov/tfr2/list.html"
    }
  ],
  "source": "faa-tfr",
  "fetchedAt": "2026-05-06T19:15:09.123Z",
  "disclaimer": "Advisory only. NOTAMs and TFRs may be added between checks. Always verify on the official FAA source before flight."
}
  • `status` is `not_supported` for any country without a NOTAM integration (everything except the US today) - the response still carries `disclaimer` and an empty `notams` array, never an error.
  • `status` is `ok` when the country is covered but no drone-relevant items intersect, and `active` when at least one does. Records are sorted critical, then warning, then info, then by ascending `distanceKm`.
  • Each record's `kind` is `"tfr"` for FAA Temporary Flight Restrictions or `"notam"` otherwise; `validUntil` is omitted for open-ended restrictions.
  • FAA TFR data activates as the upstream feed is wired into the deployment. Until then US points resolve to `ok` with an empty list - coverage exists, no records are surfaced. The `disclaimer` is attached on every response regardless.

Airspace zones

Free tier

GET /v1/airspace/zones

Drone-relevant airspace zone geometry for a country, sourced from national authorities - control zones, restricted and danger areas, and drone-specific UAS zones as GeoJSON features ready to render or run point-in-polygon against. Covers 15 countries today; an unsupported country returns 404 with the supported list, never a fabricated 'all clear'. Advisory only - always confirm on the official authority map.

ParameterTypeDefaultDescription
country*string-ISO 3166-1 alpha-2 of the authority whose zones you want (e.g. `se`, `us`, `jp`). Supported today: US, SE, NO, DK, FI, FR, ES, IE, JP, LV, LU, NL, PL, PT, CH. Unsupported codes return 404 with the live supported list.
bboxWestnumber-Western edge of the viewport. Required (with the other three bbox params) only for large national datasets - currently the US FAA UAS Facility Map; calling those without a bbox returns 400 BBOX_REQUIRED.
bboxSouthnumber-Southern edge of the viewport. See `bboxWest`.
bboxEastnumber-Eastern edge of the viewport. See `bboxWest`.
bboxNorthnumber-Northern edge of the viewport. See `bboxWest`.
Requestbash
curl -H "Authorization: Bearer di_live_..." \
  "https://api.droneinfo.app/v1/airspace/zones?country=SE"
Response (200)json
{
  "country": "se",
  "source": "lfv-wfs",
  "providerTimestamp": "2026-05-06T18:00:00Z",
  "cachedAt": "2026-05-06T19:10:11.402Z",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Polygon",
        "coordinates": [[[17.9,59.6],[18.1,59.6],[18.1,59.7],[17.9,59.7],[17.9,59.6]]]
      },
      "properties": {
        "id": "lfv-wfs:mais:CTR:4056",
        "name": "ARLANDA CTR",
        "type": "ctr",
        "country": "se",
        "lowerLimit": { "kind": "sfc" },
        "upperLimit": { "kind": "altitude", "value": 4500, "unit": "ft", "reference": "amsl" },
        "icaoClass": "C",
        "icaoCode": "ESSA"
      }
    }
  ]
}
  • `country` is required and accepts any ISO 3166-1 alpha-2 code; an unsupported country returns 404 `COUNTRY_NOT_SUPPORTED` with the current supported list - never an empty "all clear". `GET /v1/airspace/zones/countries` returns that list on its own.
  • Each feature's `properties.type` is a discriminated zone kind (`ctr`, `atz`, `tiz`, `restricted`, `danger`, `esu_required`, …). `lowerLimit`/`upperLimit` follow the `{ kind: "sfc" | "unlimited" | "altitude" | "flight_level" }` shape; `scheduledActivation: true` marks zones active only during published activations.
  • Advisory only. Zone coverage and currency vary by national source - this endpoint never asserts an area is clear to fly. Always confirm on the official authority map before flight.

Space weather (Kp)

Free tier

GET /v1/space-weather

Current planetary K-index plus a 3-day forecast and the F10.7 cm solar flux from NOAA SWPC.

No query parameters.

Requestbash
curl -H "Authorization: Bearer di_live_..." \
  "https://api.droneinfo.app/v1/space-weather"
Response (200)json
{
  "kpIndex": 0.67,
  "kpStorm": "quiet",
  "kpObservedAt": "2026-05-06T12:00:00Z",
  "solarFluxF107": 128,
  "solarFluxObservedAt": "2026-05-05T20:00:00Z",
  "forecast": [
    { "date": "2026-05-07", "kpMax": 4.33, "kpStorm": "unsettled", "kind": "forecast" },
    { "date": "2026-05-08", "kpMax": 4.0,  "kpStorm": "unsettled", "kind": "forecast" },
    { "date": "2026-05-09", "kpMax": 2.67, "kpStorm": "quiet",     "kind": "forecast" }
  ],
  "source": "noaa-swpc",
  "fetchedAt": "2026-05-06T17:11:22.840Z"
}

Aviation METAR / TAF

Hobby tier and above

GET /v1/aviation/nearest

Latest METAR observations and TAF forecasts from the nearest two ICAO airports to the coordinate, from authoritative aviation-weather feeds.

ParameterTypeDefaultDescription
lat*number-Latitude in decimal degrees, WGS84. Range −90 to 90. Three-decimal precision is enough for the cache (~111 m).
lon*number-Longitude in decimal degrees, WGS84. Range −180 to 180.
Requestbash
curl -H "Authorization: Bearer di_live_..." \
  "https://api.droneinfo.app/v1/aviation/nearest?lat=59.3293&lon=18.0686"
Response (200)json
{
  "stations": [
    { "icao": "EDDF", "name": "Frankfurt am Main",  "distanceKm": 7.7 },
    { "icao": "EDFH", "name": "Frankfurt-Hahn",     "distanceKm": 38.2 }
  ],
  "metar": [
    {
      "icaoId": "EDDF",
      "stationName": "Frankfurt am Main, DE",
      "observedAt": "2026-05-06T17:00:00.000Z",
      "rawOb": "METAR EDDF 061650Z 14014KT CAVOK 10/M07 Q1012 NOSIG",
      "temperatureC": 10,
      "dewpointC": -7,
      "windSpeedKt": 14,
      "windDirectionDeg": 140,
      "visibility": "6+",
      "altimeterHpa": 1012,
      "flightCategory": "VFR",
      "cloudCover": "CAVOK"
    }
  ],
  "taf": []
}
  • Wind in this endpoint is reported in knots - the unit native to METAR/TAF. Convert to m/s with × 0.5144 if combining with `weather/*`.
  • When the upstream feed is degraded the response still includes the resolved `stations[]` plus an `error` string in place of empty `metar`/`taf` arrays.

Rate limits & quotas

Two layers protect your traffic and our upstream providers.

Burst (per key)

10 requests per second, sliding window, applied per active key.

Exceeded burst returns 429 with Retry-After: 1.

Monthly quota (per account)

  • Free - 10,000 / month
  • Hobby - 100,000 / month
  • Pro - 500,000 / month
  • Enterprise - 1M+ with SLA

Exhausted quota returns 429 QUOTA_EXCEEDED. Upgrade instantly from /dashboard/billing.

Every successful response includes X-RateLimit-Limit-Month, X-RateLimit-Remaining-Month, and X-RateLimit-Remaining-Burst. Reading them is the cheapest way to pace traffic without polling a separate usage endpoint.

Errors

Errors share a single envelope: a stable error code and a human-readable message. Retry timing for 429 responses is in the Retry-After response header (in seconds), not in the body.

Example errorjson
{
  "error": "RATE_LIMITED",
  "message": "Burst limit exceeded"
}
StatusCodeWhen
400VALIDATION_ERRORMissing or malformed query parameter (e.g. lat out of range).
401UNAUTHENTICATEDMissing, malformed, or revoked Bearer key.
402PAYMENT_REQUIREDSubscription is past_due or canceled. Update your card on /dashboard/billing.
403TIER_FORBIDDENEndpoint or parameter requires a higher tier.
404NOT_FOUNDPath does not exist (typo). Inspect the documentation index.
429RATE_LIMITEDBurst (per-second) or pre-auth (per-IP) limit exceeded. Retry after 1 s.
429QUOTA_EXCEEDEDMonthly quota exhausted. Upgrade plan from /dashboard/billing or wait until the start of next UTC month.
502UPSTREAM_UNAVAILABLEA weather provider is degraded and we couldn't fall back. Rare; retry with exponential backoff.
503MAINTENANCEScheduled maintenance. Retry-After header indicates duration.

Multi-source merge

Safety-critical fields - wind, gusts, precipitation, visibility - are merged pessimistically across providers. We take the more flight-conservative reading (max for wind/gust/precipitation, min for visibility) and surface the primary source on the snapshot so your client can render attribution. Non-safety fields like temperature and dew point come from the primary provider so the snapshot stays internally coherent.

When a provider can’t answer (region outside its extent, upstream timeout) the contributing key is simply omitted from the JSON - treat any missing field as unknown rather than zero. We never silently substitute a different region or interpolate across gaps. Radar nowcast is labelled explicitly: radarCoverage: "ok" marks regions where we operate a national ground-radar adapter, "model-fallback" marks a global model nowcast used outside those regions, and the field is absent when no nowcast is available at all. Your client can decide whether to display the model fallback or hide it.

Data sources & attribution

DroneInfo aggregates authoritative meteorological forecasts, aviation observations, and national radar nowcasts from official government agencies. Attribution is carried on every reading via the source field on each weather snapshot, plus the per-request providerStatus[] array that reports the health of every upstream queried for the response.

The radar source reference documents the national networks we query: format, resolution, cadence, licence and required attribution, plus how each one distinguishes no coverage from no measurement from a measured zero.

Code samples

Server-side examples. Read the key from an environment variable; never ship it in client bundles.

JavaScript / Nodejavascript
const res = await fetch(
  "https://api.droneinfo.app/v1/weather/point?lat=59.3293&lon=18.0686&country=SE",
  { headers: { Authorization: `Bearer ${process.env.DRONEINFO_KEY}` } }
);
if (!res.ok) {
  throw new Error(`droneinfo ${res.status}`);
}
const data = await res.json();
console.log(data.current.windSpeed10mMs, data.current.source);
Pythonpython
import os
import httpx

with httpx.Client(
    base_url="https://api.droneinfo.app/v1",
    headers={"Authorization": f"Bearer {os.environ['DRONEINFO_KEY']}"},
    timeout=5.0,
) as c:
    r = c.get(
        "/weather/point",
        params={"lat": 59.3293, "lon": 18.0686, "country": "SE"},
    )
    r.raise_for_status()
    data = r.json()
    print(data["current"]["windSpeed10mMs"], data["current"]["source"])