{"openapi":"3.1.0","info":{"title":"Pelyr OPEN-AIS Data API","version":"1"},"servers":[{"url":"https://api.pelyr.com","description":"Produktion"}],"paths":{"/v1/sources":{"get":{"summary":"Das Nennungsverzeichnis","description":"Dieselbe Liste, die der authentifizierte Stream in seinem `welcome` schickt --\nhier ohne stehende Verbindung abrufbar.\n\nDie Eintraege `0` (`NOASSERTION`) und `1` (`Pelyr`) stehen immer da, danach je\ngefuehrter Quelle mit gepflegtem Lizenztext ein Eintrag, entdoppelt und\nnumerisch sortiert. Alle vier Felder sind immer Zeichenketten, nie `null`, nie\nabwesend -- `source` und `attribution` duerfen leer sein.\n\n`license` in `position` und `static` einer Schiffsantwort ist die `id` eines\ndieser Eintraege. Das Verzeichnis aendert sich in Tagen, nicht in Sekunden:\neinmal am Tag abrufen und mit `If-None-Match` gegen `304` pruefen genuegt.","operationId":"listSources","security":[{"customerKey":[]}],"parameters":[{"name":"If-None-Match","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"If-None-Match","default":null}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourcesResponse"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unprocessable Entity"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal Server Error"},"304":{"description":"Unveraendert."}}}},"/v1/vessels/at":{"get":{"summary":"Schiffspositionen zu einem Zeitpunkt","description":"Alle Schiffe in einer BBox zu **einem** Zeitpunkt, je Schiff mit dem Alter\nseiner Position -- der Zeitschnitt.\n\nGesucht wird in einem Fenster von `lookback_seconds` Sekunden VOR `at`\n(16 Minuten). Kandidat ist jedes Schiff, das in diesem Fenster mindestens\neinmal aus der BBox gemeldet hat; geliefert wird seine **juengste** Position\nim Fenster, nie eine aeltere -- auch dann, wenn diese juengste Position\nschon ausserhalb der BBox liegt, weil das Schiff die Box gerade verlassen\nhat. Wer nur Positionen innerhalb der Box will, filtert die Antwort selbst.\n`age_seconds` ist der Abstand der Position zu `at`. Ein Schiff, das zuletzt\nvor dem Fenster gemeldet hat, fehlt -- es ist deshalb kein \"dunkles\" Schiff.\n\nEs wird nichts interpoliert und nichts koppelnavigiert: jede Koordinate\nstand so im AIS-Funk. Eine gerechnete Position mischte unseren Rechenfehler\nin genau die Groesse, die ein Abgleich mit Satellitenbildern messen soll.\n\n`at` darf nicht in der Zukunft liegen (`400 invalid_time_range`) und muss\nin der Minutenstufe liegen (`503 track_unavailable`): die haelt den\nlaufenden UTC-Tag und die zwei davor, also mindestens 47 Stunden. Dieser\nEndpunkt liest kein Archiv. Ein leeres Gebiet liefert `200` mit\n`vessels: []`, nie `404` -- \"niemand hat gesendet\" ist eine Antwort.\n\n`truncated: true` heisst: mehr Schiffe im Fenster als der Deckel von 5000\nzulaesst; `vessels` ist dann leer, nicht gekuerzt. Die BBox verkleinern.\nA plan cap of `GET /v1/vessels` below 5000 lowers it.\n\n**The time slice depends on the plan** of the key's account\n(`constants.json` -> `billing.PLANS[].history.time_slice`): Free\ndoes not include it and answers `403 time_slice_not_in_plan`, with\na link to https://dashboard.pelyr.com/pricing in the message;\nFleet, Horizon, Global and Enterprise include it, and so does Legacy\nFree (`billing.LEGACY_PLAN`) of an account that existed at the\nlaunch of billing, until its `legacy_until`. This is checked after\nthe parameters (`400`, `422`) and before the retention (`503`). The\ntime slice of the dashboard map (`GET /api/v1/map/vessels/at`)\nbelongs to the map product and is not gated by the developer plan.\n\nTeilt sich das Ratenbudget mit `GET /v1/vessels` und `GET /v1/vessels/{mmsi}`.\nMit `If-None-Match` kostet ein unveraenderter Schnitt nur ein `304`.","operationId":"listVesselsAt","security":[{"customerKey":[]}],"parameters":[{"name":"at","in":"query","required":true,"schema":{"type":"string","format":"date-time","title":"At"}},{"name":"bbox","in":"query","required":true,"schema":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?,-?\\d+(\\.\\d+)?,-?\\d+(\\.\\d+)?,-?\\d+(\\.\\d+)?$","title":"Bbox"}},{"name":"If-None-Match","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"If-None-Match","default":null}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Zeitschnitt"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unprocessable Entity"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal Server Error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Service Unavailable"},"304":{"description":"Unveraendert."}}}},"/v1/vessels/search":{"get":{"summary":"Search vessels by MMSI, IMO or name","description":"Find vessels by **exactly one** of `mmsi`, `imo` or `name`. The answer is a\nranked list, never one silently chosen vessel, since common names exist many times.\n\n* `mmsi` and `imo` match exactly. One IMO can return several vessels, one per\n  MMSI, for example after a change of flag.\n* `name` is matched against current **and former** names after normalisation\n  (upper case, letters and digits only, a leading `MV`, `MT` or `MS` dropped).\n  Hits are ordered `exact`, then `prefix`, then `similar`; current names before\n  former names; then by `score`. **A `similar` hit is a candidate, not an\n  identification** -- compare MMSI, IMO and dimensions before relying on it.\n  A name shorter than three characters is matched exactly only.\n* `max` caps the list (default 10, at most 25). `truncated: true` means there\n  were more candidates than delivered.\n\nEach hit carries up to three groups, each with its own `ts` and `license`:\n`registry` (the vessel register: static data with first and last sighting,\nfilled only since the register was switched on), `static` (static data from\nthe live state, including voyage, present only while the vessel is heard) and\n`position`. `position.live: true` is the live position with `plausibility`\nand `flags`. `live: false` is the last position from the track history of the\nlast 30 days: its motion values are those of that moment, and it carries no\nplausibility. A group without data is omitted, never `null`.\n\n`flag_country` is the ISO 3166-1 alpha-2 code derived from the MID of the\nMMSI. It is not AIS data and not covered by any licence.\n\n`400 bad_request`: none or more than one of `mmsi`, `imo`, `name`; an IMO with\nan invalid check digit; a name without letters or digits. An empty result is\n`200` with `results: []`, never `404`.\n\nShares the rate budget with `GET /v1/vessels`, `GET /v1/vessels/{mmsi}` and\n`GET /v1/vessels/at`.","operationId":"searchVessels","security":[{"customerKey":[]}],"parameters":[{"name":"mmsi","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":999999999,"minimum":100000000},{"type":"null"}],"title":"Mmsi","default":null}},{"name":"imo","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^[0-9]{7}$"},{"type":"null"}],"title":"Imo","default":null}},{"name":"name","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name","default":null}},{"name":"max","in":"query","required":false,"schema":{"type":"integer","maximum":25,"minimum":1,"default":10,"title":"Max"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VesselSearchResult"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unprocessable Entity"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal Server Error"}}}},"/v1/vessels":{"get":{"summary":"Schiffe in einer BBox","description":"Momentaufnahme aller Schiffe im Ausschnitt `bbox`, jedes in `position` und\n`static` geteilt und je mit eigenem Zeitstempel und eigener Lizenzkennung.\n\n`max` deckelt die Zahl der Schiffe. Liegen mehr im Ausschnitt, steht\n`truncated: true` und die Auswahl ist raeumlich verteilt statt an einer Ecke\nzusammengeballt -- ein kleinerer Ausschnitt liefert dann mehr, nicht ein\ngroesseres `max`.\n\nThe plan caps `max`: Free 1000, Fleet 5000, Horizon 10000, Global 15000. A\nlarger `max` is cut to the plan's cap.\n\nZwei Grenzen: ein Ausschnitt ueber den Antimeridian wird mit `invalid_bbox`\nabgelehnt, und Positionen jenseits von ±85,05112878° Breite erscheinen hier\nnicht -- fuer sie bleibt `GET /v1/vessels/{mmsi}`.\n\nDie Momentaufnahme aktualisiert sich alle paar Sekunden; mit `If-None-Match`\nkostet ein unveraenderter Ausschnitt nur ein `304`.","operationId":"listVessels","security":[{"customerKey":[]}],"parameters":[{"name":"bbox","in":"query","required":true,"schema":{"type":"string","pattern":"^-?\\d+(\\.\\d+)?,-?\\d+(\\.\\d+)?,-?\\d+(\\.\\d+)?,-?\\d+(\\.\\d+)?$","title":"Bbox"}},{"name":"max","in":"query","required":false,"schema":{"type":"integer","maximum":15000,"minimum":1,"default":2000,"title":"Max"}},{"name":"If-None-Match","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"If-None-Match","default":null}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VesselsResponse"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unprocessable Entity"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal Server Error"},"304":{"description":"Unveraendert."}}}},"/v1/vessels/{mmsi}":{"get":{"summary":"Momentaufnahme eines Schiffs","description":"Die Momentaufnahme genau eines Schiffs, in `position` und `static` geteilt und\nje mit eigenem Zeitstempel und eigener Lizenzkennung. `static` fehlt ganz,\nsolange keine Statiknachricht kam.\n\n**`404` means \"nothing heard for over an hour\", not \"MMSI unknown\".** This\nendpoint reads only the live state. Vessels that have gone silent, and vessels\nknown only from the vessel register, are found with `GET /v1/vessels/search`.\n\nDies ist der einzige Endpunkt, der auch Positionen jenseits von ±85,05112878°\nBreite liefert.\n\nPositions from sources not licensed for API delivery are never included.","operationId":"getVessel","security":[{"customerKey":[]}],"parameters":[{"name":"mmsi","in":"path","required":true,"schema":{"type":"integer","maximum":999999999,"minimum":100000000,"title":"Mmsi"}},{"name":"If-None-Match","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"If-None-Match","default":null}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Schiff"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unprocessable Entity"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal Server Error"},"304":{"description":"Unveraendert."}}}},"/v1/vessels/{mmsi}/track":{"get":{"summary":"Schiffsspur ueber die Zeit","description":"Die Positionen eines Schiffs ueber die Zeit, gerastert auf `resolution`.\n\nDie Fenster sind **auf die Uhr gerastet** (`1h` beginnt zur vollen Stunde,\nnicht bei `from`). Je Fenster kommt hoechstens ein Punkt; leere Fenster\nerzeugen keinen, und `count` zaehlt gelieferte Punkte, nicht Fenster. Ein\nSchiff ohne Meldung im Zeitraum liefert `200` mit leerer Liste, nie `404`.\n\n`from` ist Pflicht, `to` faellt ohne Angabe auf \"jetzt\". Die groesste erlaubte\nSpanne haengt an `resolution`; darueber antwortet `400 track_span_too_large`.\nLiegt `from` vor dem Beginn der Aufzeichnung, kommt\n`400 range_before_retention` mit dem Startdatum im Fehlertext.\n\n**Wie weit zurueck ohne Freischaltung?** Direkt abfragbar sind `1min` 48\nStunden, `5min` 1 Monat, `15min` 2 Monate, `1h` 5 Jahre, `6h` 10 Jahre;\n`1d` reicht unbegrenzt zurueck. Alles Aeltere kommt aus dem Archiv und\nverlangt die Faehigkeit `archive` auf dem Schluessel -- sonst antwortet\n`403 archive_not_enabled` und traegt in `request_template` eine fertige\nE-Mail, mit der sich die Freischaltung anfragen laesst. Beruehrt ein Zeitraum\nbeide Bereiche, gilt er ganz als Archivabfrage: eine Spur mischt nie zwei\nQuellen.\n\n**History depends on the plan** of the key's account\n(`constants.json` -> `billing.PLANS[].history`): Free allows the\nresolutions `1h`, `6h` and `1d` and `from` back to the start of the\nUTC day 3 days before today; Fleet the same resolutions and 7 days;\nHorizon every resolution and 30 days; Global and Enterprise every\nresolution and the full retention above. An account that existed at\nthe launch of billing keeps Legacy Free (`billing.LEGACY_PLAN`)\nuntil its `legacy_until`, on a paid plan too (the more generous of\nboth applies): every resolution and the full retention, as before.\nA `resolution` the plan\ndoes not include, or a `from` before the plan's first day, answers\n`403 history_outside_plan`. This is checked after the parameters\n(`400`, `422`) and before the archive rule.\n\nGrobe Aufloesungen werden beim Lesen aus der feinsten vorhandenen Stufe\nabgeleitet: eine `5min`-Spur von gestern entsteht aus den Minutenpunkten,\nje Fenster der Punkt, den auch die spaetere Verdichtung behaelt. Ein\nabgeschlossenes Fenster liefert dadurch spaeter denselben Punkt wie heute;\nnur ein Fenster, das bei `to` noch laeuft, kann sich bis zu seinem Ende noch\naendern.\n\nMit `If-None-Match` kostet eine unveraenderte Spur nur ein `304`.","operationId":"getVesselTrack","security":[{"customerKey":[]}],"parameters":[{"name":"mmsi","in":"path","required":true,"schema":{"type":"integer","maximum":999999999,"minimum":100000000,"title":"Mmsi"}},{"name":"from","in":"query","required":true,"schema":{"type":"string","format":"date-time","title":"From"}},{"name":"resolution","in":"query","required":true,"schema":{"type":"string","enum":["1min","5min","15min","1h","6h","1d"],"title":"Resolution"}},{"name":"to","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"format":"date-time","title":"To","default":null}},{"name":"If-None-Match","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"If-None-Match","default":null}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Spur"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ErrorResponse"},{"$ref":"#/components/schemas/ArchiveNotEnabledResponse"}],"title":"Response 403 Getvesseltrack"}}},"description":"Forbidden"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unprocessable Entity"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal Server Error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Service Unavailable"},"304":{"description":"Unveraendert."}}}},"/v1/news":{"get":{"tags":["news"],"summary":"List news articles","description":"News articles, newest first, with all fields: our own title and summary, a link\nto the original, categories, filters, the vessels named with their MMSI where\nthe match is reliable, organisations and the risk model.\n\nEvery filter takes one value; an unknown value is `422`. `min_severity` uses\nthe ranking `none` < `advisory` < `minor` < `serious` < `critical`; articles\nwithout a severity (`risk_frame` = `none`) are left out of every\n`min_severity` filter. `since` is inclusive, `until` exclusive.\n\nPages are cursor based: pass `next_cursor` unchanged as `cursor` until it is\n`null`. A cursor this API did not return is `400 invalid_cursor`. With\n`If-None-Match`, an unchanged page costs only a `304`.\n\nArticles can appear later with an older `published_at` (analysis happens\nafter fetch, with retries); poll with an overlap and de-duplicate by `id`.\n\nRequires a key with the capability `news`. While news is not yet available,\nevery call is `503 news_unavailable`.","operationId":"listNews","security":[{"customerKey":[]}],"parameters":[{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"enum":["maritime-security","casualties","sanctions","environment","regulation","freight-markets","sale-purchase","shipbuilding","companies-finance","offshore-oil-gas","offshore-wind","ports-logistics","seafarers","technology"],"type":"string"},{"type":"null"}],"description":"Articles in this category, at any position.","title":"Category","default":null},"description":"Articles in this category, at any position."},{"name":"region","in":"query","required":false,"schema":{"anyOf":[{"enum":["europe","middle-east","africa","asia","greater-china","americas","oceania","polar"],"type":"string"},{"type":"null"}],"title":"Region","default":null}},{"name":"segment","in":"query","required":false,"schema":{"anyOf":[{"enum":["crude_tanker","product_chemical_tanker","lng_carrier","lpg_ammonia_gas_carrier","bulk_carrier","container_ship","vehicle_roro","general_cargo_heavylift","passenger_cruise_ferry","offshore_vessel","offshore_unit","tug_workboat_inland","fishing_vessel","naval_government"],"type":"string"},{"type":"null"}],"title":"Segment","default":null}},{"name":"sea_area","in":"query","required":false,"schema":{"anyOf":[{"enum":["strait-of-hormuz","persian-gulf","gulf-of-oman","arabian-sea","red-sea","bab-el-mandeb","gulf-of-aden","suez-canal","mediterranean-sea","strait-of-gibraltar","black-sea","kerch-strait","turkish-straits","baltic-sea","danish-straits","north-sea","english-channel","norwegian-barents-sea","gulf-of-guinea","cape-of-good-hope","bay-of-bengal","malacca-singapore-straits","gulf-of-thailand","south-china-sea","taiwan-strait","east-china-sea","yellow-sea","sea-of-japan","timor-sea","gulf-of-mexico","caribbean-sea","panama-canal","northern-sea-route","arctic-ocean"],"type":"string"},{"type":"null"}],"title":"Sea Area","default":null}},{"name":"country","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^[A-Z]{2}$"},{"type":"null"}],"description":"A well-formed ISO 3166-1 alpha-2 code, upper case. Unlike the other filters, an unknown code is not `422` -- it simply matches nothing.","title":"Country","default":null},"description":"A well-formed ISO 3166-1 alpha-2 code, upper case. Unlike the other filters, an unknown code is not `422` -- it simply matches nothing."},{"name":"risk_frame","in":"query","required":false,"schema":{"anyOf":[{"enum":["incident","aftermath","threat","trend","none"],"type":"string"},{"type":"null"}],"title":"Risk Frame","default":null}},{"name":"event_type","in":"query","required":false,"schema":{"anyOf":[{"enum":["collision_contact","grounding","fire_explosion","flooding_sinking","technical_failure","cargo_incident","personnel_accident","derelict_abandoned_vessel","search_rescue","severe_weather","unspecified_casualty","pollution_release","attack","piracy_robbery","hijacking_kidnap","state_seizure","military_operation","smuggling","cyber_incident","gnss_interference","sanctions_measure","sanctions_designation","deceptive_practice","detention_arrest","owner_abandoned_crew","waterway_port_restriction","route_diversion","labour_action"],"type":"string"},{"type":"null"}],"title":"Event Type","default":null}},{"name":"event_group","in":"query","required":false,"schema":{"anyOf":[{"enum":["casualty","environment","security","compliance","crew","disruption"],"type":"string"},{"type":"null"}],"description":"Articles with at least one event type of this group.","title":"Event Group","default":null},"description":"Articles with at least one event type of this group."},{"name":"min_severity","in":"query","required":false,"schema":{"anyOf":[{"enum":["none","advisory","minor","serious","critical"],"type":"string"},{"type":"null"}],"title":"Min Severity","default":null}},{"name":"conflict_related","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Conflict Related","default":null}},{"name":"since","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Published at or after, ISO 8601 with time zone.","title":"Since","default":null},"description":"Published at or after, ISO 8601 with time zone."},{"name":"until","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Published before, ISO 8601 with time zone.","title":"Until","default":null},"description":"Published before, ISO 8601 with time zone."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Page size, 1 to 100 (`news.PAGE_LIMIT_MAX`).","default":50,"title":"Limit"},"description":"Page size, 1 to 100 (`news.PAGE_LIMIT_MAX`)."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"`next_cursor` of the previous page, unchanged. Omit for the first page.","title":"Cursor","default":null},"description":"`next_cursor` of the previous page, unchanged. Omit for the first page."},{"name":"If-None-Match","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"If-None-Match","default":null}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeldungenAntwort"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unprocessable Entity"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal Server Error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Service Unavailable"},"304":{"description":"Not modified."}}}},"/v1/news/{id}":{"get":{"tags":["news"],"summary":"Get one news article","description":"One news article with all fields. `404` for an unknown id and for an article\nthat has been withdrawn.\n\nRequires a key with the capability `news`.","operationId":"getNews","security":[{"customerKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","maximum":9223372036854775807,"minimum":1,"description":"Article id.","title":"Id"},"description":"Article id."},{"name":"If-None-Match","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"If-None-Match","default":null}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Meldung"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unprocessable Entity"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal Server Error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Service Unavailable"},"304":{"description":"Not modified."},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"}}}},"/v1/vessels/{mmsi}/news":{"get":{"tags":["news"],"summary":"List news articles about a vessel","description":"News articles that name this vessel, newest first -- only mentions whose MMSI\nthis API would show (see `MeldungSchiff`). An MMSI without such a mention\nreturns `200` with an empty list, never `404`.\n\nPages and cursor as in `GET /v1/news`. Requires a key with the capability\n`news`.","operationId":"listVesselNews","security":[{"customerKey":[]}],"parameters":[{"name":"mmsi","in":"path","required":true,"schema":{"type":"integer","maximum":999999999,"minimum":100000000,"title":"Mmsi"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Page size, 1 to 100 (`news.PAGE_LIMIT_MAX`).","default":50,"title":"Limit"},"description":"Page size, 1 to 100 (`news.PAGE_LIMIT_MAX`)."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"`next_cursor` of the previous page, unchanged. Omit for the first page.","title":"Cursor","default":null},"description":"`next_cursor` of the previous page, unchanged. Omit for the first page."},{"name":"If-None-Match","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"If-None-Match","default":null}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeldungenAntwort"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unprocessable Entity"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal Server Error"},"503":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Service Unavailable"},"304":{"description":"Not modified."}}}},"/v1/alert-consent":{"post":{"tags":["alerts"],"summary":"Accept the alerts notice","description":"Accept the alerts notice for your account: no delivery guarantee, not for navigation or safety, not for tracking individuals. Needed once before the first zone, alert, webhook or test message. `notice_version` must be the current version.\n\nRequires a key with the capability `alerts`. While zone alerts are not\navailable for your account, every alert operation answers `404 not_found`.","operationId":"giveAlertConsent","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertConsentRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertConsent"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too Many Requests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"customerKey":[]}]},"delete":{"tags":["alerts"],"summary":"Withdraw the alerts notice","description":"Withdraw the accepted notice. Detection and delivery stop for the whole account; zones, alerts and alert channels stay stored until you delete them.\n\nRequires a key with the capability `alerts`. While zone alerts are not\navailable for your account, every alert operation answers `404 not_found`.","operationId":"withdrawAlertConsent","responses":{"204":{"description":"Successful Response"},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too Many Requests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"customerKey":[]}]}},"/v1/alert-zones":{"get":{"tags":["alerts"],"summary":"List zones","description":"All zones of your account, portal and API alike.\n\nRequires a key with the capability `alerts`. While zone alerts are not\navailable for your account, every alert operation answers `404 not_found`.","operationId":"listAlertZones","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertZoneList"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too Many Requests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"customerKey":[]}]},"post":{"tags":["alerts"],"summary":"Create a zone","description":"A new zone. It counts against the zone limit of your developer plan (Free: 3; `409 alert_zone_limit_reached`); zones created in the portal count against your map plan instead. Vessels already inside are not reported. Needs the accepted alerts notice (`403 alerts_terms_not_accepted`).\n\nRequires a key with the capability `alerts`. While zone alerts are not\navailable for your account, every alert operation answers `404 not_found`.","operationId":"createAlertZone","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertZoneCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertZone"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too Many Requests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"customerKey":[]}]}},"/v1/alert-zones/{zone_id}":{"get":{"tags":["alerts"],"summary":"Get a zone","description":"One of your zones. `404` for an unknown id or a zone of another account.\n\nRequires a key with the capability `alerts`. While zone alerts are not\navailable for your account, every alert operation answers `404 not_found`.","operationId":"getAlertZone","security":[{"customerKey":[]}],"parameters":[{"name":"zone_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","description":"`zone_id` of one of your zones.","title":"Zone Id"},"description":"`zone_id` of one of your zones."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertZone"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unprocessable Entity"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal Server Error"}}},"patch":{"tags":["alerts"],"summary":"Update a zone","description":"JSON merge patch (RFC 7396) of `name`, `geometry` and `active`. A new geometry increases `version`; vessels inside the new area are not reported.\n\nRequires a key with the capability `alerts`. While zone alerts are not\navailable for your account, every alert operation answers `404 not_found`.","operationId":"updateAlertZone","security":[{"customerKey":[]}],"parameters":[{"name":"zone_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","description":"`zone_id` of one of your zones.","title":"Zone Id"},"description":"`zone_id` of one of your zones."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertZoneUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertZone"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unprocessable Entity"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal Server Error"}}},"delete":{"tags":["alerts"],"summary":"Delete a zone","description":"Deletes the zone with its alerts and its event log.\n\nRequires a key with the capability `alerts`. While zone alerts are not\navailable for your account, every alert operation answers `404 not_found`.","operationId":"deleteAlertZone","security":[{"customerKey":[]}],"parameters":[{"name":"zone_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","description":"`zone_id` of one of your zones.","title":"Zone Id"},"description":"`zone_id` of one of your zones."}],"responses":{"204":{"description":"Successful Response"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unprocessable Entity"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal Server Error"}}}},"/v1/alert-zones/{zone_id}/alerts":{"get":{"tags":["alerts"],"summary":"List the alerts of a zone","description":"All alerts of one of your zones.\n\nRequires a key with the capability `alerts`. While zone alerts are not\navailable for your account, every alert operation answers `404 not_found`.","operationId":"listAlerts","security":[{"customerKey":[]}],"parameters":[{"name":"zone_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","description":"`zone_id` of one of your zones.","title":"Zone Id"},"description":"`zone_id` of one of your zones."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertList"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unprocessable Entity"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal Server Error"}}},"post":{"tags":["alerts"],"summary":"Create an alert","description":"A new alert of one of your zones. At most 5 alerts per zone (`409 alert_limit_reached`) and 50 MMSI and IMO numbers per zone over all its alerts (`409 alert_identifier_limit_reached`); write to hello@pelyr.com for more. Needs the accepted alerts notice.\n\nRequires a key with the capability `alerts`. While zone alerts are not\navailable for your account, every alert operation answers `404 not_found`.","operationId":"createAlert","security":[{"customerKey":[]}],"parameters":[{"name":"zone_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","description":"`zone_id` of one of your zones.","title":"Zone Id"},"description":"`zone_id` of one of your zones."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Alert"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Conflict"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unprocessable Entity"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal Server Error"}}}},"/v1/alert-zones/{zone_id}/alerts/{alert_id}":{"get":{"tags":["alerts"],"summary":"Get an alert","description":"One alert of one of your zones.\n\nRequires a key with the capability `alerts`. While zone alerts are not\navailable for your account, every alert operation answers `404 not_found`.","operationId":"getAlert","security":[{"customerKey":[]}],"parameters":[{"name":"zone_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","description":"`zone_id` of one of your zones.","title":"Zone Id"},"description":"`zone_id` of one of your zones."},{"name":"alert_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","description":"`alert_id` of one of the zone's alerts.","title":"Alert Id"},"description":"`alert_id` of one of the zone's alerts."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Alert"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unprocessable Entity"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal Server Error"}}},"patch":{"tags":["alerts"],"summary":"Update an alert","description":"JSON merge patch (RFC 7396). `triggers`, `criteria`, `limits` and `channel_ids` replace the whole value; new `criteria` count against the MMSI and IMO limit of the zone again (`409 alert_identifier_limit_reached`).\n\nRequires a key with the capability `alerts`. While zone alerts are not\navailable for your account, every alert operation answers `404 not_found`.","operationId":"updateAlert","security":[{"customerKey":[]}],"parameters":[{"name":"zone_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","description":"`zone_id` of one of your zones.","title":"Zone Id"},"description":"`zone_id` of one of your zones."},{"name":"alert_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","description":"`alert_id` of one of the zone's alerts.","title":"Alert Id"},"description":"`alert_id` of one of the zone's alerts."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Alert"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Conflict"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unprocessable Entity"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal Server Error"}}},"delete":{"tags":["alerts"],"summary":"Delete an alert","description":"Deletes the alert. Its matches leave the event log with it.\n\nRequires a key with the capability `alerts`. While zone alerts are not\navailable for your account, every alert operation answers `404 not_found`.","operationId":"deleteAlert","security":[{"customerKey":[]}],"parameters":[{"name":"zone_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","description":"`zone_id` of one of your zones.","title":"Zone Id"},"description":"`zone_id` of one of your zones."},{"name":"alert_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","description":"`alert_id` of one of the zone's alerts.","title":"Alert Id"},"description":"`alert_id` of one of the zone's alerts."}],"responses":{"204":{"description":"Successful Response"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unprocessable Entity"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal Server Error"}}}},"/v1/alert-channels":{"get":{"tags":["alerts"],"summary":"List alert channels","description":"Webhooks and Telegram chats of your account. Webhook URLs are masked; Telegram chats show their title only.\n\nRequires a key with the capability `alerts`. While zone alerts are not\navailable for your account, every alert operation answers `404 not_found`.","operationId":"listAlertChannels","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertChannelList"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too Many Requests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"customerKey":[]}]},"post":{"tags":["alerts"],"summary":"Add a webhook to the alert channels","description":"Adds a webhook. The URL must use `https` on port 443, name a host (no IP literal, no user info) and resolve to public addresses only (`422 alert_channel_url_rejected`). A `generic` webhook gets a signing secret, shown in this answer only. At most 3 alert channels per account (`409 alert_channel_limit_reached`) and 10 new ones per UTC day (`409 alert_daily_limit_reached`). Telegram chats are linked in the portal. Needs the accepted alerts notice.\n\nRequires a key with the capability `alerts`. While zone alerts are not\navailable for your account, every alert operation answers `404 not_found`.","operationId":"createAlertChannel","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertChannelCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertChannelWithSecret"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Unprocessable Entity","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too Many Requests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"customerKey":[]}]}},"/v1/alert-channels/{channel_id}":{"get":{"tags":["alerts"],"summary":"Get one of the alert channels","description":"One webhook or Telegram chat of your account.\n\nRequires a key with the capability `alerts`. While zone alerts are not\navailable for your account, every alert operation answers `404 not_found`.","operationId":"getAlertChannel","security":[{"customerKey":[]}],"parameters":[{"name":"channel_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","description":"`channel_id` of one of your alert channels.","title":"Channel Id"},"description":"`channel_id` of one of your alert channels."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertChannel"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unprocessable Entity"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal Server Error"}}},"patch":{"tags":["alerts"],"summary":"Update one of the alert channels","description":"JSON merge patch (RFC 7396) of `name`, `webhook_url`, `webhook_format` and `state`. `state: active` re-enables and resets the failure count. A changed URL is checked again. Switching to `generic` creates a signing secret, shown in this answer only; switching away from it deletes the secret.\n\nRequires a key with the capability `alerts`. While zone alerts are not\navailable for your account, every alert operation answers `404 not_found`.","operationId":"updateAlertChannel","security":[{"customerKey":[]}],"parameters":[{"name":"channel_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","description":"`channel_id` of one of your alert channels.","title":"Channel Id"},"description":"`channel_id` of one of your alert channels."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertChannelUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertChannelWithSecret"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unprocessable Entity"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal Server Error"}}},"delete":{"tags":["alerts"],"summary":"Delete one of the alert channels","description":"Deletes the webhook or Telegram chat and removes it from every alert.\n\nRequires a key with the capability `alerts`. While zone alerts are not\navailable for your account, every alert operation answers `404 not_found`.","operationId":"deleteAlertChannel","security":[{"customerKey":[]}],"parameters":[{"name":"channel_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","description":"`channel_id` of one of your alert channels.","title":"Channel Id"},"description":"`channel_id` of one of your alert channels."}],"responses":{"204":{"description":"Successful Response"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unprocessable Entity"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal Server Error"}}}},"/v1/alert-channels/{channel_id}/test":{"post":{"tags":["alerts"],"summary":"Send a test message","description":"Queues a test message to one of your alert channels. The answer is `202` with the `delivery_id`; the result appears in `GET /v1/alert-events`. At most 20 test messages per account and UTC day (`409 alert_daily_limit_reached`). Needs the accepted alerts notice.\n\nRequires a key with the capability `alerts`. While zone alerts are not\navailable for your account, every alert operation answers `404 not_found`.","operationId":"sendAlertChannelTest","security":[{"customerKey":[]}],"parameters":[{"name":"channel_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","description":"`channel_id` of one of your alert channels.","title":"Channel Id"},"description":"`channel_id` of one of your alert channels."}],"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertTestQueued"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Conflict"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unprocessable Entity"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal Server Error"}}}},"/v1/alert-channels/{channel_id}/rotate-secret":{"post":{"tags":["alerts"],"summary":"Rotate the signing secret of a webhook","description":"Replaces the signing secret of a `generic` webhook at once, without overlap. The new secret is shown in this answer only. `409 conflict` for Slack, Discord and Teams webhooks and Telegram chats, which have no secret.\n\nRequires a key with the capability `alerts`. While zone alerts are not\navailable for your account, every alert operation answers `404 not_found`.","operationId":"rotateAlertChannelSecret","security":[{"customerKey":[]}],"parameters":[{"name":"channel_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","description":"`channel_id` of one of your alert channels.","title":"Channel Id"},"description":"`channel_id` of one of your alert channels."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertChannelSecret"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Conflict"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unprocessable Entity"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal Server Error"}}}},"/v1/alert-events":{"get":{"tags":["alerts"],"summary":"List the event log","description":"Zone events of your account, newest first, each with the decisions of the zone's alerts (`matches`) and the messages sent for it (`deliveries`). Pages are cursor based: pass `next_cursor` unchanged as `cursor` until it is `null`; a cursor this API did not return is `400 invalid_cursor`. Filters with ids of other accounts match nothing. The log keeps 30 days.\n\nRequires a key with the capability `alerts`. While zone alerts are not\navailable for your account, every alert operation answers `404 not_found`.","operationId":"listAlertEvents","security":[{"customerKey":[]}],"parameters":[{"name":"zone_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Zone Id","default":null}},{"name":"alert_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Alert Id","default":null}},{"name":"channel_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Channel Id","default":null}},{"name":"kind","in":"query","required":false,"schema":{"anyOf":[{"enum":["zone_entered","zone_exited","zone_dwell_exceeded","zone_signal_lost","zone_status_changed"],"type":"string"},{"type":"null"}],"title":"Kind","default":null}},{"name":"mmsi","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":999999999,"minimum":100000000},{"type":"null"}],"title":"Mmsi","default":null}},{"name":"since","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"Events that occurred at or after, ISO 8601 with time zone.","title":"Since","default":null},"description":"Events that occurred at or after, ISO 8601 with time zone."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"`next_cursor` of the previous page, unchanged. Omit for the first page.","title":"Cursor","default":null},"description":"`next_cursor` of the previous page, unchanged. Omit for the first page."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"description":"Page size, 1 to 200.","default":50,"title":"Limit"},"description":"Page size, 1 to 200."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AlertEventLog"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unprocessable Entity"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal Server Error"}}}},"/v1/detection/areas":{"get":{"tags":["detection"],"summary":"List the vessel detection areas","description":"Every vessel detection area this API serves, by `name`. An area is one GeoJSON\nPolygon (WGS84, `[lon, lat]`); `south`, `west`, `north` and `east` are the\nbounds of its outer ring. `latest_sensed_at` is the acquisition time of the\nnewest listed overflight, `null` before the first. An area whose polygon is\ninvalid is left out. Areas are entered by the operator; this API cannot change\nthem.\n\nNo image is served in v1: the answers carry what was found in the image, not the\nimage.\n\nVessel detection depends on the plan of the key's account: Free does not include it\nand answers `403 detection_not_in_plan`, with a link to the pricing page in the\nmessage; Fleet, Horizon, Global and Enterprise include it, and so do Legacy Free and\nCommunity access. This is checked after the capability `https` and before the rate\nbudget, so a refused request spends none of it.\n\nRequires a key with the capability `https`. The four detection operations share\nthe rate budget with `GET /v1/vessels`, `GET /v1/vessels/{mmsi}`,\n`GET /v1/vessels/at` and `GET /v1/vessels/search`.","operationId":"listDetectionAreas","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetectionAreasResponse"}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Too Many Requests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"customerKey":[]}]}},"/v1/detection/areas/{area_id}/overflights":{"get":{"tags":["detection"],"summary":"List the overflights of a detection area","description":"The overflights of one area, newest first, at most 500: `processed` (an image\nsearched for vessels) and `cloudy` (too cloudy to search; no detections). Each\ncarries the facts of the pass, the AIS coverage at the acquisition, the counts\n`vessel_count`, `dark_count` and `sts_count`, and `has_sts`.\n\nDetections and pairs that reviewers marked as false alarms are left out, and no\nreview status is ever included.\n\n`sts_detection_limited` qualifies what an image says about STS pairs. True when\nsun glint or haze on this image makes STS pair detection unreliable, so an image\nwithout an STS pair is no evidence that no STS took place; detections are\nunaffected. Null when the image was not measured.\n\nNo image is served in v1: the answers carry what was found in the image, not the\nimage.\n\n`404 not_found` for an area this API does not serve.\n\nVessel detection depends on the plan of the key's account: Free does not include it\nand answers `403 detection_not_in_plan`, with a link to the pricing page in the\nmessage; Fleet, Horizon, Global and Enterprise include it, and so do Legacy Free and\nCommunity access. This is checked after the capability `https` and before the rate\nbudget, so a refused request spends none of it.\n\nRequires a key with the capability `https`. The four detection operations share\nthe rate budget with `GET /v1/vessels`, `GET /v1/vessels/{mmsi}`,\n`GET /v1/vessels/at` and `GET /v1/vessels/search`.","operationId":"listDetectionOverflights","security":[{"customerKey":[]}],"parameters":[{"name":"area_id","in":"path","required":true,"schema":{"type":"integer","maximum":2147483647,"minimum":1,"title":"Area Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetectionOverflightsResponse"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unprocessable Entity"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal Server Error"}}}},"/v1/detection/overflights/{overflight_id}":{"get":{"tags":["detection"],"summary":"Get one overflight's detections and STS pairs","description":"One overflight with everything found on it: `overflight` as in\n`listDetectionOverflights`, `detections` by `id`, each with its stored AIS\nvessels and the `pair_id` of its STS pair, and `pairs` by `id`, each with its\n`state` and seven reasons.\n\nThe `ais_state` of a detection is `matched`, `dark`, `no_match_possible` or\n`no_ais_expected`. `dark`: no AIS was received from a detected vessel of this size\nalthough the coverage was measured good; it does not say why. `no_match_possible`:\nno AIS match, and dark could not be decided: the coverage at the detection was not\nmeasured good, or no length was predicted. `no_ais_expected` (a small vessel,\npredicted shorter than 50 m) is never dark.\n\nAn STS pair is published as `preliminary` and re-scored once, when AIS from after\nthe acquisition has arrived; after that it is `final`.\n\nAIS facts in this answer can come from sources whose positions this API delivers\nnowhere else; each fact carries its license, and offset_seconds is the fix time\nminus the acquisition time, negative for a fix from before it.\n\nDetections and pairs that reviewers marked as false alarms are left out, and no\nreview status is ever included.\n\n`sts_detection_limited` qualifies what an image says about STS pairs. True when\nsun glint or haze on this image makes STS pair detection unreliable, so an image\nwithout an STS pair is no evidence that no STS took place; detections are\nunaffected. Null when the image was not measured.\n\nNo image is served in v1: the answers carry what was found in the image, not the\nimage.\n\n`404 not_found` for an unknown overflight, a pass that is not listed and an\noverflight of an area this API does not serve.\n\nVessel detection depends on the plan of the key's account: Free does not include it\nand answers `403 detection_not_in_plan`, with a link to the pricing page in the\nmessage; Fleet, Horizon, Global and Enterprise include it, and so do Legacy Free and\nCommunity access. This is checked after the capability `https` and before the rate\nbudget, so a refused request spends none of it.\n\nRequires a key with the capability `https`. The four detection operations share\nthe rate budget with `GET /v1/vessels`, `GET /v1/vessels/{mmsi}`,\n`GET /v1/vessels/at` and `GET /v1/vessels/search`.","operationId":"getDetectionOverflight","security":[{"customerKey":[]}],"parameters":[{"name":"overflight_id","in":"path","required":true,"schema":{"type":"integer","maximum":9223372036854775807,"minimum":1,"title":"Overflight Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetectionOverflightResult"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unprocessable Entity"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal Server Error"}}}},"/v1/detection/finds":{"get":{"tags":["detection"],"summary":"List the STS finds","description":"Every STS pair this API serves, across all areas, as a find: newest overflight\nfirst, then by `pair_id`, descending. Each find carries its overflight and\narea, the position of its detection, the pair's `state` and seven reasons,\nand its AIS partners by partner position. An STS pair is published as `preliminary` and re-scored once, when AIS from after\nthe acquisition has arrived; after that it is `final`.\n\nFilters: `area_id`; `from` (inclusive) and `to` (exclusive) on the acquisition\ntime, ISO 8601 UTC with a `Z` (`400 invalid_time_range` when malformed or when\n`from` is not before `to`); `dark_only` (a dark vessel\nneeds AIS coverage measured good). Page with `cursor` = `next_cursor` of the\nprevious page until it is `null`; a cursor this API did not issue answers\n`400 invalid_cursor`. Finds of one overflight share their acquisition time; the\ncursor neither repeats nor skips them.\n\nAIS facts in this answer can come from sources whose positions this API delivers\nnowhere else; each fact carries its license, and offset_seconds is the fix time\nminus the acquisition time, negative for a fix from before it.\n\nDetections and pairs that reviewers marked as false alarms are left out, and no\nreview status is ever included.\n\n`404 not_found` for an `area_id` this API does not serve.\n\nVessel detection depends on the plan of the key's account: Free does not include it\nand answers `403 detection_not_in_plan`, with a link to the pricing page in the\nmessage; Fleet, Horizon, Global and Enterprise include it, and so do Legacy Free and\nCommunity access. This is checked after the capability `https` and before the rate\nbudget, so a refused request spends none of it.\n\nRequires a key with the capability `https`. The four detection operations share\nthe rate budget with `GET /v1/vessels`, `GET /v1/vessels/{mmsi}`,\n`GET /v1/vessels/at` and `GET /v1/vessels/search`.","operationId":"listDetectionFinds","security":[{"customerKey":[]}],"parameters":[{"name":"area_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":2147483647,"minimum":1},{"type":"null"}],"description":"Only the finds of this area.","title":"Area Id","default":null},"description":"Only the finds of this area."},{"name":"from","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Acquired at or after, ISO 8601 UTC with a `Z`.","title":"From","default":null},"description":"Acquired at or after, ISO 8601 UTC with a `Z`."},{"name":"to","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Acquired before, ISO 8601 UTC with a `Z`; after `from`.","title":"To","default":null},"description":"Acquired before, ISO 8601 UTC with a `Z`; after `from`."},{"name":"dark_only","in":"query","required":false,"schema":{"type":"boolean","description":"Only finds with a dark vessel.","default":false,"title":"Dark Only"},"description":"Only finds with a dark vessel."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"`next_cursor` of the previous page, unchanged. Omit for the first page.","title":"Cursor","default":null},"description":"`next_cursor` of the previous page, unchanged. Omit for the first page."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"description":"Page size, 1 to 200.","default":50,"title":"Limit"},"description":"Page size, 1 to 200."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DetectionFindsResponse"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unprocessable Entity"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Too Many Requests"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Internal Server Error"}}}}},"components":{"schemas":{"Alert":{"properties":{"alert_id":{"type":"string","format":"uuid","title":"Alert Id"},"zone_id":{"type":"string","format":"uuid","title":"Zone Id"},"name":{"type":"string","title":"Name"},"active":{"type":"boolean","title":"Active"},"triggers":{"$ref":"#/components/schemas/AlertTriggers"},"criteria":{"$ref":"#/components/schemas/AlertCriteria"},"limits":{"$ref":"#/components/schemas/AlertLimits"},"channel_ids":{"items":{"type":"string","format":"uuid"},"type":"array","title":"Channel Ids"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["alert_id","zone_id","name","active","triggers","criteria","limits","channel_ids","created_at","updated_at"],"title":"Alert","description":"An alert of a zone."},"AlertChannel":{"properties":{"channel_id":{"type":"string","format":"uuid","title":"Channel Id"},"kind":{"type":"string","enum":["webhook","telegram"],"title":"Kind"},"name":{"type":"string","title":"Name"},"webhook_url_masked":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Webhook Url Masked","description":"Scheme and host of the webhook URL, the path replaced by `…`. `null` for Telegram."},"webhook_format":{"anyOf":[{"type":"string","enum":["generic","slack","discord","teams"]},{"type":"null"}],"title":"Webhook Format"},"telegram_chat_title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Telegram Chat Title","description":"`null` for webhooks."},"state":{"type":"string","enum":["active","disabled"],"title":"State"},"disabled_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Disabled Reason","description":"Why the channel is `disabled`, `null` while it is `active`: `consecutive_failures` after 20 failed delivery attempts in a row, `http_410` at once when a webhook answers 410, `telegram_stop` when the chat sends /stop, `telegram_blocked` when the bot is blocked or removed from the chat. Switch the channel on again to resume delivery."},"consecutive_failures":{"type":"integer","title":"Consecutive Failures"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["channel_id","kind","name","webhook_url_masked","webhook_format","telegram_chat_title","state","disabled_reason","consecutive_failures","created_at","updated_at"],"title":"AlertChannel","description":"One of the account's alert channels: a webhook or a Telegram chat."},"AlertChannelCreate":{"properties":{"name":{"type":"string","maxLength":80,"minLength":1,"title":"Name","description":"1 to 80 characters, no control or bidi characters."},"webhook_url":{"type":"string","maxLength":2048,"minLength":1,"title":"Webhook Url","description":"`https` URL on port 443, without user info and with a host name (no IP literal). The name must resolve to public addresses only."},"webhook_format":{"type":"string","enum":["generic","slack","discord","teams"],"title":"Webhook Format","description":"`generic` sends the signed JSON payload; `slack`, `discord` and `teams` use each service's incoming-webhook format and carry no secret."}},"additionalProperties":false,"type":"object","required":["name","webhook_url","webhook_format"],"title":"AlertChannelCreate","description":"A new webhook. Telegram chats are linked in the portal only."},"AlertChannelList":{"properties":{"channels":{"items":{"$ref":"#/components/schemas/AlertChannel"},"type":"array","title":"Channels"}},"type":"object","required":["channels"],"title":"AlertChannelList","description":"All alert channels of the account, oldest first."},"AlertChannelSecret":{"properties":{"channel_id":{"type":"string","format":"uuid","title":"Channel Id"},"secret":{"type":"string","title":"Secret"}},"type":"object","required":["channel_id","secret"],"title":"AlertChannelSecret","description":"The new signing secret. The old one stops working at once. Shown once."},"AlertChannelUpdate":{"properties":{"name":{"type":"string","maxLength":80,"minLength":1,"title":"Name","description":"1 to 80 characters, no control or bidi characters."},"webhook_url":{"type":"string","maxLength":2048,"minLength":1,"title":"Webhook Url","description":"`https` URL on port 443, without user info and with a host name (no IP literal). The name must resolve to public addresses only."},"webhook_format":{"type":"string","enum":["generic","slack","discord","teams"],"title":"Webhook Format"},"state":{"type":"string","const":"active","title":"State"}},"additionalProperties":false,"type":"object","title":"AlertChannelUpdate","description":"JSON merge patch of one of the alert channels. Absent members stay\nunchanged; none can be `null`. `webhook_url` and `webhook_format` apply\nto webhooks only, and a changed URL is checked again. `state: active`\nre-enables a disabled webhook or Telegram chat and resets its failure\ncount. Switching a webhook to `generic` creates a secret, returned once;\nswitching away from `generic` deletes it."},"AlertChannelWithSecret":{"properties":{"channel_id":{"type":"string","format":"uuid","title":"Channel Id"},"kind":{"type":"string","enum":["webhook","telegram"],"title":"Kind"},"name":{"type":"string","title":"Name"},"webhook_url_masked":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Webhook Url Masked","description":"Scheme and host of the webhook URL, the path replaced by `…`. `null` for Telegram."},"webhook_format":{"anyOf":[{"type":"string","enum":["generic","slack","discord","teams"]},{"type":"null"}],"title":"Webhook Format"},"telegram_chat_title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Telegram Chat Title","description":"`null` for webhooks."},"state":{"type":"string","enum":["active","disabled"],"title":"State"},"disabled_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Disabled Reason","description":"Why the channel is `disabled`, `null` while it is `active`: `consecutive_failures` after 20 failed delivery attempts in a row, `http_410` at once when a webhook answers 410, `telegram_stop` when the chat sends /stop, `telegram_blocked` when the bot is blocked or removed from the chat. Switch the channel on again to resume delivery."},"consecutive_failures":{"type":"integer","title":"Consecutive Failures"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"secret":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Secret","description":"`whsec_…`, only in the answer that created it, else `null`."}},"type":"object","required":["channel_id","kind","name","webhook_url_masked","webhook_format","telegram_chat_title","state","disabled_reason","consecutive_failures","created_at","updated_at","secret"],"title":"AlertChannelWithSecret","description":"As `AlertChannel`, plus the signing secret of a `generic` webhook in the\nanswer that created it. Shown once: store it now."},"AlertConsent":{"properties":{"notice_version":{"type":"string","title":"Notice Version"},"accepted_at":{"type":"string","format":"date-time","title":"Accepted At"}},"type":"object","required":["notice_version","accepted_at"],"title":"AlertConsent","description":"The accepted alerts notice of the account."},"AlertConsentRequest":{"properties":{"notice_version":{"type":"string","title":"Notice Version","description":"Version of the notice you accept. Currently `1` (`alerts.NOTICE_VERSION`); any other value is `422`."}},"additionalProperties":false,"type":"object","required":["notice_version"],"title":"AlertConsentRequest","description":"Accept the alerts notice: no delivery guarantee, not for navigation or\nsafety, not for tracking individuals."},"AlertCreate":{"properties":{"name":{"type":"string","maxLength":80,"minLength":1,"title":"Name","description":"1 to 80 characters, no control or bidi characters."},"active":{"type":"boolean","title":"Active","default":true},"triggers":{"$ref":"#/components/schemas/AlertTriggers"},"criteria":{"$ref":"#/components/schemas/AlertCriteria"},"limits":{"$ref":"#/components/schemas/AlertLimits"},"channel_ids":{"items":{"type":"string","format":"uuid"},"type":"array","title":"Channel Ids","description":"Alert channels that receive the messages; each must belong to the account (`422` otherwise)."}},"additionalProperties":false,"type":"object","required":["name","triggers"],"title":"AlertCreate","description":"A new alert of a zone."},"AlertCriteria":{"properties":{"categories":{"items":{"type":"string"},"type":"array","title":"Categories","description":"Keys of `vessel_categories`."},"subtypes":{"items":{"type":"string"},"type":"array","title":"Subtypes","description":"Keys of `vessel_subtypes`."},"mmsi":{"items":{"type":"integer","maximum":999999999.0,"minimum":100000000.0},"type":"array","title":"Mmsi","description":"MMSI and IMO numbers of all alerts of a zone count together against 50 (`alerts.IDENTIFIERS_PER_ZONE`)."},"imo":{"items":{"type":"integer","maximum":9999999.0,"minimum":1000000.0},"type":"array","title":"Imo"},"destination":{"items":{"type":"string","maxLength":20,"minLength":1},"type":"array","maxItems":10,"title":"Destination","description":"Case-insensitive substrings of the destination, at most 10."}},"additionalProperties":false,"type":"object","title":"AlertCriteria","description":"Which vessels the alert reports. All given criteria must hold; an empty\nlist means \"all\". A criterion fails when the vessel's value is unknown."},"AlertDelivery":{"properties":{"delivery_id":{"type":"string","format":"uuid","title":"Delivery Id"},"channel_id":{"type":"string","format":"uuid","title":"Channel Id"},"alert_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Alert Id"},"kind":{"type":"string","title":"Kind","description":"`event`, `digest`, `quiet_summary`, `fold` or `test`."},"status":{"type":"string","title":"Status","description":"`held`, `pending`, `retrying`, `delivered`, `failed` or `dropped`."},"attempts":{"type":"integer","title":"Attempts"},"error_class":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Class"},"http_status":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Http Status"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"delivered_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Delivered At"}},"type":"object","required":["delivery_id","channel_id","alert_id","kind","status","attempts","error_class","http_status","created_at","delivered_at"],"title":"AlertDelivery","description":"One message to one of the alert channels and its status."},"AlertEvent":{"properties":{"event_id":{"type":"integer","title":"Event Id"},"zone_id":{"type":"string","format":"uuid","title":"Zone Id"},"zone_name":{"type":"string","title":"Zone Name"},"kind":{"type":"string","enum":["zone_entered","zone_exited","zone_dwell_exceeded","zone_signal_lost","zone_status_changed"],"title":"Kind"},"mmsi":{"type":"integer","title":"Mmsi"},"occurred_at":{"type":"string","format":"date-time","title":"Occurred At"},"detail":{"type":"object","title":"Detail"},"vessel":{"$ref":"#/components/schemas/AlertVesselSnapshot"},"license":{"type":"string","title":"License","description":"Licence id of the position, as in `GET /v1/sources`."},"attribution":{"type":"string","title":"Attribution","description":"Attribution text of that licence; empty when none is required."},"matches":{"items":{"$ref":"#/components/schemas/AlertMatch"},"type":"array","title":"Matches"},"deliveries":{"items":{"$ref":"#/components/schemas/AlertDelivery"},"type":"array","title":"Deliveries"}},"type":"object","required":["event_id","zone_id","zone_name","kind","mmsi","occurred_at","detail","vessel","license","attribution","matches","deliveries"],"title":"AlertEvent","description":"One zone event with its matches and deliveries."},"AlertEventLog":{"properties":{"generated_at":{"type":"string","format":"date-time","title":"Generated At"},"count":{"type":"integer","title":"Count"},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"events":{"items":{"$ref":"#/components/schemas/AlertEvent"},"type":"array","title":"Events"},"test_deliveries":{"items":{"$ref":"#/components/schemas/AlertDelivery"},"type":"array","title":"Test Deliveries","description":"The latest test messages (at most 20), on the first page only and only without the filters `zone_id`, `alert_id`, `kind` and `mmsi`; with `since`, only the newer ones."}},"type":"object","required":["generated_at","count","next_cursor","events","test_deliveries"],"title":"AlertEventLog","description":"A page of the account's event log, newest first."},"AlertLimits":{"properties":{"cooldown_min":{"type":"integer","maximum":1440.0,"minimum":0.0,"title":"Cooldown Min","description":"Minutes after a message before the same vessel and event are reported again.","default":30},"quiet_hours":{"anyOf":[{"$ref":"#/components/schemas/AlertQuietHours"},{"type":"null"}],"default":null},"mode":{"type":"string","enum":["instant","digest_hourly","digest_daily"],"title":"Mode","default":"instant"},"digest_daily_at":{"type":"string","pattern":"^([01][0-9]|2[0-3]):[0-5][0-9]$","title":"Digest Daily At","description":"Time of the daily digest in the quiet-hours time zone, else UTC.","default":"07:00"}},"additionalProperties":false,"type":"object","title":"AlertLimits","description":"How often the alert sends."},"AlertList":{"properties":{"alerts":{"items":{"$ref":"#/components/schemas/Alert"},"type":"array","title":"Alerts"}},"type":"object","required":["alerts"],"title":"AlertList","description":"All alerts of a zone, oldest first."},"AlertMatch":{"properties":{"alert_id":{"type":"string","format":"uuid","title":"Alert Id"},"alert_name":{"type":"string","title":"Alert Name"},"outcome":{"type":"string","title":"Outcome","description":"`no_match`, `cooldown`, `held_quiet_hours`, `digested` or `queued`."},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"type":"object","required":["alert_id","alert_name","outcome","reason"],"title":"AlertMatch","description":"How one alert of the zone decided about the event."},"AlertQuietHours":{"properties":{"start":{"type":"string","pattern":"^([01][0-9]|2[0-3]):[0-5][0-9]$","title":"Start"},"end":{"type":"string","pattern":"^([01][0-9]|2[0-3]):[0-5][0-9]$","title":"End"},"tz":{"type":"string","title":"Tz","description":"IANA time zone, for example `Europe/Berlin`."}},"additionalProperties":false,"type":"object","required":["start","end","tz"],"title":"AlertQuietHours","description":"No messages inside this daily window; what happened is sent as one\nsummary when it ends. `start` after `end` spans midnight."},"AlertStageTrigger":{"properties":{"stage_min":{"type":"integer","title":"Stage Min","description":"Stage in minutes. `dwell`: one of 15, 30, 60, 120, 360, 720, 1440 (`alerts.DWELL_STAGES_MIN`); `signal_lost`: one of 15, 30, 60, 120, 360 (`alerts.SILENCE_STAGES_MIN`)."}},"additionalProperties":false,"type":"object","required":["stage_min"],"title":"AlertStageTrigger","description":"Report when a stage is reached."},"AlertStatusTrigger":{"properties":{"fields":{"items":{"type":"string","enum":["nav_status","destination"]},"type":"array","minItems":1,"title":"Fields"}},"additionalProperties":false,"type":"object","required":["fields"],"title":"AlertStatusTrigger","description":"Report changes of these fields from one known value to another."},"AlertTestQueued":{"properties":{"delivery_id":{"type":"string","format":"uuid","title":"Delivery Id"}},"type":"object","required":["delivery_id"],"title":"AlertTestQueued","description":"The test message is queued; its result appears in `GET /v1/alert-events`."},"AlertTriggers":{"properties":{"entered":{"type":"boolean","title":"Entered","default":false},"exited":{"type":"boolean","title":"Exited","default":false},"dwell":{"anyOf":[{"$ref":"#/components/schemas/AlertStageTrigger"},{"type":"null"}],"default":null},"signal_lost":{"anyOf":[{"$ref":"#/components/schemas/AlertStageTrigger"},{"type":"null"}],"default":null},"status_changed":{"anyOf":[{"$ref":"#/components/schemas/AlertStatusTrigger"},{"type":"null"}],"default":null}},"additionalProperties":false,"type":"object","title":"AlertTriggers","description":"What the alert reports. At least one trigger."},"AlertUpdate":{"properties":{"name":{"type":"string","maxLength":80,"minLength":1,"title":"Name","description":"1 to 80 characters, no control or bidi characters."},"active":{"type":"boolean","title":"Active"},"triggers":{"$ref":"#/components/schemas/AlertTriggers","title":"Triggers"},"criteria":{"anyOf":[{"$ref":"#/components/schemas/AlertCriteria"},{"type":"null"}],"default":null},"limits":{"anyOf":[{"$ref":"#/components/schemas/AlertLimits"},{"type":"null"}],"default":null},"channel_ids":{"items":{"type":"string","format":"uuid"},"type":"array","title":"Channel Ids"}},"additionalProperties":false,"type":"object","title":"AlertUpdate","description":"JSON merge patch of an alert. Absent members stay unchanged. `triggers`,\n`criteria`, `limits` and `channel_ids` replace the whole value;\n`criteria: null` and `limits: null` restore the defaults. Changes apply to\nevents not yet matched."},"AlertVesselSnapshot":{"properties":{"mmsi":{"type":"integer","title":"Mmsi"},"imo":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Imo","default":null},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name","default":null},"ship_type":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ship Type","default":null},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category","default":null},"subtype":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subtype","default":null},"destination":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Destination","default":null},"nav_status":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Nav Status","default":null},"lat":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lat","default":null},"lon":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lon","default":null},"sog":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Sog","default":null},"cog":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Cog","default":null},"fix_ts":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fix Ts","description":"Time of the fix, ISO 8601 UTC.","default":null}},"type":"object","required":["mmsi"],"title":"AlertVesselSnapshot","description":"The vessel at the time of the event. Unknown values are `null`."},"AlertZone":{"properties":{"zone_id":{"type":"string","format":"uuid","title":"Zone Id"},"name":{"type":"string","title":"Name"},"geometry":{"$ref":"#/components/schemas/AlertZonePolygon"},"active":{"type":"boolean","title":"Active","description":"Inactive zones produce no events."},"version":{"type":"integer","title":"Version","description":"Increases with every change of `geometry`."},"plan_line":{"type":"string","enum":["developer","map"],"title":"Plan Line","description":"The plan the zone counts against, fixed at creation: `developer` for a zone created through the API or MCP (your developer plan), `map` for one created in the portal (your map plan). Commercial use of its alerts follows the same plan."},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["zone_id","name","geometry","active","version","plan_line","created_at","updated_at"],"title":"AlertZone","description":"A zone of the account."},"AlertZoneCreate":{"properties":{"name":{"type":"string","maxLength":80,"minLength":1,"title":"Name","description":"1 to 80 characters, no control or bidi characters."},"geometry":{"type":"object","title":"Geometry","description":"A GeoJSON Polygon by the rules of `AlertZonePolygon`. A polygon that breaks one of them, the shape included, is `422 alert_zone_invalid_geometry`."}},"additionalProperties":false,"type":"object","required":["name","geometry"],"title":"AlertZoneCreate","description":"A new zone, active from the start; `PATCH` it with `active: false` to\npause it."},"AlertZoneList":{"properties":{"zones":{"items":{"$ref":"#/components/schemas/AlertZone"},"type":"array","title":"Zones"}},"type":"object","required":["zones"],"title":"AlertZoneList","description":"All zones of the account, oldest first."},"AlertZonePolygon":{"properties":{"type":{"type":"string","const":"Polygon","title":"Type"},"coordinates":{"items":{"items":{"prefixItems":[{"type":"number"},{"type":"number"}],"type":"array","maxItems":2,"minItems":2},"type":"array"},"type":"array","title":"Coordinates","description":"One ring of `[longitude, latitude]` positions."}},"type":"object","required":["type","coordinates"],"title":"AlertZonePolygon","description":"A GeoJSON Polygon with exactly one ring of 4 to 51 positions, first equal\nto last (3 to 50 distinct vertices). Longitude -180 to 180, latitude -85 to\n85, no antimeridian crossing, at most 2 degrees per side of its bounding\nbox, no self-intersection, non-zero area. A polygon that breaks one of\nthese rules is `422 alert_zone_invalid_geometry`."},"AlertZoneUpdate":{"properties":{"name":{"type":"string","maxLength":80,"minLength":1,"title":"Name","description":"1 to 80 characters, no control or bidi characters."},"geometry":{"type":"object","title":"Geometry","description":"A GeoJSON Polygon by the rules of `AlertZonePolygon`. A polygon that breaks one of them, the shape included, is `422 alert_zone_invalid_geometry`."},"active":{"type":"boolean","title":"Active"}},"additionalProperties":false,"type":"object","title":"AlertZoneUpdate","description":"JSON merge patch of a zone. Absent members stay unchanged; none of them\ncan be `null`. A new `geometry` increases `version` and starts the zone\nsilently again: vessels already inside are not reported."},"ArchiveNotEnabledResponse":{"properties":{"error":{"$ref":"#/components/schemas/ErrorDetail"},"contact":{"type":"string","title":"Contact"},"request_template":{"$ref":"#/components/schemas/RequestTemplate"}},"type":"object","required":["error","contact","request_template"],"title":"ArchiveNotEnabledResponse","description":"``403 archive_not_enabled`` -- die uebliche Fehlerform plus zwei Felder."},"DetectionAisVessel":{"properties":{"role":{"type":"string","enum":["match","second_position"],"title":"Role"},"ordinal":{"type":"integer","minimum":1.0,"title":"Ordinal"},"mmsi":{"type":"integer","title":"Mmsi"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"ship_type":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ship Type"},"flag":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Flag","description":"ISO 3166 alpha-2 country derived from the MMSI."},"length_m":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Length M"},"beam_m":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Beam M"},"lon":{"type":"number","title":"Lon","description":"Reported longitude of the fix."},"lat":{"type":"number","title":"Lat","description":"Reported latitude of the fix."},"fix_at":{"type":"string","format":"date-time","title":"Fix At","description":"Time of the reported position. On a `final` pair a fix may come from 5-minute data; its time is then up to 4 minutes early, so a fix from just after the acquisition can show a negative offset."},"offset_seconds":{"type":"integer","title":"Offset Seconds","description":"`fix_at` minus the acquisition time, in seconds; negative for a fix from before it. On a `final` pair a fix may come from 5-minute data; its time is then up to 4 minutes early, so a fix from just after the acquisition can show a negative offset."},"distance_m":{"type":"number","title":"Distance M","description":"Distance from the reported position to the hull or box; 0 inside it."},"sog_kn":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Sog Kn"},"cog_deg":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Cog Deg"},"heading_deg":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Heading Deg"},"nav_status":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Nav Status"},"license":{"type":"string","title":"License","description":"Licence id of the reported AIS position. Name, ship type and size come from the vessel registry and carry no licence of their own."}},"additionalProperties":false,"type":"object","required":["role","ordinal","mmsi","name","ship_type","flag","length_m","beam_m","lon","lat","fix_at","offset_seconds","distance_m","sog_kn","cog_deg","heading_deg","nav_status","license"],"title":"DetectionAisVessel","description":"One AIS vessel stored with a detection, as it was at the acquisition. A `match` is\nthe vessel the detection was matched to. For an STS pair, the partners are, in partner\norder: its `match` rows by `ordinal`; on a pair without a measured hull, its first\n`match` and then its first `second_position`; on a pair that covers two detections, the\nfirst `match` of each, lower detection id first. A `second_position` is a further AIS\nposition inside the same hull."},"DetectionArea":{"properties":{"id":{"type":"integer","minimum":1.0,"title":"Id"},"name":{"type":"string","title":"Name"},"polygon":{"$ref":"#/components/schemas/DetectionPolygon"},"south":{"type":"number","title":"South"},"west":{"type":"number","title":"West"},"north":{"type":"number","title":"North"},"east":{"type":"number","title":"East"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"latest_sensed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Latest Sensed At","description":"Acquisition time of the newest listed overflight; `null` before the first."}},"additionalProperties":false,"type":"object","required":["id","name","polygon","south","west","north","east","created_at","latest_sensed_at"],"title":"DetectionArea","description":"One area of sea searched for vessels in satellite images. `south`, `west`, `north`\nand `east` are the bounds of the outer ring of `polygon`."},"DetectionAreasResponse":{"properties":{"areas":{"items":{"$ref":"#/components/schemas/DetectionArea"},"type":"array","title":"Areas"}},"additionalProperties":false,"type":"object","required":["areas"],"title":"DetectionAreasResponse"},"DetectionFind":{"properties":{"pair_id":{"type":"integer","minimum":1.0,"title":"Pair Id","description":"The id of the STS pair, shown as `STS-<pair_id>`."},"detection_id":{"type":"integer","minimum":1.0,"title":"Detection Id","description":"The detection the find lies on; for a pair that covers two detections, the lower id."},"overflight_id":{"type":"integer","minimum":1.0,"title":"Overflight Id"},"area_id":{"type":"integer","minimum":1.0,"title":"Area Id"},"area_name":{"type":"string","title":"Area Name"},"sensed_at":{"type":"string","format":"date-time","title":"Sensed At","description":"Acquisition time."},"lon":{"type":"number","title":"Lon","description":"Longitude of the detection."},"lat":{"type":"number","title":"Lat","description":"Latitude of the detection."},"state":{"type":"string","enum":["preliminary","final"],"title":"State"},"has_dark_vessel":{"type":"boolean","title":"Has Dark Vessel","description":"A partner is dark under good AIS coverage."},"hull_length_m":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Hull Length M","description":"Null when the pair has no measured hull."},"hull_beam_m":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Hull Beam M","description":"Null when the pair has no measured hull."},"partners":{"items":{"$ref":"#/components/schemas/DetectionFindPartner"},"type":"array","maxItems":2,"title":"Partners","description":"By `ordinal`."},"reasons":{"items":{"$ref":"#/components/schemas/StsPairReason"},"type":"array","maxItems":7,"minItems":7,"title":"Reasons"}},"additionalProperties":false,"type":"object","required":["pair_id","detection_id","overflight_id","area_id","area_name","sensed_at","lon","lat","state","has_dark_vessel","hull_length_m","hull_beam_m","partners","reasons"],"title":"DetectionFind","description":"One STS find of the finds list: an STS pair with its overflight and area, at the\nposition of its detection. `reasons` are the pair's seven reasons, as in `StsPair`."},"DetectionFindPartner":{"properties":{"ordinal":{"type":"integer","maximum":2.0,"minimum":1.0,"title":"Ordinal","description":"Partner position, 1 or 2."},"mmsi":{"type":"integer","title":"Mmsi"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"license":{"type":"string","title":"License","description":"Licence id of the partner's reported AIS position. The name comes from the vessel registry and carries no licence of its own."}},"additionalProperties":false,"type":"object","required":["ordinal","mmsi","name","license"],"title":"DetectionFindPartner","description":"One AIS partner of an STS find. The pair's partners in partner order; a partner\nwithout an AIS match is not listed."},"DetectionFindsResponse":{"properties":{"finds":{"items":{"$ref":"#/components/schemas/DetectionFind"},"type":"array","maxItems":200,"title":"Finds","description":"Newest overflight first, then by `pair_id`, descending."},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor","description":"Pass it unchanged as `cursor` for the next page; `null` on the last."}},"additionalProperties":false,"type":"object","required":["finds","next_cursor"],"title":"DetectionFindsResponse"},"DetectionOverflight":{"properties":{"id":{"type":"integer","minimum":1.0,"title":"Id"},"area_id":{"type":"integer","minimum":1.0,"title":"Area Id"},"sensed_at":{"type":"string","format":"date-time","title":"Sensed At","description":"Acquisition time."},"status":{"type":"string","enum":["processed","cloudy"],"title":"Status"},"imaged_percent":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"null"}],"title":"Imaged Percent","description":"Share of the area with valid image pixels, in percent."},"cloud_percent":{"anyOf":[{"type":"number","maximum":100.0,"minimum":0.0},{"type":"null"}],"title":"Cloud Percent","description":"Cloud share of the imaged part of the area, in percent."},"ais_slice_status":{"anyOf":[{"type":"string","enum":["complete","truncated","no_data","expired"]},{"type":"null"}],"title":"Ais Slice Status","description":"The AIS positions read for the match: `complete`, `truncated` (more vessels than one read holds), `no_data` (no AIS position from anywhere was held within 15 minutes of the acquisition: a reception gap, not an empty sea) or `expired` (the AIS positions around the acquisition were no longer all held when the image was processed). `null` without an image."},"ais_vessel_count":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Ais Vessel Count","description":"AIS vessels read for the match; `null` without an image, or when `ais_slice_status` is not `complete`."},"ais_coverage":{"anyOf":[{"type":"string","enum":["good","insufficient"]},{"type":"null"}],"title":"Ais Coverage","description":"The measured AIS coverage of the area at the acquisition; `dark` needs `good`. `null` without an image, or when `ais_slice_status` is not `complete`."},"ais_coverage_share":{"anyOf":[{"type":"number","maximum":1.0,"minimum":0.0},{"type":"null"}],"title":"Ais Coverage Share","description":"The coverage measure behind `ais_coverage`, 0 to 1; `null` when `ais_coverage` is null, or when no detection was long enough to measure it."},"vessel_count":{"type":"integer","minimum":0.0,"title":"Vessel Count","description":"Vessels seen on this overflight: each served detection counts one, but a detection that holds both vessels of a served pair counts two."},"dark_count":{"type":"integer","minimum":0.0,"title":"Dark Count","description":"Of these vessels, those without an AIS match while AIS coverage was good, including the dark partners of such a pair; a vessel predicted shorter than 50 m is never dark."},"sts_count":{"type":"integer","minimum":0.0,"title":"Sts Count"},"has_sts":{"type":"boolean","title":"Has Sts","description":"`sts_count` is above 0."},"sts_detection_limited":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Sts Detection Limited","description":"True when sun glint or haze on this image makes STS pair detection unreliable, so an image without an STS pair is no evidence that no STS took place; detections are unaffected. Null when the image was not measured."},"processed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Processed At"}},"additionalProperties":false,"type":"object","required":["id","area_id","sensed_at","status","imaged_percent","cloud_percent","ais_slice_status","ais_vessel_count","ais_coverage","ais_coverage_share","vessel_count","dark_count","sts_count","has_sts","sts_detection_limited","processed_at"],"title":"DetectionOverflight","description":"One satellite overflight of an area: `processed` (an image searched for vessels) or\n`cloudy` (too cloudy to search; no image, no detections). The AIS facts and the counts\nbelong to a processed overflight; `vessel_count`, `dark_count` and `sts_count` count the\nvessels and STS pairs served for it."},"DetectionOverflightResult":{"properties":{"overflight":{"$ref":"#/components/schemas/DetectionOverflight"},"detections":{"items":{"$ref":"#/components/schemas/VesselDetection"},"type":"array","title":"Detections"},"pairs":{"items":{"$ref":"#/components/schemas/StsPair"},"type":"array","title":"Pairs"}},"additionalProperties":false,"type":"object","required":["overflight","detections","pairs"],"title":"DetectionOverflightResult","description":"One overflight's result: its detections by id, each with its AIS vessels, and its\nSTS pairs by id."},"DetectionOverflightsResponse":{"properties":{"area_id":{"type":"integer","minimum":1.0,"title":"Area Id"},"overflights":{"items":{"$ref":"#/components/schemas/DetectionOverflight"},"type":"array","maxItems":500,"title":"Overflights","description":"Newest first."}},"additionalProperties":false,"type":"object","required":["area_id","overflights"],"title":"DetectionOverflightsResponse"},"DetectionPolygon":{"properties":{"type":{"type":"string","const":"Polygon","title":"Type"},"coordinates":{"items":{"items":{"items":{"type":"number"},"type":"array"},"type":"array"},"type":"array","title":"Coordinates","description":"Rings of `[lon, lat]` positions, each closed (first = last); the first ring is the outer edge."}},"additionalProperties":false,"type":"object","required":["type","coordinates"],"title":"DetectionPolygon","description":"A GeoJSON Polygon (WGS84): the outline of an area, the box of a detection or of an\nSTS pair, or the outline of a hull measured in the image."},"ErrorCode":{"type":"string","enum":["bad_request","unauthorized","forbidden","not_found","conflict","rate_limited","internal_error","station_not_owned","station_not_found","bbox_too_large_for_res","invalid_bbox","invalid_res","invalid_ym","oauth_state_invalid","github_unavailable","stream_account_suspended","key_limit_reached","key_not_found","terms_not_accepted","account_has_stations","invalid_credentials","token_not_found","special_hex_limit_reached","ruleset_not_found","key_in_query","track_span_too_large","invalid_resolution","invalid_time_range","range_before_retention","track_unavailable","archive_not_enabled","saved_vessel_limit_reached","mail_unavailable","turnstile_failed","sar_storage_unavailable","oauth_request_expired","oauth_client_rejected","news_not_enabled","news_unavailable","invalid_cursor","alert_zone_limit_reached","alert_limit_reached","alert_identifier_limit_reached","alert_channel_limit_reached","alert_daily_limit_reached","alert_zone_invalid_geometry","alert_channel_url_rejected","alerts_not_enabled","alerts_terms_not_accepted","billing_unavailable","billing_plan_not_purchasable","billing_subscription_exists","billing_subscription_missing","billing_change_blocked","billing_signature_invalid","billing_email_required","history_outside_plan","time_slice_not_in_plan","detection_not_in_plan","map_window_expired"],"title":"ErrorCode","description":"``code`` im Fehlerobjekt der HTTP-API."},"ErrorDetail":{"properties":{"code":{"$ref":"#/components/schemas/ErrorCode"},"message":{"type":"string","title":"Message"}},"type":"object","required":["code","message"],"title":"ErrorDetail"},"ErrorResponse":{"properties":{"error":{"$ref":"#/components/schemas/ErrorDetail"}},"type":"object","required":["error"],"title":"ErrorResponse"},"Meldung":{"properties":{"id":{"type":"integer","title":"Id","description":"Permanent Pelyr id of the article."},"source":{"$ref":"#/components/schemas/MeldungQuelle"},"url":{"type":"string","title":"Url","description":"Link to the original article."},"published_at":{"type":"string","format":"date-time","title":"Published At"},"title":{"type":"string","title":"Title","description":"Our own English headline."},"summary":{"type":"string","title":"Summary","description":"Our own English summary."},"content_type":{"type":"string","title":"Content Type","description":"One of `news.CONTENT_TYPES`."},"categories":{"items":{"type":"string"},"type":"array","title":"Categories","description":"0 to 3 ids from `news.CATEGORIES`; the first is the main category."},"segments":{"items":{"type":"string"},"type":"array","title":"Segments","description":"Values from `news.SEGMENTS`."},"regions":{"items":{"type":"string"},"type":"array","title":"Regions","description":"Values from `news.REGIONS`."},"countries":{"items":{"type":"string"},"type":"array","title":"Countries","description":"ISO 3166-1 alpha-2 codes."},"sea_areas":{"items":{"type":"string"},"type":"array","title":"Sea Areas","description":"Values from `news.SEA_AREAS`."},"organisations":{"items":{"$ref":"#/components/schemas/MeldungOrganisation"},"type":"array","title":"Organisations"},"vessels":{"items":{"$ref":"#/components/schemas/MeldungSchiff"},"type":"array","title":"Vessels"},"risk":{"$ref":"#/components/schemas/MeldungGefahr"},"analysed_at":{"type":"string","format":"date-time","title":"Analysed At"}},"type":"object","required":["id","source","url","published_at","title","summary","content_type","categories","segments","regions","countries","sea_areas","organisations","vessels","risk","analysed_at"],"title":"Meldung","description":"One news article: our own title and summary, a link to the original,\nand the structured fields. Source text is never delivered. Enumerations\ngrow additively -- clients must accept values they do not know yet."},"MeldungGefahr":{"properties":{"risk_frame":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Risk Frame","description":"One of `news.RISK_FRAMES`."},"event_types":{"items":{"type":"string"},"type":"array","title":"Event Types","description":"Ids from `news.EVENT_TYPES`."},"at_risk":{"items":{"type":"string"},"type":"array","title":"At Risk","description":"Values from `news.AT_RISK`."},"severity":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Severity","description":"One of `news.SEVERITIES`, ranked `none` < `advisory` < `minor` < `serious` < `critical`; `null` when `risk_frame` is `none`."},"event_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Event Status","description":"One of `news.EVENT_STATUSES`."},"verification":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Verification","description":"One of `news.VERIFICATIONS`."},"human_impact":{"anyOf":[{"$ref":"#/components/schemas/MeldungPersonenschaden"},{"type":"null"}]},"conflict_relation":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Conflict Relation","description":"One of `news.CONFLICT_RELATIONS`."},"conflict_theatres":{"items":{"type":"string"},"type":"array","title":"Conflict Theatres","description":"Values from `news.CONFLICT_THEATRES`."},"conflict_related":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Conflict Related","description":"`true` when `conflict_relation` is `direct` or `indirect`."}},"type":"object","required":["risk_frame","event_types","at_risk","severity","event_status","verification","human_impact","conflict_relation","conflict_theatres","conflict_related"],"title":"MeldungGefahr","description":"The risk model: what happened or threatens, to what, how severe, how\nwell attested. `severity` is computed by versioned rules from the stated\nfacts -- a lower bound of what was reported, not a probability."},"MeldungOrganisation":{"properties":{"name":{"type":"string","title":"Name"},"role":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role","description":"One of `news.ORGANISATION_ROLES`; new values may appear."}},"type":"object","required":["name","role"],"title":"MeldungOrganisation","description":"An organisation named in the article, with its role in this story."},"MeldungPersonenschaden":{"properties":{"killed":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Killed"},"injured":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Injured"},"missing":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Missing"},"held_captive":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Held Captive"},"rescued_or_evacuated":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Rescued Or Evacuated"}},"type":"object","required":["killed","injured","missing","held_captive","rescued_or_evacuated"],"title":"MeldungPersonenschaden","description":"Explicitly stated numbers of people affected; `null` where the text\ngives no number. \"More than 90\" is stored as the lower bound 90."},"MeldungQuelle":{"properties":{"id":{"type":"string","title":"Id","description":"Stable source id, for example `gcaptain`."},"name":{"type":"string","title":"Name","description":"Source name to credit, for example `gCaptain`."}},"type":"object","required":["id","name"],"title":"MeldungQuelle","description":"The source of the original article."},"MeldungSchiff":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name","description":"Current name as written in the article; `null` if unnamed."},"former_names":{"items":{"type":"string"},"type":"array","title":"Former Names"},"role":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role","description":"One of `news.VESSEL_ROLES`; new values may appear."},"condition":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Condition","description":"One of `news.VESSEL_CONDITIONS`; only for `incident_subject` and `enforcement_subject`."},"stated":{"$ref":"#/components/schemas/MeldungSchiffAngaben"},"mmsi":{"anyOf":[{"type":"integer","maximum":999999999.0,"minimum":100000000.0},{"type":"null"}],"title":"Mmsi"},"match_status":{"type":"string","title":"Match Status","description":"One of `news.MATCH_STATUSES`."}},"type":"object","required":["name","former_names","role","condition","stated","mmsi","match_status"],"title":"MeldungSchiff","description":"A vessel mentioned in the article, in text order.\n\n`mmsi` is set only when the match with the vessel register is reliable\nenough for publication: always for `confirmed`; for `probable` unless the\nvessel suffered the incident or is the target of enforcement in an article\nabout a serious or critical event or about sanctions. When the MMSI is\nwithheld, `stated.imo` is withheld too. `match_status` is always shown."},"MeldungSchiffAngaben":{"properties":{"flag":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Flag","description":"ISO 3166-1 alpha-2 code of the stated flag."},"dwt":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Dwt"},"teu":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Teu"},"cbm":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Cbm"},"gt":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Gt"},"loa_m":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Loa M","description":"Stated length overall in metres."},"build_year":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Build Year"},"imo":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Imo","description":"IMO number stated in the text, only with a valid check digit. `null` whenever the MMSI of this mention is withheld."},"segment":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Segment","description":"One of `news.SEGMENTS`; new values may appear."}},"type":"object","required":["flag","dwt","teu","cbm","gt","loa_m","build_year","imo","segment"],"title":"MeldungSchiffAngaben","description":"Particulars of the vessel as the article states them, parsed. `null`\nwhere the text says nothing -- never an estimate."},"MeldungenAntwort":{"properties":{"generated_at":{"type":"string","format":"date-time","title":"Generated At"},"count":{"type":"integer","minimum":0.0,"title":"Count","description":"Number of articles in this page."},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"news":{"items":{"$ref":"#/components/schemas/Meldung"},"type":"array","title":"News"}},"type":"object","required":["generated_at","count","next_cursor","news"],"title":"MeldungenAntwort","description":"A page of news articles, newest first (`published_at`, then `id`).\n\n`next_cursor` is `null` on the last page. Pass it unchanged as `cursor`\nto get the next page; articles published while paging do not shift the\npages you have not read yet."},"Position":{"properties":{"lat":{"type":"number","maximum":90.0,"minimum":-90.0,"title":"Lat"},"lon":{"type":"number","maximum":180.0,"minimum":-180.0,"title":"Lon"},"sog":{"anyOf":[{"type":"number","maximum":102.3,"minimum":0.0},{"type":"null"}],"title":"Sog"},"cog":{"anyOf":[{"type":"number","maximum":360.0,"minimum":0.0},{"type":"null"}],"title":"Cog"},"heading":{"anyOf":[{"type":"integer","maximum":359.0,"minimum":0.0},{"type":"null"}],"title":"Heading"},"nav_status":{"anyOf":[{"type":"integer","maximum":15.0,"minimum":0.0},{"type":"null"}],"title":"Nav Status"},"rot":{"anyOf":[{"type":"number","maximum":720.0,"minimum":-720.0},{"type":"null"}],"title":"Rot"},"pos_accuracy":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Pos Accuracy"},"msg_type":{"anyOf":[{"type":"integer","maximum":27.0,"minimum":1.0},{"type":"null"}],"title":"Msg Type"},"ts":{"type":"string","format":"date-time","title":"Ts"},"license":{"type":"string","title":"License"},"plausibility":{"type":"string","enum":["unknown","high","medium","low"],"title":"Plausibility","description":"How well this position fits the vessel's previous plausible position: implied speed, reported speed and course, navigation status. `low` means the position does not fit (a jump, or an invalid MMSI); `medium` means it fits with a caveat named in `flags`, or lies on a track that started with a jump and is not yet confirmed; `unknown` means there was nothing to compare against. This is a kinematic consistency check, not a statement that the position is genuine -- see the Data Licence, section 6."},"flags":{"items":{"type":"string","enum":["implausible_speed","unreconciled_track","invalid_mmsi","speed_mismatch","course_mismatch","moving_while_moored"]},"type":"array","title":"Flags","description":"Why the plausibility is not `high`. Empty for `high` and `unknown`."}},"type":"object","required":["lat","lon","sog","cog","heading","nav_status","rot","pos_accuracy","msg_type","ts","license","plausibility","flags"],"title":"Position","description":"Die zuletzt empfangene Positionsmeldung dieses Schiffs.\n\nAlle Werte stammen aus **einer** Nachricht -- deshalb traegt die Gruppe\nihren eigenen Zeitstempel ``ts`` und ihre eigene Lizenzkennung\n``license``. Was die Nachricht nicht trug, steht als ``null``."},"QuellenEintrag":{"properties":{"id":{"type":"string","title":"Id"},"license":{"type":"string","title":"License"},"source":{"type":"string","title":"Source"},"attribution":{"type":"string","title":"Attribution"}},"type":"object","required":["id","license","source","attribution"],"title":"QuellenEintrag","description":"Ein Eintrag von ``sources[]``. Alle vier Felder immer Zeichenketten,\nnie ``null``, nie abwesend -- ``source`` und ``attribution`` duerfen leer\nsein."},"RequestTemplate":{"properties":{"to":{"type":"string","title":"To"},"subject":{"type":"string","title":"Subject"},"body":{"type":"string","title":"Body"}},"type":"object","required":["to","subject","body"],"title":"RequestTemplate","description":"Eine fertige E-Mail. Der Kunde soll sie abschicken, nicht schreiben."},"Schiff":{"properties":{"mmsi":{"type":"integer","maximum":999999999.0,"minimum":100000000.0,"title":"Mmsi"},"position":{"$ref":"#/components/schemas/Position"},"static":{"$ref":"#/components/schemas/Statik"}},"type":"object","required":["mmsi","position"],"title":"Schiff","description":"Ein Schiff: MMSI, seine letzte Position und -- sofern schon eine\nStatiknachricht kam -- seine Stammdaten.\n\nDieselbe Form liefert ``GET /v1/vessels/{mmsi}`` einzeln und\n``GET /v1/vessels`` je Eintrag von ``vessels[]``."},"SearchMatch":{"properties":{"kind":{"type":"string","enum":["exact","prefix","similar"],"title":"Kind"},"field":{"type":"string","enum":["mmsi","imo","name","former_name"],"title":"Field"},"matched_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Matched Name","description":"The matched name as last broadcast. For `mmsi` and `imo` hits the vessel's current name; `null` when no name is known."},"score":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Score","description":"Name similarity from 0 to 1; 1 for exact hits."}},"type":"object","required":["kind","field","matched_name","score"],"title":"SearchMatch","description":"Why this vessel is in the result.\n\n`kind` is how the query matched: `exact`, `prefix` (the name starts with\nthe query) or `similar` (a similar spelling). A `similar` hit is a\ncandidate, not an identification -- compare MMSI, IMO and position before\nacting on it. `field` names what matched: the MMSI, the IMO number, the\nvessel's current `name` or a `former_name`."},"SearchPosition":{"properties":{"lat":{"type":"number","maximum":90.0,"minimum":-90.0,"title":"Lat"},"lon":{"type":"number","maximum":180.0,"minimum":-180.0,"title":"Lon"},"sog":{"anyOf":[{"type":"number","maximum":102.3,"minimum":0.0},{"type":"null"}],"title":"Sog"},"cog":{"anyOf":[{"type":"number","maximum":360.0,"minimum":0.0},{"type":"null"}],"title":"Cog"},"heading":{"anyOf":[{"type":"integer","maximum":359.0,"minimum":0.0},{"type":"null"}],"title":"Heading"},"nav_status":{"anyOf":[{"type":"integer","maximum":15.0,"minimum":0.0},{"type":"null"}],"title":"Nav Status"},"rot":{"anyOf":[{"type":"number","maximum":720.0,"minimum":-720.0},{"type":"null"}],"title":"Rot"},"pos_accuracy":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Pos Accuracy"},"msg_type":{"anyOf":[{"type":"integer","maximum":27.0,"minimum":1.0},{"type":"null"}],"title":"Msg Type"},"ts":{"type":"string","format":"date-time","title":"Ts"},"license":{"type":"string","title":"License"},"plausibility":{"type":"string","enum":["unknown","high","medium","low"],"title":"Plausibility","description":"How well this position fits the vessel's previous plausible position: implied speed, reported speed and course, navigation status. `low` means the position does not fit (a jump, or an invalid MMSI); `medium` means it fits with a caveat named in `flags`, or lies on a track that started with a jump and is not yet confirmed; `unknown` means there was nothing to compare against. This is a kinematic consistency check, not a statement that the position is genuine -- see the Data Licence, section 6."},"flags":{"items":{"type":"string","enum":["implausible_speed","unreconciled_track","invalid_mmsi","speed_mismatch","course_mismatch","moving_while_moored"]},"type":"array","title":"Flags","description":"Why the plausibility is not `high`. Empty for `high` and `unknown`."},"live":{"type":"boolean","title":"Live","description":"`true` for the live position, `false` for the last stored position of a silent vessel."}},"type":"object","required":["lat","lon","sog","cog","heading","nav_status","rot","pos_accuracy","msg_type","ts","license","live"],"title":"SearchPosition","description":"The vessel's newest known position report.\n\nWith `live: true` this is the live position, heard within the last hour,\nwith its `plausibility` and `flags`. With `live: false` the vessel has\nbeen silent for over an hour and this is its last position stored in the\nlast 30 days: `sog`, `cog`, `heading`, `nav_status` and `rot` are the\nvalues of that report at `ts`, not the vessel's current state, and\n`plausibility` and `flags` are absent. All values stem from one message,\nwith its own `ts` and `license`."},"SourcesResponse":{"properties":{"generated_at":{"type":"string","format":"date-time","title":"Generated At"},"sources":{"items":{"$ref":"#/components/schemas/QuellenEintrag"},"type":"array","title":"Sources"}},"type":"object","required":["generated_at","sources"],"title":"SourcesResponse"},"Spur":{"properties":{"mmsi":{"type":"integer","maximum":999999999.0,"minimum":100000000.0,"title":"Mmsi"},"from":{"type":"string","format":"date-time","title":"From"},"to":{"type":"string","format":"date-time","title":"To"},"resolution":{"type":"string","enum":["1min","5min","15min","1h","6h","1d"],"title":"Resolution"},"count":{"type":"integer","minimum":0.0,"title":"Count"},"points":{"items":{"$ref":"#/components/schemas/Spurpunkt"},"type":"array","title":"Points"}},"type":"object","required":["mmsi","from","to","resolution","count","points"],"title":"Spur","description":"Die Antwort von ``GET /v1/vessels/{mmsi}/track``.\n\n``from`` und ``to`` wiederholen das tatsaechlich beantwortete Fenster --\n``to`` steht auch dann da, wenn die Anfrage es weggelassen hat. ``count``\nzaehlt gelieferte Punkte, nicht Fenster: ein Schiff ohne Meldung im\nZeitraum liefert eine leere Liste und keinen Fehler."},"Spurpunkt":{"properties":{"lat":{"type":"number","maximum":90.0,"minimum":-90.0,"title":"Lat"},"lon":{"type":"number","maximum":180.0,"minimum":-180.0,"title":"Lon"},"sog":{"anyOf":[{"type":"number","maximum":102.3,"minimum":0.0},{"type":"null"}],"title":"Sog"},"cog":{"anyOf":[{"type":"number","maximum":360.0,"minimum":0.0},{"type":"null"}],"title":"Cog"},"heading":{"anyOf":[{"type":"integer","maximum":359.0,"minimum":0.0},{"type":"null"}],"title":"Heading"},"nav_status":{"anyOf":[{"type":"integer","maximum":15.0,"minimum":0.0},{"type":"null"}],"title":"Nav Status"},"rot":{"anyOf":[{"type":"number","maximum":720.0,"minimum":-720.0},{"type":"null"}],"title":"Rot"},"pos_accuracy":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Pos Accuracy"},"msg_type":{"type":"integer","maximum":27.0,"minimum":1.0,"title":"Msg Type"},"ts":{"type":"string","format":"date-time","title":"Ts"},"license":{"type":"string","title":"License"}},"type":"object","required":["lat","lon","sog","cog","heading","nav_status","rot","pos_accuracy","msg_type","ts","license"],"title":"Spurpunkt","description":"Ein Punkt der Schiffsspur: ein Zeitfenster, ein Ort.\n\nWie ``position`` einer Momentaufnahme stammen alle Werte aus **einer**\nNachricht -- deshalb traegt jeder Punkt seine eigene Lizenzkennung. Was\ndie Nachricht nicht trug, steht als ``null``.\n\n``ts`` ist der **Anfang des Zeitfensters auf der Uhr**, nicht der genaue\nEmpfangszeitpunkt: `1h` beginnt zur vollen Stunde, `1d` um Mitternacht\nUTC. Je Fenster kommt hoechstens ein Punkt; leere Fenster erzeugen keinen."},"Statik":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Name"},"type":{"anyOf":[{"type":"integer","maximum":99.0,"minimum":0.0},{"type":"null"}],"title":"Type"},"imo":{"anyOf":[{"type":"integer","maximum":9999999.0,"minimum":0.0},{"type":"null"}],"title":"Imo"},"callsign":{"anyOf":[{"type":"string","maxLength":7},{"type":"null"}],"title":"Callsign"},"dest":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Dest"},"draught":{"anyOf":[{"type":"number","maximum":25.5,"minimum":0.0},{"type":"null"}],"title":"Draught"},"eta":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Eta"},"length":{"anyOf":[{"type":"integer","maximum":1022.0,"minimum":0.0},{"type":"null"}],"title":"Length"},"beam":{"anyOf":[{"type":"integer","maximum":126.0,"minimum":0.0},{"type":"null"}],"title":"Beam"},"dim_a":{"anyOf":[{"type":"integer","maximum":511.0,"minimum":0.0},{"type":"null"}],"title":"Dim A"},"dim_b":{"anyOf":[{"type":"integer","maximum":511.0,"minimum":0.0},{"type":"null"}],"title":"Dim B"},"dim_c":{"anyOf":[{"type":"integer","maximum":63.0,"minimum":0.0},{"type":"null"}],"title":"Dim C"},"dim_d":{"anyOf":[{"type":"integer","maximum":63.0,"minimum":0.0},{"type":"null"}],"title":"Dim D"},"ts":{"type":"string","format":"date-time","title":"Ts"},"license":{"type":"string","title":"License"}},"type":"object","required":["name","type","imo","callsign","dest","draught","eta","length","beam","dim_a","dim_b","dim_c","dim_d","ts","license"],"title":"Statik","description":"Die Stammdaten aus der zuletzt empfangenen Statiknachricht.\n\nWie bei ``position`` stammen alle Werte aus **einer** Nachricht, mit\neigenem ``ts`` und eigener ``license``. Das Feld ``static`` fehlt in der\nAntwort GANZ, solange keine Statiknachricht kam -- nie ein Objekt mit\nlauter ``null``. Ein frisch aufgetauchtes Schiff hat bis zu sechs Minuten\nkeine."},"StsPair":{"properties":{"id":{"type":"integer","minimum":1.0,"title":"Id"},"detection_id":{"type":"integer","minimum":1.0,"title":"Detection Id","description":"The pair's primary detection; for a pair that covers two detections, the lower id. Every detection of the pair carries its `pair_id`."},"state":{"type":"string","enum":["preliminary","final"],"title":"State"},"reasons":{"items":{"$ref":"#/components/schemas/StsPairReason"},"type":"array","maxItems":7,"minItems":7,"title":"Reasons"},"has_dark_vessel":{"type":"boolean","title":"Has Dark Vessel","description":"A partner is dark under good AIS coverage."},"box":{"$ref":"#/components/schemas/DetectionPolygon"},"hull_outline":{"anyOf":[{"$ref":"#/components/schemas/DetectionPolygon"},{"type":"null"}],"description":"Null when the pair has no measured hull."},"hull_length_m":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Hull Length M","description":"Null when the pair has no measured hull."},"hull_beam_m":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Hull Beam M","description":"Null when the pair has no measured hull."},"hull_beam_ratio":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Hull Beam Ratio","description":"Null when the pair has no measured hull."},"predicted_length_m":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Predicted Length M","description":"Null when the image gave no estimate."},"predicted_speed":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Predicted Speed","description":"Null when the image gave no estimate."},"scored_at":{"type":"string","format":"date-time","title":"Scored At"},"final_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Final At"}},"additionalProperties":false,"type":"object","required":["id","detection_id","state","reasons","has_dark_vessel","box","hull_outline","hull_length_m","hull_beam_m","hull_beam_ratio","predicted_length_m","predicted_speed","scored_at","final_at"],"title":"StsPair","description":"One STS pair: two vessels alongside each other in the image, with its seven reasons;\n`preliminary` until its one re-scoring, then `final`."},"StsPairReason":{"properties":{"code":{"type":"string","enum":["hull_shape","partner_sizes","two_ais_positions","speed","dark_partner","draught_change","duration_together"],"title":"Code"},"effect":{"type":"string","enum":["raises","lowers","none"],"title":"Effect","description":"`raises` (speaks for an STS transfer), `lowers` (speaks against it) or `none`."},"detail":{"type":"object","title":"Detail","description":"The facts of the reason; the keys depend on `code`."}},"additionalProperties":false,"type":"object","required":["code","effect","detail"],"title":"StsPairReason","description":"One reason behind an STS pair. A pair holds each of the seven codes exactly once,\nin this order, with exactly these `detail` keys (`null` where unknown):\n`hull_shape`: `beam_ratio`, `hull_length_m`, `hull_beam_m`, `detector_score`;\n`partner_sizes`: `blob_length_m`, `blob_beam_m`, `partners` (a list of\n`{mmsi, length_m, beam_m}`; `mmsi` is null when the size is estimated from the image);\n`two_ais_positions`: `mmsis` (empty unless two AIS positions lie inside the hull);\n`speed`: `predicted_speed`, `partners` (a list of `{mmsi, sog_kn}`);\n`dark_partner`: `dark_count`, `coverage` (`good`, `insufficient` or null);\n`draught_change`: `partners` (a list of `{mmsi, before_m, after_m}`);\n`duration_together`: `minutes` (null when not determinable).\n`dark_count` (0, 1 or 2): partners without an AIS match that count toward dark; they are\ndark only when `coverage` is `good`."},"VesselDetection":{"properties":{"id":{"type":"integer","minimum":1.0,"title":"Id"},"lon":{"type":"number","title":"Lon"},"lat":{"type":"number","title":"Lat"},"box":{"$ref":"#/components/schemas/DetectionPolygon"},"score":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Score","description":"Detector confidence."},"length_m":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Length M","description":"Predicted length."},"width_m":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Width M","description":"Predicted width."},"speed_kn":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Speed Kn","description":"Predicted speed."},"vessel_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Vessel Type","description":"Predicted type; the list of values grows."},"heading_deg":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Heading Deg","description":"Stated direction; `null` for none."},"heading_source":{"anyOf":[{"type":"string","enum":["model","ais"]},{"type":"null"}],"title":"Heading Source","description":"`model` (predicted, at a predicted speed of at least 5 kn) or `ais` (the matched vessel's heading, else its course)."},"ais_state":{"type":"string","enum":["matched","dark","no_match_possible","no_ais_expected"],"title":"Ais State"},"coverage_good":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Coverage Good","description":"The AIS coverage at the detection was measured good."},"faint":{"type":"boolean","title":"Faint","description":"Detector confidence under 0.9."},"pair_id":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Pair Id","description":"The id of the STS pair this detection is part of, or null."},"vessels":{"items":{"$ref":"#/components/schemas/DetectionAisVessel"},"type":"array","title":"Vessels"}},"additionalProperties":false,"type":"object","required":["id","lon","lat","box","score","length_m","width_m","speed_kn","vessel_type","heading_deg","heading_source","ais_state","coverage_good","faint","pair_id","vessels"],"title":"VesselDetection","description":"One vessel detected in the image. `ais_state` is `matched` (an AIS vessel matched),\n`dark` (no AIS was received from a detected vessel of this size although the coverage\nwas measured good; it does not say why), `no_match_possible` (no AIS match, and dark\ncould not be decided: the coverage at the detection was not measured good, or no length\nwas predicted) or `no_ais_expected` (no match, and the vessel is predicted shorter than\n50 m; never dark). `vessels` lists its stored AIS vessels by `role`, then `ordinal`."},"VesselRegistryEntry":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"imo":{"anyOf":[{"type":"integer","maximum":9999999.0,"minimum":0.0},{"type":"null"}],"title":"Imo"},"callsign":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Callsign"},"type":{"anyOf":[{"type":"integer","maximum":99.0,"minimum":0.0},{"type":"null"}],"title":"Type"},"length":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Length"},"beam":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Beam"},"dim_a":{"anyOf":[{"type":"integer","maximum":511.0,"minimum":0.0},{"type":"null"}],"title":"Dim A"},"dim_b":{"anyOf":[{"type":"integer","maximum":511.0,"minimum":0.0},{"type":"null"}],"title":"Dim B"},"dim_c":{"anyOf":[{"type":"integer","maximum":63.0,"minimum":0.0},{"type":"null"}],"title":"Dim C"},"dim_d":{"anyOf":[{"type":"integer","maximum":63.0,"minimum":0.0},{"type":"null"}],"title":"Dim D"},"first_seen":{"type":"string","format":"date-time","title":"First Seen","description":"First static message the register saw for this MMSI -- the start of the observation, not the build year of the vessel."},"last_seen":{"type":"string","format":"date-time","title":"Last Seen","description":"Last static message, updated at most once a day."},"ts":{"type":"string","format":"date-time","title":"Ts","description":"Time of the newest static message in this entry."},"license":{"type":"string","title":"License","description":"Licence id of the newest static message in this entry, fixed when it was stored. Older fields can stem from another source, and the id can name a licence that `GET /v1/sources` no longer lists."}},"type":"object","required":["name","imo","callsign","type","length","beam","dim_a","dim_b","dim_c","dim_d","first_seen","last_seen","ts","license"],"title":"VesselRegistryEntry","description":"The vessel's entry in the Pelyr vessel register: the static data heard\nfrom this MMSI, kept after the vessel falls silent.\n\nUnlike `static` it has no voyage data and stays after the vessel goes\nquiet. The register holds only vessels heard since it was switched on.\n`ts` and `license` describe the newest static message that went into the\nentry; single fields can stem from an older message or another source,\nbecause a field is only overwritten by a value, never by its absence."},"VesselSearchHit":{"properties":{"mmsi":{"type":"integer","maximum":999999999.0,"minimum":100000000.0,"title":"Mmsi"},"flag_country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Flag Country","description":"ISO 3166-1 alpha-2 code of the territory the MMSI's Maritime Identification Digits are assigned to; `null` when they are unassigned or shared by several territories. Derived from the MMSI, not from a message: not AIS data and not covered by any licence."},"match":{"$ref":"#/components/schemas/SearchMatch"},"registry":{"$ref":"#/components/schemas/VesselRegistryEntry"},"static":{"$ref":"#/components/schemas/Statik"},"position":{"$ref":"#/components/schemas/SearchPosition"}},"type":"object","required":["mmsi","flag_country","match"],"title":"VesselSearchHit","description":"One search hit: the vessel, why it matched, and what Pelyr knows about\nit. `registry`, `static` and `position` are each absent when there is\nnothing to show -- never an object full of `null`."},"VesselSearchResult":{"properties":{"generated_at":{"type":"string","format":"date-time","title":"Generated At"},"count":{"type":"integer","minimum":0.0,"title":"Count","description":"Number of hits in `results`."},"truncated":{"type":"boolean","title":"Truncated","description":"`true` when more vessels matched than `max` allows or the name search reached its candidate limit; refine the query."},"results":{"items":{"$ref":"#/components/schemas/VesselSearchHit"},"type":"array","title":"Results"}},"type":"object","required":["generated_at","count","truncated","results"],"title":"VesselSearchResult","description":"The answer of `GET /v1/vessels/search`: the best matches, best first --\nexact before prefix before similar, current names before former names.\nOne entry per vessel."},"VesselsResponse":{"properties":{"generated_at":{"type":"string","format":"date-time","title":"Generated At"},"count":{"type":"integer","minimum":0.0,"title":"Count"},"truncated":{"type":"boolean","title":"Truncated"},"vessels":{"items":{"$ref":"#/components/schemas/Schiff"},"type":"array","title":"Vessels"}},"type":"object","required":["generated_at","count","truncated","vessels"],"title":"VesselsResponse","description":"Die Antwort von ``GET /v1/vessels``.\n\n``count`` ist immer die Laenge von ``vessels`` und zaehlt nur, was\ntatsaechlich geliefert wird. ``truncated`` sagt, ob die Auswahl gekuerzt\nwurde -- dann liegen in der ``bbox`` mehr Schiffe, als ``max`` zulaesst."},"Zeitschnitt":{"properties":{"at":{"type":"string","format":"date-time","title":"At"},"lookback_seconds":{"type":"integer","minimum":0.0,"title":"Lookback Seconds"},"truncated":{"type":"boolean","title":"Truncated"},"count":{"type":"integer","minimum":0.0,"title":"Count"},"vessels":{"items":{"$ref":"#/components/schemas/Zeitschnittschiff"},"type":"array","title":"Vessels"}},"type":"object","required":["at","lookback_seconds","truncated","count","vessels"],"title":"Zeitschnitt","description":"Alle Schiffe zu EINEM Zeitpunkt: je Schiff, das in den\n`lookback_seconds` Sekunden vor `at` aus der BBox gemeldet hat, seine\njuengste Position in diesem Fenster -- auch wenn die schon ausserhalb\nder BBox liegt. Ein Schiff, das zuletzt vor dem Fenster gemeldet hat,\nfehlt -- es ist kein \"dunkles\" Schiff, nur eines ausserhalb des Fensters.\n\n`truncated: true` heisst: mehr Schiffe im Fenster als der Deckel\nzulaesst; `vessels` ist dann LEER, nicht gekuerzt, denn eine\nunvollstaendige Liste liesse jedes fehlende Schiff als \"nicht gesendet\"\nerscheinen. Die BBox verkleinern."},"Zeitschnittschiff":{"properties":{"mmsi":{"type":"integer","maximum":999999999.0,"minimum":100000000.0,"title":"Mmsi"},"lat":{"type":"number","maximum":90.0,"minimum":-90.0,"title":"Lat"},"lon":{"type":"number","maximum":180.0,"minimum":-180.0,"title":"Lon"},"sog":{"anyOf":[{"type":"number","maximum":102.3,"minimum":0.0},{"type":"null"}],"title":"Sog"},"cog":{"anyOf":[{"type":"number","maximum":360.0,"minimum":0.0},{"type":"null"}],"title":"Cog"},"heading":{"anyOf":[{"type":"integer","maximum":359.0,"minimum":0.0},{"type":"null"}],"title":"Heading"},"nav_status":{"anyOf":[{"type":"integer","maximum":15.0,"minimum":0.0},{"type":"null"}],"title":"Nav Status"},"rot":{"anyOf":[{"type":"number","maximum":720.0,"minimum":-720.0},{"type":"null"}],"title":"Rot"},"pos_accuracy":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Pos Accuracy"},"msg_type":{"type":"integer","maximum":27.0,"minimum":1.0,"title":"Msg Type"},"ts":{"type":"string","format":"date-time","title":"Ts"},"age_seconds":{"type":"integer","maximum":959.0,"minimum":0.0,"title":"Age Seconds"},"license":{"type":"string","title":"License"}},"type":"object","required":["mmsi","lat","lon","sog","cog","heading","nav_status","rot","pos_accuracy","msg_type","ts","age_seconds","license"],"title":"Zeitschnittschiff","description":"Ein Schiff im Zeitschnitt: seine juengste Position im Fenster vor\n`at`. Alle Werte stammen aus EINER Nachricht, deshalb die eigene\n`license`. `ts` ist der Empfangszeitpunkt dieser Nachricht auf die\nSekunde, `age_seconds` ihr Abstand zu `at`. Nichts ist interpoliert und\nnichts koppelnavigiert: die Koordinate stand so im Funk."}},"securitySchemes":{"customerKey":{"type":"http","scheme":"bearer"}}}}