Calmony DD connects directly to Modulr for the UK BACS rail and Griffin for fund-holding and client account banking — then exposes everything downstream through a single versioned API that agentOS and your own systems consume. No middleware you have to maintain. No hand-offs you have to monitor.
BACS RAIL / MODULR
Mandate registration, collection submission, and return processing all run over Modulr's AUDDIS and BACS channels. Calmony DD holds a single facilities-managed Service User Number — your agency never needs its own SUN, and the full BACS lifecycle runs under Calmony's FCA oversight.
AUDDIS mandate registration CreateMandateWorkflow submits to Modulr, polls for activation, and transitions the mandate automatically on confirmation.
BACS collection submission Each collection runs through SubmitCollectionWorkflow with idempotency keys — safe to retry, never double-charges.
HMAC-SHA1 signed requests Every outbound call is signed per Modulr's API spec. Inbound webhooks are verified on the same signature before any processing begins.
ARUDD / ADDACS / AWACS handling Return and amendment messages are received, decoded against the canonical reason-code catalogue, and trigger automated workflows with no manual triage required.
0N mandate migration Agencies moving from a previous SUN can bulk-migrate mandates via BACS 0N messages without re-collecting DD authorisation from tenants.

HOW IT FLOWS / END-TO-END
When an agent creates a payer mandate, CreateMandateWorkflow calls Modulr to submit the AUDDIS instruction. The mandate moves from pending to active when the 3-working-day confirmation arrives.
CollectionSchedulerCron picks up due collections and starts SubmitCollectionWorkflow per record. Modulr handles the 3-day BACS cycle; the workflow transitions status from submitted → in_clearing → collected on each settlement event.
HoldCollectedFundsWorkflow creates a fund hold in the agent's Griffin holding account. The workflow sleeps until T+5, then checks for any ARUDD or indemnity claim before releasing the hold.
ForwardFundsWorkflow computes the releasable amount (net of reserve and any pending clawbacks), calls Griffin createTransfer, records the forwarding row, and emails the agent a PDF statement.
Calmony DD handles the Modulr integration, the Griffin accounts, and the v1 API surface. Your team gets the dashboard and the API. We handle everything between tenant mandate and client account credit.
Questions before joining? Email us at sf-core-org-support-calmony-dd@saas-factory.ai
FUND CUSTODY / GRIFFIN

Once Modulr settles a collection, funds move into a
EXTERNAL API / AGENTÓS & BEYOND
The v1 REST API is the boundary between Calmony DD and the software your agency already runs. agentOS calls it today; any other system can too.
createPayer Register a tenant payer with UK sort code and account number validation — modulus check included.
createMandate Starts CreateMandateWorkflow and returns a mandate reference immediately. AUDDIS submission happens async.
SUPPORTING SERVICES / INTERNALS
Beyond the two financial providers, Calmony DD runs its own supporting services that every workflow depends on.
UK bank holidays and Bacs non-processing days seeded from Pay.UK's published calendar for the next 24 months. Every workflow that computes submission or settlement dates uses helpers from this table — no ad-hoc date arithmetic.
Every money movement writes paired debit/credit entries across accounts: payer_bank, modulr_in_transit, griffin_holding, griffin_client, reserve, and indemnity_loss. A daily integrity cron verifies the double-entry property holds across all tenants.
EXCEPTIONS / LIVE TRIAGE
A suite of daily and intra-day workflows watches every in-flight record. Mandates stuck in AUDDIS, collections overdue in clearing, holdings past their release window, webhook subscriptions approaching failure limits — each surfaces automatically as an exception for operator triage, with a direct link to the affected entity.
Stuck-mandate detector: flags pending_auddis older than 5 BACS working days
Overdue-collection alert: catches collections in submitted status past 4 working days
Holdings release detector: finds held records with holdUntil more than 2 days in the past
Griffin holding accounts per agent Each agent's collected funds sit in an isolated holding account, preventing any co-mingling between tenancies.
Automated clawback enforcement HoldCollectedFundsWorkflow wakes automatically when the 5-day window elapses and checks for outstanding ARUDD or indemnity claims before releasing.
Griffin-to-Griffin client transfers ForwardFundsWorkflow calls Griffin createTransfer from the holding account to the agent's verified client account — net of reserve and any pending clawbacks.
Reconciled against Griffin balances The daily BACS reconciliation cron pulls Griffin holding-account transactions and matches them against expected amounts, flagging any shortfall before forwarding.
cancelMandate Triggers the cancellation workflow — stops in-flight scheduled collections and submits cancellation to Modulr.
listCollections / getCollection Pull collection status in real time, including BACS lifecycle position and linked holding record.
getForwardings Retrieve completed forwarding records with the breakdown of included collections and reserve movement.
Per-org API keys Shell-issued Bearer keys (sfk_…) are scoped to one agent org. A key cannot read or act on another org's data — enforced at the database row level via RLS.
Idempotency-Key header Every mutating endpoint accepts an Idempotency-Key header. Safe to retry after a network timeout — the second call returns the original result without creating duplicate records.
OpenAPI 3.1 specification A machine-readable spec is served for SDK generators and API explorers. Documented error codes, schema shapes, and versioning conventions.
Tenant isolation tested A dedicated test suite under tests/isolation/ asserts that an authenticated session for org A cannot read or mutate any row belonging to org B across every endpoint.
Subscribe to mandate.activated, collection.settled, collection.returned, forwarding.completed, and more. Signed payloads, auto-pause on repeated failure, health-monitored every 5 minutes.
The full canonical ARUDD/ADDACS/AUDDIS reason-code set, seeded with description, category, retry-eligible flag, and suggested operator action. Enriches every exception record with human-readable context.
Payer bank account numbers are encrypted at the application layer before reaching the database. Decryption happens only when a value is needed for Modulr submission. Every decrypt writes an audit entry.
Every outbound Modulr and Griffin call — and every inbound webhook — is stored with full request, response, status, and duration. Secrets are redacted in storage. Replay any webhook from the admin console for incident response.
Forwarding failures, stuck holdings, reconciliation mismatches, and indemnity escalations trigger immediate emails and in-app notifications via the shell's built-in delivery layer — no external email API required.
Reconciliation mismatch alert: fires on every cycle with mismatchCount > 0
Webhook health monitor: runs every 5 minutes, auto-pauses subscriptions at 50 consecutive failures
