Report the observed outcome of a scored session
Close the calibration loop. Tell Goable what actually happened after a score — the self-calibration pipeline uses these to refit the per-spot curves and the verification layer measures forecast skill.
Why submit outcomes
Goable is physics-first, but physics alone can't tell you whether a Tarifa kitesurf school actually runs sessions at 18kt vs cancels at 20kt. Operator outcomes are what bend the curves to your local reality. Three things downstream consume them:
- Self-calibration — weekly Bayesian refit of the per-(activity × cell) curves, once a cell reaches ≥150 paired outcomes.
- Forecast verification — Brier Skill Score + reliability diagrams, stratified by horizon, sub-spot, cluster.
- Drift monitor — statistical-process-control CUSUM over daily skill, catches regime shifts between weekly recalibrations.
The more outcomes you submit, the more your curves diverge from the generic base profile and start tracking your operators. Until a cell reaches the threshold, scores fall back through the spatial hierarchy (sub-spot, then cluster, region, base).
Request
The sessionId in the URL is the one returned by /v1/score (UUID in the response metadata.sessionId). Outcomes can be submitted up to 48 hours after the scored window ends.
{
"outcome_type": "ran",
"detail": {
"participants": 8,
"wind_actual_kt": 18.5,
"notes": "perfect lunch session"
}
}The detail object is free-form JSON — schema is up to you. Common fields: actual wind/wave readings, participant count, cancellation reason, equipment. 202 Accepted on success (the record is queued for the next calibration batch).
Outcome types
ranSession went ahead as planned. Counts as a positive outcome — the score's prediction was confirmed by the operator running.cancelledConditions degraded — operator pulled the plug. Counts as a negative outcome for the calibration loop.no_showParticipants didn't show up. Excluded from skill scoring (it's a demand signal, not a weather signal).rescheduledMoved to a different slot. Excluded from skill scoring (the original window's verdict wasn't tested).noteFree-form annotation, no signal. Useful for operator field journals; never feeds the calibrator.Scope requirement
Your API key needs the outcomes:write scope. Live keys get it by default; test keys don't (so CI traffic doesn't pollute the calibration dataset). Mint a fresh live key from the tenant portal at console.goable.io/portal/keys if the existing one lacks the scope.
Privacy + research
Outcomes are tenant-private by default and never cross-pollinate calibration. If you've opted into the research dataset (Stream A), anonymised aggregates (k≥10, 1km² grid, 90-day lag) feed the public forecast-verification export. Opt out by flipping research_consent = false on your tenant.
Errors
403 FORBIDDEN — missing outcomes:write scope. 404 SESSION_NOT_FOUND — sessionId not in the audit log (probably scored under a different tenant or older than 48h). 422 VALIDATION_ERROR — invalid outcome_type or malformed detail JSON.