---
title: "Preview a compliance export"
method: POST
path: "/compliance-exports/preview"
tags: ["Compliance exports"]
---

# Preview a compliance export

`POST /compliance-exports/preview`

## Request

- Base URL: `https://api.purplegrain.com/api/v1`
- URL: `https://api.purplegrain.com/api/v1/compliance-exports/preview`
- Auth: HTTP bearer

What a compliance export would hold, before building it (COMPLIANCE_EXPORT.md §4 "Preview"):
per property, the rows each CSV would have, the photos, a size estimate, the count of every
record kind in the scope and date range (so the dialog can show counts and disable empty
kinds, whatever `record_types` says) and the LPA fields the records do not hold, each with
the tasks to open. The export is one owner: `organization_id`, or the caller's own account
when that is blank. `"all"` is that owner's properties only. A property id the owner does
not own is a 422 and nothing is previewed. A property of that owner the caller cannot read
is listed with `access: denied` and the 403 `detail` a read of it would return, verbatim;
it is never worked around.

Reads the records through the same policy-scoped relation the task list uses, in pages of
100; nothing is written. First-party web and mobile only: an assistant or API key is refused
with a 403 and the operation is not an MCP tool.

## Request body

- ComplianceExportRequest: What to export. Flat JSON body (`application/json`); there is no JSON:API form. One owner: `organization_id`, or the caller's own account when it is blank.
  - `organization_id` string, nullable: The organisation this export is for. Blank (omitted or null) is the caller's own account. The server stores it on the export. `properties: all`, and a missing `properties`, is every property of that one owner — never every organisation the caller belongs to, and never the personal account beside an organisation. An id that owner does not own is rejected.
  - `properties` union: `"all"` (every property of `organization_id`, or of the caller's own account when `organization_id` is blank) or a list of property ids belonging to that same owner. Omitted means `"all"`.
    - 'all'
    - string[]
  - `scope` ComplianceExportScope: Within the property. `property` (the default) is everything filed on it; `block` is the live paddocks of one block; `paddocks` and `mobs` are the chosen ones. For a block or paddocks, `include_mobs_in_paddocks` (default true) adds the mobs currently in those paddocks. A kind other than `property` is only valid with exactly one property.
    - `kind` 'property' | 'block' | 'paddocks' | 'mobs'
    - `ids` string[]: The block (one id), paddocks or mobs, all on the property. Empty for `property`.
    - `include_mobs_in_paddocks` boolean
  - `from` string, date: First record date (the Melbourne day the work was done). Defaults to twelve months before `to`.
  - `to` string, date: Last record date. Defaults to today in Melbourne.
  - `record_types` string[]: Which kinds to export. Defaults to every kind. `general` is a completed task with no typed detail.
  - `include_open` boolean: Also export open tasks that already carry drafted details, each row marked `status = open`; the zip name ends `-incl-open`.

## Response `200`

The preview.

- ComplianceExportPreview
  - `zip_name` string, required
  - `properties` ComplianceExportPreviewProperty[], required
    - `property_id` string, required
    - `name` string, nullable
    - `pic` string, nullable: The property's PIC (8 letters or digits), or null when unset. One code per property.
    - `folder` string: The property's folder in the zip: `Hillcrest (PIC 3HILL012)` when a PIC is known, else the name.
    - `access` 'ok' | 'denied', required
    - `code` string: `insufficient_access`, or `not_found` for an id that is not a property. Denied only.
    - `detail` string: The 403 detail, verbatim. Denied only.
    - `counts` ComplianceExportCounts: Rows per file, and photos.
      - `tasks` integer, required
      - `mob_register_rows` integer, required
      - `husbandry_rows` integer, required
      - `paddock_register_rows` integer, required
      - `field_work_rows` integer, required
      - `weather_rows` integer, required
      - `photos` integer, required
    - `record_type_counts` object: Every kind present in the scope and date range, whatever `record_types` says, so the dialog can show counts and disable empty kinds.
    - `missing_fields` object: Per register (`mob_register`, `paddock_register`), per LPA field, how many rows lack it and which tasks.
    - `bytes_estimate` integer
  - `totals` object, required: The counts summed over the properties that passed, plus `bytes_estimate`.
  - `ok_count` integer, required
  - `denied_count` integer, required

## Other responses

- `400`: A malformed date, an `organization_id` that is not an id, an unknown record type or scope kind, a scope other than `property` with more or fewer than one property, or a block, paddock or mob that is not on the property.
- `401`: Unauthenticated
- `403`: No accepted role in `organization_id`, no properties for this owner, every property of this owner was refused (one error per property, each with its own `detail`), or an assistant / API key.
- `422`: A property id that does not belong to `organization_id` (or to the caller's own account, when `organization_id` is blank). Nothing is previewed. The detail names no property.

## Changes

- **2026-10-24** `e285768a8f1d`: 24 warning
  - added the new `map_boundaries` enum value to the `_meta/onboarding/completed_steps/items/` response property for the response status `400` (media type: application/json)
  - added the new `map_boundaries` enum value to the `_meta/onboarding/completed_steps/items/` response property for the response status `400` (media type: application/vnd.api+json)
  - added the new `map_boundaries` enum value to the `_meta/onboarding/completed_steps/items/` response property for the response status `422` (media type: application/json)
  - added the new `map_boundaries` enum value to the `_meta/onboarding/completed_steps/items/` response property for the response status `422` (media type: application/vnd.api+json)
  - …20 more
- **2026-10-24** `92f716edc989`: 16 info
  - added the optional property `_meta` to the response with the `400` status (media type: application/json)
  - added the optional property `_meta` to the response with the `400` status (media type: application/vnd.api+json)
  - added the optional property `_meta` to the response with the `422` status (media type: application/json)
  - added the optional property `_meta` to the response with the `422` status (media type: application/vnd.api+json)
  - …12 more
- **2026-10-20** `06540345bbbc`: 2 info
  - added the new optional request property `organization_id`
  - added the non-success response with the status `422`
- **2026-10-20** `29c5c990d66e`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/purplegrain/apis/purple-grain-api/changes/compliance-exports/preview/post.md)

---

[API](https://skmtc.dev/purplegrain/apis/purple-grain-api.md) - [All operations](https://skmtc.dev/purplegrain/apis/purple-grain-api/llms.txt) - [OpenAPI document](https://skmtc.dev/purplegrain/apis/purple-grain-api/revisions/7c60f959fec9?raw)
