Skip to main content
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

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: Not available:
  • PayPathIQ-owned receipt delivery. Every route is disabled and PUT .../receipt-delivery returns 409 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.
  • 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 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. 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.