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

# Buchungsvorschlag

> Erstellt einen Buchungsvorschlag über DATEV Unternehmen Online.

Die strukturierten Daten werden direkt als Buchungsvorschlag angezeigt und können mit einem Klick verbucht werden.

**Kosten:** 1 Credit



## OpenAPI

````yaml POST /v2/datev-duo/buchungsvorschlag
openapi: 3.1.0
info:
  title: Business OS API
  description: >-
    API für Business OS – Zugang zu DATEV und Banking Enterprise-Schnittstellen.
    Alle Endpoints erfordern einen API Key im `x-api-key` Header. Credits werden
    pro API-Call abgezogen.
  version: 2.0.0
  contact:
    name: Business OS Support
    email: impressum@business-os.de
    url: https://business-os.de/kontakt
servers:
  - url: https://api.business-os.de
    description: Production
security:
  - ApiKeyAuth: []
tags:
  - name: DATEV Allgemein
    description: >-
      Modulübergreifende DATEV-Endpunkte (z. B. Abo-/Service-Diagnose für
      Mandanten)
  - name: DATEV DUO
    description: DATEV Unternehmen Online — Kassenbuch, Belegbilder und Buchungsvorschläge
  - name: DATEV ReWe - Write
    description: 'DATEV Rechnungswesen — Write: Buchungen, Kontakte, Belegtypen, Steuersätze'
  - name: DATEV ReWe - Read
    description: >-
      DATEV Rechnungswesen — Read (Export): Geschäftsjahre und weitere
      Lesemodule
  - name: Banking AIS
    description: >-
      Account Information Services — Verbindungen, Kontostände und Transaktionen
      verwalten
  - name: Banking PIS
    description: Payment Initiation Services — Zahlungen ausführen und Status abrufen
  - name: Banking Webhooks
    description: Webhook-Konfiguration für Echtzeit-Benachrichtigungen
paths:
  /v2/datev-duo/buchungsvorschlag:
    post:
      tags:
        - DATEV DUO
      summary: Buchungsvorschlag
      description: >-
        Erstellt einen Buchungsvorschlag über DATEV Unternehmen Online.


        Die strukturierten Daten werden direkt als Buchungsvorschlag angezeigt
        und können mit einem Klick verbucht werden.


        **Kosten:** 1 Credit
      parameters:
        - $ref: '#/components/parameters/ConnectionIdParam'
        - $ref: '#/components/parameters/CreditQuelleParam'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - belegdatum
                - waehrung
                - rechnungsordner
                - belegnummer
                - betrag
                - positionen
                - belegtyp
              properties:
                belegdatum:
                  type: string
                  format: date-time
                  description: >-
                    Belegdatum (z. B. Rechnungsdatum). ISO-8601-Datum und
                    -Uhrzeit mit Zeitzone (RFC 3339).
                  example: '2025-03-01T00:00:00Z'
                waehrung:
                  type: string
                  description: Währungscode nach ISO 4217.
                  example: EUR
                rechnungsordner:
                  type: string
                  description: >-
                    Name des Rechnungsordners. Muss zum Buchungstyp passen: bei
                    `EINGANGSRECHNUNG` ein Kreditorenordner, bei
                    `AUSGANGSRECHNUNG` ein Debitorenordner. Kann aus `GET
                    /v2/datev-duo/rechnungsordner` (Feld `bezeichnung`)
                    ausgelesen werden.
                  example: Eingangsrechnungen
                belegnummer:
                  type: string
                  description: Belegnummer / Rechnungsnummer.
                  maxLength: 36
                  pattern: ^[a-zA-Z0-9$%&*+\-/]{0,36}$
                  example: RE-2025-001
                betrag:
                  type: number
                  description: >-
                    Gesamtbetrag brutto (wie bei anderen DUO-Belegen). Darf
                    nicht 0 sein und muss der Summe der Positionsbeträge
                    (`positionen[].betrag`) entsprechen. Max. 10 Vorkomma- und 2
                    Nachkommastellen.
                  example: 119
                positionen:
                  type: array
                  description: Belegpositionen — mindestens eine Position erforderlich.
                  minItems: 1
                  items:
                    type: object
                    required:
                      - betrag
                    properties:
                      betrag:
                        type: number
                        description: >-
                          Bruttobetrag dieser Position. Darf nicht 0 sein. Max.
                          10 Vorkomma- und 2 Nachkommastellen.
                        example: 119
                      belegtext:
                        type: string
                        description: Positionstext, max. 60 Zeichen.
                        maxLength: 60
                        example: Büromaterial
                      steuersatzProzent:
                        type: number
                        description: Steuersatz in Prozent (z. B. 19 für 19 %).
                        example: 19
                      skontoBetrag:
                        type: number
                        description: >-
                          Fester Skontobetrag (Skonto 1). Positiv, max. 8
                          Vorkomma- und 2 Nachkommastellen. Darf den
                          Positionsbetrag nicht überschreiten. Erfordert
                          `skontoZahlungsdatum` auf Belegebene.
                      skontoProzent:
                        type: number
                        description: >-
                          Skontosatz in Prozent (Skonto 1). Max. 2 Vorkomma- und
                          2 Nachkommastellen, max. 100 %. Erfordert
                          `skontoZahlungsdatum` auf Belegebene.
                      skontoBetrag2:
                        type: number
                        description: >-
                          Fester Skontobetrag (Skonto 2). Darf `skontoBetrag`
                          und den Positionsbetrag nicht überschreiten. Erfordert
                          `skontoZahlungsdatum2` auf Belegebene.
                      skontoProzent2:
                        type: number
                        description: >-
                          Skontosatz in Prozent (Skonto 2). Muss kleiner als
                          `skontoProzent` sein. Erfordert `skontoZahlungsdatum2`
                          auf Belegebene.
                      kontoname:
                        type: string
                        description: Name des Sachkontos, max. 40 Zeichen.
                        maxLength: 40
                      kontonummer:
                        type: number
                        description: >-
                          Sachkontonummer. Die Länge muss der konfigurierten
                          Kontenlänge entsprechen.
                      buSchluessel:
                        type: string
                        description: >-
                          DATEV-Buchungsschlüssel (BU-Code). Max. 4 Zeichen, nur
                          Ziffern.
                        maxLength: 4
                        pattern: ^[0-9]{0,4}$
                      kostenstelle1:
                        type: string
                        description: Kostenstelle 1 (KOST1), max. 36 Zeichen.
                        maxLength: 36
                        example: Marketing
                      kostenstelle2:
                        type: string
                        description: Kostenstelle 2 (KOST2), max. 36 Zeichen.
                        maxLength: 36
                        example: IT-Abteilung
                belegtyp:
                  type: string
                  enum:
                    - EINGANGSRECHNUNG
                    - AUSGANGSRECHNUNG
                  description: >-
                    `EINGANGSRECHNUNG` = Eingangsrechnung (Kreditor),
                    `AUSGANGSRECHNUNG` = Ausgangsrechnung (Debitor).
                  example: EINGANGSRECHNUNG
                id:
                  type: string
                  format: uuid
                  description: >-
                    Optionale UUID zur Zuordnung von hochgeladenen Dateien zum
                    Buchungsvorschlag. Muss eine gültige UUID sein, wird
                    andernfalls ignoriert.
                adressen:
                  type: array
                  description: Optionale Adressen.
                  items:
                    type: object
                    properties:
                      stadt:
                        type: string
                        description: Ort, max. 30 Zeichen.
                        maxLength: 30
                bankkontonummer:
                  type: number
                  description: >-
                    Bankkontonummer (1–10 Ziffern). Wenn angegeben, ist
                    `bankleitzahl` erforderlich.
                bankleitzahl:
                  type: string
                  description: >-
                    Bankleitzahl. Wenn angegeben, ist `bankkontonummer`
                    erforderlich.
                  pattern: ^([1-9]|[0-9]{2,10})$
                bic:
                  type: string
                  description: BIC-Code.
                  pattern: ^[A-Z]{4}[A-Z]{2}[A-Z0-9]{2}[A-Z0-9]{0,3}$
                  example: DEUTDEFF
                iban:
                  type: string
                  description: IBAN.
                  pattern: ^[A-Z]{2}[0-9]{2}[A-Z0-9]{1,30}$
                  example: DE89370400440532013000
                kontaktKontonummer:
                  type: number
                  description: Kreditoren- oder Debitorennummer des Geschäftspartners.
                kontaktName:
                  type: string
                  description: Name des Geschäftspartners, max. 50 Zeichen.
                  maxLength: 50
                lieferdatum:
                  type: string
                  format: date-time
                  description: >-
                    Liefer- bzw. Leistungsdatum. ISO-8601-Datum und -Uhrzeit mit
                    Zeitzone (RFC 3339).
                faelligkeitsdatum:
                  type: string
                  format: date-time
                  description: >-
                    Fälligkeitsdatum. ISO-8601-Datum und -Uhrzeit mit Zeitzone
                    (RFC 3339). Muss nach `belegdatum` liegen. Pflicht, wenn
                    Skonto-Felder verwendet werden.
                skontoZahlungsdatum:
                  type: string
                  format: date-time
                  description: >-
                    Zahlungsziel für Skonto 1. ISO-8601-Datum und -Uhrzeit mit
                    Zeitzone (RFC 3339). Muss vor `faelligkeitsdatum` und nach
                    `belegdatum` liegen. Erfordert `skontoBetrag` und
                    `skontoProzent` in jeder Position.
                skontoZahlungsdatum2:
                  type: string
                  format: date-time
                  description: >-
                    Zahlungsziel für Skonto 2. ISO-8601-Datum und -Uhrzeit mit
                    Zeitzone (RFC 3339). Muss vor `faelligkeitsdatum` und nach
                    `skontoZahlungsdatum` liegen. Erfordert zusätzlich
                    `skontoBetrag2` und `skontoProzent2` in jeder Position.
                zahlungsdatum:
                  type: string
                  format: date-time
                  description: >-
                    Zahlungsdatum — markiert den Beleg als bezahlt.
                    ISO-8601-Datum und -Uhrzeit mit Zeitzone (RFC 3339).
                istZahlungsauftrag:
                  type: boolean
                  description: >-
                    Ob automatisch eine Zahlungsanweisung (Überweisung bei
                    `EINGANGSRECHNUNG`, Lastschrift bei `AUSGANGSRECHNUNG`)
                    erstellt werden soll. Muss `false` sein, wenn
                    `zahlungsbedingungenId` = 9.
                notizen:
                  type: string
                  description: Zusätzliche Notizen zum Buchungsvorschlag, max. 120 Zeichen.
                  maxLength: 120
                bestellId:
                  type: string
                  description: Bestell- bzw. Auftrags-ID.
                  maxLength: 30
                  pattern: ^[a-zA-Z0-9$%&*+\-./]{1,30}$
                zahlungsbedingungenId:
                  type: string
                  description: >-
                    Kennung der Zahlungsbedingungen (max. 3 Ziffern). Wenn
                    gesetzt, dürfen keine Skonto-Felder verwendet werden.
                  maxLength: 3
                  pattern: ^[0-9]{1,3}$
                ustId:
                  type: string
                  description: USt-IdNr. des Geschäftspartners.
                  maxLength: 15
                  pattern: ^[0-9a-zA-Z. _]{1,15}$
                ordnerVerwaltung:
                  type: object
                  description: >-
                    Optionale dreistufige Ordnerstruktur für die Belegablage.
                    Ohne Angabe wird die Standardstruktur verwendet.
                  required:
                    - kategorie
                    - ordner
                    - register
                  properties:
                    kategorie:
                      type: string
                      description: Oberste Ebene der Ordnerstruktur.
                    ordner:
                      type: string
                      description: Zweite Ebene der Ordnerstruktur.
                    register:
                      type: string
                      description: Dritte Ebene der Ordnerstruktur.
                belegbilder:
                  type: array
                  description: Optionale Belegdateien (z. B. PDF-Rechnungen).
                  items:
                    type: object
                    required:
                      - content
                    properties:
                      content:
                        type: string
                        description: Base64-kodierter Dateiinhalt.
                      dateiname:
                        type: string
                        maxLength: 255
                        description: >-
                          Dateiname inkl. Endung (nur Basisname, max. 255
                          Zeichen).
                        example: rechnung.pdf
      responses:
        '200':
          description: Buchungsvorschlag erfolgreich erstellt
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    nullable: true
                  adressen:
                    type: array
                    nullable: true
                    items:
                      type: object
                      properties:
                        stadt:
                          type: string
                          nullable: true
                  belegdatum:
                    type: string
                    format: date-time
                    nullable: true
                  belegtyp:
                    type: string
                    enum:
                      - EINGANGSRECHNUNG
                      - AUSGANGSRECHNUNG
                    example: EINGANGSRECHNUNG
                    nullable: true
                  kontaktKontonummer:
                    type: number
                    nullable: true
                  kontaktName:
                    type: string
                    nullable: true
                  erstellungsdatum:
                    type: string
                    nullable: true
                  waehrung:
                    type: string
                    example: EUR
                    nullable: true
                  lieferdatum:
                    type: string
                    format: date-time
                    nullable: true
                  skontoZahlungsdatum:
                    type: string
                    format: date-time
                    nullable: true
                  skontoZahlungsdatum2:
                    type: string
                    format: date-time
                    nullable: true
                  faelligkeitsdatum:
                    type: string
                    format: date-time
                    nullable: true
                  belegbilder:
                    nullable: true
                  iban:
                    type: string
                    nullable: true
                  bankkontonummer:
                    type: number
                    nullable: true
                  bankleitzahl:
                    type: string
                    nullable: true
                  bic:
                    type: string
                    nullable: true
                  istZahlungsauftrag:
                    type: boolean
                    nullable: true
                  rechnungsordner:
                    type: string
                    nullable: true
                  positionen:
                    type: array
                    nullable: true
                    items:
                      type: object
                      properties:
                        erstellungsdatum:
                          type: string
                          nullable: true
                        belegtext:
                          type: string
                          nullable: true
                        betrag:
                          type: number
                          nullable: true
                        steuersatzProzent:
                          type: number
                          nullable: true
                        skontoBetrag:
                          type: number
                          nullable: true
                        skontoProzent:
                          type: number
                          nullable: true
                        skontoBetrag2:
                          type: number
                          nullable: true
                        skontoProzent2:
                          type: number
                          nullable: true
                        kontoname:
                          type: string
                          nullable: true
                        kontonummer:
                          type: number
                          nullable: true
                        buSchluessel:
                          type: string
                          nullable: true
                        kostenstelle1:
                          type: string
                          nullable: true
                        kostenstelle2:
                          type: string
                          nullable: true
                  belegnummer:
                    type: string
                    example: RE-2025-001
                    nullable: true
                  notizen:
                    type: string
                    nullable: true
                  bestellId:
                    type: string
                    nullable: true
                  zahlungsdatum:
                    type: string
                    format: date-time
                    nullable: true
                  zahlungsbedingungenId:
                    type: string
                    nullable: true
                  aufgabenId:
                    type: string
                    nullable: true
                  betrag:
                    type: number
                    example: 119
                    nullable: true
                  ustId:
                    type: string
                    nullable: true
                  datevAntwort:
                    description: >-
                      Ergebnis des DATEV-Async-Tasks. `null`, wenn kein Task
                      gepollt wurde.
                    nullable: true
                    allOf:
                      - $ref: '#/components/schemas/DatevAntwort'
                  business-os:
                    type: object
                    properties:
                      neuesGuthaben:
                        type: integer
                        nullable: true
                        example: 499
        '400':
          description: >-
            Fehlende oder ungültige Pflichtfelder im JSON-Body (inkl.
            Validierung des Buchungsvorschlags).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DatevError'
              example:
                error: >-
                  Fehlende Pflichtfelder: belegdatum, waehrung, rechnungsordner,
                  belegnummer, betrag, positionen, belegtyp
        '401':
          $ref: '#/components/responses/DatevUnauthorized'
        '402':
          $ref: '#/components/responses/DatevPaymentRequired'
        '404':
          $ref: '#/components/responses/DatevNoConnection404'
        '500':
          $ref: '#/components/responses/DatevInternal500'
        '502':
          $ref: '#/components/responses/DatevBadGateway502'
        '504':
          $ref: '#/components/responses/DatevAsyncTimeout504'
        default:
          $ref: '#/components/responses/DatevServiceError'
components:
  parameters:
    ConnectionIdParam:
      name: connectionId
      in: query
      required: true
      schema:
        type: string
        format: uuid
        example: abbc18fd-ba5e-4dfd-afc4-9dec0c0ad145
      description: >-
        UUID der DATEV-Verbindung. Abrufbar über den `/connections`-Endpunkt des
        jeweiligen Moduls (z. B. `GET /v2/datev-duo/connections`).
    CreditQuelleParam:
      name: quelle
      in: query
      required: false
      schema:
        type: string
        default: API
        example: Make
      description: >-
        Kennzeichnung der Aufrufquelle für die Nutzungsanalyse. Standard bei
        Weglassen: `API` (direkter API-Aufruf). Für Automationen aus Make z. B.
        `Make` angeben.
  schemas:
    DatevAntwort:
      type: object
      description: >-
        DATEV-Antwort: Ergebnis des asynchronen DATEV-Tasks nach Abschluss. Kann
        zusätzliche Felder enthalten.
      properties:
        status:
          type: string
          description: Status
        information:
          type: array
          description: Informationen
          items:
            $ref: '#/components/schemas/DatevAntwortInformation'
      additionalProperties: true
    DatevError:
      type: object
      description: >-
        JSON-Fehlerantwort. Bei Fehlern der DATEV-Schnittstelle kann zusätzlich
        `details` gesetzt sein. Bei bekannten Fehlerkategorien ist ein stabiler
        `code` gesetzt, anhand dessen Automatisierungen reagieren können.
      required:
        - error
      properties:
        error:
          type: string
          description: Fehlermeldung
        message:
          type: string
          description: >-
            Zusätzliche Erläuterung; wenn der Header `x-api-key` fehlt: Hinweis
            zur erforderlichen Header-Zeile.
        code:
          type: string
          description: >-
            Stabiler, maschinenlesbarer Fehlercode für bekannte
            Fehlerkategorien. Wird nur gesetzt, wenn die Ursache eindeutig
            erkannt wurde.


            - `datev_connection_invalid`: Account-Key ist abgelaufen oder
            widerrufen — Reconnect über das Dashboard nötig. Begleitet von
            `reconnectUrl`.

            - `datev_export_service_missing`: Mandant hat keine relevante
            DATEV-Subscription gebucht (z. B. Belegbilderservice,
            Rechnungsdatenservice, Datenservice Export Rechnungswesen-Familie).
            Begleitet von `activeSubscriptions` mit der Liste der tatsächlich
            aktiven Services.

            - `datev_endpoint_not_authorized`: Subscription am Mandanten ist
            vorhanden und der Token gilt, aber das DATEV-RVO-Schreib-/Leserecht
            für den konkreten Endpoint fehlt für den authentifizierten Nutzer.
            Reconnect hilft hier nicht — der Steuerberater/Mandant-Inhaber muss
            in DATEV RVO das entsprechende Teilrecht freischalten.
          enum:
            - datev_connection_invalid
            - datev_export_service_missing
            - datev_endpoint_not_authorized
        reconnectUrl:
          type: string
          format: uri
          description: >-
            URL zum Business OS Dashboard, über die der Nutzer die
            DATEV-Verbindung erneuern kann. Gesetzt bei `code =
            datev_connection_invalid`.
        activeSubscriptions:
          type: array
          items:
            type: string
          description: >-
            Liste der aktuell aktiven DATEV-Service-Subscriptions des Mandanten
            (z. B. Belegbilderservice, Rechnungsdatenservice 1.0). Gesetzt bei
            `code = datev_export_service_missing`, damit Automationen erkennen,
            welche Services bereits gebucht sind.
        details:
          type: object
          description: >-
            Strukturierte Zusatzinformationen bei Antworten der
            DATEV-Schnittstelle.
          additionalProperties: true
    DatevAntwortInformation:
      type: object
      description: Ein Eintrag in der Informationsliste der DATEV-Antwort.
      properties:
        filename:
          type: string
          description: Dateiname
        message:
          type: string
          description: Nachricht
        timestamp:
          type: string
          description: Zeitstempel
          format: date-time
        type:
          type: string
          description: Typ
      additionalProperties: true
  responses:
    DatevUnauthorized:
      description: >-
        API-Key fehlt, ist ungültig, widerrufen oder abgelaufen. Fehlt der
        Header `x-api-key`, enthält die Antwort zusätzlich `message`.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/DatevError'
          examples:
            ungueltigerKey:
              summary: Ungültiger oder unbekannter Key
              value:
                error: Ungültiger API-Key
            fehlenderHeader:
              summary: Fehlender x-api-key Header
              value:
                error: Fehlende Header
                message: x-api-key Header ist erforderlich.
    DatevPaymentRequired:
      description: Nicht genügend Credits für diesen Aufruf.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/DatevError'
          example:
            error: Nicht genügend Credits
    DatevNoConnection404:
      description: >-
        Es ist keine gespeicherte DATEV-Verbindung für die Organisation
        vorhanden. Der Text in `error` nennt das gewählte DATEV-Produkt (z. B.
        DATEV Unternehmen Online).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/DatevError'
          example:
            error: Keine Verbindung gefunden für DATEV Unternehmen Online
    DatevInternal500:
      description: >-
        Unerwarteter Serverfehler oder fehlende Serverkonfiguration für den
        DATEV-Dienst.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/DatevError'
          example:
            error: API-Dienst nicht konfiguriert.
    DatevBadGateway502:
      description: >-
        Die DATEV-Schnittstelle war kurzzeitig nicht erreichbar (Netzwerk- oder
        Verbindungsfehler).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/DatevError'
          example:
            error: Die DATEV-Schnittstelle ist vorübergehend nicht erreichbar.
    DatevAsyncTimeout504:
      description: >-
        Der asynchrone DATEV-Task wurde nicht innerhalb des Zeitlimits
        abgeschlossen (max. ca. 40 Sekunden).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/DatevError'
          example:
            error: 'Async-Task-Timeout: Task wurde nicht rechtzeitig abgeschlossen.'
    DatevServiceError:
      description: >-
        Fehlerantwort der DATEV-Schnittstelle (HTTP-Status entspricht der
        DATEV-Antwort). Der Body enthält `error` und optional `details` mit
        Zusatzinformationen. Bei 403 wegen fehlendem DATEV
        Rechnungswesen-Exportservice ist zusätzlich `code =
        datev_export_service_missing` und `activeSubscriptions` gesetzt.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/DatevError'
          examples:
            mitDetails:
              summary: Beispiel mit details
              value:
                error: Validierung fehlgeschlagen
                details:
                  message: …
            exportserviceFehlt:
              summary: 403 – DATEV Rechnungswesen-Exportservice nicht abonniert
              value:
                error: >-
                  DATEV Rechnungswesen-Exportservice ist für diesen Mandanten
                  nicht abonniert. Aktive Services: Belegbilderservice,
                  Rechnungsdatenservice 1.0. Bitte den Service über DATEV beim
                  Mandant aktivieren.
                code: datev_export_service_missing
                activeSubscriptions:
                  - Belegbilderservice
                  - Rechnungsdatenservice 1.0
                details:
                  errors:
                    - message: 'RVO-Recht fehlt: Stammdaten'
            verbindungUngueltig:
              summary: 401 – DATEV-Verbindung ungültig (zur Referenz)
              value:
                error: >-
                  Die DATEV-Verbindung ist ungültig oder abgelaufen. Bitte im
                  Business OS Dashboard die Verbindung erneuern.
                code: datev_connection_invalid
                reconnectUrl: https://app.business-os.de/
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        Dein Business OS API Key. Erstelle einen unter
        [app.business-os.de](https://app.business-os.de/) → API Keys.

````