Batches API

Automatisierte Verarbeitung von Steuerdokumenten in großen Mengen

Übersicht

Die Batches API ermöglicht die automatisierte Verarbeitung von Steuerdokumenten über unsere REST-Schnittstelle. Ein Batch ist eine zusammenhängende Verarbeitungseinheit mit einem oder mehreren Dokumenten.

Batch-Verarbeitung

Mehrere Dokumente in einer Anfrage verarbeiten

Echtzeit-Fortschritt

Detaillierte Fortschrittsinformationen während der Verarbeitung

Webhooks

Automatische Benachrichtigungen bei Statusänderungen

Verarbeitungsphasen

Jeder Batch durchläuft automatisch mehrere Phasen:

  • CONVERSION - Konvertierung der Dokumente in standardisierte Formate
  • OCR - Texterkennung in gescannten Dokumenten
  • ANALYSIS - KI-gestützte Analyse und Kategorisierung
  • ORGANIZATION - Strukturierung und Sortierung der Ergebnisse
  • REPORT - Generierung der finalen Ausgabedatei

Status-Lebenszyklus

Ein Batch durchläuft verschiedene Stati während der Verarbeitung:

1
queued

Batch wurde erstellt und wartet auf Verarbeitung

2
processing

Batch wird aktiv verarbeitet (Konvertierung, Analyse, etc.)

3
completed

Verarbeitung erfolgreich abgeschlossen, Ergebnis verfügbar

!
failed

Verarbeitung fehlgeschlagen (Details in error-Feld)

Batch erstellen

Erstellt einen neuen Batch zur Verarbeitung von Steuerdokumenten.

POST /v1/batches

Idempotenz & Location

  • Senden Sie einen eindeutigen Idempotency-Key-Header (z. B. UUID), um doppelte Batch-Erstellungen bei Retries zu vermeiden.
  • Die Antwort ist 202 Accepted und enthält einen Location-Header auf die Ressource (z. B. /v1/batches/b_abc123) sowie Links in der Antwort (self, progress, result).

Erforderliche Berechtigung

Dieser Endpoint benötigt den Scope batches:write

Zielablage & Dateiuebernahme

  • Die Zielablage fuer Batch-Dateien wird serverseitigfestgelegt (implizit). Der Client uebergibt keinen Zielpfad.
  • Der Server uebernimmt die Quelldateien ueber kurzlebige Direkt-Download-URLs, die der Client bereitstellt (z. B. presigned URLs). Die tatsaechliche Speicherplattform wird von der API bestimmt und kann variieren.

Direkt-Download-URL Anforderungen

  • Nur HTTPS GET, direkt abrufbar ohne Interaktion; max. 2 Redirects.
  • Lebensdauer 5-60 Minuten empfohlen; Feld expires_at angeben.
  • Optional sha256 zur Integritaetspruefung; Mismatch = Fehler.
  • Streaming faehig (keine Zwangs-Range-Downloads). Content-Length falls bekannt.
  • Erlaubte Dateitypen: PDF, ZIP, Office, Bilder (konfigurierbar); Groessenlimits beachten.
  • Quelle muss vom Backend erreichbar sein (keine IP-Whitelists, die unsere Server ausschliessen).

Request Body

{
  "batch_name": "Steuererklärung 2024 - Q4",

  // Mandant (Optional): Kategorisierung für Endkunden
  "mandant": {
    // Option 1: Vorhandenen Mandanten verwenden
    "id": "m_existing123"

    // Option 2: Neuen Mandanten erstellen
    // "first_name": "Klaus",
    // "last_name": "Müller",
    // "tax_id": "12345678901",
    // "company_name": "Müller GmbH"
  },

  // Dokumente (mindestens 1 erforderlich)
  "documents": [
    {
      "filename": "rechnung_001.pdf",
      "source": {
        "type": "url",
        "url": "https://files.partner.example/presigned/rechnung_001.pdf",
        "expires_at": "2025-10-28T10:15:00Z", // kurzlebig (empf. 5-60 Min.)
        "sha256": "b6f2..."                    // optional Integrittsprufung
      }
    },
    {
      "filename": "belege.zip",
      "source": {
        "type": "url",
        "url": "https://partner.app/docs/belege.zip",
        "sha256": "a3b5c7d9..."  // Optional: Checksum für Validierung
      }
    }
  ],

  // Verarbeitungsoptionen (Optional)
  "processing": {
    "phases": ["conversion", "analysis"],  // Standard: beide Phasen
    "language": "de",                       // Standard: Deutsch
    "auto_dedupe": true                     // Duplikate automatisch entfernen
  },

  // Webhook für Statusbenachrichtigungen (Optional)
  "webhook_url": "https://ihre-app.de/webhooks/steuermappe",
  "webhook_secret": "s3cr3t_key_for_hmac"
}

Request Parameter

ParameterTypPflichtBeschreibung
batch_namestringJaBezeichnung des Batches (z.B. "Q4 2024")
mandantobjectNeinMandant-Zuordnung für Kategorisierung
documentsarrayJaListe der zu verarbeitenden Dokumente (min. 1)
processingobjectNeinVerarbeitungsoptionen (Phasen, Sprache, etc.)
webhook_urlstringNeinURL für Statusbenachrichtigungen via Webhook

Beispiel: cURL

curl -X POST https://api.steuermappe-pro.de/v1/batches \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "batch_name": "Steuererklärung 2024 - Q4",
    "mandant": {
      "first_name": "Klaus",
      "last_name": "Müller",
      "tax_id": "12345678901"
    },
    "documents": [
      {
        "filename": "rechnung_001.pdf",
        "source": {
          "type": "url",
          "path": "/Steuerberater/Mandant_123/rechnung_001.pdf"
        }
      }
    ],
    "processing": {
      "phases": ["conversion", "analysis"],
      "language": "de"
    },
    "webhook_url": "https://ihre-app.de/webhooks/steuermappe"
  }'

Beispiel: TypeScript

async function createBatch(accessToken: string) {
  const response = await fetch('https://api.steuermappe-pro.de/v1/batches', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${accessToken}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      batch_name: 'Steuererklärung 2024 - Q4',
      mandant: {
        first_name: 'Klaus',
        last_name: 'Müller',
        tax_id: '12345678901'
      },
      documents: [
        {
          filename: 'rechnung_001.pdf',
          source: {
            type: 'url',
            path: '/Steuerberater/Mandant_123/rechnung_001.pdf'
          }
        }
      ],
      processing: {
        phases: ['conversion', 'analysis'],
        language: 'de'
      },
      webhook_url: 'https://ihre-app.de/webhooks/steuermappe'
    })
  });

  if (!response.ok) {
    throw new Error(`Batch creation failed: ${response.status}`);
  }

  return await response.json();
}

Antwort (202 Accepted)

{
  "batch_id": "b_abc123",
  "project_id": "prj_123",
  "organization_id": "org_abc",

  "mandant": {
    "id": "m_456",
    "name": "Klaus Müller"
  },

  "status": "queued",

  "storage": {
    "provider": "managed",
    "base_path": "/<org>/<year>/<mandant>/Batch_<YYYYMMDD>_b_abc123"
  },

  "partner_code": {
    "code": "ABC123",
    "discount_percent": 15.00,
    "provision_percent": 15.00,
    "snapshot_id": "pcs_789"  // Unveränderbare Abrechnungsreferenz
  },

  "estimated_cost": {
    "conversion_eur": "8.40",
    "analysis_eur": "12.00",
    "subtotal_eur": "20.40",
    "discount_eur": "3.06",
    "total_eur": "17.34"
  },

  "estimated_duration_seconds": 180,
  "created_at": "2025-10-06T10:00:00Z"
}

Asynchrone Verarbeitung

Die Batch-Erstellung erfolgt asynchron. Der Status 202 Accepted bedeutet, dass der Batch erfolgreich in die Warteschlange eingereiht wurde. Verwenden Sie die Progress- oder Status-Endpoints, um den Fortschritt zu überwachen.

Batch-Status abrufen

Ruft den aktuellen Status und grundlegende Informationen eines Batches ab.

GET /v1/batches/{batch_id}

Erforderliche Berechtigung

Dieser Endpoint benötigt den Scope batches:read

Pfad-Parameter

ParameterTypBeschreibung
batch_idstringEindeutige ID des Batches (z.B. "b_abc123")

Beispiel: cURL

curl -X GET https://api.steuermappe-pro.de/v1/batches/b_abc123 \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Beispiel: TypeScript

async function getBatchStatus(batchId: string, accessToken: string) {
  const response = await fetch(
    `https://api.steuermappe-pro.de/v1/batches/${batchId}`,
    {
      headers: { 'Authorization': `Bearer ${accessToken}` }
    }
  );

  if (!response.ok) {
    throw new Error(`Failed to get batch: ${response.status}`);
  }

  return await response.json();
}

Antwort (200 OK)

{
  "batch_id": "b_abc123",
  "status": "processing",
  "project_id": "prj_123",
  "mandant_id": "m_456",

  "progress": {
    "overall_percent": 82,
    "current_phase": "ANALYSIS",
    "estimated_time_remaining_seconds": 45
  },

  "created_at": "2025-10-06T10:00:00Z",
  "updated_at": "2025-10-06T10:05:15Z"
}

Echtzeit-Fortschritt abrufen

Ruft detaillierte Fortschrittsinformationen eines Batches ab, inklusive aktueller Phase, Datei-Fortschritt und geschätzter Restzeit.

GET /v1/batches/{batch_id}/progress

Erforderliche Berechtigung

Dieser Endpoint benötigt den Scope batches:read

Beispiel: cURL

curl -X GET https://api.steuermappe-pro.de/v1/batches/b_abc123/progress \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Beispiel: TypeScript

async function getBatchProgress(batchId: string, accessToken: string) {
  const response = await fetch(
    `https://api.steuermappe-pro.de/v1/batches/${batchId}/progress`,
    {
      headers: { 'Authorization': `Bearer ${accessToken}` }
    }
  );

  if (!response.ok) {
    throw new Error(`Failed to get progress: ${response.status}`);
  }

  return await response.json();
}

// Polling-Beispiel: Fortschritt alle 5 Sekunden abrufen
async function pollProgress(batchId: string, accessToken: string) {
  const interval = setInterval(async () => {
    const progress = await getBatchProgress(batchId, accessToken);

    console.log(`Fortschritt: ${progress.current_phase.overall_progress}%`);
    console.log(`Phase: ${progress.current_phase.phase}`);
    console.log(`Datei: ${progress.file_progress.current_file}`);

    if (progress.status === 'completed' || progress.status === 'failed') {
      clearInterval(interval);
      console.log('Verarbeitung abgeschlossen:', progress.status);
    }
  }, 5000);
}

Antwort (200 OK)

{
  "batch_id": "b_abc123",
  "status": "processing",

  "current_phase": {
    "phase": "ANALYSIS",
    "phase_progress": 65,
    "overall_progress": 82,
    "micro_step": "processing_invoices",
    "micro_step_description": "Rechnung 7 von 12 wird analysiert",
    "estimated_time_remaining_seconds": 45
  },

  "file_progress": {
    "current_file": "rechnung_007.pdf",
    "current_index": 7,
    "total_files": 12,
    "percentage": 58.3
  },

  "phases_completed": [
    {
      "phase": "CONVERSION",
      "started_at": "2025-10-06T10:01:00Z",
      "completed_at": "2025-10-06T10:03:30Z",
      "duration_seconds": 150,
      "files_processed": 12
    },
    {
      "phase": "OCR",
      "started_at": "2025-10-06T10:03:30Z",
      "completed_at": "2025-10-06T10:05:00Z",
      "duration_seconds": 90,
      "files_processed": 12
    }
  ],

  "timestamp": "2025-10-06T10:05:15Z"
}

Polling-Empfehlung

Für die Fortschrittsüberwachung empfehlen wir ein Polling-Intervall von 5-10 Sekunden. Alternativ können Sie Webhooks verwenden, um über Statusänderungen benachrichtigt zu werden.

Ergebnis abrufen

Ruft das Verarbeitungsergebnis eines abgeschlossenen Batches ab, inklusive Download-URL für die generierte Datei.

GET /v1/batches/{batch_id}/result

Erforderliche Berechtigung

Dieser Endpoint benötigt den Scope results:read

Verfügbarkeit

Dieser Endpoint ist nur verfügbar, wenn der Batch-Status completed ist. Bei anderen Stati wird ein 404 Not Found zurückgegeben.

Beispiel: cURL

curl -X GET https://api.steuermappe-pro.de/v1/batches/b_abc123/result \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Beispiel: TypeScript

async function getBatchResult(batchId: string, accessToken: string) {
  const response = await fetch(
    `https://api.steuermappe-pro.de/v1/batches/${batchId}/result`,
    {
      headers: { 'Authorization': `Bearer ${accessToken}` }
    }
  );

  if (!response.ok) {
    throw new Error(`Failed to get result: ${response.status}`);
  }

  return await response.json();
}

// Ergebnis herunterladen
async function downloadResult(batchId: string, accessToken: string) {
  const result = await getBatchResult(batchId, accessToken);

  // Kurzlebige Direkt-Download-URL (vom Client bereitgestellt)
  const fileResponse = await fetch(result.result.download_url);
  const blob = await fileResponse.blob();

  // Als Datei speichern
  const url = window.URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = `steuermappe_${batchId}.xlsx`;
  document.body.appendChild(a);
  a.click();
  window.URL.revokeObjectURL(url);
  document.body.removeChild(a);
}

Antwort (200 OK)

{
  "batch_id": "b_abc123",
  "status": "completed",

  "result": {
    "download_url": "https://files.partner.example/presigned/belege.zip",
    "expires_at": "2025-10-28T10:15:00Z"  // Kurzlebig; ISO-8601 UTC
    "file_size_bytes": 5242880,
    "sha256": "a3b5c7d9e1f2a4b6c8d0e2f4a6b8c0d2e4f6a8b0c2d4e6f8a0b2c4d6e8f0a2b4"
  },

  "usage": {
    "pages_processed": 38,
    "documents_processed": 12,
    "conversion_duration_seconds": 150,
    "analysis_duration_seconds": 95,
    "total_duration_seconds": 245
  },

  "billing": {
    "partner_code": "ABC123",
    "snapshot_id": "pcs_789",
    "total_cost_eur": "17.34"
  }
}

Batches auflisten

Listet alle Batches für Ihr Projekt auf, mit optionalen Filtern für Status, Mandant und Zeitraum.

GET /v1/batches

Erforderliche Berechtigung

Dieser Endpoint benötigt den Scope batches:read

Query-Parameter

ParameterTypBeschreibung
statusstringFilter nach Status (queued, processing, completed, failed)
mandant_idstringFilter nach Mandant-ID
fromstringStart-Datum (ISO 8601: YYYY-MM-DD)
tostringEnd-Datum (ISO 8601: YYYY-MM-DD)
limitnumberAnzahl der Ergebnisse (Standard: 50, Max: 100)
offsetnumberPagination-Offset (Standard: 0)

Beispiel: cURL

# Alle abgeschlossenen Batches im Oktober 2025
curl -X GET "https://api.steuermappe-pro.de/v1/batches?status=completed&from=2025-10-01&to=2025-10-31&limit=50" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

# Alle Batches für einen bestimmten Mandanten
curl -X GET "https://api.steuermappe-pro.de/v1/batches?mandant_id=m_123" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Beispiel: TypeScript

interface ListBatchesOptions {
  status?: 'queued' | 'processing' | 'completed' | 'failed';
  mandant_id?: string;
  from?: string;  // YYYY-MM-DD
  to?: string;    // YYYY-MM-DD
  limit?: number;
  offset?: number;
}

async function listBatches(
  accessToken: string,
  options: ListBatchesOptions = {}
) {
  const params = new URLSearchParams();

  if (options.status) params.append('status', options.status);
  if (options.mandant_id) params.append('mandant_id', options.mandant_id);
  if (options.from) params.append('from', options.from);
  if (options.to) params.append('to', options.to);
  if (options.limit) params.append('limit', options.limit.toString());
  if (options.offset) params.append('offset', options.offset.toString());

  const response = await fetch(
    `https://api.steuermappe-pro.de/v1/batches?${params}`,
    {
      headers: { 'Authorization': `Bearer ${accessToken}` }
    }
  );

  if (!response.ok) {
    throw new Error(`Failed to list batches: ${response.status}`);
  }

  return await response.json();
}

Antwort (200 OK)

{
  "batches": [
    {
      "batch_id": "b_abc123",
      "batch_name": "Steuererklärung Q4 2024",
      "status": "completed",
      "mandant_id": "m_456",
      "mandant_name": "Klaus Müller",
      "created_at": "2025-10-06T10:00:00Z",
      "completed_at": "2025-10-06T10:04:05Z"
    },
    {
      "batch_id": "b_def456",
      "batch_name": "Jahresabschluss 2024",
      "status": "processing",
      "mandant_id": "m_789",
      "mandant_name": "Anna Schmidt GmbH",
      "created_at": "2025-10-06T11:30:00Z",
      "completed_at": null
    }
  ],
  "pagination": {
    "total": 127,
    "limit": 50,
    "offset": 0,
    "has_more": true,
    "next_url": "/v1/batches?status=completed&from=2025-10-01&to=2025-10-31&limit=50&offset=50"
  }
}

Response-Schemas

Batch-Objekt

{
  "batch_id": "string",           // Eindeutige Batch-ID
  "project_id": "string",         // Projekt-ID
  "organization_id": "string",    // Organisations-ID
  "batch_name": "string",         // Name des Batches
  "status": "string",             // queued | processing | completed | failed
  "mandant_id": "string | null",  // Optional: Mandant-ID
  "storage": { "provider": "managed", "base_path": "string" },     // Serverseitig bestimmte Zielablage
  "created_at": "string",         // ISO 8601 Timestamp
  "updated_at": "string"          // ISO 8601 Timestamp
}

Progress-Objekt

{
  "batch_id": "string",
  "status": "string",

  "current_phase": {
    "phase": "string",                        // CONVERSION | OCR | ANALYSIS | ORGANIZATION | REPORT
    "phase_progress": "number",               // 0-100
    "overall_progress": "number",             // 0-100
    "micro_step": "string",                   // Interner Schritt-Name
    "micro_step_description": "string",       // Deutsche Beschreibung
    "estimated_time_remaining_seconds": "number"
  },

  "file_progress": {
    "current_file": "string",                 // Dateiname
    "current_index": "number",                // 1-basiert
    "total_files": "number",
    "percentage": "number"                    // 0-100
  },

  "phases_completed": [
    {
      "phase": "string",
      "started_at": "string",
      "completed_at": "string",
      "duration_seconds": "number",
      "files_processed": "number"
    }
  ],

  "timestamp": "string"                       // ISO 8601
}

Result-Objekt

{
  "batch_id": "string",
  "status": "completed",

  "result": {
    "download_url": "string",                 // Kurzlebige Direkt-Download-URL (HTTPS)
    "expires_at": "string",                   // ISO 8601 UTC Ablaufzeit
    "file_size_bytes": "number",
    "sha256": "string"                        // Checksum
  },

  "usage": {
    "pages_processed": "number",
    "documents_processed": "number",
    "conversion_duration_seconds": "number",
    "analysis_duration_seconds": "number",
    "total_duration_seconds": "number"
  },

  "billing": {
    "partner_code": "string",
    "snapshot_id": "string",                  // Unveränderbare Abrechnungsreferenz
    "total_cost_eur": "string"                // Decimal als String
  }
}

Fehlerbehandlung

HTTP-Statuscodes

Status CodeBedeutungBeschreibung
200OKAnfrage erfolgreich
202AcceptedBatch wurde zur Verarbeitung angenommen
400Bad RequestUngültige Request-Parameter
401UnauthorizedFehlender oder ungültiger Access Token
403ForbiddenFehlende Berechtigung (Scope)
404Not FoundBatch nicht gefunden oder Ergebnis noch nicht verfügbar
429Too Many RequestsRate Limit überschritten
500Internal Server ErrorServerfehler (bitte Support kontaktieren)

Fehler-Response

{
  "error": "invalid_request",
  "error_description": "Missing required field: batch_name",
  "error_details": {
    "field": "batch_name",
    "reason": "required"
  }
}

Beispiel: Fehlerbehandlung

async function createBatchWithErrorHandling(
  accessToken: string,
  batchData: any
) {
  try {
    const response = await fetch(
      'https://api.steuermappe-pro.de/v1/batches',
      {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${accessToken}`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(batchData)
      }
    );

    if (!response.ok) {
      const error = await response.json();

      switch (response.status) {
        case 400:
          throw new Error(
            `Ungültige Anfrage: ${error.error_description}`
          );
        case 401:
          throw new Error('Authentifizierung fehlgeschlagen');
        case 403:
          throw new Error('Fehlende Berechtigung (Scope)');
        case 429:
          throw new Error('Rate Limit überschritten - bitte später erneut versuchen');
        default:
          throw new Error(`API-Fehler: ${response.status}`);
      }
    }

    return await response.json();

  } catch (error) {
    console.error('Batch-Erstellung fehlgeschlagen:', error);
    throw error;
  }
}

Rate Limiting

Die Batches API unterliegt Rate Limits, um die Systemstabilität zu gewährleisten:

Standard Rate Limit
100 Anfragen pro Minute pro API-Client
Batch-Erstellung
10 neue Batches pro Minute (POST /v1/batches)
Progress-Polling
Empfohlen: 5-10 Sekunden Intervall

Rate Limit Headers

Jede API-Antwort enthält Header mit Rate-Limit-Informationen:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1696598460

Rate Limit überschritten

Bei Überschreitung des Rate Limits erhalten Sie einen 429 Too Many RequestsFehler. Der Retry-After Header gibt an, nach wie vielen Sekunden Sie es erneut versuchen können.

Best Practices

Asynchrone Verarbeitung

  • ✓ Verwenden Sie Webhooks für Statusbenachrichtigungen statt dauerhaftem Polling
  • ✓ Cachen Sie Access Tokens (1 Stunde Gültigkeit)
  • ✓ Implementieren Sie exponentielles Backoff bei Fehlern

Fehlerbehandlung

  • ✓ Behandeln Sie alle HTTP-Statuscodes (4xx, 5xx)
  • ✓ Implementieren Sie Retry-Logik für temporäre Fehler (429, 500, 503)
  • ✓ Loggen Sie Fehlerdetails für Debugging

Performance

  • ✓ Batchen Sie mehrere Dokumente in einer Anfrage
  • ✓ Verwenden Sie Pagination bei großen Datenmengen (GET /v1/batches)
  • ✓ Reduzieren Sie Polling-Frequenz (max. alle 5 Sekunden)

Sicherheit

  • ✓ Speichern Sie Client Secret sicher (Umgebungsvariablen, Secret Manager)
  • ✓ Verifizieren Sie Webhook-Signaturen (HMAC)
  • ✓ Verwenden Sie HTTPS für alle Anfragen

Benötigen Sie Unterstützung?

Bei Fragen zur Batches API wenden Sie sich an unser Support-Team: api@steuermappe-pro.de