Layer400 developers · Cloud API v1
Start here · live aircraft data
Your first successful request.
This guide uses adsb.live throughout: request current aircraft positions, then read a matching ADS-B response.
1. Get approved and create a key.
Open My Account → Business API, verify your email, and submit your company and intended use. Request adsb.live for this example.
Wait for explicit administrator approval, then create a named key. Copy the secret when it is shown; it cannot be retrieved later. Your account shows the approved scopes, allowance and expiry.
2. Set the key on your server.
For production, use your server’s secret manager. For a local server-side trial, these prompts set LAYER400_API_KEY for the current terminal session. Do not put keys in browser code, URLs or a public repository.
Bash / zsh setup
# Bash / zsh: enter the key without putting it in shell history.
read -rs LAYER400_API_KEY
export LAYER400_API_KEY
# Paste at the hidden prompt, then press Enter.PowerShell 7 setup
# PowerShell 7: enter the key without displaying or saving it.
$secret = Read-Host 'Layer400 API key' -AsSecureString
$env:LAYER400_API_KEY = [System.Net.NetworkCredential]::new('', $secret).Password
$secret.Dispose()
# Run the Python or Node example below in this session.
# Close the session when finished.The data API uses Authorization: Bearer <key>. Website login cookies and receiver credentials are not substitutes.
3. Send a live ADS-B request.
Choose one language. Python uses only its standard library. For Node, save the code as request.mjs and run node request.mjs. The curl example uses Bash/zsh continuation syntax.
curl
# Store the key in LAYER400_API_KEY using your secret manager first.
curl --fail-with-body --get 'https://layer400.com/business/api/v1/live/adsb' \
--header "Authorization: Bearer $LAYER400_API_KEY" \
--user-agent 'YourOrganisation-YourIntegration/1.0' \
--data-urlencode 'bbox=-2.3,50.7,-2.0,50.9' \
--data-urlencode 'limit=250'Python
# Python 3, standard library. Run on your server.
import json, os, urllib.parse, urllib.request
key = os.environ["LAYER400_API_KEY"]
params = {"bbox": "-2.3,50.7,-2.0,50.9", "limit": 250}
url = "https://layer400.com/business/api/v1/live/adsb?" + urllib.parse.urlencode(params)
request = urllib.request.Request(url, headers={
"Authorization": "Bearer " + key,
"User-Agent": "YourOrganisation-YourIntegration/1.0",
})
with urllib.request.urlopen(request, timeout=15) as response:
result = json.load(response)
if result["next_cursor"] is not None:
print("More live pages exist; repeat with the returned cursor")
print(json.dumps(result, indent=2))Node.js
// Node.js 20+. Save as request.mjs; run: node request.mjs
const key = process.env.LAYER400_API_KEY;
if (!key) throw new Error('Set LAYER400_API_KEY on your server');
const url = new URL('https://layer400.com/business/api/v1/live/adsb');
url.searchParams.set('bbox', '-2.3,50.7,-2.0,50.9');
url.searchParams.set('limit', '250');
const response = await fetch(url, {
headers: { Authorization: 'Bearer ' + key,
'User-Agent': 'YourOrganisation-YourIntegration/1.0' },
signal: AbortSignal.timeout(15000),
});
if (!response.ok) {
throw new Error('HTTP ' + response.status + '; request ' +
(response.headers.get('x-request-id') || 'unavailable') +
'; retry-after ' + (response.headers.get('retry-after') || 'not supplied'));
}
const result = await response.json();
if (result.next_cursor !== null) console.log('More pages exist:', result.next_cursor);
console.log(JSON.stringify(result, null, 2));The example covers west=-2.3, south=50.7, east=-2.0, north=50.9. Replace these bounds with your area. It needs actual receiver coverage to return positions.
4. Read the response.
This is a fictional ADS-B example. Your real response may contain data: []; HTTP 200 with an empty array is still a successful request.
{
"version": "1",
"request_id": "11111111-2222-4333-8444-555555555555",
"generated_at": "2026-10-02T12:00:00Z",
"layer": "adsb",
"mode": "live",
"data": [
{
"public_track_id": "L4-A-0123456789ABCDEF",
"observed_at": "2026-10-02T11:59:58Z",
"longitude": -2.15,
"latitude": 50.8,
"altitude_m": 2400,
"height_agl_m": null,
"speed_mps": 105,
"heading_deg": 90,
"confidence": "single",
"confidence_score": null,
"receiver_count": 1,
"track_kind": "adsb_aircraft",
"simulated": true,
"test_broadcast": false,
"emergency_state": "unknown",
"stale_after": "2026-10-02T12:00:28Z"
}
],
"next_cursor": null,
"truncated": false
}datacontains current received aircraft positions.observed_atis the position’s report time;generated_atis the response time.- A non-null
next_cursormeans another live page is available. - Preserve simulation and TEST flags, and do not convert unknown values to zero.
If you receive 401, check the key. For 403, check adsb.live approval and the grant’s active status. For 429, wait for the allowance to reset. Full troubleshooting reference →
Documentation reviewed 2 October 2026. Coverage and access conditions.