Externe API-Dokumentation
Die auf API-Schlüsseln basierende Integration gewährt Ihnen Zugriff auf Kalender, Projekte, Kunden und Komponenten. Damit erhalten Sie die Flexibilität, Ihre Systeme zu integrieren und Prozesse zu automatisieren.
Inhaltsverzeichnis
- Authentifizierung
- Paginierung
- Kalender-API
- Projekt-API
- Kunden-API
- Komponenten-API
- Datenkonventionen
- Filterverhalten
- Berechtigungsmodell
- Fehlerbehandlung
- Integrationsmuster
- Stabilität & Versionierung
1. Authentifizierung
Alle Anfragen müssen einen API-Schlüssel im Anfrage-Header enthalten.
Authorization: Api-Key <raw_api_key>
Hinweise: - API-Schlüssel werden von Unternehmensinhabern und Administratoren erstellt und verwaltet. - Jeder Schlüssel ist auf bestimmte Ressourcenberechtigungen beschränkt. - Alle Anfragen sind automatisch dem Unternehmen zugeordnet, dem der API-Schlüssel zugewiesen ist.
Authentifizierungsfehler
| Status | Grund |
|---|---|
401 | Fehlender oder ungültiger API-Schlüssel |
401 | Fehlerhaft formatierter Authorization-Header |
401 | Inaktiver API-Schlüssel |
403 | Fehlende Ressourcenberechtigung |
402 | Unternehmen inaktiv |
2. Paginierung
Listen-Endpunkte (Kalender, Projekte, Kunden) verwenden die Paginierung mit limit/offset.
Parameter
| Parameter | Beschreibung | Standard | Max |
|---|---|---|---|
limit | Anzahl der zurückzugebenden Ergebnisse | 100 | 500 |
offset | Paginierungs-Offset | 0 | — |
Antwortstruktur
{
"count": 123,
"next": null,
"previous": null,
"results": []
}
Wenn next null ist, haben Sie die letzte Seite erreicht.
3. Kalender-API
Repräsentiert geplante Termine wie Besprechungen, Anrufe und Installationstermine. Nur lesbar.
Endpunkte
GET https://api-production.easysolar-app.com/integrations/calendar/
GET https://api-production.easysolar-app.com/integrations/calendar/{id}/
Erforderliche Berechtigung: calendar_read
Antwortbeispiel
{
"id": "7d0f4d55-3b66-4c71-a86d-2b0ef2fca6d5",
"category": "meeting",
"subject": "Erstbesichtigung vor Ort",
"description": "Besprechung der Installationsanforderungen und Dachprüfung.",
"client": {
"id": "4ab8e7cb-0a27-48f1-a0f6-6d6ecf5d8c6a",
"name": "Solar Corp",
"address": "Hauptstraße 10, Warschau",
"phone": "+48123456789",
"is_open": true
},
"participants": [
{
"first_name": "John",
"last_name": "Smith",
"email": "john.smith@example.com"
}
],
"start_at": "2026-06-15T09:00:00Z",
"end_at": "2026-06-15T10:00:00Z",
"full_day": false,
"created_at": "2026-06-01T12:30:45Z"
}
Feldreferenz
| Feld | Typ | Beschreibung |
|---|---|---|
id | UUID | Termin-ID |
category | string | Terminkategorie (siehe Werte unten) |
subject | string | Termintitel |
description | string | Weitere Notizen zum Termin |
client | object | null | Verknüpfter Kunde |
participants | array | Dem Termin zugewiesene Mitarbeiter |
start_at | datetime | Beginn des Termins (UTC) |
end_at | datetime | Ende des Termins (UTC) |
full_day | boolean | Ob der Termin den gesamten Tag umfasst |
created_at | datetime | Zeitstempel der Terminerstellung |
Kategorienwerte
| Wert | Beschreibung |
|---|---|
meeting | Besprechung |
call | Telefonanruf |
installation | Installationstermin |
contract | Vertragsunterzeichnung |
quotation | Angebotspräsentation |
Verschachtelte Objekte
Kundenobjekt:
| Feld | Typ | Beschreibung |
|---|---|---|
id | UUID | Kunden-ID |
name | string | Kundenname |
address | string | Kundenadresse |
phone | string | Telefonnummer des Kunden |
is_open | boolean | Aktiver Status des Kunden |
Teilnehmerobjekt:
| Feld | Typ | Beschreibung |
|---|---|---|
first_name | string | Vorname des Mitarbeiters |
last_name | string | Nachname des Mitarbeiters |
email | string | E-Mail-Adresse des Mitarbeiters |
Filter
| Parameter | Typ | Beschreibung |
|---|---|---|
start_at_after | datetime | Filter für Termine, die nach diesem Zeitpunkt beginnen |
start_at_before | datetime | Filter für Termine, die vor diesem Zeitpunkt beginnen |
end_at_after | datetime | Filter für Termine, die nach diesem Zeitpunkt enden |
end_at_before | datetime | Filter für Termine, die vor diesem Zeitpunkt enden |
category | string (multi) | Nach Kategorie filtern; für mehrere Werte wiederholen |
client | UUID | Nach Kunden-ID filtern |
Beispiel:
GET https://api-production.easysolar-app.com/integrations/calendar/?start_at_after=2026-01-01T00:00:00Z&category=meeting&category=call
Authorization: Api-Key <key>
4. Projekt-API
Repräsentiert kundenbezogene Projektdatensätze (z. B. PV-Anlagen). Nur lesbar.
Endpunkte
GET https://api-production.easysolar-app.com/integrations/projects/
GET https://api-production.easysolar-app.com/integrations/projects/{id}/
Erforderliche Berechtigung: projects_read
Antwortbeispiel
{
"id": "d8e22cb9-1d88-4a3d-a3fd-f954d1f23d59",
"name": "PV-Installation - Büro Warschau",
"address": "Aleje Jerozolimskie 120, Warschau",
"latitude": 52.2297,
"longitude": 21.0122,
"client": {
"id": "4ab8e7cb-0a27-48f1-a0f6-6d6ecf5d8c6a",
"name": "Solar Corp",
"address": "Hauptstraße 10, Warschau",
"phone": "+48123456789",
"is_open": true
},
"status": {
"name": "In Bearbeitung",
"order": 2
},
"currency": {
"code": "PLN",
"name": "Polnischer Zloty"
},
"total_price": "42500.00",
"payback_period": 8,
"created": "2026-05-01T09:00:00Z",
"updated": "2026-06-01T15:30:00Z"
}
Feldreferenz
| Feld | Typ | Beschreibung |
|---|---|---|
id | UUID | Projekt-ID |
name | string | Projektname |
address | string | Projektadresse |
latitude | decimal | null | Breitengrad des Projekts |
longitude | decimal | null | Längengrad des Projekts |
client | object | Verknüpfter Kunde (siehe Kundenobjekt) |
status | object | Status des Projekts |
currency | object | Für finanzielle Werte verwendete Währung |
total_price | decimal string | Aktueller Gesamtpreis des Projekts |
payback_period | integer | null | Geschätzte Amortisationsdauer in Jahren |
created | datetime | Erstellungszeitpunkt |
updated | datetime | Zeitstempel der letzten Aktualisierung |
total_pricewird als Dezimal-String zurückgegeben, um die Genauigkeit zu erhalten.payback_periodistnull, wenn sie noch nicht berechnet wurde.latitude/longitudesindnull, wenn kein Standort gesetzt ist.
Verschachtelte Objekte
Statusobjekt:
| Feld | Typ | Beschreibung |
|---|---|---|
name | string | Anzeigename des Status |
order | integer | Sortierwert des Status |
Währungsobjekt:
| Feld | Typ | Beschreibung |
|---|---|---|
code | string | ISO-Währungscode |
name | string | Währungsname |
Filter
| Parameter | Typ | Beschreibung |
|---|---|---|
created_after | datetime | Filter nach Erstellungsdatum (untere Grenze) |
created_before | datetime | Filter nach Erstellungsdatum (obere Grenze) |
updated_after | datetime | Filter nach Aktualisierungsdatum (untere Grenze) |
updated_before | datetime | Filter nach Aktualisierungsdatum (obere Grenze) |
client | UUID | Nach Kunden-ID filtern |
status | UUID | Nach Status-ID filtern |
name | string | Teilübereinstimmung des Namens ohne Beachtung von Groß-/Kleinschreibung |
Beispiel:
GET https://api-production.easysolar-app.com/integrations/projects/?client=<id>&name=solar
Authorization: Api-Key <key>
5. Kunden-API
Repräsentiert Kundenobjekte. Unterstützt Lese- und Schreiboperationen.
Endpunkte
GET https://api-production.easysolar-app.com/integrations/clients/
POST https://api-production.easysolar-app.com/integrations/clients/
GET https://api-production.easysolar-app.com/integrations/clients/{id}/
PATCH https://api-production.easysolar-app.com/integrations/clients/{id}/
Erforderliche Berechtigungen: clients_read (Lesen), clients_write (Schreiben)
Antwortbeispiel
{
"id": "4ab8e7cb-0a27-48f1-a0f6-6d6ecf5d8c6a",
"name": "Solar Corp",
"description": "Gewerbekunde, der an einer PV-Dachanlage interessiert ist.",
"address": "Hauptstraße 10, Warschau",
"latitude": 52.2297,
"longitude": 21.0122,
"phone": "+48123456789",
"is_open": true,
"created": "2026-05-01T10:15:00Z",
"updated": "2026-06-01T08:45:30Z"
}
Feldreferenz
| Feld | Typ | Beschreibung |
|---|---|---|
id | UUID | Kunden-ID |
name | string | Kundenname |
description | string | Weitere Notizen |
address | string | Kundenadresse |
latitude | decimal | null | Breitengrad des Kunden |
longitude | decimal | null | Längengrad des Kunden |
phone | string | null | Telefonnummer des Kunden |
is_open | boolean | Ob der Kunde aktuell aktiv ist |
created | datetime | Erstellungszeitpunkt |
updated | datetime | Zeitstempel der letzten Aktualisierung |
Kunden anlegen
POST https://api-production.easysolar-app.com/integrations/clients/
{
"name": "Kundenname",
"description": "Gewerbekunde",
"address": "Adresse",
"phone": "+48123456789",
"latitude": 52.2297,
"longitude": 21.0122
}
Kunden aktualisieren
PATCH https://api-production.easysolar-app.com/integrations/clients/{id}/
Geben Sie nur die Felder an, die Sie aktualisieren möchten:
{
"address": "Neue Adresse 15, Warschau",
"phone": "+48987654321"
}
Koordinatenregeln
latitudeundlongitudemüssen immer gemeinsam angegeben werden.- Wenn nur eine Koordinate angegeben wird, entsteht ein Validierungsfehler.
- Wenn kein Standort gesetzt ist, werden beide Felder als
nullzurückgegeben.
Filter
| Parameter | Typ | Beschreibung |
|---|---|---|
created_after | datetime | Filter nach Erstellungsdatum (untere Grenze) |
created_before | datetime | Filter nach Erstellungsdatum (obere Grenze) |
updated_after | datetime | Filter nach Aktualisierungsdatum (untere Grenze) |
updated_before | datetime | Filter nach Aktualisierungsdatum (obere Grenze) |
is_open | boolean | Filter nach aktivem Status (true oder false) |
name | string | Teilübereinstimmung des Namens ohne Beachtung von Groß-/Kleinschreibung |
phone | string | Teilübereinstimmung der Telefonnummer ohne Beachtung von Groß-/Kleinschreibung |
6. Komponenten-API
Erstellt Komponenten zur Verwendung in Projekten. Nur schreibbar.
Endpunkt
POST https://api-production.easysolar-app.com/integrations/components/
Erforderliche Berechtigung: components_write
Komponententypen
Drei Komponententypen werden unterstützt: panel, inverter und other.
PV-Modul
{
"type": "panel",
"manufacturer_name": "Longi",
"name": "LR5-54HPH",
"net_unit_price": "120.00",
"nominal_power": "430.000",
"length": "1.7220",
"width": "1.1340",
"weight": "21.500",
"efficiency": "0.2100000",
"short_circuit_current": "13.52000",
"open_circuit_voltage": "37.85000",
"current_temperature_coefficient": "0.045000",
"voltage_temperature_coefficient": "-0.280000",
"power_temperature_coefficient": "-0.350000"
}
| Feld | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
type | string | Ja | Muss "panel" sein |
manufacturer_name | string | Ja | Herstellername |
name | string | Ja | Modellname des PV-Moduls |
net_unit_price | decimal | Nein | Nettostückpreis |
nominal_power | decimal | Ja | Nennleistung (W). Muss zwischen 1.0 und 1000.0 liegen |
length | decimal | Ja | Länge des PV-Moduls (m). Muss zwischen 0.1 und 5.0 liegen |
width | decimal | Ja | Breite des PV-Moduls (m). Muss zwischen 0.1 und 5.0 liegen |
weight | decimal | null | Nein | Gewicht (kg) |
efficiency | decimal | Ja | Wirkungsgrad. Muss ein Verhältnis zwischen 0 und 1 sein |
short_circuit_current | decimal | Ja | Kurzschlussstrom (A). Muss zwischen 0.00001 und 999.99999 liegen |
open_circuit_voltage | decimal | Ja | Leerlaufspannung (V). Muss zwischen 0.00001 und 999.99999 liegen |
current_temperature_coefficient | decimal | null | Nein | Temperaturkoeffizient des Stroms. Falls angegeben, muss er zwischen −99.999999 und 99.999999 liegen |
voltage_temperature_coefficient | decimal | null | Nein | Temperaturkoeffizient der Spannung |
power_temperature_coefficient | decimal | null | Nein | Temperaturkoeffizient der Leistung |
Wechselrichter
{
"type": "inverter",
"manufacturer_name": "SMA",
"name": "Sunny Tripower 5.0",
"net_unit_price": "900.00",
"nominal_power": "5000.000",
"number_of_dc_inputs": 2
}
| Feld | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
type | string | Ja | Muss "inverter" sein |
manufacturer_name | string | Ja | Herstellername |
name | string | Ja | Modellname des Wechselrichters |
net_unit_price | decimal | Nein | Nettostückpreis |
nominal_power | decimal | Ja | Nennleistung (W). Muss zwischen 100.0 und 100000000.0 liegen |
number_of_dc_inputs | integer | Ja | Anzahl der DC-Eingänge. Muss mindestens 1 betragen |
Sonstige
{
"type": "other",
"name": "Montagesystem",
"unit": "Stk.",
"net_unit_price": "50.00"
}
| Feld | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
type | string | Ja | Muss "other" sein |
name | string | Ja | Komponentenname |
unit | string | Nein | Mengeneinheit |
net_unit_price | decimal | Nein | Nettostückpreis |
Antwort
{
"id": "uuid",
"type": "panel | inverter | other",
"name": "string"
}
Hinweise
- Hersteller werden automatisch angelegt, wenn sie noch nicht existieren.
- Die Einzigartigkeit der Hersteller gilt pro Unternehmen.
- Alle PV-Modul-spezifischen Felder werden vor der Erstellung validiert.
7. Datenkonventionen
IDs
Alle Ressourcen-IDs sind UUID-Strings, stabil und innerhalb eines Unternehmens weltweit eindeutig:
"id": "550e8400-e29b-41d4-a716-446655440000"
Zeitstempel
Alle Datums-/Zeitfelder werden im ISO-8601-Format zurückgegeben, immer in UTC:
"created": "2026-06-09T12:34:56Z"
Geolokalisierung
Koordinaten gelten für Kunden und Projekte. Sie werden als geografischer Punkt gespeichert und als separate Felder zurückgegeben:
"latitude": 52.2297,
"longitude": 21.0122
Umgang mit null-Werten
Felder, die nicht gesetzt sind, werden als null zurückgegeben — sie werden niemals in der Antwort ausgelassen.
8. Filterverhalten
Allgemeine Regeln
- Alle Filter sind optional, sofern nicht anders angegeben.
- Mehrere Filter werden mit UND-Logik kombiniert.
- Mehrfachauswahl-Filterwerte (z. B.
category) verwenden intern ODER-Logik. - Ungültige Filterwerte liefern je nach Feldtyp leere Ergebnisse oder einen Validierungsfehler.
Datumsbereichsfilter
Verfügbar über alle Endpunkte hinweg:
| Filterfelder | Verhalten |
|---|---|
created_after / created_before | Bereichsfilter für den Erstellungszeitpunkt |
updated_after / updated_before | Bereichsfilter für den Zeitstempel der letzten Aktualisierung |
start_at_after / start_at_before | Bereichsfilter für den Terminbeginn |
end_at_after / end_at_before | Bereichsfilter für das Terminende |
Textsuchfilter
Teilübereinstimmung bei name und phone ohne Beachtung von Groß-/Kleinschreibung:
?name=solar
Entspricht: "Solar Corp", "Mein PV-Projekt" usw.
9. Berechtigungsmodell
Die Berechtigungen des API-Schlüssels werden pro Ressource unabhängig konfiguriert:
| Ressource | Leseberechtigung | Schreibberechtigung |
|---|---|---|
| Kalender | calendar_read | nicht unterstützt |
| Projekte | projects_read | nicht unterstützt |
| Kunden | clients_read | clients_write |
| Komponenten | nicht unterstützt | components_write |
10. Fehlerbehandlung
Fehlerformat
Allgemeiner Fehler:
{
"detail": "Fehlermeldung"
}
Validierungsfehler auf Feldebene:
{
"field_name": ["Fehlermeldung"]
}
Fehlerreferenz
| Status | Kategorie | Bedeutung |
|---|---|---|
401 | Authentifizierung | Ungültiger, fehlender oder inaktiver API-Schlüssel; fehlerhaft formatierter Header |
402 | Geschäft | Unternehmen ist inaktiv |
403 | Autorisierung | Dem API-Schlüssel fehlt die erforderliche Ressourcenberechtigung |
4xx | Validierung | Fehler auf Feldebene werden als Objekt zurückgegeben |
Integrations-Checkliste
Wenn Fehler auftreten, prüfen Sie:
- Der API-Schlüssel verfügt über die richtigen Ressourcenberechtigungen.
- Das Unternehmenskonto ist aktiv.
- Alle Filterwerte (IDs usw.) gehören zum selben Unternehmenskontext.
11. Integrationsmuster
Synchronisierungsstrategie
Empfohlener Ansatz für die Synchronisierung von Daten:
- Rufen Sie den Listen-Endpunkt ab (paginiert).
- Speichern Sie das
idals externe Referenz. - Verwenden Sie das Feld
updatedfür inkrementelle Synchronisierungen.
Umgang mit Paginierung
Blättern Sie durch die Seiten, indem Sie den Offset erhöhen, bis next null ist:
GET https://api-production.easysolar-app.com/integrations/clients/?limit=100&offset=0
GET https://api-production.easysolar-app.com/integrations/clients/?limit=100&offset=100
Inkrementelle Synchronisierung
Verwenden Sie Datumsfilter, um nur Datensätze abzurufen, die sich seit Ihrer letzten Synchronisierung geändert haben:
GET https://api-production.easysolar-app.com/integrations/projects/?updated_after=2026-01-01T00:00:00Z
Bewährte Filterpraktiken
- Bevorzugen Sie ID-basierte Filter (
client,status) gegenüber Textsuchen bei Synchronisierungen mit hohem Datenvolumen. - Kombinieren Sie mehrere Filter, um die Größe des Ergebnissatzes zu reduzieren.
- Vermeiden Sie breit angelegte Textsuchen in großen Datensätzen.
12. Stabilität & Versionierung
Stabile Garantien
Folgendes ändert sich ohne eine versionierte Migration nicht:
- Endpunkt-URLs
- Feldnamen
- UUID-Format
- Paginierungsstruktur
- Authentifizierungsschema
Nicht-brechende Änderungen
- Optionale Filter (neue Filter können hinzugefügt werden)
- Erweiterung der Antwort (neue Felder können hinzugefügt werden)
Versionierungsrichtlinie
Derzeit ist in der URL keine explizite Version sichtbar. Kompatibilitätsbrechende Änderungen führen zu einem neuen Endpunkt-Namensraum:
https://api-production.easysolar-app.com/integrations/v2/...
Ergänzende Änderungen gelten als nicht brechend und können ohne Versionssprung bereitgestellt werden.
Ende der Dokumentation
