Quick start
Every request is a GET to https://sas.orc.org/api/{key}/{endpoint}, with
the parameters in the query string. To download the rating data of every active standard ORC
certificate in Greece, as JSON:
curl -o GRE_ORC.json "https://sas.orc.org/api/$ORC_API_KEY/DownRMS?CountryId=GRE&Family=ORC&ext=json"
import os
import requests
BASE = f"https://sas.orc.org/api/{os.environ['ORC_API_KEY']}"
r = requests.get(f"{BASE}/DownRMS",
params={"CountryId": "GRE", "Family": "ORC", "ext": "json"},
timeout=120)
r.raise_for_status()
for boat in r.json()["rms"]:
print(boat["SailNo"], boat["YachtName"], boat["GPH"])
const base = `https://sas.orc.org/api/${process.env.ORC_API_KEY}`;
const url = new URL(`${base}/DownBoatRMS_byrefno`);
url.search = new URLSearchParams({ RefNo: "03420004I82", ext: "json" });
const res = await fetch(url);
const body = await res.json();
if (!res.ok) throw new Error(body.errors.join("; "));
console.log(body.rms[0].YachtName, body.rms[0].GPH);
The examples read the key from an environment variable, ORC_API_KEY, so that
it never ends up in your source code.
API keys
Getting a key
Keys belong to users of ORC Sailor Services. Register there if you have not already, sign in, and ask for API access on the Developers page, saying briefly what your project is and how it will use the API. ORC e-mails you its answer. Once access is granted, you make your own keys on the same page: as many as five active at a time, one per application, so that each can be replaced on its own. A key may be given an expiry date, and works to the end of that day (UTC). Every new key is announced by e-mail to your account's address.
A key looks like this: orc_ followed by 64 hexadecimal characters.
orc_3f9a1c07e52d4b8e9a61f0c3d7b2e4a58c19f6d03b7e2a4c5d8e1f0a9b3c6d27
You are shown the key once, when you make it. ORC keeps only a fingerprint of it and cannot look it up again: if you lose it, revoke it and make a new one.
Keeping it secret
The key identifies you: anyone who has it can use the API in your name.
- Call the API from your server, never from a web page or an app you distribute. The API sends no CORS headers, so browsers refuse to let web pages on other sites read its responses.
- Keep the key out of source control; read it from configuration or an environment variable.
- The key is part of the URL, so it appears wherever URLs are recorded: server and proxy logs, error reports. Do not log full request URLs.
- If a key may have leaked, revoke it on the Developers page and make a new one.
When a key stops working
A key is refused (401) once it is revoked (by you or by ORC), once its expiry date has
passed if it was given one, or while API access is withdrawn from the account that holds it.
Making requests
GET https://sas.orc.org/api/{key}/{endpoint}?{parameters}
GETonly. Any other method is answered with405.- HTTPS. The key travels in the URL; always use
https://. - Names are not case-sensitive, neither endpoint names nor parameter names:
DownRMSanddownrms,CountryIdandcountryidare the same. Nor are values that are codes:GREorgre,DHordh. - Patterns. Parameters marked pattern below match like SQL
LIKE:%stands for any run of characters and_for a single character; without either, the value must match in full.YachtName=PEG%finds PEGA and PEGASUS. Remember to URL-encode:%is written%25in a query string. - Parameters that are not recognised are ignored. Parameters described as numbers must
be numbers. The one exception is
format, where a value the service does not know is an error rather than a different answer than you asked for.
Responses and errors
Four endpoints answer with a JSON document (RMS, activecerts,
country-fleet, sssdataex) — and three of those four will answer
XML instead, if you ask for it; the three
Down… endpoints answer with a file, sent with a Content-Disposition:
attachment header that names it, in the format you ask for with ext;
advanced-polar answers with plain text. All text is UTF-8; dates are ISO 8601.
Status codes
| Status | Meaning |
|---|---|
200 |
Success. A query that matches nothing is a success too: you get an
empty list or a file with no certificates in it, not a 404. The exception is
advanced-polar, where an empty answer could pass for a polar.
|
400 |
The request cannot be answered as asked; the message says why. |
401 |
The key is missing, malformed, unknown, revoked or expired, or API access has been withdrawn from its account. |
404 |
No such endpoint; the message lists the endpoints there are. For
advanced-polar, also: no certificate with that RefNo.
|
405 |
A method other than GET. |
500 |
The service failed. Try again later; if it persists, tell ORC. |
Error body
Every error comes as JSON, with an errors array of messages:
HTTP/1.1 401 Unauthorized
Content-Type: application/json; charset=UTF-8
{
"errors": [
"Missing or invalid API key."
]
}
XML instead of JSON
format=xml on RMS,
activecerts and
sssdataex answers with the XML document ORC's older
web service has long served for the same data, so that a program written against it can be
pointed here unchanged. The rows carry the same column names and the same values as the
JSON; only the wrapping differs.
HTTP/1.1 200 OK
Content-Type: text/xml; charset=UTF-8
<?xml version="1.0" encoding="UTF-8"?>
<ROOT>
<DATA>
<ROW RowNum="1">
<CountryId>GRE</CountryId>
<dxtID>247085</dxtID>
<RefNo>03420004HJ7</RefNo>
<dxtDate>2026-03-12T14:30:45.000Z</dxtDate>
<GPH>587.2</GPH>
<Area_Sym></Area_Sym>
…
</ROW>
…
</DATA>
<ERRORS/>
</ROOT>
- Rows are
ROWelements underDATA, numbered from 1 inRowNum, with one child element per column.RMSputs its certificate types and families beside them, inCTypandCFam. - An empty column is an empty element
(
<Area_Sym></Area_Sym>) where the JSON hasnull, and a true/false column readsTrueorFalse. - Errors go in
ERRORS, asERRORelements, under the same status code the JSON answer would carry. The node is there, empty, when all went well. - The other endpoints have no XML answer.
format=xmloncountry-fleet,advanced-polaror aDown…endpoint — whose format is alreadyext's to choose — is answered with400. format=jsonmay be written out, and is what you get in any case. Any other value is a400.
Families, types and countries
Certificate families
Wherever a parameter takes a Family, it accepts the number or the code, except
activecerts, which takes only the number.
| Number | Code | Family |
|---|---|---|
| 1 | ORC |
ORC Standard |
| 2 | SY |
Super Yacht |
| 3 | DH |
Double Handed |
| 4 | MU |
Multihull |
| 5 | NS |
Non Spinnaker |
| 6 | LI |
Light |
Certificate types
Each certificate has a type within its family. The RMS endpoint
returns this list as ctyp.
| CertType | RMSCode | Name | Family |
|---|---|---|---|
| 2 | INTL |
International | 1 ORC |
| 3 | CLUB |
Club | 1 ORC |
| 12 | JAYC |
J Class | 1 ORC |
| 4 | SYIN |
Super Yacht Measured | 2 SY |
| 5 | SYCL |
Super Yacht Declared | 2 SY |
| 1 | SYCR |
Super Yacht Corinthian Spirit | 2 SY |
| 8 | DHIN |
Double-Handed International | 3 DH |
| 9 | DHCL |
Double-Handed Club | 3 DH |
| 6 | MUIN |
Multihull International | 4 MU |
| 7 | MUCL |
Multihull Club | 4 MU |
| 14 | MUMC |
MOCRA | 4 MU |
| 10 | NSIN |
Non-Spinnaker International | 5 NS |
| 11 | NSCL |
Non-Spinnaker Club | 5 NS |
| 13 | LITE |
Light | 6 LI |
Countries
Certificates are issued by national rating offices, identified by a three-letter
CountryId such as GRE, ITA or USA. A few
identifiers are not countries: SY_ for super yachts, MU_ for
multihulls, ODD for one-design classes. The RMS
endpoint tells you which countries have certificates, and every JSON rating file carries the
list of rating offices as Countries.
Certificates and boats
Every certificate has a reference number, RefNo, unique to it: no two certificates
share one, and a boat's next certificate gets a new one. A boat can hold several certificates over
the years, in more than one family. ORC does not number boats; in general a boat is the issuing
country together with its certificate file name: CountryId and dxtName
(also called BIN).
Endpoints
Eight endpoints, each described below with its parameters and a sample answer.
GET/api/{key}/RMSJSON or XML
How many active certificates there are, by country, family, certificate type and VPP year, with totals. Use it to see which countries and years have data before downloading.
Parameters
| Name | Value | Description |
|---|---|---|
Familyoptional |
number or code | Only this family. Without it, every family except super yachts. |
RMSCodeoptional |
- |
A minus sign returns only the totals across certificate types (the rows whose
CertType is null). CertType is accepted as the same parameter.
|
includesyoptional |
yes |
When no Family is given, count super yachts too. |
formatoptional |
code | xml for the legacy XML document in place of JSON.
The default is json; any other value is a 400. |
Response
data.rows holds the counts. A null in Family, CertType or
VPPYear marks a total over that column: the row with both CertType and
VPPYear null is the country's total for the family. LastUpdate is when
the country last issued a certificate in that family. data.ctyp and
data.cfam are the certificate types and
families; readme is a short plain-text note.
{
"data": {
"rows": [
{ "CountryId": "GRE", "Family": 1, "CertType": 2, "VPPYear": 2026, "CertCount": 15,
"CountryName": "Greece", "LastUpdate": "2026-03-18T15:49:08.000Z",
"CertName": "International", "RMSCode": "INTL" },
{ "CountryId": "GRE", "Family": 1, "CertType": 3, "VPPYear": 2026, "CertCount": 84,
"CountryName": "Greece", "LastUpdate": "2026-03-18T15:49:08.000Z",
"CertName": "Club", "RMSCode": "CLUB" },
{ "CountryId": "GRE", "Family": 1, "CertType": null, "VPPYear": null, "CertCount": 99,
"CountryName": "Greece", "LastUpdate": "2026-03-18T15:49:08.000Z",
"CertName": null, "RMSCode": null },
…
],
"ctyp": [ { "CertType": 2, "CertName": "International", "RMSCode": "INTL", "Family": 1,
"Title": "International", "StatCode": null }, … ],
"cfam": [ { "Family": 1, "FamilyName": "ORC Standard" }, … ]
},
"readme": "…"
}
GET/api/{key}/activecertsJSON or XML
The active certificates that match every criterion given, one row each: who the boat is and
which certificate it holds, without the rating data. Use it to find the RefNo of a
boat's certificate, then fetch its data with DownBoatRMS_byrefno
or its polar with advanced-polar.
Parameters
All optional, combined with AND.
| Name | Match | Description |
|---|---|---|
Family |
number | Family number, 1–6. Codes such as
ORC are not accepted here and match nothing. |
VPPYear |
number | VPP year of the certificate, e.g. 2026. |
CountryId |
exact | Issuing country. |
RefNo |
exact | Certificate reference number. |
YachtName |
pattern | Boat name. |
SailNo |
pattern | Sail number, as on the certificate, e.g. GRE-970. |
Class |
pattern | Boat type or class. |
formatoptional |
code | xml for the legacy XML document in place of JSON.
The default is json; any other value is a 400. |
With no parameters you get every active certificate there is: several thousand rows. Filter by country and year whenever you can.
Response
{
"data": {
"rows": [
{
"Family": 1,
"CountryId": "GRE",
"dxtID": 246855,
"RefNo": "03420004HB1",
"dxtDate": "2026-03-10T16:44:39.000Z",
"dxtName": "GR803.dxt",
"YachtName": "FAETHON",
"SailNo": "GRE-803",
"VPPYear": 2026,
"CertType": 3,
"Expiry": "2026-12-31T00:00:00.000Z",
"IsOd": false,
"Class": "MOODY 30",
"CertName": "Club",
"FamilyName": "ORC Standard"
},
…
]
}
}
| Field | Meaning |
|---|---|
RefNo |
The certificate's reference number, unique to it. |
dxtID |
ORC's internal number for this particular certificate. |
dxtName |
Certificate file name. |
dxtDate |
When the certificate was issued. |
Expiry |
When it expires. |
IsOd |
Whether it is a one-design certificate. |
CertType, CertName, Family, FamilyName |
The certificate's type and family. |
GET/api/{key}/DownRMSfile
The rating data of every active certificate of one family in a country: what a scoring program loads before an event.
Parameters
| Name | Value | Description |
|---|---|---|
CountryIdrequired |
exact | Issuing country. |
Familydefault ORC |
number or code | The family. |
VPPYearoptional |
number | Only certificates of this VPP year. Give it with rms and csv: see the
note on the header row.
|
extdefault rms |
json, rms, csv |
The format. |
Response
A file named {CountryId}_{Family}.{ext}, e.g. GRE_ORC.json. As JSON it holds
rms, the certificates, plus Countries and ScoringOptions
(see JSON). A country with no certificates gives an empty rms
list.
GET https://sas.orc.org/api/{key}/DownRMS?CountryId=GRE&Family=ORC&VPPYear=2026&ext=json
GET/api/{key}/DownBoatRMSfile
The rating data of one boat: the newest active certificate that matches every criterion given. It never returns more than one certificate.
Parameters
| Name | Match | Description |
|---|---|---|
RefNo |
pattern | Certificate reference number. When given, all the criteria below
except ext are ignored. |
CountryId |
pattern | Issuing country. NatAuth is accepted as the same parameter. |
YachtName |
pattern | Boat name. |
SailNo |
pattern | Sail number, e.g. GRE-970. |
dxtName |
pattern | Certificate file name. .dxt is added unless the value already ends with
.dxt or %. BIN is accepted as the same parameter.
|
Family |
number or code | The family; default ORC. |
ext |
json, rms, csv |
The format; default rms. |
With loose criteria many certificates can match, and you get the newest of them,
which may not be the boat you meant. Give enough to identify the boat, or better, its
RefNo, and check YachtName and SailNo in the answer.
Response
A file named ORC.{ext}. As JSON: rms with the one certificate, plus
Countries and ScoringOptions. When nothing matches, rms is
empty (in rms and csv, only the header row is there).
GET https://sas.orc.org/api/{key}/DownBoatRMS?CountryId=GRE&SailNo=GRE-970&ext=json
GET/api/{key}/DownBoatRMS_byrefnofile
The rating data of the certificate with this reference number, whether or not
it is still active. A RefNo belongs to one certificate only, so the file holds at most one.
Parameters
| Name | Value | Description |
|---|---|---|
RefNorequired |
exact | Certificate reference number. |
extrequired |
json, rms, csv |
The format. There is no default here: without ext the file is empty. |
VPPYearoptional |
number | Return the certificate only if it is of this VPP year. |
Response
A file named {RefNo}.{ext}. As JSON it holds only rms, without
Countries and ScoringOptions. An unknown RefNo, or a certificate of
another VPP year than the one asked for, gives {"rms":[]}.
GET https://sas.orc.org/api/{key}/DownBoatRMS_byrefno?RefNo=03420004I82&ext=json
GET/api/{key}/advanced-polarplain text
The polar of one certificate: the boat's speed at each true wind speed and angle, worked out from the certificate's rating data, in the tab-separated table that weather routing software reads. It is the same polar ORC's weather routing service sends to PredictWind.
Parameters
| Name | Value | Description |
|---|---|---|
RefNorequired |
exact | The certificate's reference number, active or not. |
Response
text/plain; charset=UTF-8, sent as it is, not as a download. No header row; one line per true
wind speed in knots: first 1, 2 and 3 knots, extended below the lowest wind speed on the certificate, then
each wind speed of the certificate. Each line is the wind speed followed by pairs of true wind angle (degrees)
and boat speed (knots), in order of angle, all separated by tabs. Lines end with LF, and decimals use a point.
The angles are not the same on every line, since the best beat and gybe angles change with the wind.
Errors come as JSON like everywhere else. A RefNo with no certificate gives 404.
1 0 0 47.7 0.91 52 1.01 60 1.14 75 1.24 90 1.19 110 1.14 120 1.09 135 0.93 138.7 0.88 150 0.7 165 0.58 180 0.53
2 0 0 47.7 1.8 52 1.98 60 2.21 75 2.39 90 2.29 110 2.22 120 2.13 135 1.83 138.7 1.75 150 1.41 165 1.16 180 1.07
3 0 0 47.7 2.67 52 2.9 60 3.2 75 3.43 90 3.31 110 3.24 120 3.12 135 2.71 138.7 2.59 150 2.13 165 1.76 180 1.61
…
24 0 0 40.2 7.27 52 7.97 60 8.25 75 8.77 90 9.29 110 10.12 120 10.98 135 11.62 150 10.62 164.9 9.71 165 9.67 180 9.3
GET/api/{key}/country-fleetJSON
The boats of one country, one row each: who the boat is, from its newest certificate, whether that
certificate is still active or not. Use it for a list of a country's boats;
activecerts is the one to use for certificates that are
currently valid.
Parameters
| Name | Match | Description |
|---|---|---|
CountryIdrequired |
exact | Issuing country. Not needed when search is a
reference number, which names one certificate in the whole database; given with one
anyway, it is ignored. |
searchoptional |
text | Finds the boat someone is choosing: a whole reference number — 11 characters, looked up among every certificate there is — or else a boat name or sail number, matched anywhere inside either, within the country. A search answers at most 100 rows. Without it, the whole country comes back, however many boats that is. |
Response
One row per boat, in order of dxtName. A boat is its country and its certificate file name
together, so a boat appears once however many certificates it has held. VPPYear is the VPP
year of the certificate the row was taken from, and the rest is as that certificate has it;
Designer and Builder can be null. A country with no boats gives an empty
list.
A search that is a reference number answers with certificates instead of boats, in the
same columns — so one boat can come back more than once, and a number that was issued twice and
corrected answers with every certificate that carries it (the correction adds -2 or
-3). Part of a reference number is not one: it is matched against names and sail numbers
like any other text. Searches are not case-sensitive, and % and _ in a search
are matched as themselves, not as wildcards. A reference number that matches no certificate falls back
to the name and sail number, so a sail number of 11 characters still finds its boat — but only when a
country was given, since there is no fleet to search without one.
more says whether a search had more to give: true means it matched over 100
boats and you are seeing the first 100, in dxtName order — ask the user for a longer
search rather than a longer list. A whole country is never cut, and answers "more": false.
{
"data": {
"rows": [
{
"CountryId": "GRE",
"dxtName": "GR016.dxt",
"YachtName": "AETHER",
"SailNo": "GRE-016",
"VPPYear": 2026,
"Class": "DEHLER 30 OD",
"Designer": "JUDEL FRIEDRICH / VROELIJK ROLF",
"Builder": "DEHLER"
},
…
],
"more": false
}
}
GET/api/{key}/sssdataexJSON or XML
The scratch-sheet data of one country and VPP year: each certificate's identity with the measurements
and single numbers a scratch sheet shows — GPH, CDL, APHD,
TMF_Inshore, ILCWA, the displacements, the sail areas and the rest, 41 columns
in all.
Parameters
| Name | Value | Description |
|---|---|---|
CountryIdrequired |
exact | Issuing country. |
VPPYearrequired |
number | VPP year of the certificate, e.g. 2026. |
familyoptional |
number | Family number, 1–6. Anything else is ignored, and every family comes back. |
overrideoptional |
code | Certificate type. International is IMS here, not the
INTL of RMSCode; the others are the same codes
(CLUB, DHIN, DHCL, NSIN, NSCL,
SYIN, SYCL, SYCR, MUIN, MUCL,
MUMC, JAYC, LITE). A code it does not know is ignored,
and every type comes back. |
sortoptional |
columns | The order of the rows: column names separated by commas, each with an optional
DESC (GPH DESC, Class,SailNo). A sort naming a column
the answer has not got is ignored. |
formatoptional |
code | xml for the legacy XML document in place of JSON.
The default is json; any other value is a 400. |
Response
One row per certificate. A country and year with none gives an empty list. Without sort
the order is the database's own, which is not guaranteed: ask for the order you want.
{
"data": {
"rows": [
{
"CountryId": "GRE",
"dxtID": 247085,
"RefNo": "03420004HJ7",
"VPPYear": 2026,
"dxtName": "GR046.dxt",
"YachtName": "OPTIMUM 4",
"Class": "DEHLER 30 OD",
"SailNo": "GRE-046",
"Club": "NOK",
"dxtDate": "2026-03-12T14:30:45.000Z",
"Override": "IMS",
"Division": "R",
"GPH": 587.2,
"Family": 1,
"CertType": 2,
…
"CDL": 8.893,
"APHD": 527.9946
},
…
]
}
}
Rating data formats
The Down… endpoints give the same data in three formats. JSON is the one to use in new
software; rms and csv exist for programs that already read them.
json
UTF-8, without a byte order mark. One object per certificate in rms, each with a few hundred
fields. When metric is true, measurements are in metres, square metres and
kilograms.
{
"rms": [
{
"NatAuth": "GRE",
"BIN": "GR1925",
"CertNo": "01969",
"RefNo": "03420004HB7",
"SailNo": "GRE-1925",
"YachtName": "STELLA",
"Class": "SUN ODYSSEY 42i SD",
"Builder": "JEANNEAU",
"Designer": "LOMBARD",
"C_Type": "CLUB",
"Family": "ORC",
"Division": "C",
"IssueDate": "2026-03-10T17:00:24.885Z",
"LOA": 12.526,
"Dspl_Sailing": 9550,
"CDL": 9.435,
"GPH": 660.8,
"APHD": 578,
"APHT": 1.0381,
"OSN": 635.9,
"TMF_Inshore": 0.8141,
"TMF_Offshore": 0.9435,
"TND_Offshore_Low": 804,
"TN_Offshore_Low": 0.7463,
…
"GRE_S_AP_TOD": …,
"Allowances": {
"WindSpeeds": [4, 6, 8, 10, 12, 14, 16, 20, 24],
"WindAngles": [52, 60, 75, 90, 110, 120, 135, 150],
"R52": [1228.4, 825.3, 658.9, 572.6, 521.1, 493.2, 480, 474.7, 480.6],
…
"Beat": [1973.3, 1312.9, 1031, 881.5, 790.7, 740, 719.5, 714.7, 737.9],
…
}
}
],
"Countries": [
{ "CountryId": "ORC", "Name": "Offshore Racing Congress" },
{ "CountryId": "AUS", "Name": "Australia" },
…
],
"ScoringOptions": [
{ "Families": ["ORC", "SY", "DH", "Mu", "NS", "LI"], "CountryId": "ORC",
"Kind": "TOD", "Fieldname": "APHD", "Name": "All Purpose" },
{ "Families": ["ORC", "SY", "DH", "NS"], "CountryId": "GRE",
"Kind": "PCS", "Fieldname": "OC", "Name": "Coastal/Long Distance" },
…
]
}
The certificate
- Identity:
NatAuth(issuing country),BIN,CertNo,RefNo,SailNo,YachtName,Class,Builder,Designer,Club,C_Type(certificate type code),Family,Division,IssueDate. - Measurements:
LOA,IMSL,Draft,MB,Dspl_Sailing,Dspl_Measurement,WSS, the sail areasArea_Main,Area_Jib,Area_Sym,Area_Asym,CrewWT,Age_Year,CDL. - Single-number ratings, as printed on the certificate:
GPH,APHDandAPHT,OSN,TMF_InshoreandTMF_Offshore, the triple numbersTND_…(time on distance) andTN_…(time on time) for offshore and inshore, low, medium and high wind, and the predicted-course valuesPred_Up_…andPred_Down_…. - National options: fields prefixed with a country, such as
US_…,IRL_…orGRE_…, are ratings for that country's own scoring options. Allowances: time allowances in seconds per mile. Each array has one value per wind speed inWindSpeeds(knots).R52toR150are for each true wind angle inWindAngles(degrees);BeatandRunare the upwind and downwind VMG allowances,BeatAngleandGybeAnglethe optimum angles;WL,CRandOCare the course models used by Performance Curve Scoring.
Countries and ScoringOptions
Countries lists the rating offices. ScoringOptions lists the scoring options
each office offers (CountryId ORC for the international ones):
Kind is TOD (time on distance), TOT (time on time) or
PCS (Performance Curve Scoring), and Fieldname names the certificate field that
holds the value to score with, or for PCS the array in Allowances.
Families lists the families the option applies to.
rms
The fixed-width text format read by scoring programs: a header row naming the columns, then one line per certificate. UTF-8 with a byte order mark, CRLF line ends.
NATCERTN.FILE_ID SAILNUMB NAME TYPE BUILDER DESIGNER YEAR …
GRE00764 GR2115 GRE-2115 SELINI HALLBERG-RASSY 382HALLBERG-RASSY ENDERLEIN 1984 …
csv
The same columns, comma-separated, with a header row; text values that need it are in double quotes, and numbers use a point as the decimal separator. UTF-8 with a byte order mark, CRLF line ends.
Give VPPYear with rms and csv. Certificates from VPP 2025
onwards carry allowances for 4 knots of wind, in extra columns. The header row of a
DownRMS or DownBoatRMS_byrefno file names those columns only when the request
gives a VPPYear of 2025 or later; without it, the header is shorter than the rows.
DownBoatRMS and the json format are not affected.
Good practice
- Download what you need, and keep it. Filter by country, family and VPP year, and cache the files you fetch rather than asking again for every page view. Certificates change only when one is issued or revised.
- Allow time for large files. A country file can take a few seconds; set your HTTP timeout accordingly.
- Read fields by name and ignore the ones you don't know. New fields are added from time to time, such as the 4-knot allowances in 2025.
- Treat an empty result as an answer. No match gives
200with an empty list, not an error, except fromadvanced-polar. - Requests are recorded per key and endpoint.
Last updated 21 September 2026.