Skip to content

5.5.2.2 Files

The Files domain of farm. Raw files as received, what was skipped when parsing them and the parse jobs that processed them. Organization users see what their sources sent and what failed, upload files of their own feeds and remove them; staff see everything, retry failed jobs and ask for re-parses. It is one API, with its own contract and its own version.

5.5.2.2.1 Versions

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

The resources follow the data model. Adds the upload handshake (UploadRequest, UploadTarget) for files an Organization sends by hand, which become a SyncRun of kind full_snapshot with one raw file, and the ReparseRequest of req 51.9. The capability farm.parse_jobs.manage is proposed: req 51.9 names a Moonitoring user but the catalog has no capability for it.

Removing an uploaded file is a logical withdrawal: its active evidence is cancelled under a file_removal WriteCommit, while the original object remains under the raw-retention policy until erasure. RawFileView adds withdrawn_at to the API response without changing the meaning of RawMetadata.deleted_at, which records physical deletion. Repeating a withdrawal does not append another cancellation revision, and a pending parse must not republish withdrawn evidence. Uploading the same bytes of a withdrawn file returns 409; this contract does not introduce a restore operation.

An upload is known only when the server has verified the stored object's uncompressed hash and size and the object remains available. An erased or missing object cannot satisfy this condition: if its metadata already exists, announcing it returns 409 without automatically restoring it. The response always supplies either the known raw file or upload instructions. Reusing bytes does not certify that the current delivery was processed, and a full-snapshot label alone does not establish completeness or authorize inferred deletions. Downloading an erased raw returns 410; an unexpectedly unavailable object returns 409. Neither response includes a signed URL.

5.5.2.2.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 a farm's raw files GET /organizations/{organization_id}/raw-files Organization users, staff or clients farm.ingestion.read or farm.ingestion.read_all
Read a raw file's metadata GET /raw-files/{raw_file_id} Organization users, staff or clients farm.ingestion.read or farm.ingestion.read_all
Get a download link POST /raw-files/{raw_file_id}/download-url Organization users, staff or clients farm.ingestion.read or farm.ingestion.read_all
Remove an uploaded file POST /raw-files/{raw_file_id}/remove Organization users farm.animal_records.edit_own
List a raw file's skips GET /raw-files/{raw_file_id}/skips Organization users, staff or clients farm.ingestion.read or farm.ingestion.read_all
List a raw file's parse jobs GET /raw-files/{raw_file_id}/parse-jobs Organization users, staff or clients farm.ingestion.read or farm.ingestion.read_all
Announce an upload POST /organizations/{organization_id}/uploads Organization users farm.animal_records.edit_own
Commit an upload POST /uploads/{upload_id}/commit Organization users farm.animal_records.edit_own
Summarize a farm's skips GET /organizations/{organization_id}/skips Organization users, staff or clients farm.ingestion.read or farm.ingestion.read_all
Get the row-level detail of a skip POST /skips/{skip_id}/detail-url Organization users, staff or clients farm.ingestion.read or farm.ingestion.read_all
List parse jobs GET /parse-jobs Organization users, staff or clients farm.ingestion.read or farm.ingestion.read_all
Ask for a re-parse POST /parse-jobs Staff farm.parse_jobs.manage
Read a parse job GET /parse-jobs/{job_id} Organization users, staff or clients farm.ingestion.read or farm.ingestion.read_all
Retry a failed job POST /parse-jobs/{job_id}/retry Staff farm.parse_jobs.manage

5.5.2.2.3 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.

5.5.2.2.4 Rules Confirmed with the Implementation

Decided on 2026-11-05, from the choices made while building farm:

  • Raw objects are zstd frames, addressed by content: raw/<farm>/<feed>/<hash_type>/<data_hash>.zst, hashes in lower-case hex (xxh3 is the 64-bit variant). At commit the server reads the object, decompresses it and checks its hash and size before it records the RawMetadata, so only verified objects are ever reused.
  • Run logs are raw/<farm>/<feed>/runs/<run>.jsonl; the run records the path, and a commit that names another path is a 422.
  • Skip logs are JSONL at raw/<farm>/<feed>/skips/<job>/<n>.jsonl, one object per skipped row, as the parser gives it.