API Error Handling

Overview

This page is the reference for how the autorouter API reports errors, and lists every error — HTTP status code plus, where one exists, a stable machine-readable code — that each endpoint can return. It complements the API overview, which covers the general HTTP status codes used across the whole API.

The error response

When a request fails, the API returns a non-2xx HTTP status code. In most (but not all — see below) cases the response body is a JSON object of the form:

{
   "error": "human readable error message",
   "code": "STABLE_MACHINE_READABLE_CODE",
   "data": null,
   "retryable": false
}
  • error is a human-readable message intended for display or logging. It is not guaranteed to remain stable between requests or API versions — do not branch your application logic on its exact text.
  • code is a stable, machine-readable identifier you can safely branch on in your application (for example DUPLICATE_FILING or FILING_VALIDATION_FAILED). Where an endpoint below lists a code for a given condition, that code is part of the documented, versioned contract. Some endpoints do not yet supply a code for every error condition; where none is listed, only the HTTP status code is guaranteed and code will be null.
  • data carries optional detail — a list of IFPS errors, what an upstream system answered, the identifiers of a conflicting record. It is null whenever there is nothing further to report, which is the normal case. The contents of data are not part of the contract unless the field is marked below. Unmarked content is diagnostic: its presence, its shape and its field names may change in any release, without notice and without an API version change, and two endpoints returning the same code may put different things there. Log it, show it, use it while debugging — but do not branch application logic on it. A field marked is different: whenever that condition is reported it is present, keeps its name, type and meaning, and will not be removed or repurposed without an API version change. Build on those freely. If you find yourself depending on something unmarked, tell us — we will either mark it or give it a better place.
  • retryable tells you whether repeating the identical request can succeed. It is true only for momentary infrastructure conditions — an engine restarting, a host briefly at capacity, an upstream system not answering — and false whenever the outcome is a property of the request itself, so that repeating it would fail the same way. Prefer this over inferring retryability from the status code: several conditions return 502 or 503 but are permanent. It is present on every JSON error response.

So the contract is the HTTP status, the code, retryable, and the fields of data. error is what you put in front of a person, and the rest of data is what you put in a log — those descriptions say what it holds today, not what it will always hold.
A request body sent with a JSON content type is parsed before the request reaches the endpoint. If it is not valid JSON, or is a JSON scalar rather than an object, the API answers 400 with the code INVALID_JSON and quotes the JSON parser’s diagnosis in error. This is reported instead of, not in addition to, the endpoint’s own complaint about a missing field — a body that does not parse carries no fields at all, whatever it appears to contain. Take particular care to escape control characters inside JSON strings: a literal newline in a value, which is easy to introduce by interpolating a text field into a JSON template, makes the entire body unparseable and must be sent as \n.

Retrying

When retryable is true and the status is 503 or 504, the response also carries a Retry-After header giving the number of seconds to wait. Retry with exponential backoff and give up after a few attempts; if a retryable error persists for more than a minute or two, treat it as an outage and open a support ticket rather than continuing to poll.

When retryable is false, repeating the request unchanged is pointless — the request, the flight plan, or the state of the resource has to change first. In particular a routing or parsing failure caused by the flight plan itself (PARSE_FAILED) is never retryable, whereas a failure to reach the engine that would have parsed it (ROUTER_UNREACHABLE, ROUTER_BUSY) always is.
A small number of endpoints — mostly authentication/authorization failures raised by shared middleware — return only the HTTP status code with an empty body, rather than the JSON shape above. This is noted explicitly wherever it applies below. Treat any endpoint that returns 401 or 403 as potentially body-less unless the endpoint’s table says otherwise.

The /oauth2/token endpoint is a deliberate exception: because it implements the OAuth 2.0 specification, its error responses follow the OAuth2 error shape instead of the shape above — see the Authentication section.

HTTP status codes

Status Meaning
200 Request completed successfully.
400 Invalid request data. Some of the data passed to the call is not valid.
401 Not authorized. You supplied no credentials, expired credentials, or invalid credentials. Retry with correct credentials.
403 Access denied. You do not have permission to access the resource or perform the operation. Repeating the request will not help.
404 Object not found. Most likely an object referenced through the request URL was not found, or could not be accessed due to insufficient privileges.
409 Conflict. The request could not be completed because it conflicts with the current state of the resource (for example, filing a flight plan that has already been filed). Repeating the request unchanged will not help; the underlying state must change first.
422 Unprocessable entity. The request was well-formed but failed validation (for example, a flight plan that does not pass IFPS validation or was rejected by Eurocontrol). The response body contains details on what failed.
429 Too many requests. You have exceeded a rate limit or a plan limit. Wait before retrying.
500 Internal error processing the request. Please report this along with the scenario that triggered it.
502 Bad gateway. An upstream system the request depends on (for example Eurocontrol/IFPS, the AFTN gateway) returned an invalid or unexpected response. Do not assume this is temporary — most 502s here are permanent, and retryable is what tells you which one you have.
503 The server cannot handle the request at this time due to capacity or connectivity issues. Retry later; open a support ticket if this persists.
504 Gateway timeout. An upstream system the request depends on did not respond in time. The request can be retried.

Stable error codes

The table below lists every stable code value currently defined, grouped by category, together with the HTTP status it is normally paired with and whether the condition is worth retrying. The Retryable column matches the retryable field of the response body exactly. These are used most extensively by the Flightplans API; a handful are also used by the Routes and Aircraft APIs. Endpoints that reference one of these codes are noted in their section below.

Code Status Retryable Meaning
Authorization / access
NOT_AUTHORIZED 403 no You are not authorized to perform this operation (for example, no filing privileges, or acting on behalf of a user without delegation).
FLIGHTPLAN_NOT_FOUND 404 no The referenced flight plan does not exist, or you do not have access to it.
ROUTE_NOT_FOUND 404 no The referenced route does not exist, or you do not have access to it.
Bad request / state
INVALID_JSON 400 no The request body was sent with a JSON content type but is not valid JSON, or is a JSON scalar rather than an object. Can be returned by any endpoint that takes a body; error carries the parser’s diagnosis, for example an unescaped control character inside a string.
INVALID_BRIEFING 400 no Required briefing information was not supplied when filing.
INVALID_CUSTOMERREF 400 no The customerref supplied when filing cannot be stored as sent: it is not a string, not valid UTF-8, longer than 64 characters, or contains control characters (a newline, for example). The value is otherwise opaque to us and is stored exactly as sent, which is why an unusable one is refused rather than adjusted. Surrounding whitespace is trimmed, and an empty reference is treated as none at all.
INVALID_TIME 400 no A supplied time (e.g. departure/arrival time) is invalid.
EOBT_OUT_OF_RANGE 400 no The requested EOBT is outside the range allowed for the operation.
PLAN_LIMIT_EXCEEDED 429 no You have reached the maximum number of active flight plans allowed for your account. Waiting does not help — the limit only clears when one of your plans is closed.
WRONG_STATE 409 no The flight plan is not in a state that allows this operation (for example, sending an arrival message for a plan that is not filed).
DUPLICATE_FILING 409 no A matching flight plan or route has already been filed/created. Where the duplicate is one we detected ourselves — an AFTN or LVNL filing matching an active plan of yours — data.fplid is the flight ID of the plan in the way, the same ID the /flightplan/file/{flightid}/… operations take. Where Eurocontrol reports the conflict instead, we look for a live plan of yours matching the flight and include fplid the same way when we find one, but that one is unmarked: the conflict can be a plan filed for the aircraft by somebody else, and Eurocontrol matches a time frame where we match an exact EOBT, so it is not always there. On route creation there is no such id at all.
ALREADY_CANCELLED 409 no The flight plan was already cancelled (including externally, e.g. by ATC).
Validation
VALIDATION_FAILED 422 no The flight plan does not validate under the new parameters (for example, cannot be brought forward to the requested time).
FILING_VALIDATION_FAILED 422 no The flight plan failed final validation prior to filing. The validator’s output is part of error, one CODE: description per line, and can be shown as it stands; data.ifpserrors currently breaks the same errors up the way an IFPS rejection does, unmarked for now. Filing again with "force": true submits the plan anyway, which may put it into the manual queue at Eurocontrol.
NOT_IFPS_APPLICABLE 422 no The flight plan does not contain an IFR segment within the Eurocontrol region and cannot be accepted for IFPS filing.
FILING_REJECTED 422 no Eurocontrol/IFPS rejected the message — the flight plan on filing, or the cancellation, delay, departure or arrival message on the corresponding endpoint. error names every reason IFPS gave, and data.ifpserrors lists them field by field, see IFPS rejections.
Upstream / infrastructure
PARSE_TIMEOUT 504 yes The flight plan parser did not return a result in time.
PARSE_FAILED 422 or 502 no The flight plan itself could not be parsed — 422 for a structurally invalid plan (e.g. a non-existent airway segment), 502 when the parser accepted it but returned no usable result. Submitting the same plan again gives the same outcome. Where the parser produced structured errors, data carries them as error2, the same structure a successful parse returns them in. This code is never used for a failure to reach the parsing engine; those get ROUTER_UNREACHABLE, ROUTER_BUSY or ROUTER_ERROR.
EUROCONTROL_ERROR 502 no Eurocontrol/NM B2B returned an invalid, unexpected, or permanently failing response. The NM reply status and its explanation, where NM gave one, are part of error; data repeats them for your log. Please report these — they generally mean something on our side or NM’s needs fixing.
EUROCONTROL_UNAVAILABLE 503 yes Eurocontrol could not be reached, or reported a momentary condition of its own (SERVICE_UNAVAILABLE, RESOURCE_OVERLOAD, a quota that resets). Nothing was sent — retry shortly, honouring Retry-After.
AFTN_SEND_FAILED 502 no An AFTN message could not be sent (invalid input, or a permanent gateway failure).
AFTN_GATEWAY_UNREACHABLE 503 yes The AFTN gateway is temporarily unreachable; nothing was sent. Retry shortly.
LVNL_SEND_FAILED 502 no A message to LVNL (Dutch ANSP) could not be sent.
LVNL_PILOT_TEL_MISSING 422 no LVNL requires a pilot telephone number for Dutch VFR departures, and none was supplied on the flight plan.
REFILE_FAILED 500 no Refiling a modified flight plan failed after the original was already cancelled/changed.
PERSIST_FAILED 500 no The flight plan was accepted upstream but could not be persisted on our side.
INTERNAL_ERROR 500 no Generic internal server error. Used when no more specific code applies.
ROUTER_UNREACHABLE 503 yes The routing or parsing engine could not be reached at all — no engine available, name resolution failure, connection refused, or the connection dropped mid-exchange. Purely an infrastructure condition: there is nothing wrong with your request and the same request will normally succeed once the engine is back. Retry after the interval in Retry-After.
ROUTER_BUSY 503 yes The routing or parsing engine was reached but is at capacity and refused the work. Retry after the interval in Retry-After.
ROUTER_TIMEOUT 504 yes The routing engine was reached but did not produce a result in time.
ROUTER_ERROR 502 no The routing engine returned an unexpected, malformed or invalid response, or rejected what was sent to it. Retrying produces the same result — please report this.
Aircraft
AIRCRAFT_CONVERSION_FAILED 400 no The submitted aircraft definition failed validation or could not be converted to the internal format. The error message contains the specific reason.

Outside of the codes above, most endpoints currently report errors by HTTP status and message only, without a stable code. This is called out per endpoint below.

IFPS rejections

Every message we send to Eurocontrol on behalf of a flight plan — the filing itself, and the cancellation, delay, departure and arrival messages — can be refused by IFPS. That is a property of the request, not an upstream failure: it comes back as 422 with code FILING_REJECTED. The refusal is explained in error, one IFPS code and description per line, and listed field by field in data.ifpserrors . All five endpoints answer alike:

HTTP 422
{
   "error": "Eurocontrol rejected the flight plan:\n(R)PROF204: RS: TRAFFIC VIA LFPT IS ON FORBIDDEN ROUTE",
   "code": "FILING_REJECTED",
   "data": {
      "ifpserrors": [
         {"code": "(R)PROF204", "description": "RS: TRAFFIC VIA LFPT IS ON FORBIDDEN ROUTE", "anomalycomment": null}
      ]
   },
   "retryable": false
}

ifpserrors is contractual: it is always present on this code, always a list even when IFPS gave a single reason, and each entry always has a code and a description. The list is empty in the rare case where IFPS refused the message without stating a reason, so handle that rather than assuming a first element. anomalycomment is a free-text remark an IFPS operator may have added and is usually null.

The rest of data is not contractual. On the four endpoints that act on an already filed plan it also names the ifplid the message referred to; filing has none, because nothing was filed.

error is the part to show a pilot: it names every reason IFPS gave, one per line, and needs no assembly — reach for ifpserrors when you want to branch on a specific IFPS code rather than print it.

Two things about IFPS text are worth knowing whichever of the two you read: the code arrives as IFPS writes it, including the severity prefix ((R) for a rejection), and a description may itself contain colons — (R)PROF204: RS: TRAFFIC VIA… above is one code and one description, not two.

Retrying the identical request will be rejected the same way. Depending on the IFPS code, the fix is either to correct the flight plan and file again, or to accept that the flight is in a state that no longer allows the operation (a cancellation for a flight that already departed, for instance).

Errors by API

Authentication

See Authentication via OAuth 2.0 for the full authentication flow. POST /oauth2/token follows the OAuth 2.0 error response shape instead of the standard shape:

{
   "error": "invalid_grant",
   "error_description": "human readable description"
}
Endpoint Status Code When it happens
POST /oauth2/token 403 ratelimited Too many failed login attempts; try again later.
403 validated Account needs to be validated.
403 activated Account has not yet been activated by an administrator.
403 privileges Account does not have API access privileges (client-credentials grant).
403 toomanytokens Too many active access tokens outstanding for this account.
403 Incorrect password, or unknown client/account (standard OAuth2 invalid_client/invalid_grant).
400 Malformed token request per the OAuth2 spec (invalid_request, unsupported_grant_type, invalid_scope).
GET /oauth2/authorize 401 Not authenticated. No response body.

Every endpoint above that requires a session or bearer token can additionally fail before reaching the handler with:

  • 401 — no credentials supplied, or credentials invalid/expired.
  • 403 — credentials valid but insufficient privilege for the operation.

These two are raised by shared authentication middleware ahead of every protected endpoint in the API (not just this section) and currently return an empty body — status code only, no JSON, no code.

Aircraft

Endpoint Status Code When it happens
POST /aircraft, PUT /aircraft/{id} 400 Missing/invalid callsign, manufacturer, model, year, ICAO type, or MTOM.
404 (PUT) Aircraft not found, or not owned by you.
400 AIRCRAFT_CONVERSION_FAILED Aircraft definition could not be converted. The error message contains the specific reason (e.g. unknown manufacturer, invalid massunitname, invalid propulsion type).
409 An aircraft with this registration and model already exists.
500 INTERNAL_ERROR A database error occurred while saving the aircraft.
GET /aircraft/{id}, DELETE /aircraft/{id} 404 Aircraft not found, deleted, or not accessible to you.
GET /aircraft 400 Missing pagination parameters.
PUT /aircraft/{id}/default 404 Your account record could not be found (does not validate that {id} is a real aircraft).
GET /aircraft/{id}/performance, POST /aircraft/performance 400 / 404 AIRCRAFT_CONVERSION_FAILED / — Aircraft not found/accessible (404), or the submitted aircraft definition is invalid (400 with AIRCRAFT_CONVERSION_FAILED).
502 / 503 / 504 ROUTER_ERROR / ROUTER_UNREACHABLE / ROUTER_TIMEOUT The router returned an unexpected reply (502, ROUTER_ERROR, permanent), could not be reached (503, ROUTER_UNREACHABLE, retry) or did not complete the performance computation in time (504, ROUTER_TIMEOUT, retry).
PUT /aircraft/{id}/defaultloading 404 / 500 — / INTERNAL_ERROR Aircraft not found/accessible, or its stored definition is corrupt.

Routes

Endpoint Status Code When it happens
POST /router 400 Invalid optimization target, aircraft definition, or missing/malformed departure, destination, or alternate.
404 Referenced aircraft not found or not accessible.
422 PARSE_FAILED Departure, destination, and departure time could not all be derived from the supplied flight plan text. Note that the cause is not always the text itself — a supplied aircraft the parser cannot build a profile from fails the same way, and error2 in data says which part the parser objected to. Not retryable: the request has to change.
502 / 503 / 504 ROUTER_ERROR / ROUTER_UNREACHABLE / ROUTER_BUSY / PARSE_TIMEOUT Deriving those fields needs the parsing engine, which could not be reached or is at capacity (503, retry), did not answer in time (504, retry), or answered with something unusable (502, permanent). Unlike PARSE_FAILED this says nothing about your flight plan.
403 NOT_AUTHORIZED Not authorized to create a route on behalf of the given user.
409 DUPLICATE_FILING A route with the generated id already exists.
PUT /router/hide, PUT /router/{routeid}/hide 404 Route id not found, or not owned by you.
PUT /router/{routeid} 400 Flight plan missing, or the update failed (route id not found or not owned by you — both conditions currently return the same 400).
PUT /router/{routeid}/longpoll, /stop, /close 404 Route id not found, or you may not drive its routing session. Delegates need route_create on the authorizer’s account, which they have for any route they requested on its behalf.

Apart from that 404, PUT /router/{routeid}/longpoll, /stop, and /close respond 200; a routing-engine-side failure is reported as an error field inside the 200 response body rather than as an HTTP error status. Inspect the body on these three endpoints even on success. Alongside error the body carries transient: true means the engine was momentarily unavailable and you should keep polling, since the routing session survives and resumes once the engine is back; false means the failure is permanent and polling should stop.

Flightplans

This is the one part of the API with consistent, stable error codes end to end — see the code table above for what each one means.

Endpoint Status Code When it happens
POST /flightplan/file/{routeid} (file a flight plan) 403 NOT_AUTHORIZED No filing privileges.
429 PLAN_LIMIT_EXCEEDED Maximum number of active flight plans exceeded. The allowance belongs to the account the plan is filed into, so when a delegate files on somebody’s behalf it is that account’s open plans that count, not the delegate’s.
400 INVALID_BRIEFING Briefing information missing.
400 INVALID_CUSTOMERREF The optional customerref in the request body cannot be stored as sent. Raised before the flight plan is submitted anywhere, so a refusal never leaves a plan filed.
404 ROUTE_NOT_FOUND Route could not be accessed.
404 FLIGHTPLAN_NOT_FOUND Refile only (flightid and eobt given in the body): the flight plan being refiled does not exist, or you may not file into the account that owns it. Filing on somebody else’s behalf needs fpl_file or fpl_delaybringforward on their account.
504 PARSE_TIMEOUT Flight plan parser poll limit exceeded.
502 PARSE_FAILED Flight plan parsing failed or returned an unexpected result. Not retryable — the plan has to change.
502 / 503 ROUTER_ERROR / ROUTER_UNREACHABLE / ROUTER_BUSY The parsing engine could not be reached or is at capacity (503, retry), or answered with something unusable (502, permanent). Distinct from PARSE_FAILED: nothing is wrong with the flight plan.
422 NOT_IFPS_APPLICABLE No IFR segment within the Eurocontrol region.
422 FILING_VALIDATION_FAILED Final validation before filing failed. error carries the validation detail; refile with "force": true to submit anyway.
422 LVNL_PILOT_TEL_MISSING Pilot phone number required for Dutch VFR departure.
502 EUROCONTROL_ERROR Eurocontrol/NM B2B returned an invalid or permanently failing response.
503 EUROCONTROL_UNAVAILABLE Eurocontrol is temporarily unavailable; nothing was filed. Retry shortly.
409 DUPLICATE_FILING A matching flight plan — same aircraft, aerodromes and EOBT — is already active. On an AFTN or LVNL filing this is our own check, since neither gateway detects duplicates itself, and data.fplid is the flight ID of the plan in the way — the same ID the /flightplan/file/{flightid}/… operations take, so a client can cancel or delay it directly. On an NM B2B filing the refusal is Eurocontrol’s own; error then quotes the reason Eurocontrol gave, and data names the blocking plan the same way whenever we can identify one of yours as the cause — unmarked, because we cannot always. Cancelling that plan, or moving its EOBT, clears the condition either way. data also carries the plan’s created timestamp and, where it has one, its customerref.
409 DUPLICATE_FILING You already have another active flight plan carrying the same customerref. Unlike the previous condition this check runs for every filing method, including NM B2B, and cannot be skipped with skipduplicatecheck — a customerref is expected to identify one flight for you. data.fplid is the flight ID of the plan already carrying that reference. Cancel or delay that plan, or file this one with a different reference, to clear the condition.
422 FILING_REJECTED IFPS rejected the flight plan. error names the IFPS error codes, see IFPS rejections.
500 PERSIST_FAILED Filing succeeded upstream but could not be persisted.
502 LVNL_SEND_FAILED Sending the LVNL flight plan message failed.
502 AFTN_SEND_FAILED AFTN filing message could not be sent (permanent failure).
503 AFTN_GATEWAY_UNREACHABLE AFTN gateway temporarily unreachable; nothing was sent.
POST /flightplan/file/{flightid}/cancel 400 No reason supplied in the request body.
403 NOT_AUTHORIZED No privilege to cancel flight plans.
404 FLIGHTPLAN_NOT_FOUND Flight plan not found or not accessible.
409 ALREADY_CANCELLED Flight plan was already cancelled externally.
422 FILING_REJECTED IFPS refused the cancellation message, typically because the flight is no longer in a state that can be cancelled. error names the IFPS error codes, see IFPS rejections.
502 EUROCONTROL_ERROR Eurocontrol returned an error status, or a filing status we cannot act on.
503 EUROCONTROL_UNAVAILABLE Eurocontrol could not be reached or is temporarily unavailable; the cancellation was not sent. Retry shortly.
502 LVNL_SEND_FAILED Sending the LVNL cancellation failed.
502 / 503 AFTN_SEND_FAILED / AFTN_GATEWAY_UNREACHABLE AFTN cancellation message could not be sent.
POST /flightplan/file/{flightid}/delay 403 NOT_AUTHORIZED No privilege to delay flight plans.
404 FLIGHTPLAN_NOT_FOUND Flight plan not found or not accessible.
400 EOBT_OUT_OF_RANGE New EOBT outside the valid range: it must always be in the future, for flight plans filed through Eurocontrol (NM B2B) no more than 5 days ahead, and for flight plans filed through AFTN or LVNL it must fall on the same UTC day as the current EOBT (the DLA message carries a time but no date).
504 PARSE_TIMEOUT Re-parse poll limit exceeded.
502 PARSE_FAILED Re-parsing the flight plan failed. Not retryable — the plan has to change.
502 / 503 ROUTER_ERROR / ROUTER_UNREACHABLE / ROUTER_BUSY The parsing engine could not be reached or is at capacity (503, retry), or answered with something unusable (502, permanent). Distinct from PARSE_FAILED: nothing is wrong with the flight plan.
409 ALREADY_CANCELLED Flight plan was already cancelled externally.
422 FILING_REJECTED IFPS refused the delay message. error names the IFPS error codes, see IFPS rejections.
502 EUROCONTROL_ERROR Eurocontrol returned an error status, or a filing status we cannot act on.
503 EUROCONTROL_UNAVAILABLE Eurocontrol could not be reached or is temporarily unavailable; the delay was not sent. Retry shortly.
502 / 503 LVNL_SEND_FAILED / AFTN_SEND_FAILED / AFTN_GATEWAY_UNREACHABLE Sending the delay message failed.
POST /flightplan/file/{flightid}/bringforward 403 NOT_AUTHORIZED No privilege to modify flight plans.
400 EOBT_OUT_OF_RANGE New EOBT outside the valid range.
404 FLIGHTPLAN_NOT_FOUND Flight plan not found or not accessible.
504 PARSE_TIMEOUT Re-parse poll limit exceeded.
502 PARSE_FAILED Re-parsing the flight plan failed. Not retryable — the plan has to change.
502 / 503 ROUTER_ERROR / ROUTER_UNREACHABLE / ROUTER_BUSY The parsing engine could not be reached or is at capacity (503, retry), or answered with something unusable (502, permanent). Distinct from PARSE_FAILED: nothing is wrong with the flight plan.
422 VALIDATION_FAILED Flight plan does not validate at the earlier time.
409 ALREADY_CANCELLED Flight plan was already cancelled externally. Nothing was changed, and the plan is now marked cancelled here too.
422 FILING_REJECTED IFPS refused the cancellation message that starts the refile. Nothing was changed. error names the IFPS error codes, see IFPS rejections.
502 EUROCONTROL_ERROR Eurocontrol returned an error status, or a filing status we cannot act on, while cancelling. Nothing was changed.
503 EUROCONTROL_UNAVAILABLE Eurocontrol could not be reached or is temporarily unavailable; the cancellation was not sent and nothing was changed. Retry shortly.
502 / 503 LVNL_SEND_FAILED / AFTN_SEND_FAILED / AFTN_GATEWAY_UNREACHABLE Sending the cancellation message that starts the refile failed. Nothing was changed.
500 REFILE_FAILED The original plan was cancelled but the modified plan could not be filed. The original is gone — create a new flight plan. Every failure before this point leaves the original plan untouched and keeps its own status and code.
POST /flightplan/file/{flightid}/departure, POST /flightplan/file/{flightid}/arrival 404 FLIGHTPLAN_NOT_FOUND Flight plan not found or not accessible.
409 WRONG_STATE Flight plan is not in filed state (departure) / is closed (arrival).
400 INVALID_TIME Invalid departure/arrival time.
422 FILING_REJECTED IFPS refused the departure or arrival message, for example a DEP for a flight that already departed. error names the IFPS error codes, see IFPS rejections.
502 EUROCONTROL_ERROR Eurocontrol returned an error status, or a filing status we cannot act on.
503 EUROCONTROL_UNAVAILABLE Eurocontrol could not be reached or is temporarily unavailable; the message was not sent. Retry shortly.
PUT /flightplan/fpal/verify 500 Verification could not be run.
GET /flightplan/fpal/{id} 400 Invalid document id.
404 Document not found.

GET /flightplan (parse), GET /flightplan/validate, GET /flightplan/file, and GET /flightplan/file/{flightid} do not raise HTTP-level errors for business-logic failures. GET /flightplan and GET /flightplan/convert do report infrastructure failures, though: 503 with ROUTER_UNREACHABLE when no parsing engine can be reached, 503 with ROUTER_BUSY when the engine is at capacity, 504 with PARSE_TIMEOUT when it does not answer in time, and 502 with ROUTER_ERROR when it answers with something unusable. Only the last of these is permanent.

Endpoint Status Code When it happens
GET /navdata/airport 400 No search parameters supplied.

Weather

Endpoint Status Code When it happens
GET /met/gramet 400 Invalid format, or neither a flight plan nor a waypoint list supplied.
503 ROUTER_UNREACHABLE / ROUTER_BUSY The chart engine could not be reached, is at capacity, or the computed chart could not be fetched back off the host. Retry after the interval in Retry-After.
504 ROUTER_TIMEOUT Chart generation did not complete in time. Retryable.
502 ROUTER_ERROR The engine returned an unexpected reply, or no chart at all, for this input. Not retryable.

GET /met/metartaf/{icao} responds 200 with metar/taf set to null for an unknown or data-less station rather than a 404 — there is currently no way to distinguish “no data yet” from “invalid station” via the status code. GET /met/modeldate likewise always responds 200, with null if the timestamp could not be determined.

Briefing

Endpoint Status Code When it happens
POST /flightplan/file/{flightid}/briefing, POST /flightplan/{routeid}/briefing (generate a briefing pack) 400 method or items missing, or method is not one of email/telegram/download.
403 A briefing pack is already being generated for you.
404 Flight plan/route not found.
500 The briefing pack could not be queued or generated.
GET .../briefing (fetch/generate, blocking) 404 / 500 Flight plan/route not found, or generation timed out/failed.
GET .../briefing/{token} (poll/download) 404 / 500 Not ready yet (404), or generation failed (500). No response body on either.

Documents

Endpoint Status Code When it happens
GET /pams/id/{docid} 404 Document id is not numeric or not found, or the file is missing on disk.
GET /pams/airport/{icao}/package 404 Invalid ICAO, unknown airport, or no plates available to build a package.
POST /pams/airport 400 Request body is not an array, or is not JSON (see note below).
GET /pams[/{authority}[/{language}[/{aiptype}[/{section}]]]] 400 A path segment is supplied without the segment(s) before it (e.g. language without authority).

GET /pams/airport/{icao}/POST /pams/airport respond 200 with an empty list for a malformed airport code rather than an error. A non-JSON request body on POST /pams/airport returns a plain 400 with no response body, rather than the standard JSON error shape.

NOTAMs

Endpoint Status Code When it happens
GET /notam 400 An itema entry is not a valid 4-character ICAO location indicator pattern.

Messages

Endpoint Status Code When it happens
GET /message 400 Invalid timeout (must be 0–300) or limit (must be 1–100).
POST /message/acknowledge, POST /message/{id}/acknowledge 400 An id in the request is not a valid non-negative integer.

Acknowledging an id that doesn’t exist, or that belongs to another user, is currently a silent no-op (200), not an error. GET /message/count has no error conditions.

Every request — regardless of API — is first checked against the requested API version; a missing or unsupported version returns a bodiless 400 before your request reaches any endpoint. See Versioning.