> ## Documentation Index
> Fetch the complete documentation index at: https://docs.qonto.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Create a Bulk Transfer

> OAuth scope: `payment.write`

This operation requires [Strong Customer Authentication](/api-reference/business-api/authentication/sca/sca-flows), except when all transfers include a `beneficiary_id` and [all beneficiaries are trusted](/api-reference/business-api/payments-transfers/sepa-transfers/beneficiaries/sepa-beneficiaries/trust), in which case **SCA is not required**.
However, if at least one transfer passes the `beneficiary` object then **SCA will be triggered**.

<Note>
  Example of SCA usage: [Postman visual flow](https://www.postman.com/qontoteam/workspace/qonto-public-api/flow/6670429eb7bd63003156bd57)
</Note>

Creates a batch of SEPA transfers for asynchronous processing. If the payload is valid, a `BulkTransfer` is created and returned, which can be polled via `GET v2/sepa/bulk_transfers/:id`.

You can either provide a `beneficiary_id` for a known beneficiary or `beneficiary` data which will create an untrusted beneficiary on the fly.

**Note**:
- if a beneficiary with the same IBAN already exists, the provided details (such as name) will be updated;
- this endpoint is not trusting the beneficiary - you can trust a beneficiary through the Qonto app (for more details, please refer to [this article](https://support-de.qonto.com/hc/en-us/articles/23949206250641-How-can-I-mark-a-payee-as-trustworthy#h_925061f25d)) or through [this endpoint](/api-reference/business-api/payments-transfers/sepa-transfers/beneficiaries/sepa-beneficiaries/trust) (available for Embed partners only).

Business rules and validations are applied to each individual transfer after the `BulkTransfer` is created. For instance, transfers above 30,000 EUR require at least one attachment. This validation is performed asynchronously, meaning the `BulkTransfer` will be created, but if the attachment is missing, the result for that transfer will contain an error.

By default, transfers will be processed as **instant**. If instant processing isn't possible, it will automatically fall back to standard processing. It will be the case if the amount of the individual transfer is above the following thresholds 👇
<AccordionGroup>
  <Accordion title="Untrusted beneficiary">
    - The individual transfer is above 5,000 EUR;
    - More than 20,000 EUR have been sent to this beneficairy within 24 hours.
  </Accordion>
  <Accordion title="Trusted beneficiary">
    - The individual transfer is above 10,000 EUR;
    - More than 50,000 EUR have been sent to this beneficairy within 24 hours.
  </Accordion>
</AccordionGroup>

To learn more about instant transfers, please read [this article](https://support-fr.qonto.com/hc/en-us/articles/23947629441681-How-to-make-an-instant-transfer-in-euros-SEPA).




## OpenAPI

````yaml POST /v2/sepa/bulk_transfers
openapi: 3.1.1
info:
  version: v2
  title: Qonto
servers:
  - url: https://thirdparty.qonto.com
    description: Production URL
  - url: https://thirdparty-sandbox.staging.qonto.co
    description: Sandbox URL
security:
  - OAuth:
      - organization.read
      - membership.read
      - membership.write
      - attachment.write
      - internal_transfer.write
      - payment.write
      - supplier_invoice.write
      - supplier_invoice.read
      - client_invoices.read
      - client_invoice.write
      - client.read
      - client.write
      - product.read
      - product.write
      - request_review.write
      - request_review.read
      - team.read
      - team.write
      - request_transfers.write
      - insurance_contract.read
      - insurance_contract.write
      - card.read
      - card.write
      - bank_account.write
      - beneficiary.trust
      - webhook
      - payment_link.write
      - payment_link.read
      - sepa_direct_debit.read
      - sepa_direct_debit.write
      - terminal.read
      - terminal.write
  - SecretKey: []
paths:
  /v2/sepa/bulk_transfers:
    parameters:
      - $ref: '#/components/parameters/X-Qonto-Staging-Token'
    post:
      tags:
        - SEPA Transfers
      summary: Create a Bulk Transfer
      description: >
        OAuth scope: `payment.write`


        This operation requires [Strong Customer
        Authentication](/api-reference/business-api/authentication/sca/sca-flows),
        except when all transfers include a `beneficiary_id` and [all
        beneficiaries are
        trusted](/api-reference/business-api/payments-transfers/sepa-transfers/beneficiaries/sepa-beneficiaries/trust),
        in which case **SCA is not required**.

        However, if at least one transfer passes the `beneficiary` object then
        **SCA will be triggered**.


        <Note>
          Example of SCA usage: [Postman visual flow](https://www.postman.com/qontoteam/workspace/qonto-public-api/flow/6670429eb7bd63003156bd57)
        </Note>


        Creates a batch of SEPA transfers for asynchronous processing. If the
        payload is valid, a `BulkTransfer` is created and returned, which can be
        polled via `GET v2/sepa/bulk_transfers/:id`.


        You can either provide a `beneficiary_id` for a known beneficiary or
        `beneficiary` data which will create an untrusted beneficiary on the
        fly.


        **Note**:

        - if a beneficiary with the same IBAN already exists, the provided
        details (such as name) will be updated;

        - this endpoint is not trusting the beneficiary - you can trust a
        beneficiary through the Qonto app (for more details, please refer to
        [this
        article](https://support-de.qonto.com/hc/en-us/articles/23949206250641-How-can-I-mark-a-payee-as-trustworthy#h_925061f25d))
        or through [this
        endpoint](/api-reference/business-api/payments-transfers/sepa-transfers/beneficiaries/sepa-beneficiaries/trust)
        (available for Embed partners only).


        Business rules and validations are applied to each individual transfer
        after the `BulkTransfer` is created. For instance, transfers above
        30,000 EUR require at least one attachment. This validation is performed
        asynchronously, meaning the `BulkTransfer` will be created, but if the
        attachment is missing, the result for that transfer will contain an
        error.


        By default, transfers will be processed as **instant**. If instant
        processing isn't possible, it will automatically fall back to standard
        processing. It will be the case if the amount of the individual transfer
        is above the following thresholds 👇

        <AccordionGroup>
          <Accordion title="Untrusted beneficiary">
            - The individual transfer is above 5,000 EUR;
            - More than 20,000 EUR have been sent to this beneficairy within 24 hours.
          </Accordion>
          <Accordion title="Trusted beneficiary">
            - The individual transfer is above 10,000 EUR;
            - More than 50,000 EUR have been sent to this beneficairy within 24 hours.
          </Accordion>
        </AccordionGroup>


        To learn more about instant transfers, please read [this
        article](https://support-fr.qonto.com/hc/en-us/articles/23947629441681-How-to-make-an-instant-transfer-in-euros-SEPA).
      operationId: createSepaBulkTransfers
      parameters:
        - $ref: '#/components/parameters/X-Qonto-2fa-Preference'
        - $ref: '#/components/parameters/X-Qonto-Idempotency-Key'
        - $ref: '#/components/parameters/X-Qonto-Sca-Session-Token'
        - $ref: '#/components/parameters/X-Qonto-MFA'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BulkSepaTransferRequest'
      responses:
        '200':
          description: Successfully creates a BulkTransfer for processing
          content:
            application/json:
              schema:
                type: object
                required:
                  - bulk_transfer
                properties:
                  bulk_transfer:
                    $ref: '#/components/schemas/BulkSepaTransferJobResponse'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BadRequestResponseBody'
              examples:
                reference is missing:
                  value:
                    errors:
                      - code: missing_key
                        detail: reference is missing
                        source:
                          pointer: /bulk_transfers/2/reference
                amount is missing:
                  value:
                    errors:
                      - code: missing_key
                        detail: amount is missing
                        source:
                          pointer: /bulk_transfers/1/amount
                with invalid amount:
                  value:
                    errors:
                      - code: invalid
                        detail: amount must be greater than 0
                        source:
                          pointer: /bulk_transfers/4/amount
                attachment_ids exceeds max limit:
                  value:
                    errors:
                      - code: above_max_size
                        detail: attachment_ids cannot be greater than 5
                        source:
                          pointer: /bulk_transfers/0/attachment_ids
                with unknown beneficiary:
                  value:
                    errors:
                      - code: beneficiary_not_found
                        detail: >-
                          Beneficiary with
                          id=66b7e300-0126-4905-9688-27b445a48c4e not found
                        source:
                          pointer: /bulk_transfers/20/beneficiary_id
                with unknown bank account:
                  value:
                    errors:
                      - code: bank_account_not_found
                        detail: >-
                          BankAccount with
                          id=420e13ac-9d3e-4c11-93a1-0c3c8304f2df not found
                        source:
                          pointer: /bank_account_id
                invalid vop proof token:
                  value:
                    errors:
                      - code: vop_proof_token_invalid
                        detail: VOP proof token is invalid
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                type: object
                properties:
                  errors:
                    type: array
                    items:
                      $ref: '#/components/schemas/UnauthorizedError'
              examples:
                missing vop proof token:
                  value:
                    errors:
                      - code: vop_proof_token_missing
                        detail: VOP proof token is required
                authorization_header_missing:
                  value:
                    errors:
                      - code: authorization_header_missing
                        detail: authorization header missing
                authorization_token_invalid:
                  value:
                    errors:
                      - code: authorization_token_invalid
                        detail: authorization token invalid
        '403':
          $ref: '#/components/responses/403-Forbidden'
          description: Forbidden
      security:
        - OAuth:
            - payment.write
components:
  parameters:
    X-Qonto-Staging-Token:
      name: X-Qonto-Staging-Token
      in: header
      description: >-
        Required only for Sandbox API requests; to get one, please sign up to
        the [Developer Portal](https://developers.qonto.com/).
      schema:
        type: string
    X-Qonto-2fa-Preference:
      name: X-Qonto-2fa-Preference
      in: header
      description: >-
        Learn more in [Strong Customer
        Authentication](/api-reference/business-api/authentication/sca/sca-flows).
      schema:
        type: string
        enum:
          - paired-device
          - passkey
          - mock
          - sms-otp
        default: paired-device
    X-Qonto-Idempotency-Key:
      name: X-Qonto-Idempotency-Key
      in: header
      required: true
      description: >-
        Learn more in [Idempotent
        Requests](/get-started/general/idempotent-requests).
      schema:
        type: string
        example: 123e4567-e89b-12d3-a456-426614174000
    X-Qonto-Sca-Session-Token:
      name: X-Qonto-Sca-Session-Token
      in: header
      description: >-
        Learn more in [Strong Customer
        Authentication](/api-reference/business-api/authentication/sca/sca-flows).
      schema:
        type: string
    X-Qonto-MFA:
      name: X-Qonto-MFA
      in: header
      description: >-
        Learn more in the [SMS OTP
        Flow](/api-reference/business-api/authentication/sca/sca-flows#sms-otp-flow).
      schema:
        type: string
  schemas:
    BulkSepaTransferRequest:
      type: object
      required:
        - bank_account_id
        - bulk_transfers
        - vop_proof_token
      properties:
        vop_proof_token:
          type: string
          description: >-
            Proof token from a bulk payee verification attempt. Use the token
            from [bulk verify
            payee](/api-reference/business-api/payments-transfers/sepa-transfers/verify-payee/bulk-verify-payee#tag/Bulk-Verify-SEPA-Payee/operation/bulkVerifyPayee)
            to opt-out from the verification.
          example: proof_1234567890abcdef
        bank_account_id:
          type: string
          format: uuid
          description: >-
            The ID of the bank account from which the amount will be debited
            from.
        bulk_transfers:
          type: array
          description: List of SEPA transfers to process (up to 400).
          maxItems: 400
          items:
            $ref: '#/components/schemas/BulkTransferRequest'
    BulkSepaTransferJobResponse:
      type: object
      required:
        - id
        - initiator_id
        - created_at
        - updated_at
        - total_count
        - completed_count
        - pending_count
        - failed_count
        - results
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier for the bulk transfer job.
        initiator_id:
          type: string
          format: uuid
          description: Unique identifier for the member that created the BulkTransfer.
        created_at:
          type: string
          format: date-time
          example: '2025-04-22T12:00:00Z'
          description: UTC, the time at which the bulk transfer was first recorded.
        updated_at:
          type: string
          format: date-time
          example: '2025-04-22T12:00:00Z'
          description: UTC, the time at which the bulk transfer was last updated.
        total_count:
          type: integer
          description: Total number of transfers in the job.
          example: 400
        completed_count:
          type: integer
          description: Total number of transfers successfully completed in the job.
          example: 200
        failed_count:
          type: integer
          description: Total number of transfers failed in the job.
          example: 150
        pending_count:
          type: integer
          description: Total number of transfers pending in the job.
          example: 50
        results:
          type: array
          description: Detailed status of each individual transfer in the job.
          items:
            $ref: '#/components/schemas/Result'
    BadRequestResponseBody:
      type: object
      properties:
        errors:
          type: array
          items:
            $ref: '#/components/schemas/BadRequestError'
      required:
        - errors
    UnauthorizedError:
      type: object
      properties:
        code:
          type: string
          description: Error code.
        detail:
          type: string
          description: Human readable error that explains error `code`.
      required:
        - code
        - detail
      x-examples:
        Invalid credentials:
          code: unauthorized
          detail: Invalid credentials
    BulkTransferRequest:
      type: object
      required:
        - amount
        - client_transfer_id
        - reference
      properties:
        beneficiary_id:
          type:
            - string
            - 'null'
          format: uuid
          description: The ID of the SEPA beneficiary
        beneficiary:
          type:
            - object
            - 'null'
          required:
            - name
            - iban
          properties:
            name:
              type: string
              description: The name of the beneficiary
              example: Alice In Wonderland
            iban:
              type: string
              description: The IBAN of the beneficiary
              example: DE91100000000123456789
            bic:
              type: string
              description: The BIC of the beneficiary
              example: DEUTDEDDXXX
            email:
              type: string
              description: The email of the beneficiary
              example: beneficiary@example.com
            activity_tag:
              $ref: '#/components/schemas/ActivityTagEnum'
        reference:
          type: string
          description: The reference of the transfer
          example: Inventory
          maxLength: 140
        amount:
          type: string
          example: '100.50'
          pattern: ^\d+(\.\d{1,2})?$
          description: >-
            Corresponds to the amount of the transaction in the `currency` of
            the bank account. Amounts must be
            https://www.w3.org/TR/payment-request/#dfn-valid-decimal-monetary-value.
        scheduled_date:
          type: string
          format: date
          description: >-
            The date for the transfer to be executed in YYYY-MM-DD format.

            If not provided, the transfer will be executed the same day or the
            next available date.
        note:
          type: string
          description: A note for the transfer
          example: Inventory goods for restaurant in Paris
        attachment_ids:
          type: array
          description: >-
            You can link up to 5 attachments per transfer by passing the
            `attachment_ids` parameter. You can upload your attachments using
            our [POST
            /v2/attachments](/api-reference/business-api/endpoints/attachments/upload-an-attachment)
            endpoint. <br>**Note: For SEPA transfers above 30,000 EUR at least
            one attachment is required**
          items:
            type: string
            format: uuid
        client_transfer_id:
          type: string
          format: uuid
          description: >-
            A unique identifier provided by the client to track and distinguish
            individual transfers within a bulk transfer creation request.
    Result:
      type: object
      required:
        - client_transfer_id
        - transfer_id
        - errors
        - status
      properties:
        client_transfer_id:
          type: string
          format: uuid
          description: Client-provided key to identify the transfer within the job.
        transfer_id:
          type:
            - string
            - 'null'
          format: uuid
          description: ID of the created transfer (populated if the status=completed).
        errors:
          type:
            - array
            - 'null'
          description: List of errors for the transfer (populated if the status=failed).
          items:
            $ref: '#/components/schemas/Error'
        status:
          type: string
          enum:
            - pending
            - completed
            - failed
    BadRequestError:
      type: object
      properties:
        code:
          type: string
          description: Error code.
        detail:
          type: string
          description: Human readable error that explains error `code`.
        source:
          type: object
          properties:
            pointer:
              type: string
              description: >-
                The property in the request body that caused the error
                (optional).
            parameter:
              type: string
              description: The query parameter that caused the error (optional).
      required:
        - code
        - detail
      x-examples:
        Authorization field missing:
          code: bad_request
          detail: Authorization field missing
    ForbiddenResponseBody:
      type: object
      properties:
        errors:
          type: array
          items:
            $ref: '#/components/schemas/ForbiddenError'
      required:
        - errors
    ActivityTagEnum:
      type:
        - string
        - 'null'
      enum:
        - atm
        - fallback
        - fees
        - finance
        - food_and_grocery
        - gas_station
        - hardware_and_equipment
        - hotel_and_lodging
        - insurance
        - it_and_electronics
        - legal_and_accounting
        - logistics
        - manufacturing
        - marketing
        - office_rental
        - office_supply
        - online_service
        - other_expense
        - other_income
        - other_service
        - pending
        - refund
        - restaurant_and_bar
        - sales
        - salary
        - subscription
        - tax
        - transport
        - treasury_and_interco
        - utility
        - voucher
    Error:
      type: object
      title: Errors
      properties:
        errors:
          type: array
          items:
            anyOf:
              - $ref: '#/components/schemas/UnauthorizedError'
              - $ref: '#/components/schemas/BadRequestError'
              - $ref: '#/components/schemas/ForbiddenError'
              - $ref: '#/components/schemas/NotFoundError'
              - $ref: '#/components/schemas/UnprocessableEntityError'
    ForbiddenError:
      type: object
      properties:
        code:
          type: string
          description: Error code.
        detail:
          type: string
          description: Human readable error that explains error `code`.
      required:
        - code
        - detail
      x-examples:
        Insufficient permissions:
          code: forbidden
          detail: User does not have sufficient permissions for this action.
    NotFoundError:
      type: object
      properties:
        code:
          type: string
          description: Error code.
        detail:
          type: string
          description: Human readable error that explains error `code`.
        source:
          type: object
          properties:
            parameter:
              type: string
              description: The parameter that causes the error.
      required:
        - code
        - detail
      x-examples:
        Object not found:
          code: not_found
          detail: Object not found
          source:
            parameter: id
    UnprocessableEntityError:
      type: object
      properties:
        status:
          type: string
          example: unprocessable entity
        code:
          type: string
          description: Error code.
          example: missing_key
        detail:
          type: string
          description: Human readable error that explains error `code`.
          example: property is missing
        message:
          type: string
          example: property id is missing
        source:
          type: object
          properties:
            pointer:
              type: string
              description: >-
                The property and the item in an array (if applicable) that
                causes the error.
              example: id
      required:
        - code
        - detail
      x-examples:
        Missing property:
          code: missing_key
          detail: property is missing
          source:
            pointer: /external_transfer/atrribute
  responses:
    403-Forbidden:
      description: Returns a forbidden error.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ForbiddenResponseBody'
          examples:
            Insufficient permissions:
              value:
                errors:
                  - code: forbidden
                    detail: User does not have sufficient permissions for this action.
  securitySchemes:
    OAuth:
      type: oauth2
      description: >
        Bearer authorization header: `Bearer <token>`, where `<token>` is the
        access token received from the authorization server at the end of the
        [OAuth 2.0
        flow](/get-started/business-api/authentication/oauth/oauth-flow).
      flows:
        authorizationCode:
          refreshUrl: https://oauth.qonto.com/oauth2/token
          authorizationUrl: https://oauth.qonto.com/oauth2/auth
          scopes:
            attachment.read: Retrieve attachments
            attachment.write: Upload attachments and remove attachments from transactions
            bank_account.write: Create, update and close bank accounts
            beneficiary.trust: Trust SEPA beneficiaries
            card.read: Retrieve cards
            card.write: Create or update cards
            client.read: Retrieve clients
            client.write: Create clients
            client_invoice.write: Create client invoices
            client_invoices.read: Retrieve client invoices and credit notes
            einvoicing.read: Retrieve e-invoicing settings
            embed_auth_link.write: Create Embed auth links
            insurance_contract.read: Retrieve insurance contracts
            insurance_contract.write: Create and update insurance contracts
            internal_transfer.write: >-
              Create internal transfers (between 2 Qonto accounts of the same
              organization)
            international_transfer.write: Create international transfers
            membership.read: Retrieve the authentified membership
            membership.write: Invite team members
            offline_access: Retrieve a refresh token
            organization.read: >-
              Retrieve organization, bank accounts, transactions, transfers,
              beneficiaries, labels, memberships, requests & statements
            payment.write: Create external transfers and untrust beneficiaries
            payment_link.read: >-
              Retrieve payment links, their payments, and the available payment
              methods
            payment_link.write: >-
              Connect to the payment links provider, create and deactivate
              payment links
            product.read: Retrieve products
            product.write: Create products
            request_cards.write: Create card requests
            request_review.write: Approve or decline requests
            request_transfers.write: Create transfer requests
            sepa_direct_debit.read: View SEPA Direct Debit payments
            sepa_direct_debit.write: Manage SEPA Direct Debit payments
            supplier_invoice.read: Retrieve supplier invoices
            supplier_invoice.write: Create supplier invoices
            team.read: Retrieve teams
            team.write: Create teams
            terminal.read: View your payment terminals
            terminal.write: Configure your terminals and initiate payments
            webhook: >-
              Receive a notification each time a particular event occurs in
              Qonto
          tokenUrl: https://oauth.qonto.com/oauth2/token
    SecretKey:
      type: apiKey
      description: cf. [API key](/get-started/business-api/authentication/api-key)
      name: Authorization
      in: header

````