This API must be implemented by platforms that provide their own capital to businesses.
Note that this endpoint is not hosted by finmid.
It is called by finmid to instruct the platform to execute a bank transfer to the specified beneficiary to payout a funding.
The platform must process the payment and return a successful HTTP response to acknowledge receipt of the request.
Once the payment request has been processed, the platform must notify finmid of its success or failure via the Receive Payout Confirmation webhook.
Idempotency
The idempotency_key uniquely identifies each transaction request. If finmid sends a request with an idempotency_key that was already successfully processed, the platform should return a 409 - CONFLICT response without executing the payment again.
Beneficiary verification
We recommend that the platform verifies the beneficiary before executing the payment. Specifically, the platform should look up the business in its own system using the provided iban and confirm that the beneficiary is a known customer. If the IBAN does not match any registered business, the platform should reject the request with a 400 - validation error.
Authentication & message integrity
Every request from finmid is signed using HTTP Message Signatures (RFC 9421), combined with IP whitelisting.
What is signed
finmid signs the following components of each request:
| Component | Description |
|---|---|
@method | HTTP method (POST) |
@path | Request path |
content-type | Media type of the body |
content-digest | SHA-256 hash of the request body (see below) |
Request headers
Each signed request includes the following additional HTTP headers:
| Header | Description |
|---|---|
Content-Digest | SHA-256 hash of the request body, formatted as sha-256=:<base64-encoded-hash>: |
Signature-Input | Describes which components are signed and includes signature metadata |
Signature | The cryptographic signature (base64-encoded) |
Signature metadata
The Signature-Input header contains the following metadata parameters:
| Parameter | Description |
|---|---|
keyid | Identifier of the public key to use for verification. finmid will provide the public key during integration setup. |
alg | Signing algorithm. finmid uses ed25519. |
created | Unix timestamp (seconds) when the signature was created. |
expires | Unix timestamp (seconds) after which the signature is no longer valid (created + 60 seconds) |
nonce | Random unique value (UUID) generated per request attempt, including retries. Used exclusively for replay attack prevention — independent from the idempotency_key in the request body, which serves business-level idempotency. The nonce store can use a short TTL aligned with the signature validity window (expires - created). |
Example signed request
POST /api/v1/transaction HTTP/1.1
Host: platform.example.com
Content-Type: application/json
Content-Digest: sha-256=:q83vRzQK3YpS6cJ8iX9u6pHc9T6YxQZ3S8KcYpVvC8E=:
Signature-Input: sig1=("@method" "@path" "content-type" "content-digest");created=1773135059;expires=1773135119;keyid="finmid-prod-key-1";alg="ed25519";nonce="f47ac10b-58cc-4372-a567-0e02b2c3d479"
Signature: sig1=:dGhpcyBpcyBhbiBleGFtcGxlIHNpZ25hdHVyZQ==:
{"idempotency_key":"op-fund-2026.crd-001.biz-123","beneficiary":{"iban":"DE89370400440532013000","bic":"COBADEFFXXX","name":"John Doe"}, ...}
Verification steps (server-side)
The platform must verify each incoming request:
- Parse
Signature-Inputto extract signed components and metadata. - Reconstruct the signature base — the canonical string built from the signed components in the exact order specified by
Signature-Input. - Retrieve the public key using
keyid. finmid will provide the public key during integration setup. - Verify the
Signatureagainst the reconstructed signature base using the public key and theed25519algorithm. - Validate the
Content-Digestheader by computing SHA-256 of the received body and comparing. - Enforce temporal and replay policies:
- Reject if
createdis in the future (allow ~30 seconds clock skew). - Reject if current time is after
expires. - Reject if the
noncehas already been seen within the validity window.
- Reject if
If any step fails, return 401 Unauthorized.
Key exchange
During integration setup, finmid will provide:
- The Ed25519 public key for signature verification.
- The
keyidvalue that will appear inSignature-Input. - The list of IP addresses to whitelist for additional security.
Key rotation will be coordinated between finmid and the platform, with advance notice.
Base URL
The base URL for this endpoint is the platform's own server URL, configured during the integration setup with finmid.
The following is a suggestion, the platform can customise it to their needs:
POST <platform-base-url>/api/v1/transaction