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

# Certification and capabilities

> What the loan and service-charge journeys cover, what is proven where, and what is unavailable.

PayPathIQ proves each published journey with a repeatable synthetic harness. This page states the capabilities the `/v1` runtime supports, the ones it does not, and how the evidence is kept apart so that one kind of proof is never mistaken for another.

## Certification status

| Evidence | Status |
| - | - |
| Local proof: both profiles in both feed modes run through the public route handlers on freshly migrated PostgreSQL, each request and response validated against the strict schemas, the generated OpenAPI document and the published examples | Done and repeatable |
| Deployed sandbox run of the exact released build | Pending. It is recorded only after the sandbox environment is available and the harness passes against it. |
| Payment provider acceptance (a real provider confirmation of a hosted payment) | Not yet evidenced. A hosted payment is confirmed only by a verified provider event. |
| Client recovery activation | Not part of certification. A Client authorizes it separately, per connection. |

Do not treat a sandbox as certified until the deployed run is recorded on your connection. A passing local run proves the code, not a deployment, a provider account or a Client's decision.

## Capabilities

Supported for `credit_union.v1` and `property_management.v1`, with the same shared `/v1` core:

* Customer and Receivable intake, one record per request or as bounded [asynchronous batches](/concepts#asynchronous-batches).
* [Transaction and snapshot-only feed modes](/concepts#source-balance-snapshots). Snapshot-only connections send [ordered balance snapshots](/concepts#source-balance-snapshots); their event balance writes (payments, refunds, reversals, credit notes, adjustments and write-offs) return [`409 financial_operation_required`](/problems/financial_operation_required).
* [Payments with partial allocation, refunds and reversals](/concepts#payment-observations), and [non-cash corrections](/concepts#non-cash-financial-changes).
* [Complete books](/concepts#complete-books-and-missing-records), [source freshness](/concepts#source-freshness) and [explicit recovery instructions](/concepts#recovery-entry).
* [Hosted payment requests](/concepts#hosted-payment-requests) up to the payment link, which the payer opens; PayPathIQ never takes card data.
* [Payment reconciliation](/concepts#payment-reconciliation) against accounting receipt lines, and [partner-owned delivery](/concepts#partner-owned-delivery) records.
* [Collection summaries](/concepts#collection-summaries), the [change feed](/change-feed) and signed [webhooks](/webhooks).

Not available:

* PayPathIQ-owned receipt delivery. Every route is disabled and `PUT .../receipt-delivery` returns [`409 receipt_delivery_route_unsupported`](/problems/receipt_delivery_route_unsupported) because no Blockman receipt-posting endpoint, no Blockman transaction CSV format and no Xero write contract is verified. Keep the connection's receipt delivery owner as `partner`. With the owner set to `paypathiq`, partner delivery and reconciliation operations return [`409 receipt_delivery_owner_mismatch`](/problems/receipt_delivery_owner_mismatch).
* Confirming a payment from the API. Only a verified provider event confirms a hosted payment.
* Production ingestion, recovery or payment-provider activation as part of certification.

## The worked synthetic journey

The loan and the service-charge journey are identical except for the Receivable type: a loan sends `financialType: "loan_balance"` with a `creditUnion` object, a service charge sends `financialType: "service_charge_demand"` with a `propertyManagement` object. Each run uses its own identifiers, so it can be repeated.

1. Read the contract, then confirm that a missing key and an unknown key return `401 invalid_api_key` and that another Client's code returns `403 client_scope_denied`. Take a change-feed cursor with `from=latest`.
2. Create a Customer with a Contact, replay it (`200`), patch it with `application/merge-patch+json`, and confirm that another media type returns `415`.
3. Create two Receivables (EUR 1,000.00 and EUR 400.00). Replaying the identical request returns `200`; a different balance at the same revision returns `409`; a descriptive patch needs a newer `sourceRevision`.
4. Authorize recovery for the first Receivable with a revision 1 instruction. The response reports `recoveryHeld: true` while the connection is not activated for collection. Withdraw it with revision 2.
5. In transaction mode, record a EUR 300.00 payment allocating EUR 250.00 (EUR 50.00 stays unapplied), a partial refund, a full reversal and the three non-cash corrections, checking each resulting balance. An allocation above the balance returns `409 allocation_exceeds_balance`; a refund above what the payment allocated returns `409 payment_observation_conflict`. In snapshot-only mode the same event writes return `409 financial_operation_required` and a newer ordered snapshot sets the balance instead.
6. Submit an ordered balance snapshot, replay it, and confirm a position that is not higher returns `409 source_position_conflict`.
7. Create a hosted payment request for the second Receivable's exact balance. A changed body returns `409 payment_request_conflict` and a stale amount `409 payment_request_stale`. The response carries the payment link; a later read returns `paymentUrl: null`.
8. After a verified provider event confirms the payment, acknowledge it with two payment reconciliations (a partial receipt line, then the remainder). Read the delivery and see `accountingAcceptance: "acknowledged"`; a delivery attempt on its own never changes it.
9. Submit a batch of a Customer and a Receivable, wait for `succeeded`, and replay it. Submit a batch with a missing dependency and see `failed` and `dependency_failed` per record, then resubmit the corrected records under a new batch.
10. Declare a complete book from the two successful batches. A wrong `expectedReceivableCount` returns `409 book_completion_unverified`. Receivables outside the book are held as `missing_from_complete_book`, never deleted or settled, and the collection summary shows it.
11. Configure a webhook endpoint, read the change feed from the cursor of step 1 page by page, resume from the same cursor and see the same events, and verify each webhook signature with the one-time signing secret.

## Run the harness

The harness is `pnpm certify:inbound-api` in `apps/paypathiq`. It sends only synthetic records, paces itself under the 60 requests per minute limit, refuses production hosts, and writes a redacted summary with no keys, secrets or payload bodies. Use `--dry-run` to check the contract digest without sending anything. Your own integration tests can follow the steps above with the [OpenAPI document](https://docs.paypathiq.com/generated/inbound-api-v1.openapi.json) and the examples it carries; every example is validated against the strict schemas in PayPathIQ's own tests.

## Measured and declared limits

The published limits are declared values: a 256 KiB request body, 100 records per batch, 2 queued or running batches per connection, 60 requests per minute with one concurrent request per key, 30 days of change-feed retention, and the webhook delivery schedule in [Webhooks](/webhooks#where-the-limits-come-from). They are not load-tested. The deployed run records the latencies it observes, but those are observations from one synthetic run, not a service-level commitment.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.