# APS Web catalog 1.0.0

Fixed oracle: Charter c4 b5566059982903fa34951a96ceec7c9253558446, catalog-c4 §§1–4. Public Web read contract, independent of responder v3/v2 packs and SDK operations.

| Route | Query | Closed response |
| --- | --- | --- |
| GET /api/agent/aps/catalog | q (UTF-8 ≤512B; NFKC/trim/casefold), status=all/recruiting/evaluated/not_started, sort=name/latest, page_size=10/25/50/100, page≥1, snapshot_id?, cursor? | ln_church.aps_catalog.v1 / $defs.list |
| GET /api/agent/aps/catalog/{svc_128bithex} | snapshot_id?, page_size?, page?, cursor? | ln_church.aps_catalog_service.v1 / $defs.detail |

All card fields and task references are required; nullable values and unavailable counts remain distinct from numerical zero. ResultSummary reads the selected immutable public aggregate; ref fixes study, wave, snapshot and published_at. Read existing `/api/agent/aps/studies/{study_id}?snapshot_id={result_ref.snapshot_id}` and answers routes for conditions/results, and the existing Task detail route for published Tasks. Do not mix ongoing answers into that result.

No payer proof, signature, payment, Jev, external URL fetch or Task generation. Existing origin/quota policy and no-store/no-cache apply. Unknown/duplicate query fields or mismatched cursor/query give400 invalid_request. Page>1 requires snapshot/cursor. Hidden/direct unknown service404; generation unavailable410 snapshot_unavailable; projection/read availability unknown503 temporarily_unavailable. Explicit refresh is a new page1 request without snapshot/cursor. Historical generations retain current stop/delete guards and never silently switch.

Q01 uses existing selections[].source_snapshot_id in APS prepare/quote. Selection is retained through preview, quote, order and generation. Errors use existing envelope/field_errors `{path,code}`:422 source_snapshot_invalid,410 snapshot_unavailable at selections[i].source_snapshot_id; inaccessible resource404; read outage503. A new unpaid registration rechecks the same selection before dispatch; an existing payment attempt recovers its original binding.

Q02 uses existing generic registration.participation. Only INCLUDE with complete frozen S/count=0 is422 invalid_structure / field_errors registration.participation.source_task_id:empty_participation_set at quote/replayed unpaid quote and initial unpaid dispatch. S includes all structurally accepted respondents irrespective of quality/payment. ANY/EXCLUDE, incomplete S and existing attempts preserve their contracts. Rule version aps-source-selection.c4 is private quote/intent binding.

Implementation evidence and isolated reproducible inputs: tests/evidence/v1814/backend-b5. UI and SDK connections are owned by DC's subsequent handoff, not verified by Backend.
