Redispatch Export REST API

HTTP Endpunkt für Export von Redispatch 2.0-fähigen Anlagen (≥100 kW). Async Processing mit Job-Status-Polling.

📡 REST API ⚡ HTTP POST 🔄 Async Job 🔐 Bearer Auth

📡 Endpunkt

POST /api/grid-operations/redispatch-export

🔐 Auth

Bearer Token

⚡ Response

Async Job ID

💾 Format

JSON

REST API Übersicht

HTTP Endpunkt

POST https://api.cernion.de/api/grid-operations/redispatch-export

Authentication

Verwenden Sie einen Bearer Token im Authorization Header:

Authorization: Bearer YOUR_API_TOKEN

🔑 API Token anfordern: [email protected]

Request Body

Parameter Typ Required Beschreibung
gridOperator string ✅ Ja Netzbetreiber-Name (Fuzzy Matching unterstützt)
minCapacity number ❌ Nein Mindestleistung in kW (default: 100)
types array ❌ Nein Anlagentypen: solar, wind, storage, combustion, biomass
autoConfirm boolean ❌ Nein Bestätigung überspringen (default: true)

Beispiel Request Body

{
  "gridOperator": "Stadtwerke München",
  "minCapacity": 100,
  "types": ["solar", "wind"],
  "autoConfirm": true
}

Response

Der Endpunkt startet einen asynchronen Job und gibt sofort eine Job-ID zurück:

{
  "success": true,
  "jobId": "job_abc123def456",
  "status": "queued",
  "message": "Job started. Use GET /api/system/job-status/{jobId} to check progress."
}

Job Status abfragen

GET https://api.cernion.de/api/system/job-status/job_abc123def456

Job Status Response

{
  "jobId": "job_abc123def456",
  "status": "succeeded",
  "progress": 100,
  "result": {
    "gridOperator": "Stadtwerke München",
    "installations": [
      {
        "mastrNummer": "SEE123456789012",
        "name": "PV Anlage Beispielstraße",
        "type": "solar",
        "capacityKW": 250,
        "location": "München",
        "commissioningDate": "2020-05-15"
      }
    ],
    "totalCount": 47,
    "totalCapacityMW": 12.5
  }
}

Code-Beispiele

cURL Beispiel

# Job starten
curl -X POST https://api.cernion.de/api/grid-operations/redispatch-export \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "gridOperator": "Stadtwerke München",
    "minCapacity": 100,
    "types": ["solar", "wind"]
  }'

# Job Status abfragen
curl -X GET https://api.cernion.de/api/system/job-status/job_abc123def456 \
  -H "Authorization: Bearer YOUR_API_TOKEN"

# Job Ergebnis abrufen
curl -X GET https://api.cernion.de/api/system/job-result/job_abc123def456 \
  -H "Authorization: Bearer YOUR_API_TOKEN"

JavaScript/Node.js Beispiel

const API_TOKEN = 'YOUR_API_TOKEN';
const BASE_URL = 'https://api.cernion.de';

// Job starten
async function startRedispatchExport() {
  const response = await fetch(`${BASE_URL}/api/grid-operations/redispatch-export`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${API_TOKEN}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      gridOperator: 'Stadtwerke München',
      minCapacity: 100,
      types: ['solar', 'wind']
    })
  });
  
  const data = await response.json();
  console.log('Job ID:', data.jobId);
  return data.jobId;
}

// Job Status polling
async function pollJobStatus(jobId) {
  const response = await fetch(`${BASE_URL}/api/system/job-status/${jobId}`, {
    headers: {
      'Authorization': `Bearer ${API_TOKEN}`
    }
  });
  
  const data = await response.json();
  
  if (data.status === 'succeeded') {
    // Ergebnis abrufen
    const resultResponse = await fetch(`${BASE_URL}/api/system/job-result/${jobId}`, {
      headers: { 'Authorization': `Bearer ${API_TOKEN}` }
    });
    return await resultResponse.json();
  } else if (data.status === 'failed') {
    throw new Error('Job failed: ' + data.error);
  } else {
    // Noch nicht fertig, nochmal prüfen
    await new Promise(resolve => setTimeout(resolve, 2000));
    return pollJobStatus(jobId);
  }
}

// Alles zusammen
(async () => {
  const jobId = await startRedispatchExport();
  const result = await pollJobStatus(jobId);
  console.log('Ergebnis:', result);
})();

Python Beispiel

import requests
import time

API_TOKEN = 'YOUR_API_TOKEN'
BASE_URL = 'https://api.cernion.de'

def start_redispatch_export():
    """Job starten"""
    response = requests.post(
        f'{BASE_URL}/api/grid-operations/redispatch-export',
        headers={
            'Authorization': f'Bearer {API_TOKEN}',
            'Content-Type': 'application/json'
        },
        json={
            'gridOperator': 'Stadtwerke München',
            'minCapacity': 100,
            'types': ['solar', 'wind']
        }
    )
    data = response.json()
    print(f'Job ID: {data["jobId"]}')
    return data['jobId']

def poll_job_status(job_id, max_attempts=30):
    """Job Status polling mit Timeout"""
    for attempt in range(max_attempts):
        response = requests.get(
            f'{BASE_URL}/api/system/job-status/{job_id}',
            headers={'Authorization': f'Bearer {API_TOKEN}'}
        )
        data = response.json()
        
        if data['status'] == 'succeeded':
            # Ergebnis abrufen
            result_response = requests.get(
                f'{BASE_URL}/api/system/job-result/{job_id}',
                headers={'Authorization': f'Bearer {API_TOKEN}'}
            )
            return result_response.json()
        elif data['status'] == 'failed':
            raise Exception(f'Job failed: {data.get("error")}')
        
        print(f'Status: {data["status"]}, Progress: {data.get("progress", 0)}%')
        time.sleep(2)
    
    raise TimeoutError('Job timeout after 60 seconds')

# Alles zusammen
if __name__ == '__main__':
    job_id = start_redispatch_export()
    result = poll_job_status(job_id)
    
    print(f'\\nErgebnis:')
    print(f'Netzbetreiber: {result["gridOperator"]}')
    print(f'Anlagen gefunden: {result["totalCount"]}')
    print(f'Gesamtleistung: {result["totalCapacityMW"]} MW')

Anwendungsfälle

🏭 Portfolio-Analyse

Gesamtüberblick aller Redispatch-Anlagen im Netzgebiet für strategische Netzplanung

📊 Risiko-Assessment

Identifikation von Anlagen mit hohem Abregelungsrisiko basierend auf Standort und Kapazität

💼 CAPEX-Planung

Netzausbaupriorisierung durch Mapping von Anlagen-Hotspots und Engpasspunkten

📈 Compliance-Reporting

Monatliche Überwachung neuer Anlagen für §13 EnWG und Redispatch 2.0 Meldepflichten

Rate Limits & Best Practices

⏱️ Rate Limits

  • 60 Requests/Minute pro API Token
  • 1000 Requests/Tag im Starter-Tarif
  • 429 Status Code bei Überschreitung
  • Retry-After Header beachten

🔄 Async Job Handling

  • Job-Status alle 2-5 Sekunden abfragen
  • Timeout nach 60 Sekunden implementieren
  • Exponential Backoff verwenden
  • Webhook-Alternative für große Jobs nutzen

⚠️ Error Handling

  • 400: Validation Error (Parameter prüfen)
  • 401: Unauthorized (Token ungültig)
  • 404: Netzbetreiber nicht gefunden
  • 429: Rate Limit (Retry-After beachten)
  • 500: Server Error (Support kontaktieren)

💡 Performance-Tipps

  • Results cachen (gültig für 24h)
  • Batch-Verarbeitung nachts durchführen
  • minCapacity nutzen (kleinere Datasets)
  • types Filter für gezieltes Querying

ROI durch API-Integration

Szenario Manuelle Arbeit Mit REST API Zeitersparnis Kostenersparnis/Jahr
Monatliches Reporting (1 Netzbetreiber) 4h (Excel + MaStR-Portal) 5 min (API Call + Visualisierung) 3h 55 min/Monat 2.820€ (47h × 60€/h)
Portfolio-Analyse (5 Netzbetreiber) 20h (manuelle Aggregation) 15 min (parallel API Calls) 19h 45 min/Quartal 4.740€ (79h × 60€/h)
Risiko-Assessment (tägliches Update) 1h (tägliche MaStR-Abfrage) 2 min (automatisiertes Script) 58 min/Tag 14.500€ (242 Arbeitstage × 60€/h)
Gesamtersparnis — 22.060€/Jahr

💡 Break-Even nach 1 Monat bei typischer Stadtwerke-Nutzung (API Kosten: 99€/Monat)

Häufig gestellte Fragen (FAQ)

Wie lange dauert ein typischer Job?

Für Stadtwerke mit 50-200 Anlagen: 5-15 Sekunden. Große Netzbetreiber (>500 Anlagen): bis zu 60 Sekunden. Verwenden Sie Polling mit 2-5 Sekunden Intervall.

Kann ich mehrere Netzbetreiber parallel abfragen?

Ja! Starten Sie mehrere Jobs parallel und pollen Sie die Status unabhängig. Beachten Sie das Rate Limit von 60 Requests/Minute.

Werden die Daten gecached?

Ja, die MaStR-Daten werden 24 Stunden gecached. Bei erneuter Abfrage desselben Netzbetreibers erhalten Sie sofortige Antwort (kein Job-Polling notwendig).

Was ist der Unterschied zu /api/energy-market/installations?

/redispatch-export filtert automatisch auf Redispatch 2.0-fähige Anlagen ≥100 kW und gibt aggregierte Statistiken. /installations ist eine allgemeine Suchfunktion für alle Anlagen.

Wie aktuell sind die MaStR-Daten?

Wir synchronisieren täglich mit dem offiziellen Marktstammdatenregister der Bundesnetzagentur. Daten sind maximal 24 Stunden alt.

Kann ich Webhooks für Job-Completion nutzen?

Ja, im Business Tier (ab 299€/Monat). Konfigurieren Sie einen Webhook-Endpunkt und erhalten Sie Push-Benachrichtigungen statt Polling.

Welche Netzbetreiber werden unterstützt?

Alle deutschen Verteilnetzbetreiber (VNB) und Übertragungsnetzbetreiber (ÜNB). Fuzzy Matching unterstützt Abkürzungen: "StW München", "Stadtwerke München", "SWM" funktionieren alle.

Bereit für die Integration?

Fordern Sie Ihren API-Token an und starten Sie in 5 Minuten.

Durchschnittliche Setup-Zeit: 5 Minuten. Erste Anfragen nach wenigen Minuten.