mTLS client certificates
On this page
The Payout server-to-server APIs are authenticated with an mTLS client certificate that you obtain from a Qualified Trust Service Provider (QTSP) and import into your Payout account. The same certificate infrastructure is reused by every server-to-server product:
- M2M Withdrawals — Payout API v2 withdrawal initiation, including optional Verification of Payee. Requires a QWAC for the mTLS connection plus a QSEAL for detached payment-instruction signatures.
- (more products to come — same import flow.)
If you already imported a certificate for one product, you can reuse it for the other(s) as long as it satisfies their respective profile requirements.
Certificate profiles
| Profile | What it is | Required for |
|---|---|---|
| QWAC (Qualified Website Authentication Certificate) | Establishes the mTLS connection. Issued by a QTSP, listed in the EU Trusted List. | All server-to-server APIs |
| QSEAL (Qualified Electronic Seal Certificate) | Signs payment instructions (detached JWS). Issued by a QTSP. | M2M Withdrawals only |
A standard eIDAS QWAC and QSEAL are sufficient — no PSD2-specific extensions (QcStatement-PSD2 per ETSI TS 119 495, PSP role attributes such as PSP_AS/PSP_PI/PSP_AI/PSP_IC) are required. Those are issued only to licensed payment service providers; M2M clients are typically merchants and other B2B entities and obtain plain qualified certificates from a supported EU Trusted List QTSP (currently I.CA and Disig; for another issuer, contact tech@payout.one).
Common requirements for all profiles:
- Issued by a QTSP listed in the EU Trusted List. Currently supported issuers: I.CA (První certifikační autorita) and Disig. To use a certificate from another EU Trusted List QTSP, contact tech@payout.one and we will add its CA to our trust store.
- Contains your organisation identifier (IČO / LEI / VAT) in the
organizationIdentifiersubject attribute. - Key usage matches the certificate's role:
- QWAC —
digitalSignature+keyEncipherment - QSEAL —
nonRepudiation
- QWAC —
- Minimum key size: RSA 2048 or ECDSA P-256.
Generate the private keys yourself and send only the CSR to the QTSP. The private keys must never leave your infrastructure.
Endpoints
Certificate management lives on the standard hosts (not the mTLS hosts), because import happens before mTLS is usable:
| Environment | Host |
|---|---|
| Sandbox | https:// |
| Production | https:// |
| Method | Path | Purpose |
|---|---|---|
POST |
/ |
Obtain Bearer token from client_id + client_secret |
POST |
/ |
Import a QWAC or QSEAL certificate |
GET |
/ |
List your imported certificates |
GET |
/ |
Check certificate approval status |
DELETE |
/ |
Remove a certificate |
Setup
1. Obtain certificate(s) from a QTSP
See the Certificate profiles table above for which profiles you need. Then submit a CSR to the QTSP of your choice.
2. Obtain a Bearer token
curl -X POST https://app.payout.one/api/v1/authorize \
-H "Content-Type: application/json" \
-d '{"client_id":"<CLIENT_ID>","client_secret":"<CLIENT_SECRET>"}'
Response:
{ "token": "...", "valid_for": 6000 }
3. Import your certificate(s)
Upload the PEM-encoded certificate (public part only, never the private key):
curl -X POST https://app.payout.one/api/v1/mtls/certificates \
-H "Authorization: Bearer <TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"type": "qwac",
"pem": "-----BEGIN CERTIFICATE-----\n..."
}'
For M2M Withdrawals, repeat for the QSEAL certificate with "type": "qseal".
Response (initial state pending):
{
"type": "qwac",
"thumbprint": "49165a9f...",
"status": "pending",
"issuer_dn": "CN=...,O=...",
"subject_dn": "C=SK,...,organizationIdentifier=NTRSK-12345678,CN=...",
"subject_org_id": "NTRSK-12345678",
"valid_from": "2025-06-09T06:23:06Z",
"valid_until": "2026-06-09T06:23:06Z"
}
4. Wait for manual approval
Payout manually verifies that the imported certificates match the contractual data of your account. You can check the status at any time:
curl https://app.payout.one/api/v1/mtls/certificates/<thumbprint>/status \
-H "Authorization: Bearer <TOKEN>"
After approval the status changes to approved and the certificate becomes usable.
5. Start calling the API
Once the certificate is approved, present it during the TLS handshake against the relevant mTLS host:
| API | mTLS host (sandbox) | mTLS host (production) |
|---|---|---|
| M2M Withdrawals | api-mtls-sandbox.payout.one |
api-mtls.payout.one |
Lifecycle
Renewal
When your certificate approaches expiry, obtain a new one from the QTSP and import it via POST /api/v1/mtls/certificates. The new certificate is approved separately and runs in parallel with the previous one until that one expires — no downtime.
Revocation (by you)
You can remove your own certificate at any time:
curl -X DELETE https://app.payout.one/api/v1/mtls/certificates/<thumbprint> \
-H "Authorization: Bearer <TOKEN>"
Revocation (by Payout)
Payout may also revoke a certificate if it has been compromised or if the contractual relationship ends. You will be notified by email and via webhook (mtls_certificate.revoked).
Compromise
If you suspect your private key has been compromised:
- Revoke the certificate at the QTSP that issued it.
- Remove it from Payout (
DELETE). - Notify Payout at
security@payout.one. - Generate a new key pair and obtain a fresh certificate.
- Import the new certificate and wait for re-approval.
HTTP error codes
| Code | Meaning |
|---|---|
401 Unauthorized |
Missing or invalid Bearer token. |
403 Forbidden |
Certificate not approved, not owned by your account, or expired/ |
404 Not Found |
Certificate with the given thumbprint not found (or not owned by your account). |
409 Conflict |
Certificate with the same thumbprint already imported. |
422 Unprocessable Entity |
Validation error (malformed PEM, key usage doesn't match the declared type, issuer not in Payout's trust store / unsupported QTSP, missing field, etc.). |
| TLS handshake refused | At the mTLS host: client certificate missing, expired, revoked, or not issued by a trusted QTSP. |
- Need help? Contact support.
- Questions? Contact sales.
- Service status? status.payout.one.
- LLM? Read llms.txt.