Skip to content

5.5.2.5 Observations

The Observations domain of farm. Measured and computed values about animals, groups and farm products, with the catalogs that give them meaning (types, methods, contexts, body sites), the sessions and samples that group them, the selections among proved duplicates and the derivations of computed values. Readers see the current revision or the data as it was at a write number. Model predictions are requested here and recorded as computed observations. It is one API, with its own contract and its own version.

5.5.2.5.1 Versions

Version Status Prod URL Contract
v1 Proposed https://farm.moonitoring.com/observations/v1 observations/v1/openapi.yaml

The resources follow the data model. ObservationEntry is parsed from an app raw file like every source. Predictions (PredictionRequest) and the model catalog (AvailableModel) have no entity: they are the surface of farm.models.use and of the model APIs of ai-model-platform. ObservationLineage is the read of the LINEAGE rule.

5.5.2.5.2 Operations

Every operation names who calls it and the capability it checks (x-moonitoring-audience, x-moonitoring-capability in the contract); every capability is in the catalog of the data model (req 1002, 1006). Lists are paged by cursor, writes that create something carry an Idempotency-Key, errors are Problem Details.

Operation Request Who Capability
List observations GET /organizations/{organization_id}/observations Organization users, staff or clients farm.animal_records.read or farm.canonical_data.read_all
Record an observation POST /organizations/{organization_id}/observations Organization users farm.animal_records.edit_own
Read an observation GET /observations/{observation_id} Organization users, staff or clients farm.animal_records.read or farm.canonical_data.read_all
List an observation's revisions GET /observations/{observation_id}/revisions Organization users, staff or clients farm.animal_records.read or farm.canonical_data.read_all
Read an observation's lineage GET /observations/{observation_id}/lineage Organization users, staff or clients farm.animal_records.read or farm.canonical_data.read_all
Read the duplicate selection GET /observations/{observation_id}/selection Organization users, staff or clients farm.animal_records.read or farm.canonical_data.read_all
Correct an observation POST /observations/{observation_id}/correct Organization users farm.animal_records.edit_own
Cancel an observation POST /observations/{observation_id}/cancel Organization users farm.animal_records.edit_own
Read a derivation GET /derivations/{derivation_id} Organization users, staff or clients farm.animal_records.read or farm.canonical_data.read_all
List sessions GET /organizations/{organization_id}/sessions Organization users, staff or clients farm.animal_records.read or farm.canonical_data.read_all
Read a session GET /sessions/{session_id} Organization users, staff or clients farm.animal_records.read or farm.canonical_data.read_all
List a session's observations GET /sessions/{session_id}/observations Organization users, staff or clients farm.animal_records.read or farm.canonical_data.read_all
List samples GET /organizations/{organization_id}/samples Organization users, staff or clients farm.animal_records.read or farm.canonical_data.read_all
Read a sample GET /samples/{sample_id} Organization users, staff or clients farm.animal_records.read or farm.canonical_data.read_all
List product lots GET /organizations/{organization_id}/product-materials Organization users, staff or clients farm.animal_records.read or farm.canonical_data.read_all
Read a product lot GET /product-materials/{material_id} Organization users, staff or clients farm.animal_records.read or farm.canonical_data.read_all
List the models an Organization may use GET /organizations/{organization_id}/models Organization users farm.models.use
Request predictions POST /organizations/{organization_id}/predictions Organization users farm.models.use, entitlement farm.models.<model>
List observation types GET /observation-types Organization users, staff or clients none: any member of the Organization
Create an observation type version POST /observation-types Staff farm.reference_data.manage
Read an observation type GET /observation-types/{type_id} Organization users, staff or clients none: any member of the Organization
Activate an observation type POST /observation-types/{type_id}/activate Staff farm.reference_data.manage
Retire an observation type POST /observation-types/{type_id}/retire Staff farm.reference_data.manage
List observation methods GET /observation-methods Organization users, staff or clients none: any member of the Organization
Create an observation method version POST /observation-methods Staff farm.reference_data.manage
List observation contexts GET /observation-contexts Organization users, staff or clients none: any member of the Organization
Create an observation context POST /observation-contexts Staff farm.reference_data.manage
List body sites GET /body-sites Organization users, staff or clients none: any member of the Organization
Create a body site POST /body-sites Staff farm.reference_data.manage

5.5.2.5.3 gRPC

ai-model-platform batch scoring appends predictions as computed observations and events, under one WriteCommit per farm that references the ModelRun.

Service RPC Callers
ComputedRecordsService AppendComputedRecords ai-model-platform

The contract is observations.proto, package moonitoring.farm.observations.v1:

// Proposed contract, version 1. Status: proposal for review, not confirmed design.
//
// How model outputs enter the canonical data: as observations or events with a ComputedSourceOrigin, the model and
// its version as origin version, and a derivation that names the exact input revisions, under one WriteCommit of kind
// computation that references the ModelRun.
// Callers: ai-model-platform (batch scoring writes predictions back; req 19.*.4, 57, 61, 62).
// Deadline: 60 s per stream; a batch opens one stream per farm.
// The callers listed are authentication only (decided 2026-11-11): each RPC below names who may call it and what
// it sees, and refuses anyone else with PERMISSION_DENIED.
// x-moonitoring-callers: ai-model-platform
// x-moonitoring-requirements: 19.*.4, 57, 61, 62
syntax = "proto3";

package moonitoring.farm.observations.v1;

import "google/protobuf/timestamp.proto";

service ComputedRecordsService {
  // Appends computed observations and events for one farm under one WriteCommit. The stream is committed when it
  // closes cleanly and rolled back otherwise; a record identical to the last revision produces no new revision.
  // Callers: ai-model-platform only. Sees: only its commit; it writes only computed records of a ModelRun it
  // started.
  rpc AppendComputedRecords(stream AppendComputedRecordsRequest) returns (AppendComputedRecordsResponse);
}

message AppendComputedRecordsRequest {
  oneof payload {
    // Sent once, first.
    Header header = 1;
    ComputedObservation observation = 2;
    ComputedEvent event = 3;
  }
}

message Header {
  string request_id = 1;
  string farm_id = 2;
  // The ModelRun the records come from (ai-model-platform).
  string model_run_id = 3;
  // The write number the model read; inputs must be at or below it.
  int64 data_seq = 4;
  // The ComputedSourceOrigin and its OriginVersion (the model and its version).
  string origin_version_id = 5;
}

message ComputedObservation {
  // Exactly one subject.
  string animal_id = 1;
  string animal_group_id = 2;
  string observation_type_id = 3;
  // ObservationTime as JSON, as defined in the shared types.
  string time_json = 4;
  // ObservationValue as JSON.
  string value_json = 5;
  string context_id = 6;
  // Stable key of this output within the model run, so a replay produces no duplicate.
  string source_record_key = 7;
  Derivation derivation = 8;
}

message ComputedEvent {
  string animal_id = 1;
  string animal_group_id = 2;
  // The CanonicalEvent subtype, e.g. HeatEvent.
  string event_type = 3;
  // EventTime as JSON.
  string occurred_json = 4;
  // The typed fields of the subtype as JSON.
  string fields_json = 5;
  string source_record_key = 6;
  Derivation derivation = 7;
}

message Derivation {
  // CodedValue as JSON: the transformation, with its version.
  string transformation_json = 1;
  // Exact revisions the output was computed from.
  repeated RecordReference inputs = 2;
  string parameters_json = 3;
  google.protobuf.Timestamp computed_at = 4;
}

message RecordReference {
  // observation, event, session, resolved_event, period, animal_link, sample, product_material, ...
  string entity_kind = 1;
  string revision_id = 2;
}

message AppendComputedRecordsResponse {
  // The WriteCommit that made the records available.
  int64 write_seq = 1;
  int32 observations_written = 2;
  int32 events_written = 3;
  // Records identical to their last revision.
  int32 unchanged = 4;
}

5.5.2.5.4 Contract v1

Proposed version

v1 is a proposal for review: its endpoints, errors and capabilities were designed from the requirements and the flows and are not confirmed. It leaves proposal with its first release; from then on it changes only as described in Every API Is Versioned.