Skip to content

API-Referenz ​

Basis-URL: https://api.saw-sg.de/v1
Auth: Authorization: Bearer {token} — alle Endpunkte außer /auth/register und /auth/login


Auth ​

POST /v1/auth/register ​

Neuen Account erstellen.

Body:

json
{ "name": "Max", "email": "max@example.com", "password": "geheim123", "password_confirmation": "geheim123" }

Response 201:

json
{ "data": { "user": { "id": 1, "name": "Max", "email": "...", "role": "user", "plan": "free", "onboarding_completed": false }, "token": "1|abc..." } }

POST /v1/auth/login ​

Anmelden und Token erhalten.

Body: { "email": "...", "password": "..." }
Response 200: Wie register
Response 401: { "error": "invalid_credentials", "message": "..." }


POST /v1/auth/logout 🔒 ​

Token invalidieren. Response 200: { "message": "Erfolgreich abgemeldet." }


GET /v1/auth/me 🔒 ​

Eingeloggten User laden. Response 200: { "data": { user } }


POST /v1/auth/onboarding/complete 🔒 ​

Onboarding als abgeschlossen markieren. Response 200: { "message": "..." }


Templates ​

GET /v1/templates 🔒 ​

Verfügbare Simulations-Vorlagen laden.

Response 200:

json
{ "data": [ { "id": 1, "name": "SaaS Startup", "industry": "Software / SaaS", "description": "...", "difficulty": "medium" } ] }

Companies (Simulationen) ​

GET /v1/companies 🔒 ​

Alle Simulationen des eingeloggten Users.

Response 200:

json
{
  "data": [{
    "id": 1, "name": "MeineSaaS", "industry": "...", "legal_form": "einzelunternehmen",
    "status": "founding", "simulation_mode": "realistic",
    "simulation_state": { "current_tick": 9, "simulated_date": "2026-06-30", "phase": "founding", "tick_speed": "day", "is_paused": false }
  }]
}

POST /v1/companies 🔒 ​

Neue Simulation anlegen. Erstellt automatisch alle 1:1-Records (SimulationState, Bank, Institutionen etc.)

Body:

json
{
  "name": "MeineSaaS GmbH",
  "industry": "Software / SaaS",
  "legal_form": "einzelunternehmen",
  "simulation_mode": "realistic",
  "template_id": 1,
  "personal_expenses": 2500,
  "side_income": 3000
}

Response 201: { "data": { company } }


GET /v1/companies/{id} 🔒 ​

Einzelne Simulation laden (inkl. SimulationState, Config, FounderFinance).


PATCH /v1/companies/{id} 🔒 ​

Name, Simulationsmodus oder Tick-Speed ändern.

Body (alle optional): { "name": "...", "simulation_mode": "aggressive", "tick_speed": "week" }


DELETE /v1/companies/{id} 🔒 ​

Simulation und alle zugehörigen Daten löschen.


Simulation Engine ​

GET /v1/companies/{id}/simulation/state 🔒 ​

Aktuellen Simulationsstand laden.

Response 200:

json
{ "data": { "company_id": 1, "current_tick": 9, "simulated_date": "2026-06-30", "phase": "founding", "tick_speed": "day", "is_paused": false, "is_processing": false } }

GET /v1/companies/{id}/simulation/dashboard 🔒 ​

Dashboard-Daten: KPIs, Events, Kontostand, Kundenzahl.

Response 200:

json
{
  "data": {
    "company": { "id": 1, "name": "...", "status": "founding" },
    "simulation": { "tick": 9, "simulated_date": "2026-06-30", "phase": "founding", "is_paused": false },
    "kpi": { "revenue_monthly": 0, "expenses_monthly": 0, "profit_monthly": 0, "risk_index": 0, "stability_index": 50 },
    "bank_balance": 0,
    "customer_count": 0,
    "recent_events": []
  },
  "meta": { "tick": 9, "simulated_date": "2026-06-30" }
}

POST /v1/companies/{id}/simulation/tick 🔒 ​

Simulation um 1 Tick (= 1 Tag) voranschreiten.

Response 200:

json
{ "data": { "tick": 10, "simulated_date": "2026-07-01", "phase": "founding", "events_count": 0, "month_changed": true, "is_paused": false } }

POST /v1/companies/{id}/simulation/advance 🔒 ​

Simulation um N Tage voranschreiten.

Body: { "days": 7 } (1–365)
Response 200: { "data": { "ticks_processed": 7, "last_tick": { ... } } }


POST /v1/companies/{id}/simulation/pause 🔒 ​

Simulation pausieren.

POST /v1/companies/{id}/simulation/resume 🔒 ​

Simulation fortsetzen.


Fehler-Format ​

json
{ "error": "invalid_credentials", "message": "E-Mail oder Passwort ist falsch.", "status": 401 }

Validierungsfehler (422):

json
{ "message": "The name field is required.", "errors": { "name": ["The name field is required."] } }

Mitarbeiter (Phase 4) ​

GET /v1/companies/{id}/employees 🔒 ​

Alle Mitarbeiter. Status: probation, active, fired, resigned

GET /v1/companies/{id}/employees/candidates?role=support 🔒 ​

3 Kandidaten-Vorschläge für eine Rolle (mit KI-Backstory wenn Claude konfiguriert).

POST /v1/companies/{id}/employees 🔒 ​

Mitarbeiter einstellen. Body: { "name": "...", "role": "support", "archetype": "zuverlässiger", "salary_monthly": 2800 }

DELETE /v1/companies/{id}/employees/{id} 🔒 ​

Mitarbeiter entlassen. Gibt 422 zurück wenn keine Abmahnung vorhanden (mit Risiko-Hinweis).

POST /v1/companies/{id}/employees/{id}/force-fire 🔒 ​

Erzwungene Kündigung ohne Abmahnung (erhöht Risiko-Index, erzeugt critical Event).


KI-Coach (Phase 4) ​

Claude API

Coach-Antworten nutzen claude-sonnet wenn ANTHROPIC_API_KEY gesetzt ist. Ohne Key: regelbasierter Fallback (kein Fehler).

GET /v1/companies/{id}/coach 🔒 ​

Coach-Gespräch laden (wird bei erstem Aufruf angelegt, KI-Begrüßung).

Response: { "data": { "messages": [...], "claude_active": true } }

POST /v1/companies/{id}/coach 🔒 ​

Nachricht senden. Coach antwortet mit aktuellem Unternehmenskontext (Kontostand, Kunden, KPIs, offene Tasks).

Body: { "message": "Was sollte ich als nächstes tun?" }

DELETE /v1/companies/{id}/coach 🔒 ​

Gespräch zurücksetzen.


Async Queue (Phase 4) ​

Ab 50 aktiven Kunden laufen Ticks asynchron:

Sync (< 50 Kunden): POST /tick → 200 OK { data: tickResult }

Async (≥ 50 Kunden): POST /tick → 202 Accepted { data: { async: true } } → Frontend pollt GET /simulation/state bis is_processing = false


n8n Webhook (Phase 4) ​

POST /api/v1/webhooks/n8n/tick-complete
X-Webhook-Secret: {N8N_WEBHOOK_SECRET}

{ "company_id": 1 }

Setzt is_processing = false — wird von n8n nach abgeschlossenem Async-Job aufgerufen.

Bürokratie & Events (Phase 2) ​

GET /v1/companies/{id}/tasks 🔒 ​

Aufgaben laden. Optional: ?status=pending|overdue|completed

Response 200:

json
{ "data": [{ "id": 1, "type": "impressum", "title": "Impressum erstellen", "status": "pending", "due_tick": 7, "penalty_amount": "1500.00", "sort_order": 4 }] }

PATCH /v1/companies/{id}/tasks/{taskId}/complete 🔒 ​

Aufgabe als erledigt markieren. Erzeugt automatisch ein Completion-Event.

GET /v1/companies/{id}/events 🔒 ​

Ereignisse laden. Optional: ?severity=info|warning|critical, ?unread=true

PATCH /v1/companies/{id}/events/{eventId}/read 🔒 ​

Event als gelesen markieren.

POST /v1/companies/{id}/events/read-all 🔒 ​

Alle Events als gelesen markieren.


Institutionen (Phase 2) ​

GET /v1/companies/{id}/institutions 🔒 ​

Alle 12 Institutionen mit Status und ungelesener Nachrichten-Anzahl.

Response 200:

json
{ "data": [{ "key": "hausbank", "name": "Hausbank", "is_active": true, "unread_count": 1 }] }

GET /v1/companies/{id}/institutions/{institution}/messages 🔒 ​

Alle Nachrichten einer Institution. Markiert sie automatisch als gelesen.

GET /v1/companies/{id}/institutions/{institution}/chat 🔒 ​

Gesprächsverlauf laden (wird angelegt falls nicht vorhanden).

POST /v1/companies/{id}/institutions/{institution}/chat 🔒 ​

Nachricht an Institution senden.

Body: { "message": "Wie hoch ist mein Kontostand?" }
Response 200: { "data": { "institution": "hausbank", "persona_name": "Thomas Weber", "messages": [...], "last_response": "..." } }


Bank (Phase 2) ​

GET /v1/companies/{id}/bank 🔒 ​

Kontostand und letzte 20 Transaktionen.

POST /v1/companies/{id}/bank/deposit 🔒 ​

Kapitaleinlage einzahlen (100–1.000.000 €).

Body: { "amount": 5000, "description": "Startkapital" }


Postamt (Phase 2) ​

GET /v1/companies/{id}/postamt/inbox 🔒 ​

Alle eingehenden Behördenbriefe + Anzahl ungelesener Nachrichten.

GET /v1/companies/{id}/postamt/outbox 🔒 ​

Alle versendeten Briefe mit Sendungsverfolgung.

POST /v1/companies/{id}/postamt/send 🔒 ​

Brief an eine Behörde senden.

Body:

json
{ "recipient_institution": "finanzamt", "subject": "Anmeldung", "content": "...", "send_type": "einschreiben" }

send_type: standard (0,85€, 2 Tage) · einschreiben (4,05€, 2 Tage) · einschreiben_rueckschein (6,45€, 3 Tage) · express (12,90€, 1 Tag)

GET /v1/companies/{id}/postamt/track/{tracking} 🔒 ​

Sendungsverfolgung per Tracking-Nummer (z.B. VTABC12345).

GET /v1/companies/{id}/postamt/send-types 🔒 ​

Alle verfügbaren Versandarten mit Kosten und Lieferzeit.


Rechtsdokumente (Phase 2) ​

GET /v1/companies/{id}/documents 🔒 ​

Alle Pflichtdokumente (impressum, agb, datenschutz) mit Status.

Status: missing → draft → submitted → approved

PATCH /v1/companies/{id}/documents/{type} 🔒 ​

Dokument-Status aktualisieren. Schließt automatisch den zugehörigen Task ab.

Body: { "status": "approved", "content": "Impressum gemäß §5 TMG..." }
type: impressum · agb · datenschutz

Venturo — Simulate Your Venture