Skip to content
Updraft Docs
Türkçe

Schemas · API reference

Body_upload_flight_v1_flights_post

NameTypeDescription
file requiredstring (binary)IGC, GPX or FIT file, byte for byte as recorded; the format is detected from the content
external_pilot_hash requiredstringHMAC-SHA256 of the client's pilot id, 64 hex characters; the HMAC key stays with the client
^[0-9a-fA-F]{64}$
consent_version requiredintegerVersion of the consent text the pilot accepted
0 ≤ x ≤ 32767
source required"kunduzo"Uploading platform
external_refstring | nullClient's own flight reference
1–200 chars
sportSportSport of the flight (optional, default paragliding); stored with a new flight. Shared layers count only paragliding flights for now
default "paragliding"

ConsentReceipt

What the request changed. No pilot identity is returned.

NameTypeDescription
event required"withdrawn" | "granted"
scope required"pilot" | "flights"
recorded requiredbooleanA new consent event was written; false: it was already in effect (repeated request), nothing changed
flights_in_scope requiredintegerFlights the request covers (deleted ones aside); 0 for a pilot-wide withdrawal, which only covers later uploads
flights_affected requiredintegerWithdrawal by list: flights that counted towards the shared layers and no longer do; 0 for a pilot-wide withdrawal. Grant: flights not in the layers now that are checked again (consent and quality)
received_at requiredstring (date-time)Time the request was recorded (UTC)
layers_updated_by requiredstring (date-time) | nullWithdrawal by list: the layers no longer contain these flights by this time (received_at + 24 h); null for a pilot-wide withdrawal (no flight leaves the layers) and for a grant

ConsentRequest

Pilot-wide (no flight_ids) or for the listed flights of that pilot.

NameTypeDescription
external_pilot_hash requiredstringHMAC-SHA256 of the client's pilot id, 64 hex characters; the same value as external_pilot_hash of the uploads
^[0-9a-fA-F]{64}$
consent_version requiredintegerVersion of the consent text the pilot acted on
0 ≤ x ≤ 32767
source required"kunduzo"Platform the pilot gave or withdrew it on
flight_idsarray<string (uuid)> | nullUpdraft flight ids (flight_id of the upload response) of this pilot. Omitted: pilot-wide; a pilot-wide withdrawal covers the flights uploaded from now on (earlier flights stay in the anonymous aggregates), a pilot-wide grant every flight
1–1000 items

DeletionReceiptOut

What the request recorded. No pilot identity and no flight id is returned.

NameTypeDescription
deletion_id requiredstring (uuid) | nullThe deletion request covering this one (GET /v1/deletions/{id}): new when recorded, else the earlier request that already covers it; null when there is nothing to delete (pilot unknown to Updraft or already erased)
scope required"pilot" | "flights"
recorded requiredbooleanA new deletion was recorded; false: everything asked was already deleted or being deleted (repeated request), nothing changed
flights_in_scope requiredintegerWith flight_ids: the listed flights; pilot-wide: the flights of the covering request
status required"pending" | "completed"completed: raw files, fix files and thermal events are gone
received_at requiredstring (date-time)When the covering request was received (UTC)
layers_updated_by requiredstring (date-time)The published layers no longer contain these flights by this time (received_at + 24 h)

DeletionRequestBody

Pilot-wide (no flight_ids) or the listed flights of that pilot.

NameTypeDescription
external_pilot_hash requiredstringHMAC-SHA256 of the client's pilot id, 64 hex characters; the same value as external_pilot_hash of the uploads
^[0-9a-fA-F]{64}$
source required"kunduzo"Platform the pilot asked on
flight_idsarray<string (uuid)> | nullUpdraft flight ids (flight_id of the upload response) of this pilot. Omitted: pilot-wide, every flight of the pilot and the pilot's link to the client's pilot id
1–1000 items

DeletionStatusOut

Progress of one deletion request. No pilot identity and no flight id.

NameTypeDescription
deletion_id requiredstring (uuid)
scope required"pilot" | "flights"
status required"pending" | "completed"
flights requiredintegerFlights the request deletes
flights_completed requiredintegerOf these, flights whose files are gone
received_at requiredstring (date-time)
completed_at requiredstring (date-time) | nullEvery flight done (pilot-wide: also the pilot's masks and link); null while pending
layers_updated_by requiredstring (date-time)received_at + 24 h

ErrorBody

NameTypeDescription
code requiredstring
detail requiredstring
errorsarray<object> | null

FlightReceipt

The stored flight. Pilot identity, track and altitude are never returned.

NameTypeDescription
flight_id requiredstring (uuid)uuid5 of the file's SHA-256; same bytes, same id
status required"accepted" | "duplicate"accepted (202): new flight, queued; duplicate (200): already stored
igc_sha256 requiredstringSHA-256 of the uploaded bytes (IGC, GPX or FIT), lower case hex
flown_on requiredstring (date)Local (Europe/Istanbul) date of the first valid fix
consent_version requiredintegerConsent text version stored with the flight
sport requiredSportSport stored with the flight; a duplicate keeps the sport of the first upload. Shared layers count only paragliding flights for now
processing required"pending" | "processed" | "failed"
usable_for_layers requiredbooleanCounts towards shared layers (consent and quality); false until processed
received_at requiredstring (date-time)Time this upload was received (UTC)

ForecastCell

NameTypeDescription
lat requirednumberLatitude of the 0.25° cell centre the forecast is for
lon requirednumberLongitude of the cell centre

ForecastInfo

NameTypeDescription
source requiredstring | nullForecast service (open-meteo); null when off
model requiredstring | nullWeather model (icon_eu); null when off
cell requiredForecastCell
fetched_at requiredstring (date-time) | nullWhen our forecast server produced this forecast (UTC); the model run is at most about 9 hours older. Null without a forecast
attribution requiredstringRequired data attribution (CC BY 4.0)

Health

NameTypeDescription
status required"ok"
version requiredstring

HTTPValidationError

NameTypeDescription
detailarray<ValidationError>

IncidentRegion

NameTypeDescription
id requiredstring (uuid)
slug requiredstring
name requiredstring

IncidentType

docs/02 features; the same list as migration 0013 (a test compares).

"collision_obstacle" | "takeoff_problem" | "landing_problem" | "rotor_turbulence" | "power_line" | "airspace" | "other"

MultiPolygonGeometry

NameTypeDescription
type required"MultiPolygon"
coordinates requiredarray<array<array<[number, number]>>>Polygons → rings → [longitude, latitude] (WGS 84), simplified

NoticeText

NameTypeDescription
tr requiredstring
en requiredstring

OpenDataAttribution

NameTypeDescription
tr requiredstring
en requiredstring

OpenDataFileInfo

NameTypeDescription
name requiredstringFile name, e.g. sites.geojson
layer requiredstring | nullthermals_r7, thermals_r9, sites, hazards, skyways; null for README.md and LICENSE.txt
format requiredstringgeoparquet (GeoParquet 1.1), geojson, markdown (README), text (LICENSE)
rows requiredinteger | nullFeatures in the layer; null for documents
size_bytes requiredinteger
sha256 requiredstringSHA-256 of the file, 64 lowercase hex characters

OpenDataList

NameTypeDescription
releases requiredarray<OpenDataReleaseInfo>Newest year first; may be empty

OpenDataReleaseInfo

NameTypeDescription
year requiredintegerRelease year (the content is the build day's cumulative state)
generated_on requiredstring (date)UTC day the package was built
open_data_version requiredintegerPackage format version
license_id requiredstringCC-BY-4.0
license_url requiredstring
attribution requiredOpenDataAttributionRequired credit line (docs/29 §2)
thresholds requiredOpenDataThresholdsPrivacy thresholds at build time
files requiredarray<OpenDataFileInfo>Package files (manifest.json not listed)

OpenDataThresholds

NameTypeDescription
min_pilots_grid requiredintegerDistinct pilots behind every thermal cell
min_pilots_features requiredintegerDistinct pilots behind every site and hazard
min_pilots_skyways requiredintegerDistinct pilots behind every skyway

PackFileInfo

One PMTiles file; a MapLibre source of the same name reads it as pmtiles://.

NameTypeDescription
kind required"base" | "contours" | "terrain" | "hillshade" | "power"Base map source the file replaces offline (docs/02 §6)
file requiredstringFile name, {kind}.pmtiles
url requiredstringTime-limited GET URL (until expires_at); supports HTTP range requests
size_bytes requiredinteger
sha256 requiredstringSHA-256 of the file, 64 lowercase hex characters
tile_type required"mvt" | "webp"
tile_compression required"gzip" | "none"
min_zoom requiredinteger
max_zoom requiredintegerHighest zoom in the file; MapLibre over-zooms beyond it
tile_count requiredinteger
source_build_id requiredstringBase map build the file was cut from
attribution requiredstringAttribution of the source (may hold HTML links)

PackInfo

NameTypeDescription
region requiredstring
name requiredstring | nullRegion name when cut from regions
pack_version requiredstringYYYYMMDD[-n]; a larger value is a newer pack. Compare it with the downloaded one to decide whether to download again
created_at requiredstring (date-time)
bbox required[number, number, number, number][west, south, east, north] degrees, WGS 84: every tile meeting it is in
4–4 items
size_bytes requiredintegerSum of the files
max_zoom requiredinteger
zoom_trimmed requiredbooleanTrue when zoom levels were dropped to stay under the size limit
files requiredarray<PackFileInfo>
attribution requiredstringCredit line to show with the offline map
expires_at requiredstring (date-time)The file URLs stop working at this time (UTC)

PilotMaskCreate

home: a circle (center, radius_m optional). custom: a circle (center + radius_m) or a polygon.

NameTypeDescription
external_pilot_hash requiredstringHMAC-SHA256 of the client's pilot id, 64 hex characters; the same value as external_pilot_hash of the uploads
^[0-9a-fA-F]{64}$
source required"kunduzo"Platform the pilot set the mask on
kind required"home" | "custom"home: the pilot's home (at most one per pilot); custom: another place
centerPilotMaskPoint | nullCentre of a circle
radius_minteger | nullCircle radius in metres. home: at least the home mask default (privacy settings, 2000) and the default when omitted; custom: 200-10000, required with center
1 ≤ x ≤ 10000
polygonPilotMaskPolygonIn | nullcustom only, instead of a circle; area between a 200 m and a 10000 m circle's

PilotMaskList

NameTypeDescription
items requiredarray<PilotMaskOut>The pilot's masks, oldest first
max_masks requiredintegerMasks a pilot may have

PilotMaskOut

One mask of the pilot, with its geometry (for the client's own pilot only).

NameTypeDescription
id requiredstring (uuid)
kind required"home" | "custom"
center requiredPilotMaskPoint | nullhome: the circle centre; custom: null
radius_m requiredinteger | nullhome: the circle radius; custom: null
polygon requiredPilotMaskPolygon
area_km2 requirednumberArea of the stored geometry, 3 decimals
created_at requiredstring (date-time)

PilotMaskPoint

NameTypeDescription
lat requirednumberLatitude (WGS84, degrees)
-90 ≤ x ≤ 90
lon requirednumberLongitude (WGS84, degrees)
-180 ≤ x ≤ 180

PilotMaskPolygon

NameTypeDescription
type required"Polygon"
coordinates requiredarray<array<array<number>>>The stored geometry, [lon, lat] with 6 decimals (a circle as its polygon)

PilotMaskPolygonIn

GeoJSON Polygon with one ring (no holes), positions [lon, lat].

NameTypeDescription
type required"Polygon"
coordinates requiredarray<array<[number, number]>>One closed ring of 4-500 [lon, lat] positions (last = first); a valid, non self-intersecting polygon
1–1 items

PilotMaskReceipt

What the change recorded. No pilot identity is returned.

NameTypeDescription
mask requiredPilotMaskOut | nullThe new mask; null after a removal
removed_id requiredstring (uuid) | nullThe removed mask; null after an addition
flights_affected requiredintegerThe pilot's flights that are processed again with the changed masks
received_at requiredstring (date-time)Time the change was recorded (UTC)
layers_updated_by requiredstring (date-time)The published layers follow the change by this time (received_at + 24 h)

PointGeometry

NameTypeDescription
type required"Point"
coordinates required[number, number][longitude, latitude], WGS 84
2–2 items

PublicIncident

NameTypeDescription
id requiredstring (uuid)Incident id (stable while the record exists)
type requiredIncidentTypeKind of incident (fixed list, docs/02 features)
period_from requiredstringStart of the period: YYYY or YYYY-MM (never a day)
^[0-9]{4}(-(0[1-9]|1[0-2]))?$
period_to requiredstringEnd of the period: YYYY or YYYY-MM
^[0-9]{4}(-(0[1-9]|1[0-2]))?$
precaution requiredstringWhat to do or avoid here (moderator's note)
0–280 chars
lon requirednumberLongitude, WGS 84, 5 decimals
-180 ≤ x ≤ 180
lat requirednumberLatitude, WGS 84, 5 decimals
-90 ≤ x ≤ 90

PublicReplay

A shared flight for the 3D replay. No pilot identity, no flight id, no clock time, no maximum altitude field; masked stretches are gaps between parts.

NameTypeDescription
id requiredstringThe share's public_id
summary requiredPublicReplaySummary
parts requiredarray<PublicReplayPart>Time ordered; a masked stretch between two parts is not returned
thermals requiredarray<PublicReplayThermal>Thermal events starting inside a part; empty when none
max_points requiredinteger

PublicReplayPart

One unmasked stretch of the flight as parallel arrays (one entry per point).

NameTypeDescription
t requiredarray<number>Seconds since the first returned fix (0.1 s)
lon requiredarray<number>
lat requiredarray<number>
alt_gps requiredarray<integer | null>GNSS altitude, m
alt_baro requiredarray<integer | null>Pressure altitude, m; null without sensor
vario requiredarray<number | null>Vertical speed, m/s; null when unknown

PublicReplaySummary

NameTypeDescription
flown_on requiredstring (date)Day of the flight (no time of day)
duration_s requiredinteger | null
distance_m requiredinteger | null
takeoff_name requiredstring | nullNearest public (approved) take-off site within 500 m, if any
landing_name requiredstring | nullNearest public (approved) landing site within 500 m
fix_count requiredintegerVisible (unmasked, usable) fixes before thinning
point_count requiredintegerPoints returned

PublicReplayThermal

NameTypeDescription
lon requirednumberCore of the thermal
lat requirednumber
start_s requirednumberStart, seconds on the same clock as the parts
duration_s requiredinteger
gain_m requiredintegerHeight gained, m
avg_climb_ms requirednumberMean climb rate, m/s

RegionCollection

NameTypeDescription
type required"FeatureCollection"
features requiredarray<RegionFeature>

RegionFeature

NameTypeDescription
type required"Feature"
id requiredstring (uuid)
bbox required[number, number, number, number][west, south, east, north] of the full boundary, degrees
4–4 items
geometry requiredMultiPolygonGeometry
properties requiredRegionListProperties

RegionHourClimb

NameTypeDescription
hour_bucket requiredintegerLocal 2-hour bucket (Europe/Istanbul), 0 = 00:00-02:00
0 ≤ x ≤ 11
avg_climb_ms requirednumberMean climb of the thermals in the region, m/s

RegionIncidentsResponse

NameTypeDescription
region requiredIncidentRegion
incidents requiredarray<PublicIncident>Approved incidents of the region, by period, newest first (no ranking)

RegionListProperties

NameTypeDescription
slug requiredstringShort name (regions.slug), used in Atlas addresses
name requiredstring
updated_at requiredstring (date-time)Last change of the region (UTC)
summary requiredRegionSummary | nullNull when the profile is not computed yet or withheld after a threshold increase (as GET /v1/regions/{region}/profile)

RegionMonth

NameTypeDescription
month requiredintegerLocal calendar month
1 ≤ x ≤ 12
flyable_days requiredintegerLocal dates in this month, over all years, on which at least one flight from the region lasted longer than 15 minutes
0 ≤ x
years requiredintegerYears with flights in this month (divide for a mean)
1 ≤ x

RegionProfile

regions.profile (docs/02 regions); values below the thresholds are absent.

NameTypeDescription
version required1Profile rules and shape version
processing_version requiredintegerFix pipeline version of the inputs
1 ≤ x
thresholds requiredRegionThresholds
support requiredRegionSupport | nullBand of pilots behind the region's flights; null below the threshold
takeoffs requiredarray<RegionTakeoff>Approved take-offs in the region
months requiredarray<RegionMonth>Months passing the threshold, in order
wind requiredRegionWind
avg_flight_duration_min requiredinteger | nullMean airborne time of the region's flights, minutes
0 ≤ x
hours requiredarray<RegionHourClimb>Hour buckets passing the threshold, in order
best_hour_bucket requiredinteger | nullHour bucket with the highest mean climb
0 ≤ x ≤ 11

RegionProfileResponse

NameTypeDescription
id requiredstring (uuid)
slug requiredstring
name requiredstring
updated_at requiredstring (date-time)Last change of the region (UTC)
profile requiredRegionProfile | nullNull when not computed yet, or withheld after a threshold increase until the next nightly run

RegionSummary

Headline values of the region profile; every one is absent below the thresholds.

NameTypeDescription
support requiredRegionSupport | nullBand of pilots behind the region's flights; null below the threshold
months requiredarray<integer>Months (1-12) passing the threshold, in order; a missing month means 'not enough data', not 'not flown'
dominant_sector requiredinteger | nullDominant 850 hPa wind sector (0 = north, 45° steps)
0 ≤ x ≤ 7
best_hour_bucket requiredinteger | nullLocal 2-hour bucket with the highest mean climb
0 ≤ x ≤ 11
avg_flight_duration_min requiredinteger | nullMean airborne time of the region's flights, minutes
0 ≤ x
takeoffs requiredintegerApproved take-offs in the region (profile list)
0 ≤ x

RegionSupport

NameTypeDescription
confidence required"low" | "medium" | "high"Pilots behind the region's flights: low (3 to 4), medium (5 to 9), high (10 or more)
min_pilots requiredinteger | nullAt least this many different pilots, floored to 3, 5, 10, 20, 50, 100; the exact count is never returned

RegionTakeoff

NameTypeDescription
id requiredstring (uuid)Site id (GET /v1/sites)
name requiredstring | nullName given by a moderator; null if none yet
lon requirednumberLongitude, WGS 84, 6 decimals
-180 ≤ x ≤ 180
lat requirednumberLatitude, WGS 84, 6 decimals
-90 ≤ x ≤ 90
headings requiredarray<integer> | nullLaunch directions (degrees, 45° sectors)
elevation_m requiredinteger | nullGround elevation in metres (DEM)
confidence required"low" | "medium" | "high"
min_pilots requiredinteger | null

RegionThresholds

NameTypeDescription
min_pilots requiredintegermin_pilots_regions used for this profile
1 ≤ x
min_flights requiredintegermin_flights_regions used for this profile
1 ≤ x

RegionWind

NameTypeDescription
dominant_sector requiredinteger | nullSector with the most flights when its share is at least 0.3
0 ≤ x ≤ 7
sectors requiredarray<RegionWindSector>

RegionWindSector

NameTypeDescription
sector requiredinteger850 hPa wind the air came from, 45° sectors, 0 = north
0 ≤ x ≤ 7
share requirednumberShare of the flights with a known sector
0 ≤ x ≤ 1

RouteGraphInfo

NameTypeDescription
built_at requiredstring (date-time)Last change of the region's precomputed graph
rule_version requiredinteger

RouteLanding

NameTypeDescription
id requiredstring (uuid)Public landing (GET /v1/sites)
name requiredstring | null
lat requirednumber
lon requirednumber

RouteOption

NameTypeDescription
id requiredstringStable within the answer: the direction code
direction required"n" | "ne" | "e" | "se" | "s" | "sw" | "w" | "nw"General direction from the take-off
waypoints requiredarray<RouteWaypoint>
reasons requiredarray<string>i18n keys routes.reason.<code> (docs/10 §20)

RoutesResponse

NameTypeDescription
takeoff requiredRouteTakeoff
date requiredstring (date)Local date (Europe/Istanbul)
hour requiredintegerLocal hour (Europe/Istanbul)
0 ≤ x ≤ 23
timezone required"Europe/Istanbul"
wind requiredRouteWind
options requiredarray<RouteOption>A few options in compass order (clockwise from north); not ranked
empty requiredstring | nulli18n key routes.empty.<code> when there is no option; else null
forecast requiredForecastInfo
graph requiredRouteGraphInfo
notice required"routes.notice.preflight_only"i18n key of the fixed notice (docs/04 §3)
notice_text requiredNoticeTextThe notice itself: pre-flight planning only; the pilot decides; airspace and legal limits are checked separately

RouteTakeoff

NameTypeDescription
id requiredstring (uuid)
name requiredstring | null
lat requirednumber
lon requirednumber

RouteWaypoint

NameTypeDescription
lat requirednumberCentre of the thermal cell (H3 r9, about 0.1 km²)
lon requirednumber
support required"high" | "medium"Support band of the cell over all months (high from 10 pilots, medium from 5; never an exact count)
conditions required"hour_and_wind" | "wind" | "hour" | "general"Which breakdown weighted the cell: the day's hour and wind sector, the sector only, the hour only, or the general pattern
along_skyway requiredbooleanThe leg arriving here follows a public skyway
landings requiredarray<RouteLanding>Landing alternatives within reach of this waypoint, nearest first

RouteWind

NameTypeDescription
sector requiredinteger | null850 hPa wind sector used for weighting (0 = from the north, 45° slices clockwise); null without a forecast
0 ≤ x ≤ 7
direction_deg requiredinteger | null850 hPa wind, from
0 ≤ x ≤ 360
speed_ms requirednumber | null850 hPa wind speed, m/s
0 ≤ x

ShareOut

The flight's active share. No pilot identity, no flight data.

NameTypeDescription
public_id requiredstringUnguessable link id: 22 characters of 0-9A-Za-z (about 131 random bits), not derived from the flight
url_path requiredstringPath of the Atlas page, /flights/{public_id}; the client joins it to the Atlas origin
created_at requiredstring (date-time)When this share was opened (UTC)

ShareRequestBody

The pilot who acts and the consent text version they acted on.

NameTypeDescription
external_pilot_hash requiredstringHMAC-SHA256 of the client's pilot id, 64 hex characters; the same value as external_pilot_hash of the upload. The flight must be this pilot's
^[0-9a-fA-F]{64}$
consent_version requiredintegerVersion of the consent text the pilot shared (or stopped sharing) under; stored with the public_replay consent event
0 ≤ x ≤ 32767
source required"kunduzo"Platform the pilot acted on

Site

NameTypeDescription
type required"Feature"
id requiredstring (uuid)
geometry requiredPointGeometry
properties requiredSitePropertiesPublic attributes of a site. Never: pilot identity, flights, exact pilot count.

SiteCollection

NameTypeDescription
type required"FeatureCollection"
features requiredarray<Site>
next_cursor requiredstring | nullPass as cursor for the next page; null on the last page

SiteProperties

Public attributes of a site. Never: pilot identity, flights, exact pilot count.

NameTypeDescription
kind required"takeoff" | "landing"
name requiredstring | nullName given by a moderator; null if none yet
headings requiredarray<integer> | nullTakeoff: launch directions (downhill azimuth, degrees, 45° sectors); null when not derived (no DEM yet) or for landings
slope_deg requiredinteger | nullTakeoff: slope in degrees (DEM)
elevation_m requiredinteger | nullTakeoff: ground elevation in metres (DEM)
area_m2 requiredinteger | nullLanding: area of the landing points' hull, m²
confidence required"low" | "medium" | "high"Support from flight data: low (3 to 4 pilots), medium (5 to 9), high (10 or more). Moderator or OSM sites below 3 pilots are low
min_pilots requiredinteger | nullAt least this many different pilots used the site, floored to 3, 5, 10, 20, 50, 100; null for moderator or OSM sites under 3. The exact count is never returned
version requiredintegerIncrements on every change of the site
updated_at requiredstring (date-time)Last change (UTC)

SlopeConditions

NameTypeDescription
date requiredstring (date)Local date (Europe/Istanbul)
timezone required"Europe/Istanbul"
cell requiredForecastCellCentre of the 0.25° cell the answer is for
hours requiredarray<SlopeHour>Local hours 05-21
forecast_state required"available" | "out_of_range" | "unavailable"available; out_of_range (date outside today..today + 4, sun only); unavailable (forecast server off or failed, sun only)
forecast requiredForecastInfo
method_version requiredintegerVersion of the slope rule (docs/07 §9b)
notice required"slopes.notice.preflight_only"i18n key of the fixed notice: pre-flight planning only; the pilot decides

SlopeHour

NameTypeDescription
time requiredstring (date-time)UTC hour; values are instantaneous
local_hour requiredintegerHour in Europe/Istanbul
0 ≤ x ≤ 23
sun requiredSunSun at the cell centre (style state sun_azimuth/altitude)
wind_10m requiredWind | null10 m forecast wind; null without a forecast
wind_850hpa requiredWind | null850 hPa forecast wind (about 1,500 m); null without a forecast

Sport

flights.sport (migration 0016, SPORT-001). Layers count only PARAGLIDING for now.

"paragliding" | "hang_gliding" | "sailplane" | "paramotor" | "hike_and_fly" | "other"

SuitabilityHour

NameTypeDescription
time requiredstring (date-time)UTC hour; forecast values are instantaneous
level required"green" | "yellow" | "red" | "unknown"
reasons requiredarray<string>i18n keys suitability.reason.<code>
wind_10m requiredWind | null10 m wind; null without a forecast
wind_850hpa requiredWind | null850 hPa wind (about 1,500 m)
heading_offset_deg requiredinteger | nullAngle of the 10 m wind to the nearest launch heading (0 = straight in); null for light wind, unknown headings or no forecast

SuitabilityResponse

NameTypeDescription
site_id requiredstring (uuid)
date requiredstring (date)Local date (Europe/Istanbul)
timezone required"Europe/Istanbul"
headings requiredarray<integer> | nullLaunch directions used (downhill azimuth, degrees); null when not derived
slots requiredarray<SuitabilitySlot>
forecast requiredForecastInfo
rule_version requiredintegerVersion of the rating rule
notice required"suitability.notice.preflight_only"i18n key of the fixed notice: pre-flight planning only, not for in-flight use; the pilot decides (docs/04 §3)

SuitabilitySlot

NameTypeDescription
start requiredstring (date-time)Local start (Europe/Istanbul, with offset)
end requiredstring (date-time)Local end (exclusive)
level required"green" | "yellow" | "red" | "unknown"green looks suitable, yellow caution, red looks unsuitable, unknown no forecast; the worst of the slot's hours
reasons requiredarray<string>i18n keys suitability.reason.<code> (docs/10 §14)
hours requiredarray<SuitabilityHour>

Sun

NameTypeDescription
azimuth_deg requirednumberClockwise from north, one decimal
0 ≤ x < 360
altitude_deg requirednumberAbove the horizon, one decimal; negative = night
-90 ≤ x ≤ 90

ValidationError

NameTypeDescription
loc requiredarray<string | integer>
msg requiredstring
type requiredstring
inputany
ctxobject

VideoFormat

Aspect ratio in the URL and the object key; both are 1080p.

"16x9" | "9x16"

VideoInfo

A video of a shared flight. No pilot, no flight id: the share's public_id only.

NameTypeDescription
public_id requiredstring
format required"16:9" | "9:16"
length_s required15 | 30Longest video, seconds: 15 (default; about 3.5 minutes to make) or 30 (about 7 minutes). A flight is shown at least 10x faster, so a short flight gives a shorter video
status required"queued" | "rendering" | "ready" | "failed"queued → rendering → ready; failed after every retry failed
status_path requiredstringPath of the status route of this video
url requiredstring | nullTime-limited download URL (MP4, H.264) when ready, else null
expires_at requiredstring (date-time) | nullurl stops working at this time (UTC)
width requiredinteger
height requiredinteger
fps requiredinteger | null30 when ready
duration_s requirednumber | nullLength of the video, seconds, when ready
size_bytes requiredinteger | null
sha256 requiredstring | nullSHA-256 of the MP4 when ready
error required"replay_gone" | "render_failed" | nullWhy it failed: render_failed (asking again retries), replay_gone

VideoLength

Longest video, seconds: what a request asks for (Q-023). The worker's UPDRAFT_RENDER_MAX_SECONDS (default 30) caps it.

15 | 30

VideoRequest

NameTypeDescription
format required"16:9" | "9:16"Aspect ratio: 16:9 landscape or 9:16 portrait (stories, reels)
resolution"1080p"Only 1080p (1920x1080 / 1080x1920)
default "1080p"
length_s15 | 30Longest video, seconds: 15 (default; about 3.5 minutes to make) or 30 (about 7 minutes). A flight is shown at least 10x faster, so a short flight gives a shorter video
default 15

Wind

NameTypeDescription
direction_deg requiredintegerWhere the wind comes from, degrees
0 ≤ x ≤ 360
speed_ms requirednumberSpeed in m/s, one decimal
0 ≤ x