Coastal Intelligence
Issued not yet
Assistant LLM provider: LLM …

Logger and gateway integrators

Observations webhook

POST readings for a site from a logger, gateway or app: the key, the item fields, the accepted properties and units, the all-or-nothing and idempotence rules, and the response shape.

Last reviewed

What it is for

A logger, a buoy gateway or a phone app that wants to push readings for a site sends them to POST /sites/{site_id}/observations. The readings land next to the site's other observations (source webhook, scale site) and are used by the signals and the assistant like any other site-scale observation. They are operator records: the agency tools never return them (REST API).

Authentication

Send the deployment's webhook key in the X-API-Key header. It is one machine credential set by the deployment's administrator (not an agency key, not issued through the access request form) and it is administrator-equivalent: give it only to systems you control. When no key is configured the endpoint is disabled and answers 503; a missing or wrong key is 401.

Request

A JSON array of 1 to 10,000 items, each shaped like a SOSA observation (observed property, simple result with unit, result time, sensor):

FieldTypeRequiredMeaning
propertystringyesThe observed property: one of the ids in the table below (sst, salinity, hs, ...).
valuenumberyesThe result, a finite number.
unitstringyesThe property's canonical unit or a convertible spelling (unit table below); the value is stored in the canonical unit.
timestringyesResult time, ISO 8601 with an offset (Z or +HH:MM); not more than 1 hour in the future.
depth_mnumbernoMetres below the surface (0 to 11 000); omit for the surface or a value without depth.
sensor_idstringnoThe sensor, letters, digits and . _ : - (up to 64 characters); each sensor is its own series.

Observable properties

The property ids the webhook accepts, with the canonical unit each is stored in:

PropertyCanonical unit (QUDT)Stored as
air_tempDEG_CdegC
catchment_rain_mmMilliMmm
chlMilliGM-PER-M3mg/m3
condition_indexUNITLESS1
dirDEGdeg
faiUNITLESS1
harvest_kgKiloGMkg
hsMm
length_mMm
mldMm
ndviUNITLESS1
no3MilliMOL-PER-M3mmol/m3
o2MilliMOL-PER-M3mmol/m3
parMOL-PER-M2-DAYmol/m2/d
pct_mortalityPERCENT%
po4MilliMOL-PER-M3mmol/m3
rainMilliMmm
salinityPSUPSU
sstDEG_CdegC
sst20mDEG_CdegC
swell_hsMm
tpSECs
tp_peakSECs
turbidityUNITLESS1
tzSECs
uM-PER-SECm s-1
vM-PER-SECm s-1
water_level_latMm
wet_kgKiloGMkg
windKNkn
wind_dirDEGdeg

Units

Case and spaces are ignored; the QUDT name (for example DEG_C or unit:DEG_C) and the stored spelling are always accepted. Other spellings are converted to the canonical unit; the original value and unit are kept in the row's metadata.

Canonical (QUDT)Stored asAlso accepted (converted where needed)
DEG_CdegCC, celsius, deg C, deg_c, degF, degree_C, degree_Celsius, degrees_C, K, kelvin, °C, °F
PSUPSU1e-3, PSS-78, pss78, psu
MilliGM-PER-M3mg/m3mg m-3, mg.m-3, mg/m^3, milligram m-3, ug L-1, ug/L, ug/l
MilliMOL-PER-M3mmol/m3millimol m-3, mmol m-3, mmol.m-3, mmol/m^3, uM, umol L-1, umol/L
MOL-PER-M2-DAYmol/m2/dmol m-2 d-1, mol m-2 day-1, mol/m2/day, mol/m^2/d
Mmcm, ft, meter, meters, metre, metres
SECsmin, sec, second, seconds
DEGdegdeg true, degree, degrees, degT, °
KNknkm/h, knot, knots, kt, kts, m s-1, m/s
M-PER-SECm s-1cm/s, kn, m.s-1, m/s, ms-1
MilliMmmcm, in, kg m-2, m
UNITLESS1, -, dimensionless, none, ratio, unitless
KiloGMkgg, lb, t, tonnes
PERCENT%fraction, pct, percent

Rules

  • All or nothing. Any invalid item answers 422 and nothing is stored. detail is a list of {loc, msg, type} with loc = ["body", <item index>, <field>]. Two items with the same property, sensor, depth and time are refused too (422 on the later one).
  • Idempotent. Re-sending an observation (same site, property, sensor, depth and time) updates its value in place; the response counts it under updated.
  • Stored row. Variable = property, value and unit in the canonical unit, time in UTC, product webhook:<sensor_id> (or webhook without a sensor), metadata with the sensor, the time received and, when converted, the value and unit as sent.
  • 404 for an unknown site; 409 for a site that has no operator account to own the records.
  • Clock skew: a time more than 1 hour in the future is refused.

Example of the shape

Shape only: the values are placeholders, not readings.

curl -X POST https://coastal-intelligence.triskelionaisystems.com/api/sites/<site id>/observations \
  -H "X-API-Key: $WEBHOOK_API_KEY" -H "Content-Type: application/json" \
  -d '[{"property":"<property id>","value":"<number>","unit":"<unit>","time":"<YYYY-MM-DDThh:mm:ssZ>","depth_m":"<number, optional>","sensor_id":"<id, optional>"},{"property":"<property id>","value":"<number>","unit":"<unit>","time":"<YYYY-MM-DDThh:mm:ss+01:00>"}]'

201 Created with:

{
  "site_id": "<site id>",
  "received": "<number of items>",
  "observations": {
    "inserted": "<count>",
    "updated": "<count>"
  },
  "variables": [
    "<property id>",
    "<...>"
  ],
  "products": [
    "webhook",
    "webhook:<sensor_id>"
  ]
}
Observations webhook · Developers · Coastal Intelligence