The setup & administration endpoints an operator or workspace admin uses to stand a tenant up and keep it running — bank connections and channel activation, approvals, users, workspace/company admin, and session sign-in. These are session-authenticated (an X-API-Key gets 403); the day-to-day integration surface is in the API reference.
Connections
Bank connection setup, channel activation, and EBICS onboarding (session-authenticated, Admin only)
GET/connectivity/profiles
List connectivity profiles (channel info per bank)
Read-only metadata: which channel each bank uses (sftp / danske-ws / nordea-ca / bankconnect / ebics), its pre-known server/endpoint details, and SFTP wizard config. No auth required.
Responses
| Status | Description |
|---|
| 200 | Connectivity profiles |
Example response (200)
{
"items": [
{}
]
}
GET/connections
List bank connections for a company
Parameters
| Name | In | Required | Description |
|---|
platformId string | query | yes | |
companyId string | query | yes | |
Responses
| Status | Description |
|---|
| 200 | Connection list |
| 401 | Sign in required |
Example response (200)
{
"items": [
{
"id": "string",
"bankKey": "nordea-dk",
"bankName": "Nordea Danmark",
"environment": "test",
"channelType": "sftp",
"active": false,
"steps": {
"introEmailSent": false,
"pgpGenerated": false,
"bankPublicKeyAdded": false,
"serverInfoAdded": false,
"sftpUserAdded": false,
"approversAssigned": false,
"certsIssued": false,
"bankCertAdded": false,
"ebicsKeysGenerated": false,
"ebicsBankKeysFetched": false,
"wsConfigAdded": false
},
"sshPublicKey": "string",
"pgpPublicKey": "string",
"approverUserIds": [
"string"
],
"createdAt": "2026-01-01T00: 00: 00Z"
}
]
}
POST/connections
Create (or find existing) bank connection: starts the setup wizard
Creates a bank connection for the given company, or returns the existing one if already set up. Platform-admin note: if you are authenticated as a workspace (platform) admin, you must enter a company context first via POST /auth/company-context before calling this endpoint. Without it you will receive: "select a company context first."
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
bankKey | BankKey | yes | |
environment | enum | no | |
Example
{
"platformId": "string",
"companyId": "string",
"bankKey": "nordea-dk",
"environment": "test"
}
Responses
| Status | Description |
|---|
| 201 | Connection created |
| 400 | Invalid request |
| 401 | Sign in required |
| 403 | Admin required |
Example response (201)
{
"connection": {
"id": "string",
"bankKey": "nordea-dk",
"bankName": "Nordea Danmark",
"environment": "test",
"channelType": "sftp",
"active": false,
"steps": {
"introEmailSent": false,
"pgpGenerated": false,
"bankPublicKeyAdded": false,
"serverInfoAdded": false,
"sftpUserAdded": false,
"approversAssigned": false,
"certsIssued": false,
"bankCertAdded": false,
"ebicsKeysGenerated": false,
"ebicsBankKeysFetched": false,
"wsConfigAdded": false
},
"sshPublicKey": "string",
"pgpPublicKey": "string",
"approverUserIds": [
"string"
],
"createdAt": "2026-01-01T00: 00: 00Z"
},
"readiness": {
"ready": false,
"missing": [
"string"
],
"score": 0
}
}
GET/connections/{id}
Get a single connection + readiness
Parameters
| Name | In | Required | Description |
|---|
id string | path | yes | |
platformId string | query | yes | |
companyId string | query | yes | |
Responses
| Status | Description |
|---|
| 200 | Connection + readiness |
| 404 | Not found |
Example response (200)
{
"connection": {
"id": "string",
"bankKey": "nordea-dk",
"bankName": "Nordea Danmark",
"environment": "test",
"channelType": "sftp",
"active": false,
"steps": {
"introEmailSent": false,
"pgpGenerated": false,
"bankPublicKeyAdded": false,
"serverInfoAdded": false,
"sftpUserAdded": false,
"approversAssigned": false,
"certsIssued": false,
"bankCertAdded": false,
"ebicsKeysGenerated": false,
"ebicsBankKeysFetched": false,
"wsConfigAdded": false
},
"sshPublicKey": "string",
"pgpPublicKey": "string",
"approverUserIds": [
"string"
],
"createdAt": "2026-01-01T00: 00: 00Z"
},
"readiness": {
"ready": false,
"missing": [
"string"
],
"score": 0
}
}
PUT/connections/{id}/signing-cert
Pin the bank's published signing certificate
Stores the bank's PUBLISHED X.509 signing certificate (PEM or base64-DER) on the connection so inbound Web Services signatures are verified against it (fail-closed on any mismatch). Admin only. Validates the cert parses (400 on bad input). Returns the cert subject + expiry so the operator can confirm they pinned the right cert; the raw PEM is never returned. GET /connections/{id} then surfaces signingCertSubject / signingCertExpiry.
Parameters
| Name | In | Required | Description |
|---|
id string | path | yes | |
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
cert | string | yes | The bank's published signing certificate — PEM (-----BEGIN CERTIFICATE-----) or base64-DER. |
Example
{
"platformId": "string",
"companyId": "string",
"cert": "string"
}
Responses
| Status | Description |
|---|
| 200 | Pinned |
| 400 | Bad certificate or non-WS connection |
| 401 | Sign in required |
| 403 | Admin required |
Example response (200)
{
"connectionId": "string",
"certSubject": "string",
"certExpiry": "2026-01-01T00: 00: 00Z"
}
POST/connections/{id}/generate-pgp
Generate our PGP key pair (SFTP channel)
Parameters
| Name | In | Required | Description |
|---|
id string | path | yes | |
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
Example
{
"platformId": "string",
"companyId": "string"
}
Responses
| Status | Description |
|---|
| 200 | PGP key pair generated |
| 401 | Sign in required |
| 403 | Admin required |
Example response (200)
{
"connection": {
"id": "string",
"bankKey": "nordea-dk",
"bankName": "Nordea Danmark",
"environment": "test",
"channelType": "sftp",
"active": false,
"steps": {
"introEmailSent": false,
"pgpGenerated": false,
"bankPublicKeyAdded": false,
"serverInfoAdded": false,
"sftpUserAdded": false,
"approversAssigned": false,
"certsIssued": false,
"bankCertAdded": false,
"ebicsKeysGenerated": false,
"ebicsBankKeysFetched": false,
"wsConfigAdded": false
},
"sshPublicKey": "string",
"pgpPublicKey": "string",
"approverUserIds": [
"string"
],
"createdAt": "2026-01-01T00: 00: 00Z"
},
"readiness": {
"ready": false,
"missing": [
"string"
],
"score": 0
}
}
POST/connections/{id}/bank-key
Save the bank's PGP public key (SFTP channel)
Parameters
| Name | In | Required | Description |
|---|
id string | path | yes | |
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
armoredKey | string | yes | ASCII-armored PGP public key block. |
Example
{
"platformId": "string",
"companyId": "string",
"armoredKey": "string"
}
Responses
| Status | Description |
|---|
| 200 | Bank key saved |
| 401 | Sign in required |
| 403 | Admin required |
Example response (200)
{
"connection": {
"id": "string",
"bankKey": "nordea-dk",
"bankName": "Nordea Danmark",
"environment": "test",
"channelType": "sftp",
"active": false,
"steps": {
"introEmailSent": false,
"pgpGenerated": false,
"bankPublicKeyAdded": false,
"serverInfoAdded": false,
"sftpUserAdded": false,
"approversAssigned": false,
"certsIssued": false,
"bankCertAdded": false,
"ebicsKeysGenerated": false,
"ebicsBankKeysFetched": false,
"wsConfigAdded": false
},
"sshPublicKey": "string",
"pgpPublicKey": "string",
"approverUserIds": [
"string"
],
"createdAt": "2026-01-01T00: 00: 00Z"
},
"readiness": {
"ready": false,
"missing": [
"string"
],
"score": 0
}
}
POST/connections/{id}/server-info
Save SFTP server info (host, port, paths, fingerprint)
Parameters
| Name | In | Required | Description |
|---|
id string | path | yes | |
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
host | string | yes | |
port | integer | no | |
uploadPath | string | no | |
downloadPath | string | no | |
hostFingerprint | string | no | |
Example
{
"platformId": "string",
"companyId": "string",
"host": "string",
"port": 22,
"uploadPath": "string",
"downloadPath": "string",
"hostFingerprint": "string"
}
Responses
| Status | Description |
|---|
| 200 | Server info saved |
| 401 | Sign in required |
| 403 | Admin required |
Example response (200)
{
"connection": {
"id": "string",
"bankKey": "nordea-dk",
"bankName": "Nordea Danmark",
"environment": "test",
"channelType": "sftp",
"active": false,
"steps": {
"introEmailSent": false,
"pgpGenerated": false,
"bankPublicKeyAdded": false,
"serverInfoAdded": false,
"sftpUserAdded": false,
"approversAssigned": false,
"certsIssued": false,
"bankCertAdded": false,
"ebicsKeysGenerated": false,
"ebicsBankKeysFetched": false,
"wsConfigAdded": false
},
"sshPublicKey": "string",
"pgpPublicKey": "string",
"approverUserIds": [
"string"
],
"createdAt": "2026-01-01T00: 00: 00Z"
},
"readiness": {
"ready": false,
"missing": [
"string"
],
"score": 0
}
}
POST/connections/{id}/sftp-user
Set SFTP username and generate SSH key pair (single combined call)
Sets the SFTP username AND generates the SSH key pair in one call: you cannot pre-generate the key before you have the username. The username must be obtained from the bank first; only then can you call this endpoint. The response includes the connection + readiness state, from which you can retrieve the generated SSH public key to send to the bank for whitelisting.
Parameters
| Name | In | Required | Description |
|---|
id string | path | yes | |
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
username | string | yes | SFTP username assigned by the bank. Required: the SSH key generation and username registration are a single atomic operation. |
Example
{
"platformId": "string",
"companyId": "string",
"username": "string"
}
Responses
| Status | Description |
|---|
| 200 | Username set + SSH key generated |
| 401 | Sign in required |
| 403 | Admin required |
Example response (200)
{
"connection": {
"id": "string",
"bankKey": "nordea-dk",
"bankName": "Nordea Danmark",
"environment": "test",
"channelType": "sftp",
"active": false,
"steps": {
"introEmailSent": false,
"pgpGenerated": false,
"bankPublicKeyAdded": false,
"serverInfoAdded": false,
"sftpUserAdded": false,
"approversAssigned": false,
"certsIssued": false,
"bankCertAdded": false,
"ebicsKeysGenerated": false,
"ebicsBankKeysFetched": false,
"wsConfigAdded": false
},
"sshPublicKey": "string",
"pgpPublicKey": "string",
"approverUserIds": [
"string"
],
"createdAt": "2026-01-01T00: 00: 00Z"
},
"readiness": {
"ready": false,
"missing": [
"string"
],
"score": 0
}
}
POST/connections/{id}/approvers
Assign approver users to a connection
Assigns which users may approve payments on this connection. Approvers and approval policy are separate: the policy (under POST /approvals/policies) defines the rule (how many approvers, any amount thresholds); this endpoint assigns the eligible users per connection. Both must be in place for a connection to reach go-live. Note: users must first exist in the company: create them with POST /users before assigning them as approvers.
Parameters
| Name | In | Required | Description |
|---|
id string | path | yes | |
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
userIds | string[] | yes | User IDs of company members with the Approver role. Must already exist in the company. Max 200 (enforced server-side): each id costs a user lookup, so the list is bounded rather than unbounded input behind admin auth. |
Example
{
"platformId": "string",
"companyId": "string",
"userIds": [
"string"
]
}
Responses
| Status | Description |
|---|
| 200 | Approvers assigned |
| 401 | Sign in required |
| 403 | Admin required |
| 422 | One or more user IDs are not valid approvers in this company |
Example response (200)
{
"connection": {
"id": "string",
"bankKey": "nordea-dk",
"bankName": "Nordea Danmark",
"environment": "test",
"channelType": "sftp",
"active": false,
"steps": {
"introEmailSent": false,
"pgpGenerated": false,
"bankPublicKeyAdded": false,
"serverInfoAdded": false,
"sftpUserAdded": false,
"approversAssigned": false,
"certsIssued": false,
"bankCertAdded": false,
"ebicsKeysGenerated": false,
"ebicsBankKeysFetched": false,
"wsConfigAdded": false
},
"sshPublicKey": "string",
"pgpPublicKey": "string",
"approverUserIds": [
"string"
],
"createdAt": "2026-01-01T00: 00: 00Z"
},
"readiness": {
"ready": false,
"missing": [
"string"
],
"score": 0
}
}
POST/connections/{id}/activate
Mark SFTP connection active (after the bank has whitelisted the SSH key)
Parameters
| Name | In | Required | Description |
|---|
id string | path | yes | |
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
Example
{
"platformId": "string",
"companyId": "string"
}
Responses
| Status | Description |
|---|
| 200 | Connection activated |
| 401 | Sign in required |
| 403 | Admin required |
Example response (200)
{
"connection": {
"id": "string",
"bankKey": "nordea-dk",
"bankName": "Nordea Danmark",
"environment": "test",
"channelType": "sftp",
"active": false,
"steps": {
"introEmailSent": false,
"pgpGenerated": false,
"bankPublicKeyAdded": false,
"serverInfoAdded": false,
"sftpUserAdded": false,
"approversAssigned": false,
"certsIssued": false,
"bankCertAdded": false,
"ebicsKeysGenerated": false,
"ebicsBankKeysFetched": false,
"wsConfigAdded": false
},
"sshPublicKey": "string",
"pgpPublicKey": "string",
"approverUserIds": [
"string"
],
"createdAt": "2026-01-01T00: 00: 00Z"
},
"readiness": {
"ready": false,
"missing": [
"string"
],
"score": 0
}
}
POST/connections/{id}/intro-email-sent
Mark intro email as sent (tracks wizard progress)
Parameters
| Name | In | Required | Description |
|---|
id string | path | yes | |
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
Example
{
"platformId": "string",
"companyId": "string"
}
Responses
| Status | Description |
|---|
| 200 | Updated |
| 401 | Sign in required |
| 403 | Admin required |
Example response (200)
{
"connection": {
"id": "string",
"bankKey": "nordea-dk",
"bankName": "Nordea Danmark",
"environment": "test",
"channelType": "sftp",
"active": false,
"steps": {
"introEmailSent": false,
"pgpGenerated": false,
"bankPublicKeyAdded": false,
"serverInfoAdded": false,
"sftpUserAdded": false,
"approversAssigned": false,
"certsIssued": false,
"bankCertAdded": false,
"ebicsKeysGenerated": false,
"ebicsBankKeysFetched": false,
"wsConfigAdded": false
},
"sshPublicKey": "string",
"pgpPublicKey": "string",
"approverUserIds": [
"string"
],
"createdAt": "2026-01-01T00: 00: 00Z"
},
"readiness": {
"ready": false,
"missing": [
"string"
],
"score": 0
}
}
POST/connections/{id}/ws-environment
Toggle a Web Services connection between TEST and PRODUCTION
Requires an already-activated connection (certificates issued); does not re-run PKI.
Parameters
| Name | In | Required | Description |
|---|
id string | path | yes | |
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
environment | enum | yes | |
Example
{
"platformId": "string",
"companyId": "string",
"environment": "TEST"
}
Responses
| Status | Description |
|---|
| 200 | Environment updated |
| 401 | Sign in required |
| 403 | Admin required |
Example response (200)
{
"connection": {
"id": "string",
"bankKey": "nordea-dk",
"bankName": "Nordea Danmark",
"environment": "test",
"channelType": "sftp",
"active": false,
"steps": {
"introEmailSent": false,
"pgpGenerated": false,
"bankPublicKeyAdded": false,
"serverInfoAdded": false,
"sftpUserAdded": false,
"approversAssigned": false,
"certsIssued": false,
"bankCertAdded": false,
"ebicsKeysGenerated": false,
"ebicsBankKeysFetched": false,
"wsConfigAdded": false
},
"sshPublicKey": "string",
"pgpPublicKey": "string",
"approverUserIds": [
"string"
],
"createdAt": "2026-01-01T00: 00: 00Z"
},
"readiness": {
"ready": false,
"missing": [
"string"
],
"score": 0
}
}
POST/connections/{id}/covered-banks
Set which member banks a shared connection covers
For a shared (group) connection. The store clamps the set to the bank's group and always includes the connection's own bank.
Parameters
| Name | In | Required | Description |
|---|
id string | path | yes | |
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
coveredBankKeys | string[] | yes | Bank keys this connection serves (clamped to the bank's group). |
Example
{
"platformId": "string",
"companyId": "string",
"coveredBankKeys": [
"string"
]
}
Responses
| Status | Description |
|---|
| 200 | Covered banks updated |
| 401 | Sign in required |
| 403 | Admin required |
Example response (200)
{
"connection": {
"id": "string",
"bankKey": "nordea-dk",
"bankName": "Nordea Danmark",
"environment": "test",
"channelType": "sftp",
"active": false,
"steps": {
"introEmailSent": false,
"pgpGenerated": false,
"bankPublicKeyAdded": false,
"serverInfoAdded": false,
"sftpUserAdded": false,
"approversAssigned": false,
"certsIssued": false,
"bankCertAdded": false,
"ebicsKeysGenerated": false,
"ebicsBankKeysFetched": false,
"wsConfigAdded": false
},
"sshPublicKey": "string",
"pgpPublicKey": "string",
"approverUserIds": [
"string"
],
"createdAt": "2026-01-01T00: 00: 00Z"
},
"readiness": {
"ready": false,
"missing": [
"string"
],
"score": 0
}
}
GET/connections/{id}/intro-email
Render the bank intro email (draft to send to the bank contact)
Parameters
| Name | In | Required | Description |
|---|
id string | path | yes | |
platformId string | query | yes | |
companyId string | query | yes | |
Responses
| Status | Description |
|---|
| 200 | Rendered email (subject + body) |
| 404 | Not found |
GET/banks/{bankKey}/setup-info
Per-bank setup descriptor for the wizard UI
Returns the channel kind, requirements text, field definitions, pre-known server/endpoint details, and SFTP wizard screens for a bank. Used by the setup wizard to render the correct flow.
Parameters
| Name | In | Required | Description |
|---|
bankKey BankKey | path | yes | |
Responses
| Status | Description |
|---|
| 200 | Setup descriptor |
| 404 | Unknown bank |
POST/banks/{bankKey}/guide-feedback
Report that a bank's setup guide is wrong
Sends the customer's note about a bank's setup guide to BankConnector. The bank, its data central, the company and the platform are attached server-side from the route + session — the body carries only the message, so a caller cannot file feedback as another company.
Parameters
| Name | In | Required | Description |
|---|
bankKey BankKey | path | yes | |
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
message | string | yes | What was confusing, or what the bank did differently. |
Example
{
"platformId": "string",
"companyId": "string",
"message": "string"
}
Responses
| Status | Description |
|---|
| 200 | Feedback sent |
| 400 | Empty or over-long message |
| 401 | Not signed in |
| 404 | Unknown bank |
| 502 | The feedback could not be mailed — retry |
Example response (200)
{
"sent": false
}
GET/banks/{bankKey}/settings
Get per-company settings for a specific bank
Parameters
| Name | In | Required | Description |
|---|
bankKey BankKey | path | yes | |
platformId string | query | yes | |
companyId string | query | yes | |
Responses
| Status | Description |
|---|
| 200 | Bank settings (null if none saved) |
PATCH/banks/{bankKey}/settings
Update per-company settings for a specific bank (partial patch)
Payment-affecting fields (agreementId, debtorAgreementId, chargeBearer, executionDateOffsetDays, approvalPolicyId, painVersion, batchBooking, authorisationCode, authorisationProprietary) require Admin. The selected pin is open to any member. debtorAgreementId is the bank's second agreement identifier (e.g. the Nordea CAW/CCM agreement number) — auto-filled into payments[i].debtor.organisationId (scheme BANK) when the payment omits it; agreementId fills initiatingParty.organisationId (scheme CUST). batchBooking and the authorisation pair are per-AGREEMENT pain.001 facts (PmtInf/BtchBookg and GrpHdr/Authstn): omit or send null to keep the bank profile's default. authorisationCode (ISO Authorisation1Code) and authorisationProprietary are mutually exclusive — sending both is a 400.
Parameters
| Name | In | Required | Description |
|---|
bankKey BankKey | path | yes | |
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | no | |
companyId | string | no | |
agreementId | string | no | |
debtorAgreementId | string | no | |
chargeBearer | enum | no | |
executionDateOffsetDays | integer | no | |
approvalPolicyId | string | no | |
painVersion | enum | no | |
batchBooking | boolean | no | |
authorisationCode | enum | no | |
authorisationProprietary | string | no | |
selected | boolean | no | |
Example
{
"platformId": "string",
"companyId": "string",
"agreementId": "string",
"debtorAgreementId": "string",
"chargeBearer": "SLEV",
"executionDateOffsetDays": 0,
"approvalPolicyId": "string",
"painVersion": "pain.001.001.03",
"batchBooking": false,
"authorisationCode": "AUTH",
"authorisationProprietary": "string",
"selected": false
}
Responses
| Status | Description |
|---|
| 200 | Settings saved |
| 401 | Sign in required |
| 403 | Admin required for payment-affecting fields |
GET/bank-settings
List all per-company bank settings in one call
Parameters
| Name | In | Required | Description |
|---|
platformId string | query | yes | |
companyId string | query | yes | |
Responses
| Status | Description |
|---|
| 200 | All saved bank settings for this company |
Example response (200)
{
"settings": [
{}
]
}
POST/connections/{id}/activate-danske
Activate Danske EDI Web Services (automated cert enrolment)
Calls the Danske bxd.fi activation endpoint with the one-time PIN, self-issues the signing + encryption certificates, and marks the connection active. Admin only.
Parameters
| Name | In | Required | Description |
|---|
id string | path | yes | |
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
userId | string | yes | Agreement number (User ID) from Danske. |
pin | string | yes | One-time transfer key from Danske. |
Example
{
"platformId": "string",
"companyId": "string",
"userId": "string",
"pin": "string"
}
Responses
| Status | Description |
|---|
| 200 | Activated |
| 400 | Activation failed (wrong PIN, network, etc.) |
| 401 | Sign in required |
| 403 | Admin required |
Example response (200)
{
"connection": {
"id": "string",
"bankKey": "nordea-dk",
"bankName": "Nordea Danmark",
"environment": "test",
"channelType": "sftp",
"active": false,
"steps": {
"introEmailSent": false,
"pgpGenerated": false,
"bankPublicKeyAdded": false,
"serverInfoAdded": false,
"sftpUserAdded": false,
"approversAssigned": false,
"certsIssued": false,
"bankCertAdded": false,
"ebicsKeysGenerated": false,
"ebicsBankKeysFetched": false,
"wsConfigAdded": false
},
"sshPublicKey": "string",
"pgpPublicKey": "string",
"approverUserIds": [
"string"
],
"createdAt": "2026-01-01T00: 00: 00Z"
},
"readiness": {
"ready": false,
"missing": [
"string"
],
"score": 0
}
}
POST/connections/{id}/activate-nordea
Activate Nordea Corporate Access (HMAC cert enrolment via SMS code)
Generates a Nordea-format signing CSR, sends the HMAC-signed enrolment request to Nordea's Corporate Access endpoint using the SMS activation code, and stores the issued certificate. Admin only.
Parameters
| Name | In | Required | Description |
|---|
id string | path | yes | |
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
holderName | string | yes | Certificate-holder name (CN) as printed in the Nordea agreement. |
signerId | string | yes | Signer ID from the agreement. |
senderId | string | no | |
country | string | yes | |
activationCode | string | yes | 10-digit SMS activation code from Nordea. |
Example
{
"platformId": "string",
"companyId": "string",
"holderName": "string",
"signerId": "string",
"senderId": "string",
"country": "string",
"activationCode": "string"
}
Responses
| Status | Description |
|---|
| 200 | Activated |
| 400 | Activation failed |
| 401 | Sign in required |
| 403 | Admin required |
Example response (200)
{
"connection": {
"id": "string",
"bankKey": "nordea-dk",
"bankName": "Nordea Danmark",
"environment": "test",
"channelType": "sftp",
"active": false,
"steps": {
"introEmailSent": false,
"pgpGenerated": false,
"bankPublicKeyAdded": false,
"serverInfoAdded": false,
"sftpUserAdded": false,
"approversAssigned": false,
"certsIssued": false,
"bankCertAdded": false,
"ebicsKeysGenerated": false,
"ebicsBankKeysFetched": false,
"wsConfigAdded": false
},
"sshPublicKey": "string",
"pgpPublicKey": "string",
"approverUserIds": [
"string"
],
"createdAt": "2026-01-01T00: 00: 00Z"
},
"readiness": {
"ready": false,
"missing": [
"string"
],
"score": 0
}
}
POST/connections/{id}/activate-bankconnect
Activate Bank Connect (DK gateway: automated cert enrolment)
Enrols the signing certificate with the Bank Connect data central (BD/BEC/SDC), stores the issued certificate and bank public key, and marks the connection active. Data central and country are pre-filled from the bank profile. Admin only.
Parameters
| Name | In | Required | Description |
|---|
id string | path | yes | |
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
organisationId | string | yes | Bank registration number. |
functionId | string | yes | Per-agreement routing code from the bank. |
activationCode | string | yes | One-time activation code from the bank. |
Example
{
"platformId": "string",
"companyId": "string",
"organisationId": "string",
"functionId": "string",
"activationCode": "string"
}
Responses
| Status | Description |
|---|
| 200 | Activated |
| 400 | Activation failed or bank has no Bank Connect data central |
| 401 | Sign in required |
| 403 | Admin required |
| 404 | Connection not found |
Example response (200)
{
"connection": {
"id": "string",
"bankKey": "nordea-dk",
"bankName": "Nordea Danmark",
"environment": "test",
"channelType": "sftp",
"active": false,
"steps": {
"introEmailSent": false,
"pgpGenerated": false,
"bankPublicKeyAdded": false,
"serverInfoAdded": false,
"sftpUserAdded": false,
"approversAssigned": false,
"certsIssued": false,
"bankCertAdded": false,
"ebicsKeysGenerated": false,
"ebicsBankKeysFetched": false,
"wsConfigAdded": false
},
"sshPublicKey": "string",
"pgpPublicKey": "string",
"approverUserIds": [
"string"
],
"createdAt": "2026-01-01T00: 00: 00Z"
},
"readiness": {
"ready": false,
"missing": [
"string"
],
"score": 0
}
}
POST/connections/{id}/renew-danske
Renew the Danske EDI Web Services certificates
Issues fresh signing + encryption keypairs/CSRs to Danske's PKI via RenewCertificate — the request is enveloped-signed with the current signing certificate and XML-encrypted to the bank certificate (PKI WS spec §7) — and commits the new keys + certificates atomically on success. Run before the 2-year certificate expiry (the cert-expiring alerts fire at 30/14/7 days). A failed renewal leaves the current credentials untouched. Admin only.
Parameters
| Name | In | Required | Description |
|---|
id string | path | yes | |
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
Example
{
"platformId": "string",
"companyId": "string"
}
Responses
| Status | Description |
|---|
| 200 | Renewed |
| 400 | Renewal failed (current credentials left untouched) |
| 401 | Sign in required |
| 403 | Admin required |
| 404 | Connection not found |
Example response (200)
{
"connection": {
"id": "string",
"bankKey": "nordea-dk",
"bankName": "Nordea Danmark",
"environment": "test",
"channelType": "sftp",
"active": false,
"steps": {
"introEmailSent": false,
"pgpGenerated": false,
"bankPublicKeyAdded": false,
"serverInfoAdded": false,
"sftpUserAdded": false,
"approversAssigned": false,
"certsIssued": false,
"bankCertAdded": false,
"ebicsKeysGenerated": false,
"ebicsBankKeysFetched": false,
"wsConfigAdded": false
},
"sshPublicKey": "string",
"pgpPublicKey": "string",
"approverUserIds": [
"string"
],
"createdAt": "2026-01-01T00: 00: 00Z"
},
"readiness": {
"ready": false,
"missing": [
"string"
],
"score": 0
}
}
POST/connections/{id}/renew-op
Renew the OP (Finland) Web Services signing certificate
Issues a fresh keypair + CSR (same subject as the current certificate: CN=WS username, C=FI) to OP's Certificate Service — the CertApplicationRequest is signed with the CURRENT key (guide §4.1.4), so NO transfer key is needed while the current certificate is valid — and commits the new key + certificate atomically on success, refusing a certificate whose public key does not match the CSR (OP silently returns copies of prior certificates). Run before the ~2-year expiry (alerts at 30/14/7 days; the daily auto-renew sweep also acts inside the 30-day horizon): a LAPSED OP certificate cannot be renewed at all — the customer starts over with a NEW transfer key from OP. Admin only.
Parameters
| Name | In | Required | Description |
|---|
id string | path | yes | |
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
Example
{
"platformId": "string",
"companyId": "string"
}
Responses
| Status | Description |
|---|
| 200 | Renewed |
| 404 | Connection not found |
Example response (200)
{
"connection": {
"id": "string",
"bankKey": "nordea-dk",
"bankName": "Nordea Danmark",
"environment": "test",
"channelType": "sftp",
"active": false,
"steps": {
"introEmailSent": false,
"pgpGenerated": false,
"bankPublicKeyAdded": false,
"serverInfoAdded": false,
"sftpUserAdded": false,
"approversAssigned": false,
"certsIssued": false,
"bankCertAdded": false,
"ebicsKeysGenerated": false,
"ebicsBankKeysFetched": false,
"wsConfigAdded": false
},
"sshPublicKey": "string",
"pgpPublicKey": "string",
"approverUserIds": [
"string"
],
"createdAt": "2026-01-01T00: 00: 00Z"
},
"readiness": {
"ready": false,
"missing": [
"string"
],
"score": 0
}
}
POST/connections/{id}/renew-nordea
Renew the Nordea Corporate Access signing certificate
Issues a fresh keypair + CSR (same subject as the current certificate) to Nordea's Certificate Service — the CertApplicationRequest is signed with the current certificate in place of the HMAC (Certificate Management §3.1.2), so no new SMS activation code is needed while the current certificate is valid — and commits the new key + certificate atomically on success. Run before the 2-year expiry (alerts at 30/14/7 days). A failed renewal leaves the current credentials untouched. Admin only.
Parameters
| Name | In | Required | Description |
|---|
id string | path | yes | |
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
Example
{
"platformId": "string",
"companyId": "string"
}
Responses
| Status | Description |
|---|
| 200 | Renewed |
| 400 | Renewal failed (current credentials left untouched) |
| 401 | Sign in required |
| 403 | Admin required |
| 404 | Connection not found |
Example response (200)
{
"connection": {
"id": "string",
"bankKey": "nordea-dk",
"bankName": "Nordea Danmark",
"environment": "test",
"channelType": "sftp",
"active": false,
"steps": {
"introEmailSent": false,
"pgpGenerated": false,
"bankPublicKeyAdded": false,
"serverInfoAdded": false,
"sftpUserAdded": false,
"approversAssigned": false,
"certsIssued": false,
"bankCertAdded": false,
"ebicsKeysGenerated": false,
"ebicsBankKeysFetched": false,
"wsConfigAdded": false
},
"sshPublicKey": "string",
"pgpPublicKey": "string",
"approverUserIds": [
"string"
],
"createdAt": "2026-01-01T00: 00: 00Z"
},
"readiness": {
"ready": false,
"missing": [
"string"
],
"score": 0
}
}
POST/connections/{id}/renew-bankconnect
Renew the Bank Connect customer certificate
Issues a fresh keypair + CSR (CN=functionId) to the Bank Connect data central via renewCustomerCertificate, signed with the current certificate, and commits the new key + certificate atomically on success. Run before the 3-year certificate expiry (the cert-expiring alerts fire at 30/14/7 days); the bank revokes the previous certificate 48 hours after a successful renewal. Admin only.
Parameters
| Name | In | Required | Description |
|---|
id string | path | yes | |
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
Example
{
"platformId": "string",
"companyId": "string"
}
Responses
| Status | Description |
|---|
| 200 | Renewed |
| 400 | Renewal failed (current credentials left untouched) |
| 401 | Sign in required |
| 403 | Admin required |
| 404 | Connection not found |
Example response (200)
{
"connection": {
"id": "string",
"bankKey": "nordea-dk",
"bankName": "Nordea Danmark",
"environment": "test",
"channelType": "sftp",
"active": false,
"steps": {
"introEmailSent": false,
"pgpGenerated": false,
"bankPublicKeyAdded": false,
"serverInfoAdded": false,
"sftpUserAdded": false,
"approversAssigned": false,
"certsIssued": false,
"bankCertAdded": false,
"ebicsKeysGenerated": false,
"ebicsBankKeysFetched": false,
"wsConfigAdded": false
},
"sshPublicKey": "string",
"pgpPublicKey": "string",
"approverUserIds": [
"string"
],
"createdAt": "2026-01-01T00: 00: 00Z"
},
"readiness": {
"ready": false,
"missing": [
"string"
],
"score": 0
}
}
POST/connections/{id}/ebics-params
Save EBICS connection parameters (Host ID, Partner ID, User ID, …)
Parameters
| Name | In | Required | Description |
|---|
id string | path | yes | |
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
url | string | yes | EBICS server URL. |
hostId | string | yes | Bank-assigned Host ID. |
partnerId | string | yes | Customer ID (PartnerID) from the bank. |
userId | string | yes | Subscriber ID (UserID) from the bank. |
protocolVersion | string | no | |
signatureVersion | string | no | |
subscriberMode | enum | no | One shared technical subscriber, or one EBICS subscriber per approver. |
veuOnly | boolean | no | Per-user only: this agreement routes every order through VEU (refuses multi-signature uploads) — delivery uploads one ES and adds the rest via HVE. |
uploaderUserId | string | no | Per-user only: DESIGNATED uploader (app user id) — which subscriber transports payment uploads and acts for VEU orders. Must be a user in this company; the subscriber must be ACTIVE at delivery time (delivery fails with a clear error otherwise). Empty string clears the designation (default: first active subscriber). May be a non-approver transport-class subscriber for veuOnly agreements. |
Example
{
"platformId": "string",
"companyId": "string",
"url": "string",
"hostId": "string",
"partnerId": "string",
"userId": "string",
"protocolVersion": "H005",
"signatureVersion": "A006",
"subscriberMode": "technical",
"veuOnly": false,
"uploaderUserId": "string"
}
Responses
| Status | Description |
|---|
| 200 | EBICS params saved |
| 401 | Sign in required |
| 403 | Admin required |
Example response (200)
{
"connection": {
"id": "string",
"bankKey": "nordea-dk",
"bankName": "Nordea Danmark",
"environment": "test",
"channelType": "sftp",
"active": false,
"steps": {
"introEmailSent": false,
"pgpGenerated": false,
"bankPublicKeyAdded": false,
"serverInfoAdded": false,
"sftpUserAdded": false,
"approversAssigned": false,
"certsIssued": false,
"bankCertAdded": false,
"ebicsKeysGenerated": false,
"ebicsBankKeysFetched": false,
"wsConfigAdded": false
},
"sshPublicKey": "string",
"pgpPublicKey": "string",
"approverUserIds": [
"string"
],
"createdAt": "2026-01-01T00: 00: 00Z"
},
"readiness": {
"ready": false,
"missing": [
"string"
],
"score": 0
}
}
POST/connections/{id}/ebics-generate-keys
Generate EBICS subscriber keys (authentication, encryption, signature)
Parameters
| Name | In | Required | Description |
|---|
id string | path | yes | |
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
Example
{
"platformId": "string",
"companyId": "string"
}
Responses
| Status | Description |
|---|
| 200 | Keys generated |
| 401 | Sign in required |
| 403 | Admin required |
Example response (200)
{
"connection": {
"id": "string",
"bankKey": "nordea-dk",
"bankName": "Nordea Danmark",
"environment": "test",
"channelType": "sftp",
"active": false,
"steps": {
"introEmailSent": false,
"pgpGenerated": false,
"bankPublicKeyAdded": false,
"serverInfoAdded": false,
"sftpUserAdded": false,
"approversAssigned": false,
"certsIssued": false,
"bankCertAdded": false,
"ebicsKeysGenerated": false,
"ebicsBankKeysFetched": false,
"wsConfigAdded": false
},
"sshPublicKey": "string",
"pgpPublicKey": "string",
"approverUserIds": [
"string"
],
"createdAt": "2026-01-01T00: 00: 00Z"
},
"readiness": {
"ready": false,
"missing": [
"string"
],
"score": 0
}
}
POST/connections/{id}/ebics-fetch-htd
Fetch the bank's record of the EBICS agreement (HTD/HKD) and store the discovery snapshot
Runs EBICS HTD (technical subscriber) or HKD (per-user mode) against the bank and persists the result on the connection: accounts on the agreement, permitted order types/BTFs with bank-side signature quorums, and each subscriber's bank-side status + signature class. Requires the bank keys (run ebics-fetch-hpb first). Pre-activation returns notActivatedYet instead of failing, so it can be polled as an activation check. In per-user mode, approvers the bank reports as ready are advanced to active automatically.
Parameters
| Name | In | Required | Description |
|---|
id string | path | yes | |
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
Example
{
"platformId": "string",
"companyId": "string"
}
Responses
| Status | Description |
|---|
| 200 | Discovery result (fetched flag, message, and the parsed agreement data when available) |
| 401 | Sign in required |
| 403 | Admin required |
Example response (200)
{
"connection": {
"id": "string",
"bankKey": "nordea-dk",
"bankName": "Nordea Danmark",
"environment": "test",
"channelType": "sftp",
"active": false,
"steps": {
"introEmailSent": false,
"pgpGenerated": false,
"bankPublicKeyAdded": false,
"serverInfoAdded": false,
"sftpUserAdded": false,
"approversAssigned": false,
"certsIssued": false,
"bankCertAdded": false,
"ebicsKeysGenerated": false,
"ebicsBankKeysFetched": false,
"wsConfigAdded": false
},
"sshPublicKey": "string",
"pgpPublicKey": "string",
"approverUserIds": [
"string"
],
"createdAt": "2026-01-01T00: 00: 00Z"
},
"readiness": {
"ready": false,
"missing": [
"string"
],
"score": 0
}
}
POST/connections/{id}/ebics-renew
Rotate the EBICS subscriber keys in-band (HCS)
Sends an HCS order: the NEW three keys (signature/authentication/encryption), authorised by the CURRENT signature key — no new INI letter or bank re-activation. Two-phase and key-loss safe: the new keyset is staged before sending and promoted only on a confirmed accept; an ambiguous (post-commit) outcome keeps both keysets and the next call resolves automatically by probing which keyset the bank accepts. Per-user mode rotates one approver at a time (pass userId).
Parameters
| Name | In | Required | Description |
|---|
id string | path | yes | |
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
userId | string | no | Per-user mode: the approver whose subscriber to rotate. |
Example
{
"platformId": "string",
"companyId": "string",
"userId": "string"
}
Responses
| Status | Description |
|---|
| 200 | Renewal outcome (renewed | ambiguous | resolved-kept-old | resolved-promoted | unresolved) |
| 401 | Sign in required |
| 403 | Admin required |
Example response (200)
{
"connection": {
"id": "string",
"bankKey": "nordea-dk",
"bankName": "Nordea Danmark",
"environment": "test",
"channelType": "sftp",
"active": false,
"steps": {
"introEmailSent": false,
"pgpGenerated": false,
"bankPublicKeyAdded": false,
"serverInfoAdded": false,
"sftpUserAdded": false,
"approversAssigned": false,
"certsIssued": false,
"bankCertAdded": false,
"ebicsKeysGenerated": false,
"ebicsBankKeysFetched": false,
"wsConfigAdded": false
},
"sshPublicKey": "string",
"pgpPublicKey": "string",
"approverUserIds": [
"string"
],
"createdAt": "2026-01-01T00: 00: 00Z"
},
"readiness": {
"ready": false,
"missing": [
"string"
],
"score": 0
}
}
POST/connections/{id}/ebics-veu-pending
List the orders pending signature at the bank (EBICS VEU / HVU)
Read-only: queries the bank's VEU queue via HVU using the first active per-user subscriber as transport. Returns order type + order number, signature progress (done/required), and whether each order is still signable. Per-user connections only. Normally empty - payments arrive fully signed; a veuOnly agreement or an interrupted co-sign parks orders here.
Parameters
| Name | In | Required | Description |
|---|
id string | path | yes | |
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
Example
{
"platformId": "string",
"companyId": "string"
}
Responses
| Status | Description |
|---|
| 200 | Pending orders (veuPending array on the connection response) |
| 401 | Sign in required |
| 403 | Admin required |
Example response (200)
{
"connection": {
"id": "string",
"bankKey": "nordea-dk",
"bankName": "Nordea Danmark",
"environment": "test",
"channelType": "sftp",
"active": false,
"steps": {
"introEmailSent": false,
"pgpGenerated": false,
"bankPublicKeyAdded": false,
"serverInfoAdded": false,
"sftpUserAdded": false,
"approversAssigned": false,
"certsIssued": false,
"bankCertAdded": false,
"ebicsKeysGenerated": false,
"ebicsBankKeysFetched": false,
"wsConfigAdded": false
},
"sshPublicKey": "string",
"pgpPublicKey": "string",
"approverUserIds": [
"string"
],
"createdAt": "2026-01-01T00: 00: 00Z"
},
"readiness": {
"ready": false,
"missing": [
"string"
],
"score": 0
}
}
POST/connections/{id}/ebics-suspend
Emergency-suspend the subscriber's EBICS access (SPR)
Sends an authenticated SPR order telling the bank to immediately suspend this subscriber's access — the compromised-key kill switch. One-directional: restoring access requires re-onboarding (new INI/HIA + letter). Also deactivates the connection locally so polling/delivery stops. Per-user mode suspends the named (or first active) approver.
Parameters
| Name | In | Required | Description |
|---|
id string | path | yes | |
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
userId | string | no | Per-user mode: the approver to suspend. |
Example
{
"platformId": "string",
"companyId": "string",
"userId": "string"
}
Responses
| Status | Description |
|---|
| 200 | Suspend result (bank return code + message) |
| 401 | Sign in required |
| 403 | Admin required |
Example response (200)
{
"connection": {
"id": "string",
"bankKey": "nordea-dk",
"bankName": "Nordea Danmark",
"environment": "test",
"channelType": "sftp",
"active": false,
"steps": {
"introEmailSent": false,
"pgpGenerated": false,
"bankPublicKeyAdded": false,
"serverInfoAdded": false,
"sftpUserAdded": false,
"approversAssigned": false,
"certsIssued": false,
"bankCertAdded": false,
"ebicsKeysGenerated": false,
"ebicsBankKeysFetched": false,
"wsConfigAdded": false
},
"sshPublicKey": "string",
"pgpPublicKey": "string",
"approverUserIds": [
"string"
],
"createdAt": "2026-01-01T00: 00: 00Z"
},
"readiness": {
"ready": false,
"missing": [
"string"
],
"score": 0
}
}
POST/connections/{id}/ebics-veu-complete
Complete an interrupted VEU co-sign for a pending order (HVE)
Re-drives the remaining approvers' HVE signatures for an order the bank is holding. Identify the payment by documentId, or by the pending order's dataDigest (matched server-side to the sent pain.001). Digest re-checked via HVD before signing — never co-signs a mismatched order.
Parameters
| Name | In | Required | Description |
|---|
id string | path | yes | |
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
documentId | string | no | The sent payment (its frozen pain.001 is signed). |
orderDigest | string | no | The pending order's dataDigest, to resolve the payment. |
orderId | string | no | The bank order number to select the pending order. |
Example
{
"platformId": "string",
"companyId": "string",
"documentId": "string",
"orderDigest": "string",
"orderId": "string"
}
Responses
| Status | Description |
|---|
| 200 | Co-sign results (per approver) + executionReady |
| 401 | Sign in required |
| 403 | Admin required |
Example response (200)
{
"connection": {
"id": "string",
"bankKey": "nordea-dk",
"bankName": "Nordea Danmark",
"environment": "test",
"channelType": "sftp",
"active": false,
"steps": {
"introEmailSent": false,
"pgpGenerated": false,
"bankPublicKeyAdded": false,
"serverInfoAdded": false,
"sftpUserAdded": false,
"approversAssigned": false,
"certsIssued": false,
"bankCertAdded": false,
"ebicsKeysGenerated": false,
"ebicsBankKeysFetched": false,
"wsConfigAdded": false
},
"sshPublicKey": "string",
"pgpPublicKey": "string",
"approverUserIds": [
"string"
],
"createdAt": "2026-01-01T00: 00: 00Z"
},
"readiness": {
"ready": false,
"missing": [
"string"
],
"score": 0
}
}
GET/connections/{id}/ebics-letter
Download the EBICS initialisation letter (PDF, base64-encoded)
Returns the signed INI/HIA initialisation letter as a base64-encoded PDF. Print, sign, and send to the bank to complete EBICS subscriber activation.
Parameters
| Name | In | Required | Description |
|---|
id string | path | yes | |
platformId string | query | yes | |
companyId string | query | yes | |
Responses
| Status | Description |
|---|
| 200 | PDF as base64 |
| 404 | Not found or keys not yet generated |
Example response (200)
{
"pdfBase64": "string",
"filename": "string"
}
Approvals
Maker-checker approval policies + the pending-approval queue (session, Admin/Approver)
GET/approvals/pending
List payments awaiting approval
Parameters
| Name | In | Required | Description |
|---|
companyId string | query | yes | |
Responses
| Status | Description |
|---|
| 200 | Pending approval requests |
| 401 | Sign in required |
Example response (200)
{
"items": [
{}
],
"nextCursor": "string"
}
POST/approvals/{id}/approve
Approve a pending payment (maker ≠ checker enforced)
An approver other than the maker approves the request; once the policy's required approvals are met the payment proceeds to delivery. May require a 2FA code/backup code if step-up is configured.
Parameters
| Name | In | Required | Description |
|---|
id string | path | yes | |
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
reason | string | no | |
code | string | no | 2FA TOTP code (if step-up required). |
backupCode | string | no | |
Example
{
"platformId": "string",
"companyId": "string",
"reason": "string",
"code": "string",
"backupCode": "string"
}
Responses
| Status | Description |
|---|
| 200 | Approval recorded (and payment dispatched if fully approved) |
| 401 | Sign in required |
| 403 | Maker cannot approve own payment / not an approver |
POST/approvals/{id}/reject
Reject a pending payment
Parameters
| Name | In | Required | Description |
|---|
id string | path | yes | |
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
reason | string | no | |
Example
{
"platformId": "string",
"companyId": "string",
"reason": "string"
}
Responses
| Status | Description |
|---|
| 200 | Rejection recorded |
| 401 | Sign in required |
GET/approvals/policies
List approval policies for a company
Parameters
| Name | In | Required | Description |
|---|
companyId string | query | yes | |
Responses
| Status | Description |
|---|
| 200 | Policies |
| 401 | Sign in required |
Example response (200)
{
"policies": [
{}
]
}
POST/approvals/policies
Create an approval policy (Admin)
Defines required approver count + amount thresholds. Admin only.
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
name | string | yes | |
requiredApprovals | integer | no | |
thresholdAmount | string | no | |
currency | string | no | |
Example
{
"platformId": "string",
"companyId": "string",
"name": "string",
"requiredApprovals": 0,
"thresholdAmount": "string",
"currency": "string"
}
Responses
| Status | Description |
|---|
| 201 | Policy created |
| 401 | Sign in required |
| 403 | Admin required |
POST/approvals/policies/{id}
Edit a DRAFT approval policy (Admin)
Edit a policy's name / required approver count / thresholds. Works only on a DRAFT version — an Active version is immutable (409); change it via /approvals/policies/{id}/propose then co-sign.
Parameters
| Name | In | Required | Description |
|---|
id string | path | yes | |
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
name | string | no | |
requiredApprovals | integer | no | |
thresholdAmount | string | no | |
currency | string | no | |
Example
{
"platformId": "string",
"companyId": "string",
"name": "string",
"requiredApprovals": 0,
"thresholdAmount": "string",
"currency": "string"
}
Responses
| Status | Description |
|---|
| 200 | Updated draft policy |
| 401 | Sign in required |
| 403 | Admin required |
| 409 | Version is not a draft / conflict |
Example response (200)
{
"policy": {}
}
POST/approvals/policies/{id}/lock
Activate (lock) a draft approval policy (Admin)
Locks a DRAFT version → Active and immutable. Runs the quorum check (a dual policy needs ≥2 named approvers); fails 409 if it can't be met. An Active version is changed only via propose + co-sign.
Parameters
| Name | In | Required | Description |
|---|
id string | path | yes | |
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
Example
{
"platformId": "string",
"companyId": "string"
}
Responses
| Status | Description |
|---|
| 200 | Policy activated |
| 401 | Sign in required |
| 403 | Admin required |
| 409 | Quorum not met / conflict |
Example response (200)
{
"policy": {}
}
POST/approvals/policies/{id}/propose
Propose a change to an Active policy (Admin)
Clones the Active version to an editable draft v(n+1). Edit the draft (POST /approvals/policies/{draftId}), then submit it for activation via POST /approvals/changes/{changeId}/submit and have a second Admin co-sign via POST /approvals/changes/{changeId}/cosign. The old version is retained forever once superseded.
Parameters
| Name | In | Required | Description |
|---|
id string | path | yes | |
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
Example
{
"platformId": "string",
"companyId": "string"
}
Responses
| Status | Description |
|---|
| 201 | Draft version created |
| 401 | Sign in required |
| 403 | Admin required |
| 409 | Base not Active / change already in progress |
Example response (201)
{
"policy": {}
}
GET/approvals/bank-rosters
Who may approve payments on each covered bank
One row per COVERED BANK (danske-dk) — never per connection: one connection may serve several country banks. bound: false means the bank inherits the company default (which is also what a bank added tomorrow gets); sharedWith names the other banks in the query that resolve to the same policy.
Parameters
| Name | In | Required | Description |
|---|
companyId string | query | yes | |
bankKeys string | query | yes | Comma-separated covered bank keys (repeatable). |
Responses
| Status | Description |
|---|
| 200 | One roster row per covered bank |
| 400 | No bank keys named |
| 401 | Sign in required |
Example response (200)
{
"items": [
{
"bankKey": "string",
"policyId": "string",
"policyName": "string",
"builtIn": false,
"bound": false,
"approverUserIds": [
"string"
],
"requiredApprovals": 0,
"sharedWith": [
"string"
]
}
]
}
POST/approvals/bank-rosters
Set who may approve payments on covered banks (Admin)
ALL-OR-NOTHING across the set: the ratchet judges each bank, but if ANY bank's roster shrinks nothing moves until a second Admin co-signs the one request naming them all. 200 = in force now; 202 = accepted and NOT in force, change is the request awaiting that signature. No policy is ever edited in place — each bank is moved to a policy carrying the wanted roster on its current rule, so a policy shared with other banks is left untouched.
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
targets | object[] | yes | |
Example
{
"platformId": "string",
"companyId": "string",
"targets": [
{
"bankKey": "string",
"approverUserIds": [
"string"
]
}
]
}
Responses
| Status | Description |
|---|
| 200 | In force now |
| 202 | Accepted — NOT in force; awaiting a second Admin's co-sign |
| 400 | Malformed roster set |
| 401 | Sign in required |
| 403 | Admin required |
| 409 | Refused by the ratchet (e.g. only one Admin) / a change is already awaiting co-sign |
Example response (200)
{
"banks": [
{}
],
"pending": false
}
GET/approvals/changes
List approval-policy change requests (Admin)
The dual-co-sign change requests for the company. ?status=pending (default) | activated | cancelled.
Parameters
| Name | In | Required | Description |
|---|
status enum | query | no | |
Responses
| Status | Description |
|---|
| 200 | Change requests |
| 401 | Sign in required |
| 403 | Admin required |
Example response (200)
{
"changes": [
{}
]
}
POST/approvals/changes/{changeId}/{action}
Submit / co-sign / cancel a policy change (Admin)
action=submit — the proposer submits the draft for activation (counts as the FIRST of 2 co-signs). action=cosign — a SECOND, distinct Admin co-signs: the new version goes Active, the base is Superseded, and attached banks re-point to the new version. action=cancel — any Admin cancels a pending change (the draft is discarded; the base stays Active). A 2nd co-sign by the same Admin is refused (409).
Parameters
| Name | In | Required | Description |
|---|
changeId string | path | yes | |
action enum | path | yes | |
Request body required
| Property | Type | Required | Description |
|---|
platformId | string | yes | |
companyId | string | yes | |
Example
{
"platformId": "string",
"companyId": "string"
}
Responses
| Status | Description |
|---|
| 200 | Change updated |
| 401 | Sign in required |
| 403 | Admin required |
| 409 | Same-admin co-sign / conflict |
Example response (200)
{
"change": {},
"policy": {},
"supersededId": "string",
"affectedBanks": [
"string"
]
}