> ## Documentation Index
> Fetch the complete documentation index at: https://docs.batchrelay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Asset sessions and event image imports

> Stage, review, and commit event images without binding files before review.

> The checked-in Go OpenAPI and handler tests define these routes, but a usable
> deployment also needs the studio-asset and event-image-import adapters,
> authorized API-key scopes, backing state stores, and deployment configuration.
> Do not treat source routes or CLI help as deployment evidence. The public
> `batchrelay` CLI source provides a Smart Crop V2 folder workflow and a raw
> request alternative. Public HTTPS source ingestion and durable image-import
> commit remain fail-closed until their server adapters are configured and
> deployed.

An asset session is studio-scoped and carries a declared purpose and destination.
The current route contract does not promise one universal session implementation
for every catalog, branding, event, and template use case. Permanent records
should reference Batch Relay asset IDs, never a third-party URL.

```text theme={null}
create session -> upload or ingest -> finalize -> prepare import -> review -> commit
```

The current OpenAPI session routes are:

```text theme={null}
POST /v1/studios/{studio_id}/asset-sessions
GET  /v1/studios/{studio_id}/asset-sessions/{session_id}
PUT  /v1/studios/{studio_id}/asset-sessions/{session_id}/assets/{asset_id}
POST /v1/studios/{studio_id}/asset-sessions/{session_id}/finalize
POST /v1/studios/{studio_id}/asset-sessions/{session_id}/cancel
```

The current OpenAPI event-import routes are:

```text theme={null}
POST  /v1/studios/{studio_id}/events/{event_id}/image-imports
GET   /v1/studios/{studio_id}/events/{event_id}/image-imports/{import_id}
PATCH /v1/studios/{studio_id}/events/{event_id}/image-imports/{import_id}
POST  /v1/studios/{studio_id}/events/{event_id}/image-imports/{import_id}/commit
POST  /v1/studios/{studio_id}/events/{event_id}/image-imports/{import_id}/cancel
```

An import request references an `asset_session_id`, an
`expected_session_revision`, and a manifest. A raw request may use either a
`staged` or `smart_crop_masters_preview` manifest; the latter also carries the
frozen `smart_crop_manifest` document. Nothing should bind to the event until
the durable commit adapter rechecks the current state.

## Resolution policy

Every requested output reports source pixels, output inches, effective PPI,
grade, and a human message.

| Grade     | Effective PPI | Result                        |
| --------- | ------------- | ----------------------------- |
| `ready`   | 300 or higher | Accept normally.              |
| `warning` | 150 to 299    | Show the warning in review.   |
| `blocked` | Below 150     | Require an explicit override. |

A below-minimum override requires both an acknowledgement and a non-empty
reason. Batch Relay records the actor, time, policy version, affected output,
effective PPI, and reason. It does not upscale the source or suppress the
warning.

Use a deployment that has the required adapters and scopes. The CLI's Smart
Crop V2 folder workflow creates the session, uploads declared masters,
finalizes it, and prepares the import with one stable root idempotency key:

```bash theme={null}
batchrelay events images prepare --event evt_example \
  --folder ./masters \
  --manifest ./Smart-Crop-Masters-Preview.json \
  --mapping-csv ./mapping.csv \
  --idempotency-key smart-crop-event-20260829
```

`--mapping-csv` is optional. The folder must contain the declared JPEG masters.
The CLI rejects an incomplete or altered manifest before any request: it
requires schema version `batchrelay.smart-crops/v1`, coordinate space
`oriented-source-pixels-top-left`, a producer name/version, 1–500 declared
JPEGs, and matching local bytes, SHA-256, dimensions, and safe filenames. It
passes the frozen Smart Crop manifest through unchanged; it does not recalculate
crop rectangles.

For an already-created session or a non-folder caller, the raw primitive is
still available:

```bash theme={null}
batchrelay events images prepare --event evt_example --file image-import.json \
  --idempotency-key image-import-20260829
batchrelay events images review imp_example --event evt_example --file review.json
batchrelay events images commit imp_example --event evt_example \
  --file commit.json --idempotency-key image-commit-20260829
```

The asset and import lifecycle uses authoritative optimistic-concurrency
revisions. The raw request bodies are:

```json theme={null}
// finalize.json
{ "expected_revision": 4 }
```

```json theme={null}
// image-import.json for a staged session
{
  "asset_session_id": "ass_example",
  "expected_session_revision": 5,
  "manifest": {
    "kind": "staged",
    "entries": [{ "client_local_id": "master-001", "asset_id": "asset_example" }]
  }
}
```

```json theme={null}
// review.json
{
  "expected_revision": 6,
  "resolution_overrides": [{
    "policy_version": "resolution-v1",
    "reason": "customer-supplied-only-source",
    "effective_ppi": 120,
    "output": "print-8x10"
  }]
}
// commit.json
{ "expected_revision": 7 }
```

Review returns PPI diagnostics with source pixels, output inches, effective
PPI, grade, and human message. Below-minimum work requires an explicit audit
override; it is not silently upscaled. Re-read the returned revision after
every lifecycle step and use that value for the next review, commit, or cancel.

The lower-level commands remain available for explicitly managed sessions:
`batchrelay assets sessions create|upload|get|finalize|cancel` and
`batchrelay events images get|cancel`. A session upload is one declared local
JPEG; do not substitute a public HTTPS URL until ingestion is deployed.

The CLI source currently has the folder/manifest path above, but its local
build must stay in lockstep with the generated public API client before it can
be released. The configured deployment is still the product gate: source
ingestion from public HTTPS URLs and durable event-image commit fail closed
without their corresponding server-side adapters.

## Recovery

Retry uploads with the same session and idempotency key. Fix a manifest or CSV
before retrying prepare. Review unresolved bindings rather than committing
them. A stale commit returns a conflict, so prepare and review again with the
current revisions. Cancel abandoned sessions and imports instead of reusing an
expired upload grant.
