Skip to main content
reference 3 min read

API overview

Concepts, base URL, conventions, and the three ways to authenticate against the we-fly API.

What the API exposes

CapabilityScope required
List a pilot's flightsflights:read
Read a single flight (scoring, metadata, basic analysis)flights:read
Upload an IGC flight on the pilot's behalfflights:write
Delete a flightflights:delete
Read the pilot's profile (name, club, CIVL id)profile:read
Read the pilot's email addressprofile:email
Update the pilot's profile (planned, not yet shipped)profile:write
Read public community data (sites, leaderboards) (planned)community:read

The exhaustive scope list and what each grants is in the Scopes reference.

Three ways to authenticate

we-fly supports three credential flows, picked by how your integration runs:

FlowWhen to useDoc
Client credentials (OAuth 2.0)A backend you control accesses your own account programmatically (sync from another tracker, automated import, etc.)Server-to-server
Authorization Code + PKCE (OAuth 2.0)A third-party app or site wants to act on behalf of any we-fly user who grants consentUser authorization
Device code (RFC 8628)A CLI tool, vario, or embedded device with no usable browserDevice authorization grant
API keysPersonal scripts, weekend hacksPersonal API keys

All three end up presenting a Bearer token to the API. The difference is how that token was obtained and which user it represents.

Base URL

https://we-fly.cloud

Use https:// only. The API does not redirect from http://; bad schemes get a connection error.

Versioning

Path prefixStatus
/api/v1/...Stable. Breaking changes require a new prefix (/api/v2/...) and a 6-month deprecation window with a Sunset header.
/api/oauth/...Stable. RFC 6749 / 7009 / 7662. The shapes of these endpoints are pinned by the RFCs.
/.well-known/oauth-authorization-serverStable. RFC 8414.

Anything not under /api/v1/... or /api/oauth/... is not part of the public contract — it's internal to the dashboard and may change without notice.

Conventions

Request format

  • All request bodies are JSON unless explicitly noted (the OAuth token endpoint and the upload endpoint accept additional content types per their respective specs).
  • All headers and parameters are case-insensitive in name but case-sensitive in value (so Authorization: Bearer … works, but Bearer wf_at_FOOBearer wf_at_foo).

Response format

  • Success: 2xx with a JSON body shaped as { "data": …, … }.
  • Failure: 4xx/5xx with { "error": "code", "error_description": "human prose" }.
  • Lists are wrapped in { "data": [...], "pagination": { … } }.

Time

  • All timestamps are ISO 8601 in UTC with a trailing Z ("2026-05-27T14:30:00.000Z").
  • The flight_date field is calendar-date only ("YYYY-MM-DD"), parsed from the IGC HFDTE header.

IDs

  • Flight IDs and user IDs are MongoDB hex ObjectIds (24 chars, [a-f0-9]).
  • Client IDs are opaque strings prefixed wf_app_.
  • Tokens are opaque strings prefixed wf_at_ (access) / wf_rt_ (refresh) / wf_key_ (API key) / wf_code_ (authorization code) / wf_dc_ (device code) / wf_secret_ (client secret) / wf_whsec_ (webhook signing secret).
  • The prefix is stable — your secret scanner can pattern-match on it.

Operational requirements

  • Always send a User-Agent that identifies your integration. We use it in support requests and to scope rate-limit adjustments. Example: User-Agent: XContestSync/1.2 (+https://xcontest.org).
  • Honour Retry-After on 429 responses. Hammering us when limited will get your app suspended.
  • Refresh tokens are single-use. See the refresh-token rotation rules — if you replay an old refresh token, your entire token chain is revoked and the user has to re-authorise.
  • Never store secrets in client-side code (browser bundle, mobile app binary). Public clients must use PKCE; confidential clients must keep clientSecret server-side only.

Sandbox / staging

There is currently no separate sandbox environment. We recommend you register a pending application against production and test with your own account first — pending applications are restricted to read-only scopes for their owner, so the blast radius is contained. Promote to approved (admin action) once you're ready to onboard other users.