- Issue invoices from an external tool (e.g. an ERP or invoicing platform) and want to trigger SDD collections programmatically
- Build a direct debit payment method into your own product on top of Qonto
To use the API, you must be eligible for SEPA Direct Debit and have the feature activated in the Qonto app. Go to Business Account → Incoming Direct Debits to check your eligibility and create your SCI (SEPA Creditor Identifier).
To test the API in the sandbox environment, follow the sandbox setup guide to enable SDD collections for your test organization.
How SDD collection works
1. Authenticate with the right scopes
All SDD endpoints are protected by OAuth 2.0. Request the following scopes depending on the operations you need:
You can manage your OAuth credentials from the Developer Portal.
2. Create a mandate
A mandate is the authorization from your customer (the debtor) to collect payments from their bank account. You must have a valid, signed mandate before collecting any payment. To create a mandate, send aPOST request to /v2/sepa/direct_debit_mandates. The payment_info object is optional; when provided, it stores first-payment details on the mandate for the signature request and approval communications. It does not create or schedule a collection.
Minimal request (mandate only):
payment_info to create only the mandate. Include it to attach first-payment details to the mandate; it does not create a collection. To collect after the customer signs, create a subscription via POST /v2/sepa/direct_debit_subscriptions referencing the mandate and payment details.
Example with payment_info:
sign_url — a link your customer must visit to sign the mandate electronically, whether or not payment_info was provided. You can send this URL yourself or have Qonto send the signature request email automatically by setting send_mandate_signature_email: true. The email can be sent for a standalone mandate; it omits the amount and date when payment_info is absent.
payment_info was included in the request, the response includes a payment_info object (a snapshot of the details provided at creation). The root schedule_type and notify_client fields are deprecated in favor of payment_info.schedule_type and payment_info.notify_client.
payment_info also accepts a recurring schedule, so the signature request shows the frequency to your customer:
iban with the last four digits visible (for example, ••••3000).
Once your customer signs, you will receive a v1/sepa-direct-debit-mandates webhook with event accepted (see Webhooks below). You can also poll the mandate status with a GET request to /v2/sepa/direct_debit_mandates/{direct_debit_mandate_id}.
You can list all mandates for a given client by sending a GET request to /v2/sepa/direct_debit_mandates?client_id={client_id}.
3. Create a subscription
A subscription represents a one-off or recurring payment schedule against a mandate. Once you have a signed mandate, you can trigger a subscription at any time. Send aPOST request to /v2/sepa/direct_debit_subscriptions:
direct_debit_mandate_id as shown above.
Creating a mandate and collection in one step: omit direct_debit_mandate_id. A new mandate will be created automatically and the response will include a sign_url.
Recurring collections: set schedule_type to weekly, monthly, quarterly, yearly, or custom (with schedule_custom_interval and schedule_custom_unit, e.g. every 2 weeks). Use schedule_total_collection_count to limit the number of collections, or omit it for a schedule without end. Qonto then creates each collection automatically.
schedule_next_collection_date and, when the schedule has an end, schedule_end_date. To stop a recurring series, cancel the mandate with POST /v2/sepa/direct_debit_mandates/{id}/cancel.
You can retrieve a specific subscription with a GET request to /v2/sepa/direct_debit_subscriptions/{direct_debit_subscription_id}, or list all subscriptions with GET /v2/sepa/direct_debit_subscriptions.
4. Track collection outcomes
Once a subscription has been triggered, Qonto processes it through the SEPA banking network. You can track the outcome in two ways: Webhooks (recommended): subscribe tov1/sepa-direct-debit-collections to receive real-time notifications when a collection status changes (see Webhooks below).
Polling: retrieve a collection by ID with a GET request to /v2/sepa/direct_debit_collections/{direct_debit_collection_id}, or list all collections — optionally filtered by subscription — with GET /v2/sepa/direct_debit_collections?direct_debit_subscription_id={id}.
Mandate statuses
Collection statuses
When a collection fails, the
status_reason field provides additional detail (e.g. insufficient_funds, amount_limit_reached, account_closed). The full list of allowed values is documented in the API reference.
Webhooks
Subscribe to webhook topics to receive real-time notifications about key events. Theevent field in the webhook payload body identifies what happened.
v1/sepa-direct-debit-mandates
Example payload:
v1/sepa-direct-debit-collections
Tip: TheExample payload (failed):eventfield uses a simplified set of outcomes (completed,failed,returned,refunded). Forfailedevents,data.statusretains the fine-grained value (declined,rejected, orcanceled) so you can handle each case precisely.
Summary
Here are the steps to follow when integrating SDD collection:- Request the right OAuth scopes:
sepa_direct_debit.readand/orsepa_direct_debit.writefrom the Developer Portal - Create a mandate:
POST /v2/sepa/direct_debit_mandates— share or send thesign_urlto your customer - Wait for mandate acceptance: subscribe to
v1/sepa-direct-debit-mandateswebhooks, or pollGET /v2/sepa/direct_debit_mandates/{id} - Create a subscription:
POST /v2/sepa/direct_debit_subscriptionswith the signed mandate ID, amount, and collection date - Track the outcome: subscribe to
v1/sepa-direct-debit-collectionswebhooks, or pollGET /v2/sepa/direct_debit_collections/{id}