{"id":1067,"date":"2026-07-23T11:42:42","date_gmt":"2026-07-23T11:42:42","guid":{"rendered":"https:\/\/www.autorouter.aero\/wiki\/?page_id=1067"},"modified":"2026-08-05T18:03:27","modified_gmt":"2026-08-05T18:03:27","slug":"api-error-handling","status":"publish","type":"page","link":"https:\/\/www.autorouter.aero\/wiki\/api\/api-error-handling\/","title":{"rendered":"API Error Handling"},"content":{"rendered":"<h1 id=\"overview\">Overview<\/h1>\n<p>This page is the reference for how the autorouter API reports errors, and lists every error \u2014 HTTP status code plus, where one exists, a stable machine-readable <code>code<\/code> \u2014 that each endpoint can return. It complements the <a href=\"\/wiki\/api\/\">API overview<\/a>, which covers the general HTTP status codes used across the whole API.<\/p>\n<h2>The error response<\/h2>\n<p>When a request fails, the API returns a non-2xx HTTP status code. In most (but not all \u2014 see below) cases the response body is a JSON object of the form:<\/p>\n<pre>{\n   \"error\": \"human readable error message\",\n   \"code\": \"STABLE_MACHINE_READABLE_CODE\",\n   \"data\": null,\n   \"retryable\": false\n}<\/pre>\n<ul>\n<li><strong>error<\/strong> is a human-readable message intended for display or logging. It is <strong>not<\/strong> guaranteed to remain stable between requests or API versions \u2014 do not branch your application logic on its exact text.<\/li>\n<li><strong>code<\/strong> is a stable, machine-readable identifier you can safely branch on in your application (for example <code>DUPLICATE_FILING<\/code> or <code>FILING_VALIDATION_FAILED<\/code>). Where an endpoint below lists a <code>code<\/code> for a given condition, that code is part of the documented, versioned contract. Some endpoints do not yet supply a <code>code<\/code> for every error condition; where none is listed, only the HTTP status code is guaranteed and <code>code<\/code> will be <code>null<\/code>.<\/li>\n<li><strong>data<\/strong> carries optional detail \u2014 a list of IFPS errors, what an upstream system answered, the identifiers of a conflicting record. It is <code>null<\/code> whenever there is nothing further to report, which is the normal case. <strong>The contents of <code>data<\/code> are not part of the contract unless the field is marked <strong>\u2020<\/strong> below.<\/strong> 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>code<\/code> may put different things there. Log it, show it, use it while debugging \u2014 but do not branch application logic on it. A field marked <strong>\u2020<\/strong> 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 \u2014 we will either mark it or give it a better place.<\/li>\n<li><strong>retryable<\/strong> tells you whether repeating the identical request can succeed. It is <code>true<\/code> only for momentary infrastructure conditions \u2014 an engine restarting, a host briefly at capacity, an upstream system not answering \u2014 and <code>false<\/code> 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.<\/li>\n<\/ul>\n<p>So the contract is the HTTP status, the <code>code<\/code>, <code>retryable<\/code>, and the <strong>\u2020<\/strong> fields of <code>data<\/code>. <code>error<\/code> is what you put in front of a person, and the rest of <code>data<\/code> is what you put in a log \u2014 those descriptions say what it holds today, not what it will always hold.<br \/>\nA 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 <strong>400<\/strong> with the code <code>INVALID_JSON<\/code> and quotes the JSON parser&#8217;s diagnosis in <code>error<\/code>. This is reported instead of, not in addition to, the endpoint&#8217;s own complaint about a missing field \u2014 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 <code>\\n<\/code>.<\/p>\n<h2>Retrying<\/h2>\n<p>When <code>retryable<\/code> is <code>true<\/code> and the status is 503 or 504, the response also carries a <code>Retry-After<\/code> 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.<\/p>\n<p>When <code>retryable<\/code> is <code>false<\/code>, repeating the request unchanged is pointless \u2014 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 (<code>PARSE_FAILED<\/code>) is never retryable, whereas a failure to reach the engine that would have parsed it (<code>ROUTER_UNREACHABLE<\/code>, <code>ROUTER_BUSY<\/code>) always is.<br \/>\nA small number of endpoints \u2014 mostly authentication\/authorization failures raised by shared middleware \u2014 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&#8217;s table says otherwise.<\/p>\n<p>The <code>\/oauth2\/token<\/code> endpoint is a deliberate exception: because it implements the <a href=\"https:\/\/datatracker.ietf.org\/doc\/html\/rfc6749\">OAuth 2.0<\/a> specification, its error responses follow the OAuth2 error shape instead of the shape above \u2014 see the <a href=\"#authentication\">Authentication<\/a> section.<\/p>\n<h2>HTTP status codes<\/h2>\n<table>\n<thead>\n<tr>\n<th>Status<\/th>\n<th>Meaning<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><strong>200<\/strong><\/td>\n<td>Request completed successfully.<\/td>\n<\/tr>\n<tr>\n<td><strong>400<\/strong><\/td>\n<td>Invalid request data. Some of the data passed to the call is not valid.<\/td>\n<\/tr>\n<tr>\n<td><strong>401<\/strong><\/td>\n<td>Not authorized. You supplied no credentials, expired credentials, or invalid credentials. Retry with correct credentials.<\/td>\n<\/tr>\n<tr>\n<td><strong>403<\/strong><\/td>\n<td>Access denied. You do not have permission to access the resource or perform the operation. Repeating the request will not help.<\/td>\n<\/tr>\n<tr>\n<td><strong>404<\/strong><\/td>\n<td>Object not found. Most likely an object referenced through the request URL was not found, or could not be accessed due to insufficient privileges.<\/td>\n<\/tr>\n<tr>\n<td><strong>409<\/strong><\/td>\n<td>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.<\/td>\n<\/tr>\n<tr>\n<td><strong>422<\/strong><\/td>\n<td>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.<\/td>\n<\/tr>\n<tr>\n<td><strong>429<\/strong><\/td>\n<td>Too many requests. You have exceeded a rate limit or a plan limit. Wait before retrying.<\/td>\n<\/tr>\n<tr>\n<td><strong>500<\/strong><\/td>\n<td>Internal error processing the request. Please report this along with the scenario that triggered it.<\/td>\n<\/tr>\n<tr>\n<td><strong>502<\/strong><\/td>\n<td>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 \u2014 most 502s here are permanent, and <code>retryable<\/code> is what tells you which one you have.<\/td>\n<\/tr>\n<tr>\n<td><strong>503<\/strong><\/td>\n<td>The server cannot handle the request at this time due to capacity or connectivity issues. Retry later; open a support ticket if this persists.<\/td>\n<\/tr>\n<tr>\n<td><strong>504<\/strong><\/td>\n<td>Gateway timeout. An upstream system the request depends on did not respond in time. The request can be retried.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Stable error codes<\/h2>\n<p>The table below lists every stable <code>code<\/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 <em>Retryable<\/em> column matches the <code>retryable<\/code> field of the response body exactly. These are used most extensively by the <a href=\"#flightplans\">Flightplans<\/a> API; a handful are also used by the <a href=\"#routes\">Routes<\/a> and <a href=\"#aircraft\">Aircraft<\/a> APIs. Endpoints that reference one of these codes are noted in their section below.<\/p>\n<table>\n<thead>\n<tr>\n<th>Code<\/th>\n<th>Status<\/th>\n<th>Retryable<\/th>\n<th>Meaning<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td colspan=\"4\"><em>Authorization \/ access<\/em><\/td>\n<\/tr>\n<tr>\n<td><code>NOT_AUTHORIZED<\/code><\/td>\n<td>403<\/td>\n<td>no<\/td>\n<td>You are not authorized to perform this operation (for example, no filing privileges, or acting on behalf of a user without delegation).<\/td>\n<\/tr>\n<tr>\n<td><code>FLIGHTPLAN_NOT_FOUND<\/code><\/td>\n<td>404<\/td>\n<td>no<\/td>\n<td>The referenced flight plan does not exist, or you do not have access to it.<\/td>\n<\/tr>\n<tr>\n<td><code>ROUTE_NOT_FOUND<\/code><\/td>\n<td>404<\/td>\n<td>no<\/td>\n<td>The referenced route does not exist, or you do not have access to it.<\/td>\n<\/tr>\n<tr>\n<td colspan=\"4\"><em>Bad request \/ state<\/em><\/td>\n<\/tr>\n<tr>\n<td><code>INVALID_JSON<\/code><\/td>\n<td>400<\/td>\n<td>no<\/td>\n<td>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; <code>error<\/code> carries the parser&#8217;s diagnosis, for example an unescaped control character inside a string.<\/td>\n<\/tr>\n<tr>\n<td><code>INVALID_BRIEFING<\/code><\/td>\n<td>400<\/td>\n<td>no<\/td>\n<td>Required briefing information was not supplied when filing.<\/td>\n<\/tr>\n<tr>\n<td><code>INVALID_CUSTOMERREF<\/code><\/td>\n<td>400<\/td>\n<td>no<\/td>\n<td>The <code>customerref<\/code> 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.<\/td>\n<\/tr>\n<tr>\n<td><code>INVALID_TIME<\/code><\/td>\n<td>400<\/td>\n<td>no<\/td>\n<td>A supplied time (e.g. departure\/arrival time) is invalid.<\/td>\n<\/tr>\n<tr>\n<td><code>EOBT_OUT_OF_RANGE<\/code><\/td>\n<td>400<\/td>\n<td>no<\/td>\n<td>The requested EOBT is outside the range allowed for the operation.<\/td>\n<\/tr>\n<tr>\n<td><code>PLAN_LIMIT_EXCEEDED<\/code><\/td>\n<td>429<\/td>\n<td>no<\/td>\n<td>You have reached the maximum number of active flight plans allowed for your account. Waiting does not help \u2014 the limit only clears when one of your plans is closed.<\/td>\n<\/tr>\n<tr>\n<td><code>WRONG_STATE<\/code><\/td>\n<td>409<\/td>\n<td>no<\/td>\n<td>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).<\/td>\n<\/tr>\n<tr>\n<td><code>DUPLICATE_FILING<\/code><\/td>\n<td>409<\/td>\n<td>no<\/td>\n<td>A matching flight plan or route has already been filed\/created. Where the duplicate is one we detected ourselves \u2014 an AFTN or LVNL filing matching an active plan of yours \u2014 <code>data.fplid<\/code> <strong>\u2020<\/strong> is the flight ID of the plan in the way, the same ID the <code>\/flightplan\/file\/{flightid}\/\u2026<\/code> operations take. Where Eurocontrol reports the conflict instead, we look for a live plan of yours matching the flight and include <code>fplid<\/code> 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.<\/td>\n<\/tr>\n<tr>\n<td><code>ALREADY_CANCELLED<\/code><\/td>\n<td>409<\/td>\n<td>no<\/td>\n<td>The flight plan was already cancelled (including externally, e.g. by ATC).<\/td>\n<\/tr>\n<tr>\n<td colspan=\"4\"><em>Validation<\/em><\/td>\n<\/tr>\n<tr>\n<td><code>VALIDATION_FAILED<\/code><\/td>\n<td>422<\/td>\n<td>no<\/td>\n<td>The flight plan does not validate under the new parameters (for example, cannot be brought forward to the requested time).<\/td>\n<\/tr>\n<tr>\n<td><code>FILING_VALIDATION_FAILED<\/code><\/td>\n<td>422<\/td>\n<td>no<\/td>\n<td>The flight plan failed final validation prior to filing. The validator&#8217;s output is part of <code>error<\/code>, one <code>CODE: description<\/code> per line, and can be shown as it stands; <code>data.ifpserrors<\/code> currently breaks the same errors up the way an <a href=\"#ifps-rejections\">IFPS rejection<\/a> does, unmarked for now. Filing again with <code>\"force\": true<\/code> submits the plan anyway, which may put it into the manual queue at Eurocontrol.<\/td>\n<\/tr>\n<tr>\n<td><code>NOT_IFPS_APPLICABLE<\/code><\/td>\n<td>422<\/td>\n<td>no<\/td>\n<td>The flight plan does not contain an IFR segment within the Eurocontrol region and cannot be accepted for IFPS filing.<\/td>\n<\/tr>\n<tr>\n<td><code>FILING_REJECTED<\/code><\/td>\n<td>422<\/td>\n<td>no<\/td>\n<td>Eurocontrol\/IFPS rejected the message \u2014 the flight plan on filing, or the cancellation, delay, departure or arrival message on the corresponding endpoint. <code>error<\/code> names every reason IFPS gave, and <code>data.ifpserrors<\/code> <strong>\u2020<\/strong> lists them field by field, see <a href=\"#ifps-rejections\">IFPS rejections<\/a>.<\/td>\n<\/tr>\n<tr>\n<td colspan=\"4\"><em>Upstream \/ infrastructure<\/em><\/td>\n<\/tr>\n<tr>\n<td><code>PARSE_TIMEOUT<\/code><\/td>\n<td>504<\/td>\n<td><strong>yes<\/strong><\/td>\n<td>The flight plan parser did not return a result in time.<\/td>\n<\/tr>\n<tr>\n<td><code>PARSE_FAILED<\/code><\/td>\n<td>422 or 502<\/td>\n<td>no<\/td>\n<td>The flight plan itself could not be parsed \u2014 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, <code>data<\/code> carries them as <code>error2<\/code>, the same structure a successful parse returns them in. This code is <strong>never<\/strong> used for a failure to reach the parsing engine; those get <code>ROUTER_UNREACHABLE<\/code>, <code>ROUTER_BUSY<\/code> or <code>ROUTER_ERROR<\/code>.<\/td>\n<\/tr>\n<tr>\n<td><code>EUROCONTROL_ERROR<\/code><\/td>\n<td>502<\/td>\n<td>no<\/td>\n<td>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 <code>error<\/code>; <code>data<\/code> repeats them for your log. Please report these \u2014 they generally mean something on our side or NM&#8217;s needs fixing.<\/td>\n<\/tr>\n<tr>\n<td><code>EUROCONTROL_UNAVAILABLE<\/code><\/td>\n<td>503<\/td>\n<td><strong>yes<\/strong><\/td>\n<td>Eurocontrol could not be reached, or reported a momentary condition of its own (<code>SERVICE_UNAVAILABLE<\/code>, <code>RESOURCE_OVERLOAD<\/code>, a quota that resets). Nothing was sent \u2014 retry shortly, honouring <code>Retry-After<\/code>.<\/td>\n<\/tr>\n<tr>\n<td><code>AFTN_SEND_FAILED<\/code><\/td>\n<td>502<\/td>\n<td>no<\/td>\n<td>An AFTN message could not be sent (invalid input, or a permanent gateway failure).<\/td>\n<\/tr>\n<tr>\n<td><code>AFTN_GATEWAY_UNREACHABLE<\/code><\/td>\n<td>503<\/td>\n<td><strong>yes<\/strong><\/td>\n<td>The AFTN gateway is temporarily unreachable; nothing was sent. Retry shortly.<\/td>\n<\/tr>\n<tr>\n<td><code>LVNL_SEND_FAILED<\/code><\/td>\n<td>502<\/td>\n<td>no<\/td>\n<td>A message to LVNL (Dutch ANSP) could not be sent.<\/td>\n<\/tr>\n<tr>\n<td><code>LVNL_PILOT_TEL_MISSING<\/code><\/td>\n<td>422<\/td>\n<td>no<\/td>\n<td>LVNL requires a pilot telephone number for Dutch VFR departures, and none was supplied on the flight plan.<\/td>\n<\/tr>\n<tr>\n<td><code>REFILE_FAILED<\/code><\/td>\n<td>500<\/td>\n<td>no<\/td>\n<td>Refiling a modified flight plan failed after the original was already cancelled\/changed.<\/td>\n<\/tr>\n<tr>\n<td><code>PERSIST_FAILED<\/code><\/td>\n<td>500<\/td>\n<td>no<\/td>\n<td>The flight plan was accepted upstream but could not be persisted on our side.<\/td>\n<\/tr>\n<tr>\n<td><code>INTERNAL_ERROR<\/code><\/td>\n<td>500<\/td>\n<td>no<\/td>\n<td>Generic internal server error. Used when no more specific code applies.<\/td>\n<\/tr>\n<tr>\n<td><code>ROUTER_UNREACHABLE<\/code><\/td>\n<td>503<\/td>\n<td><strong>yes<\/strong><\/td>\n<td>The routing or parsing engine could not be reached at all \u2014 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 <code>Retry-After<\/code>.<\/td>\n<\/tr>\n<tr>\n<td><code>ROUTER_BUSY<\/code><\/td>\n<td>503<\/td>\n<td><strong>yes<\/strong><\/td>\n<td>The routing or parsing engine was reached but is at capacity and refused the work. Retry after the interval in <code>Retry-After<\/code>.<\/td>\n<\/tr>\n<tr>\n<td><code>ROUTER_TIMEOUT<\/code><\/td>\n<td>504<\/td>\n<td><strong>yes<\/strong><\/td>\n<td>The routing engine was reached but did not produce a result in time.<\/td>\n<\/tr>\n<tr>\n<td><code>ROUTER_ERROR<\/code><\/td>\n<td>502<\/td>\n<td>no<\/td>\n<td>The routing engine returned an unexpected, malformed or invalid response, or rejected what was sent to it. Retrying produces the same result \u2014 please report this.<\/td>\n<\/tr>\n<tr>\n<td colspan=\"4\"><em>Aircraft<\/em><\/td>\n<\/tr>\n<tr>\n<td><code>AIRCRAFT_CONVERSION_FAILED<\/code><\/td>\n<td>400<\/td>\n<td>no<\/td>\n<td>The submitted aircraft definition failed validation or could not be converted to the internal format. The error message contains the specific reason.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Outside of the codes above, most endpoints currently report errors by HTTP status and message only, without a stable <code>code<\/code>. This is called out per endpoint below.<\/p>\n<h2 id=\"ifps-rejections\">IFPS rejections<\/h2>\n<p>Every message we send to Eurocontrol on behalf of a flight plan \u2014 the filing itself, and the cancellation, delay, departure and arrival messages \u2014 can be refused by IFPS. That is a property of the request, not an upstream failure: it comes back as <strong>422<\/strong> with code <code>FILING_REJECTED<\/code>. The refusal is explained in <code>error<\/code>, one IFPS code and description per line, and listed field by field in <code>data.ifpserrors<\/code> <strong>\u2020<\/strong>. All five endpoints answer alike:<\/p>\n<pre>HTTP 422\n{\n   \"error\": \"Eurocontrol rejected the flight plan:\\n(R)PROF204: RS: TRAFFIC VIA LFPT IS ON FORBIDDEN ROUTE\",\n   \"code\": \"FILING_REJECTED\",\n   \"data\": {\n      \"ifpserrors\": [\n         {\"code\": \"(R)PROF204\", \"description\": \"RS: TRAFFIC VIA LFPT IS ON FORBIDDEN ROUTE\", \"anomalycomment\": null}\n      ]\n   },\n   \"retryable\": false\n}<\/pre>\n<p><code>ifpserrors<\/code> <strong>\u2020<\/strong> 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>code<\/code> and a <code>description<\/code>. 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. <code>anomalycomment<\/code> is a free-text remark an IFPS operator may have added and is usually <code>null<\/code>.<\/p>\n<p>The rest of <code>data<\/code> is not contractual. On the four endpoints that act on an already filed plan it also names the <code>ifplid<\/code> the message referred to; filing has none, because nothing was filed.<\/p>\n<p><code>error<\/code> is the part to show a pilot: it names every reason IFPS gave, one per line, and needs no assembly \u2014 reach for <code>ifpserrors<\/code> when you want to branch on a specific IFPS code rather than print it.<\/p>\n<p>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 (<code>(R)<\/code> for a rejection), and a description may itself contain colons \u2014 <code>(R)PROF204: RS: TRAFFIC VIA\u2026<\/code> above is one code and one description, not two.<\/p>\n<p>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).<\/p>\n<h1 id=\"errors-by-api\">Errors by API<\/h1>\n<h2 id=\"authentication\">Authentication<\/h2>\n<p>See <a href=\"\/wiki\/api\/authentication\/\">Authentication via OAuth 2.0<\/a> for the full authentication flow. <code>POST \/oauth2\/token<\/code> follows the <a href=\"https:\/\/datatracker.ietf.org\/doc\/html\/rfc6749#section-5.2\">OAuth 2.0 error response shape<\/a> instead of the standard shape:<\/p>\n<pre>{\n   \"error\": \"invalid_grant\",\n   \"error_description\": \"human readable description\"\n}<\/pre>\n<table>\n<thead>\n<tr>\n<th>Endpoint<\/th>\n<th>Status<\/th>\n<th>Code<\/th>\n<th>When it happens<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>POST \/oauth2\/token<\/code><\/td>\n<td>403<\/td>\n<td><code>ratelimited<\/code><\/td>\n<td>Too many failed login attempts; try again later.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>403<\/td>\n<td><code>validated<\/code><\/td>\n<td>Account needs to be validated.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>403<\/td>\n<td><code>activated<\/code><\/td>\n<td>Account has not yet been activated by an administrator.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>403<\/td>\n<td><code>privileges<\/code><\/td>\n<td>Account does not have API access privileges (client-credentials grant).<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>403<\/td>\n<td><code>toomanytokens<\/code><\/td>\n<td>Too many active access tokens outstanding for this account.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>403<\/td>\n<td>\u2014<\/td>\n<td>Incorrect password, or unknown client\/account (standard OAuth2 <code>invalid_client<\/code>\/<code>invalid_grant<\/code>).<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>400<\/td>\n<td>\u2014<\/td>\n<td>Malformed token request per the OAuth2 spec (<code>invalid_request<\/code>, <code>unsupported_grant_type<\/code>, <code>invalid_scope<\/code>).<\/td>\n<\/tr>\n<tr>\n<td><code>GET \/oauth2\/authorize<\/code><\/td>\n<td>401<\/td>\n<td>\u2014<\/td>\n<td>Not authenticated. No response body.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Every endpoint above that requires a session or bearer token can additionally fail before reaching the handler with:<\/p>\n<ul>\n<li><strong>401<\/strong> \u2014 no credentials supplied, or credentials invalid\/expired.<\/li>\n<li><strong>403<\/strong> \u2014 credentials valid but insufficient privilege for the operation.<\/li>\n<\/ul>\n<p>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 \u2014 status code only, no JSON, no <code>code<\/code>.<\/p>\n<h2 id=\"aircraft\">Aircraft<\/h2>\n<table>\n<thead>\n<tr>\n<th>Endpoint<\/th>\n<th>Status<\/th>\n<th>Code<\/th>\n<th>When it happens<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>POST \/aircraft<\/code>, <code>PUT \/aircraft\/{id}<\/code><\/td>\n<td>400<\/td>\n<td>\u2014<\/td>\n<td>Missing\/invalid callsign, manufacturer, model, year, ICAO type, or MTOM.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>404<\/td>\n<td>\u2014<\/td>\n<td>(PUT) Aircraft not found, or not owned by you.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>400<\/td>\n<td><code>AIRCRAFT_CONVERSION_FAILED<\/code><\/td>\n<td>Aircraft definition could not be converted. The error message contains the specific reason (e.g. unknown manufacturer, invalid massunitname, invalid propulsion type).<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>409<\/td>\n<td>\u2014<\/td>\n<td>An aircraft with this registration and model already exists.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>500<\/td>\n<td><code>INTERNAL_ERROR<\/code><\/td>\n<td>A database error occurred while saving the aircraft.<\/td>\n<\/tr>\n<tr>\n<td><code>GET \/aircraft\/{id}<\/code>, <code>DELETE \/aircraft\/{id}<\/code><\/td>\n<td>404<\/td>\n<td>\u2014<\/td>\n<td>Aircraft not found, deleted, or not accessible to you.<\/td>\n<\/tr>\n<tr>\n<td><code>GET \/aircraft<\/code><\/td>\n<td>400<\/td>\n<td>\u2014<\/td>\n<td>Missing pagination parameters.<\/td>\n<\/tr>\n<tr>\n<td><code>PUT \/aircraft\/{id}\/default<\/code><\/td>\n<td>404<\/td>\n<td>\u2014<\/td>\n<td>Your account record could not be found (does not validate that <code>{id}<\/code> is a real aircraft).<\/td>\n<\/tr>\n<tr>\n<td><code>GET \/aircraft\/{id}\/performance<\/code>, <code>POST \/aircraft\/performance<\/code><\/td>\n<td>400 \/ 404<\/td>\n<td><code>AIRCRAFT_CONVERSION_FAILED<\/code> \/ \u2014<\/td>\n<td>Aircraft not found\/accessible (404), or the submitted aircraft definition is invalid (400 with <code>AIRCRAFT_CONVERSION_FAILED<\/code>).<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>502 \/ 503 \/ 504<\/td>\n<td><code>ROUTER_ERROR<\/code> \/ <code>ROUTER_UNREACHABLE<\/code> \/ <code>ROUTER_TIMEOUT<\/code><\/td>\n<td>The router returned an unexpected reply (502, <code>ROUTER_ERROR<\/code>, permanent), could not be reached (503, <code>ROUTER_UNREACHABLE<\/code>, retry) or did not complete the performance computation in time (504, <code>ROUTER_TIMEOUT<\/code>, retry).<\/td>\n<\/tr>\n<tr>\n<td><code>PUT \/aircraft\/{id}\/defaultloading<\/code><\/td>\n<td>404 \/ 500<\/td>\n<td>\u2014 \/ <code>INTERNAL_ERROR<\/code><\/td>\n<td>Aircraft not found\/accessible, or its stored definition is corrupt.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2 id=\"routes\">Routes<\/h2>\n<table>\n<thead>\n<tr>\n<th>Endpoint<\/th>\n<th>Status<\/th>\n<th>Code<\/th>\n<th>When it happens<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>POST \/router<\/code><\/td>\n<td>400<\/td>\n<td>\u2014<\/td>\n<td>Invalid optimization target, aircraft definition, or missing\/malformed departure, destination, or alternate.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>404<\/td>\n<td>\u2014<\/td>\n<td>Referenced aircraft not found or not accessible.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>422<\/td>\n<td><code>PARSE_FAILED<\/code><\/td>\n<td>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 \u2014 a supplied aircraft the parser cannot build a profile from fails the same way, and <code>error2<\/code> in <code>data<\/code> says which part the parser objected to. Not retryable: the request has to change.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>502 \/ 503 \/ 504<\/td>\n<td><code>ROUTER_ERROR<\/code> \/ <code>ROUTER_UNREACHABLE<\/code> \/ <code>ROUTER_BUSY<\/code> \/ <code>PARSE_TIMEOUT<\/code><\/td>\n<td>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 <code>PARSE_FAILED<\/code> this says nothing about your flight plan.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>403<\/td>\n<td><code>NOT_AUTHORIZED<\/code><\/td>\n<td>Not authorized to create a route on behalf of the given user.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>409<\/td>\n<td><code>DUPLICATE_FILING<\/code><\/td>\n<td>A route with the generated id already exists.<\/td>\n<\/tr>\n<tr>\n<td><code>PUT \/router\/hide<\/code>, <code>PUT \/router\/{routeid}\/hide<\/code><\/td>\n<td>404<\/td>\n<td>\u2014<\/td>\n<td>Route id not found, or not owned by you.<\/td>\n<\/tr>\n<tr>\n<td><code>PUT \/router\/{routeid}<\/code><\/td>\n<td>400<\/td>\n<td>\u2014<\/td>\n<td>Flight plan missing, or the update failed (route id not found or not owned by you \u2014 both conditions currently return the same 400).<\/td>\n<\/tr>\n<tr>\n<td><code>PUT \/router\/{routeid}\/longpoll<\/code>, <code>\/stop<\/code>, <code>\/close<\/code><\/td>\n<td>404<\/td>\n<td>\u2014<\/td>\n<td>Route id not found, or you may not drive its routing session. Delegates need <code>route_create<\/code> on the authorizer&#8217;s account, which they have for any route they requested on its behalf.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Apart from that 404, <code>PUT \/router\/{routeid}\/longpoll<\/code>, <code>\/stop<\/code>, and <code>\/close<\/code> respond <strong>200<\/strong>; a routing-engine-side failure is reported as an <code>error<\/code> field inside the 200 response body rather than as an HTTP error status. Inspect the body on these three endpoints even on success. Alongside <code>error<\/code> the body carries <code>transient<\/code>: <code>true<\/code> means the engine was momentarily unavailable and you should keep polling, since the routing session survives and resumes once the engine is back; <code>false<\/code> means the failure is permanent and polling should stop.<\/p>\n<h2 id=\"flightplans\">Flightplans<\/h2>\n<p>This is the one part of the API with consistent, stable error codes end to end \u2014 see the <a href=\"#overview\">code table above<\/a> for what each one means.<\/p>\n<table>\n<thead>\n<tr>\n<th>Endpoint<\/th>\n<th>Status<\/th>\n<th>Code<\/th>\n<th>When it happens<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>POST \/flightplan\/file\/{routeid}<\/code> (file a flight plan)<\/td>\n<td>403<\/td>\n<td><code>NOT_AUTHORIZED<\/code><\/td>\n<td>No filing privileges.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>429<\/td>\n<td><code>PLAN_LIMIT_EXCEEDED<\/code><\/td>\n<td>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&#8217;s behalf it is that account&#8217;s open plans that count, not the delegate&#8217;s.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>400<\/td>\n<td><code>INVALID_BRIEFING<\/code><\/td>\n<td>Briefing information missing.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>400<\/td>\n<td><code>INVALID_CUSTOMERREF<\/code><\/td>\n<td>The optional <code>customerref<\/code> 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.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>404<\/td>\n<td><code>ROUTE_NOT_FOUND<\/code><\/td>\n<td>Route could not be accessed.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>404<\/td>\n<td><code>FLIGHTPLAN_NOT_FOUND<\/code><\/td>\n<td>Refile only (<code>flightid<\/code> and <code>eobt<\/code> 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&#8217;s behalf needs <code>fpl_file<\/code> or <code>fpl_delaybringforward<\/code> on their account.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>504<\/td>\n<td><code>PARSE_TIMEOUT<\/code><\/td>\n<td>Flight plan parser poll limit exceeded.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>502<\/td>\n<td><code>PARSE_FAILED<\/code><\/td>\n<td>Flight plan parsing failed or returned an unexpected result. Not retryable \u2014 the plan has to change.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>502 \/ 503<\/td>\n<td><code>ROUTER_ERROR<\/code> \/ <code>ROUTER_UNREACHABLE<\/code> \/ <code>ROUTER_BUSY<\/code><\/td>\n<td>The parsing engine could not be reached or is at capacity (503, retry), or answered with something unusable (502, permanent). Distinct from <code>PARSE_FAILED<\/code>: nothing is wrong with the flight plan.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>422<\/td>\n<td><code>NOT_IFPS_APPLICABLE<\/code><\/td>\n<td>No IFR segment within the Eurocontrol region.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>422<\/td>\n<td><code>FILING_VALIDATION_FAILED<\/code><\/td>\n<td>Final validation before filing failed. <code>error<\/code> carries the validation detail; refile with <code>\"force\": true<\/code> to submit anyway.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>422<\/td>\n<td><code>LVNL_PILOT_TEL_MISSING<\/code><\/td>\n<td>Pilot phone number required for Dutch VFR departure.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>502<\/td>\n<td><code>EUROCONTROL_ERROR<\/code><\/td>\n<td>Eurocontrol\/NM B2B returned an invalid or permanently failing response.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>503<\/td>\n<td><code>EUROCONTROL_UNAVAILABLE<\/code><\/td>\n<td>Eurocontrol is temporarily unavailable; nothing was filed. Retry shortly.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>409<\/td>\n<td><code>DUPLICATE_FILING<\/code><\/td>\n<td>A matching flight plan \u2014 same aircraft, aerodromes and EOBT \u2014 is already active. On an AFTN or LVNL filing this is our own check, since neither gateway detects duplicates itself, and <code>data.fplid<\/code> <strong>\u2020<\/strong> is the flight ID of the plan in the way \u2014 the same ID the <code>\/flightplan\/file\/{flightid}\/\u2026<\/code> operations take, so a client can cancel or delay it directly. On an NM B2B filing the refusal is Eurocontrol&#8217;s own; <code>error<\/code> then quotes the reason Eurocontrol gave, and <code>data<\/code> names the blocking plan the same way whenever we can identify one of yours as the cause \u2014 unmarked, because we cannot always. Cancelling that plan, or moving its EOBT, clears the condition either way. <code>data<\/code> also carries the plan&#8217;s <code>created<\/code> timestamp and, where it has one, its <code>customerref<\/code>.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>409<\/td>\n<td><code>DUPLICATE_FILING<\/code><\/td>\n<td>You already have another active flight plan carrying the same <code>customerref<\/code>. Unlike the previous condition this check runs for every filing method, including NM B2B, and cannot be skipped with <code>skipduplicatecheck<\/code> \u2014 a <code>customerref<\/code> is expected to identify one flight for you. <code>data.fplid<\/code> <strong>\u2020<\/strong> 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.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>422<\/td>\n<td><code>FILING_REJECTED<\/code><\/td>\n<td>IFPS rejected the flight plan. <code>error<\/code> names the IFPS error codes, see <a href=\"#ifps-rejections\">IFPS rejections<\/a>.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>500<\/td>\n<td><code>PERSIST_FAILED<\/code><\/td>\n<td>Filing succeeded upstream but could not be persisted.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>502<\/td>\n<td><code>LVNL_SEND_FAILED<\/code><\/td>\n<td>Sending the LVNL flight plan message failed.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>502<\/td>\n<td><code>AFTN_SEND_FAILED<\/code><\/td>\n<td>AFTN filing message could not be sent (permanent failure).<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>503<\/td>\n<td><code>AFTN_GATEWAY_UNREACHABLE<\/code><\/td>\n<td>AFTN gateway temporarily unreachable; nothing was sent.<\/td>\n<\/tr>\n<tr>\n<td><code>POST \/flightplan\/file\/{flightid}\/cancel<\/code><\/td>\n<td>400<\/td>\n<td><\/td>\n<td>No <code>reason<\/code> supplied in the request body.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>403<\/td>\n<td><code>NOT_AUTHORIZED<\/code><\/td>\n<td>No privilege to cancel flight plans.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>404<\/td>\n<td><code>FLIGHTPLAN_NOT_FOUND<\/code><\/td>\n<td>Flight plan not found or not accessible.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>409<\/td>\n<td><code>ALREADY_CANCELLED<\/code><\/td>\n<td>Flight plan was already cancelled externally.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>422<\/td>\n<td><code>FILING_REJECTED<\/code><\/td>\n<td>IFPS refused the cancellation message, typically because the flight is no longer in a state that can be cancelled. <code>error<\/code> names the IFPS error codes, see <a href=\"#ifps-rejections\">IFPS rejections<\/a>.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>502<\/td>\n<td><code>EUROCONTROL_ERROR<\/code><\/td>\n<td>Eurocontrol returned an error status, or a filing status we cannot act on.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>503<\/td>\n<td><code>EUROCONTROL_UNAVAILABLE<\/code><\/td>\n<td>Eurocontrol could not be reached or is temporarily unavailable; the cancellation was not sent. Retry shortly.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>502<\/td>\n<td><code>LVNL_SEND_FAILED<\/code><\/td>\n<td>Sending the LVNL cancellation failed.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>502 \/ 503<\/td>\n<td><code>AFTN_SEND_FAILED<\/code> \/ <code>AFTN_GATEWAY_UNREACHABLE<\/code><\/td>\n<td>AFTN cancellation message could not be sent.<\/td>\n<\/tr>\n<tr>\n<td><code>POST \/flightplan\/file\/{flightid}\/delay<\/code><\/td>\n<td>403<\/td>\n<td><code>NOT_AUTHORIZED<\/code><\/td>\n<td>No privilege to delay flight plans.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>404<\/td>\n<td><code>FLIGHTPLAN_NOT_FOUND<\/code><\/td>\n<td>Flight plan not found or not accessible.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>400<\/td>\n<td><code>EOBT_OUT_OF_RANGE<\/code><\/td>\n<td>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).<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>504<\/td>\n<td><code>PARSE_TIMEOUT<\/code><\/td>\n<td>Re-parse poll limit exceeded.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>502<\/td>\n<td><code>PARSE_FAILED<\/code><\/td>\n<td>Re-parsing the flight plan failed. Not retryable \u2014 the plan has to change.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>502 \/ 503<\/td>\n<td><code>ROUTER_ERROR<\/code> \/ <code>ROUTER_UNREACHABLE<\/code> \/ <code>ROUTER_BUSY<\/code><\/td>\n<td>The parsing engine could not be reached or is at capacity (503, retry), or answered with something unusable (502, permanent). Distinct from <code>PARSE_FAILED<\/code>: nothing is wrong with the flight plan.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>409<\/td>\n<td><code>ALREADY_CANCELLED<\/code><\/td>\n<td>Flight plan was already cancelled externally.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>422<\/td>\n<td><code>FILING_REJECTED<\/code><\/td>\n<td>IFPS refused the delay message. <code>error<\/code> names the IFPS error codes, see <a href=\"#ifps-rejections\">IFPS rejections<\/a>.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>502<\/td>\n<td><code>EUROCONTROL_ERROR<\/code><\/td>\n<td>Eurocontrol returned an error status, or a filing status we cannot act on.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>503<\/td>\n<td><code>EUROCONTROL_UNAVAILABLE<\/code><\/td>\n<td>Eurocontrol could not be reached or is temporarily unavailable; the delay was not sent. Retry shortly.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>502 \/ 503<\/td>\n<td><code>LVNL_SEND_FAILED<\/code> \/ <code>AFTN_SEND_FAILED<\/code> \/ <code>AFTN_GATEWAY_UNREACHABLE<\/code><\/td>\n<td>Sending the delay message failed.<\/td>\n<\/tr>\n<tr>\n<td><code>POST \/flightplan\/file\/{flightid}\/bringforward<\/code><\/td>\n<td>403<\/td>\n<td><code>NOT_AUTHORIZED<\/code><\/td>\n<td>No privilege to modify flight plans.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>400<\/td>\n<td><code>EOBT_OUT_OF_RANGE<\/code><\/td>\n<td>New EOBT outside the valid range.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>404<\/td>\n<td><code>FLIGHTPLAN_NOT_FOUND<\/code><\/td>\n<td>Flight plan not found or not accessible.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>504<\/td>\n<td><code>PARSE_TIMEOUT<\/code><\/td>\n<td>Re-parse poll limit exceeded.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>502<\/td>\n<td><code>PARSE_FAILED<\/code><\/td>\n<td>Re-parsing the flight plan failed. Not retryable \u2014 the plan has to change.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>502 \/ 503<\/td>\n<td><code>ROUTER_ERROR<\/code> \/ <code>ROUTER_UNREACHABLE<\/code> \/ <code>ROUTER_BUSY<\/code><\/td>\n<td>The parsing engine could not be reached or is at capacity (503, retry), or answered with something unusable (502, permanent). Distinct from <code>PARSE_FAILED<\/code>: nothing is wrong with the flight plan.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>422<\/td>\n<td><code>VALIDATION_FAILED<\/code><\/td>\n<td>Flight plan does not validate at the earlier time.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>409<\/td>\n<td><code>ALREADY_CANCELLED<\/code><\/td>\n<td>Flight plan was already cancelled externally. Nothing was changed, and the plan is now marked cancelled here too.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>422<\/td>\n<td><code>FILING_REJECTED<\/code><\/td>\n<td>IFPS refused the cancellation message that starts the refile. Nothing was changed. <code>error<\/code> names the IFPS error codes, see <a href=\"#ifps-rejections\">IFPS rejections<\/a>.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>502<\/td>\n<td><code>EUROCONTROL_ERROR<\/code><\/td>\n<td>Eurocontrol returned an error status, or a filing status we cannot act on, while cancelling. Nothing was changed.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>503<\/td>\n<td><code>EUROCONTROL_UNAVAILABLE<\/code><\/td>\n<td>Eurocontrol could not be reached or is temporarily unavailable; the cancellation was not sent and nothing was changed. Retry shortly.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>502 \/ 503<\/td>\n<td><code>LVNL_SEND_FAILED<\/code> \/ <code>AFTN_SEND_FAILED<\/code> \/ <code>AFTN_GATEWAY_UNREACHABLE<\/code><\/td>\n<td>Sending the cancellation message that starts the refile failed. Nothing was changed.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>500<\/td>\n<td><code>REFILE_FAILED<\/code><\/td>\n<td>The original plan was cancelled but the modified plan could not be filed. The original is gone \u2014 create a new flight plan. Every failure before this point leaves the original plan untouched and keeps its own status and code.<\/td>\n<\/tr>\n<tr>\n<td><code>POST \/flightplan\/file\/{flightid}\/departure<\/code>, <code>POST \/flightplan\/file\/{flightid}\/arrival<\/code><\/td>\n<td>404<\/td>\n<td><code>FLIGHTPLAN_NOT_FOUND<\/code><\/td>\n<td>Flight plan not found or not accessible.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>409<\/td>\n<td><code>WRONG_STATE<\/code><\/td>\n<td>Flight plan is not in filed state (departure) \/ is closed (arrival).<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>400<\/td>\n<td><code>INVALID_TIME<\/code><\/td>\n<td>Invalid departure\/arrival time.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>422<\/td>\n<td><code>FILING_REJECTED<\/code><\/td>\n<td>IFPS refused the departure or arrival message, for example a DEP for a flight that already departed. <code>error<\/code> names the IFPS error codes, see <a href=\"#ifps-rejections\">IFPS rejections<\/a>.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>502<\/td>\n<td><code>EUROCONTROL_ERROR<\/code><\/td>\n<td>Eurocontrol returned an error status, or a filing status we cannot act on.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>503<\/td>\n<td><code>EUROCONTROL_UNAVAILABLE<\/code><\/td>\n<td>Eurocontrol could not be reached or is temporarily unavailable; the message was not sent. Retry shortly.<\/td>\n<\/tr>\n<tr>\n<td><code>PUT \/flightplan\/fpal\/verify<\/code><\/td>\n<td>500<\/td>\n<td>\u2014<\/td>\n<td>Verification could not be run.<\/td>\n<\/tr>\n<tr>\n<td><code>GET \/flightplan\/fpal\/{id}<\/code><\/td>\n<td>400<\/td>\n<td>\u2014<\/td>\n<td>Invalid document id.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>404<\/td>\n<td>\u2014<\/td>\n<td>Document not found.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><code>GET \/flightplan<\/code> (parse), <code>GET \/flightplan\/validate<\/code>, <code>GET \/flightplan\/file<\/code>, and <code>GET \/flightplan\/file\/{flightid}<\/code> do not raise HTTP-level errors for business-logic failures. <code>GET \/flightplan<\/code> and <code>GET \/flightplan\/convert<\/code> do report infrastructure failures, though: <strong>503<\/strong> with <code>ROUTER_UNREACHABLE<\/code> when no parsing engine can be reached, <strong>503<\/strong> with <code>ROUTER_BUSY<\/code> when the engine is at capacity, <strong>504<\/strong> with <code>PARSE_TIMEOUT<\/code> when it does not answer in time, and <strong>502<\/strong> with <code>ROUTER_ERROR<\/code> when it answers with something unusable. Only the last of these is permanent.<\/p>\n<h2 id=\"navdata\">Navdata<\/h2>\n<table>\n<thead>\n<tr>\n<th>Endpoint<\/th>\n<th>Status<\/th>\n<th>Code<\/th>\n<th>When it happens<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>GET \/navdata\/airport<\/code><\/td>\n<td>400<\/td>\n<td>\u2014<\/td>\n<td>No search parameters supplied.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2 id=\"weather\">Weather<\/h2>\n<table>\n<thead>\n<tr>\n<th>Endpoint<\/th>\n<th>Status<\/th>\n<th>Code<\/th>\n<th>When it happens<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>GET \/met\/gramet<\/code><\/td>\n<td>400<\/td>\n<td>\u2014<\/td>\n<td>Invalid <code>format<\/code>, or neither a flight plan nor a waypoint list supplied.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>503<\/td>\n<td><code>ROUTER_UNREACHABLE<\/code> \/ <code>ROUTER_BUSY<\/code><\/td>\n<td>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 <code>Retry-After<\/code>.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>504<\/td>\n<td><code>ROUTER_TIMEOUT<\/code><\/td>\n<td>Chart generation did not complete in time. Retryable.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>502<\/td>\n<td><code>ROUTER_ERROR<\/code><\/td>\n<td>The engine returned an unexpected reply, or no chart at all, for this input. Not retryable.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><code>GET \/met\/metartaf\/{icao}<\/code> responds <strong>200<\/strong> with <code>metar<\/code>\/<code>taf<\/code> set to <code>null<\/code> for an unknown or data-less station rather than a 404 \u2014 there is currently no way to distinguish &#8220;no data yet&#8221; from &#8220;invalid station&#8221; via the status code. <code>GET \/met\/modeldate<\/code> likewise always responds <strong>200<\/strong>, with <code>null<\/code> if the timestamp could not be determined.<\/p>\n<h2 id=\"briefing\">Briefing<\/h2>\n<table>\n<thead>\n<tr>\n<th>Endpoint<\/th>\n<th>Status<\/th>\n<th>Code<\/th>\n<th>When it happens<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>POST \/flightplan\/file\/{flightid}\/briefing<\/code>, <code>POST \/flightplan\/{routeid}\/briefing<\/code> (generate a briefing pack)<\/td>\n<td>400<\/td>\n<td>\u2014<\/td>\n<td><code>method<\/code> or <code>items<\/code> missing, or <code>method<\/code> is not one of <code>email<\/code>\/<code>telegram<\/code>\/<code>download<\/code>.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>403<\/td>\n<td>\u2014<\/td>\n<td>A briefing pack is already being generated for you.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>404<\/td>\n<td>\u2014<\/td>\n<td>Flight plan\/route not found.<\/td>\n<\/tr>\n<tr>\n<td><\/td>\n<td>500<\/td>\n<td>\u2014<\/td>\n<td>The briefing pack could not be queued or generated.<\/td>\n<\/tr>\n<tr>\n<td><code>GET ...\/briefing<\/code> (fetch\/generate, blocking)<\/td>\n<td>404 \/ 500<\/td>\n<td>\u2014<\/td>\n<td>Flight plan\/route not found, or generation timed out\/failed.<\/td>\n<\/tr>\n<tr>\n<td><code>GET ...\/briefing\/{token}<\/code> (poll\/download)<\/td>\n<td>404 \/ 500<\/td>\n<td>\u2014<\/td>\n<td>Not ready yet (404), or generation failed (500). No response body on either.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2 id=\"documents\">Documents<\/h2>\n<table>\n<thead>\n<tr>\n<th>Endpoint<\/th>\n<th>Status<\/th>\n<th>Code<\/th>\n<th>When it happens<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>GET \/pams\/id\/{docid}<\/code><\/td>\n<td>404<\/td>\n<td>\u2014<\/td>\n<td>Document id is not numeric or not found, or the file is missing on disk.<\/td>\n<\/tr>\n<tr>\n<td><code>GET \/pams\/airport\/{icao}\/package<\/code><\/td>\n<td>404<\/td>\n<td>\u2014<\/td>\n<td>Invalid ICAO, unknown airport, or no plates available to build a package.<\/td>\n<\/tr>\n<tr>\n<td><code>POST \/pams\/airport<\/code><\/td>\n<td>400<\/td>\n<td>\u2014<\/td>\n<td>Request body is not an array, or is not JSON (see note below).<\/td>\n<\/tr>\n<tr>\n<td><code>GET \/pams[\/{authority}[\/{language}[\/{aiptype}[\/{section}]]]]<\/code><\/td>\n<td>400<\/td>\n<td>\u2014<\/td>\n<td>A path segment is supplied without the segment(s) before it (e.g. <code>language<\/code> without <code>authority<\/code>).<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><code>GET \/pams\/airport\/{icao}<\/code>\/<code>POST \/pams\/airport<\/code> respond <strong>200<\/strong> with an empty list for a malformed airport code rather than an error. A non-JSON request body on <code>POST \/pams\/airport<\/code> returns a plain <strong>400<\/strong> with no response body, rather than the standard JSON error shape.<\/p>\n<h2 id=\"notams\">NOTAMs<\/h2>\n<table>\n<thead>\n<tr>\n<th>Endpoint<\/th>\n<th>Status<\/th>\n<th>Code<\/th>\n<th>When it happens<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>GET \/notam<\/code><\/td>\n<td>400<\/td>\n<td>\u2014<\/td>\n<td>An <code>itema<\/code> entry is not a valid 4-character ICAO location indicator pattern.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2 id=\"messages\">Messages<\/h2>\n<table>\n<thead>\n<tr>\n<th>Endpoint<\/th>\n<th>Status<\/th>\n<th>Code<\/th>\n<th>When it happens<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><code>GET \/message<\/code><\/td>\n<td>400<\/td>\n<td>\u2014<\/td>\n<td>Invalid <code>timeout<\/code> (must be 0\u2013300) or <code>limit<\/code> (must be 1\u2013100).<\/td>\n<\/tr>\n<tr>\n<td><code>POST \/message\/acknowledge<\/code>, <code>POST \/message\/{id}\/acknowledge<\/code><\/td>\n<td>400<\/td>\n<td>\u2014<\/td>\n<td>An id in the request is not a valid non-negative integer.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Acknowledging an id that doesn&#8217;t exist, or that belongs to another user, is currently a silent no-op (<strong>200<\/strong>), not an error. <code>GET \/message\/count<\/code> has no error conditions.<\/p>\n<p>Every request \u2014 regardless of API \u2014 is first checked against the requested API version; a missing or unsupported version returns a bodiless <strong>400<\/strong> before your request reaches any endpoint. See <a href=\"\/wiki\/api\/#versioning\">Versioning<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Overview This page is the reference for how the autorouter API reports errors, and lists every error \u2014 HTTP status code plus, where one exists, a stable machine-readable code \u2014 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 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":33,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-1067","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.autorouter.aero\/wiki\/wp-json\/wp\/v2\/pages\/1067","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.autorouter.aero\/wiki\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.autorouter.aero\/wiki\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.autorouter.aero\/wiki\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.autorouter.aero\/wiki\/wp-json\/wp\/v2\/comments?post=1067"}],"version-history":[{"count":11,"href":"https:\/\/www.autorouter.aero\/wiki\/wp-json\/wp\/v2\/pages\/1067\/revisions"}],"predecessor-version":[{"id":1091,"href":"https:\/\/www.autorouter.aero\/wiki\/wp-json\/wp\/v2\/pages\/1067\/revisions\/1091"}],"up":[{"embeddable":true,"href":"https:\/\/www.autorouter.aero\/wiki\/wp-json\/wp\/v2\/pages\/33"}],"wp:attachment":[{"href":"https:\/\/www.autorouter.aero\/wiki\/wp-json\/wp\/v2\/media?parent=1067"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}