Gateway API
Send middleware for the FedNow Service: idempotency-keyed REST northbound,
event-sourced state machine on SQLite, a real outbox, a background
reconciler that resolves timeouts via pacs.028 (never a blind resend), and
a swappable southbound (simulator today — HTTP or MQ semantics — the real
IBM MQ adapter per docs/design/mq-transport.md).
New here? The repo-root QUICKSTART sends a payment in five minutes. SDKs: Python · Java.
cargo run -p fednow-sim # terminal 1FEDNOW_GW_SOUTHBOUND=mq cargo run -p fednow-gateway # terminal 2# or both at once: docker compose up --buildREST API
Section titled “REST API”| Method | Path | Purpose |
|---|---|---|
POST |
/payments |
Submit a payment. Idempotency-Key header mandatory (missing → 400). Profile violation → 422 + {"codes": [...]}. |
GET |
/payments/{key} |
Current state (404 for unknown keys). |
POST |
/payments/{key}/reconcile |
Drive one reconciliation pass now (also runs on the background sweeper). |
GET |
/ops/summary |
Operational snapshot: counts by state, outbox_pending, oldest_unresolved_age_secs. |
GET |
/healthz |
Liveness. |
Submission body (amounts are integer cents):
{ "reference": "ORDER0001", "amount_cents": 125000, "debtor_name": "Jane Example", "debtor_account": "123456789012", "creditor_name": "John Example", "creditor_account": "987654321000", "creditor_agent_routing_number": "992000008", "category_purpose": "CONS", "end_to_end_identification": "optional — defaults to reference", "uetr": "optional"}States: CREATED → VALIDATED → SUBMITTED → ACK_PENDING → SETTLED | REJECTED,
plus TIMEOUT_UNRESOLVED (a work item, resolved by the reconciler — see the
timeout chapter).
Configuration (environment)
Section titled “Configuration (environment)”| Variable | Default | Meaning |
|---|---|---|
FEDNOW_GW_ADDR |
0.0.0.0:8090 |
REST listen address |
FEDNOW_GW_SIM_URL |
http://localhost:8080 |
Southbound target (fednow-sim) |
FEDNOW_GW_SOUTHBOUND |
http |
http = synchronous dev mode; mq = production semantics (fire-and-forget sends + advice queue, enveloped messages) |
FEDNOW_GW_SENDER_RTN |
991000009 |
Your connection party id (routing number) |
FEDNOW_GW_DB |
fednow-gateway.db |
SQLite event store path (state survives restarts) |
FEDNOW_GW_TIMEOUT_SECS |
20 |
Presumed timeout: ACK_PENDING older than this becomes TIMEOUT_UNRESOLVED |
FEDNOW_GW_BACKOFF_SECS |
30 |
Minimum interval between pacs.028 queries per payment |
FEDNOW_GW_SWEEP_SECS |
10 |
Background sweeper cadence (outbox retry → advice pump → reconciliation) |
Operating notes
Section titled “Operating notes”- Watch
/ops/summary.outbox_pendinggrowing means the transport is down or refusing;oldest_unresolved_age_secsis the number to page on. - Restart-safe by construction: events and the outbox are SQLite rows written transactionally; reopening the database replays every payment.
- Never resend. There is deliberately no endpoint to re-emit a pacs.008. Ambiguity is resolved by pacs.028 — the handbook explains why the obvious alternative loses money.
Pacsmith is an independent open-source project. Not affiliated with, endorsed by or sponsored by the Federal Reserve. FedNow is a service mark of the Federal Reserve Banks.