{"openapi":"3.1.0","info":{"title":"SwissHuman API","version":"1.0.0","description":"**An API for the physical world.** AI can think, software can act digitally, humans can act in the physical world – diese API verbindet die drei.\n\n**Drei Wege:**\n1. **`POST /tasks` mit `objective`** – «POST /human»: Freitext-Ziel + Deadline + Budget. Wir wählen den Skill, füllen den Task Contract, nennen den Preis und lösen – je nach Freigabe-Regeln – direkt aus.\n2. **Strukturiert** (`POST /tasks` mit `service_id` + `details`) – für eigene Agenten.\n3. **Chat** (`/conversations`) – unser Concierge führt das Gespräch mit deinen Nutzer:innen. Ideal für Whitelabel.\n\n**Auth:** `Authorization: Bearer sh_live_…` plus `X-End-User-Id` (stabile ID der Person in deinem System).\n\n**Lebenszyklus (phase):** NEEDS_INFORMATION → QUOTED → ASSIGNING → ASSIGNED → IN_PROGRESS ⇄ WAITING_FOR_CLIENT / WAITING_FOR_HUMAN → RESULT_SUBMITTED → COMPLETED (| CANCELLED | FAILED). Ergebnisse werden vor der Übergabe gegen Anforderungen und Nachweise geprüft (AI_VALIDATION).\n\n**Freigabestufen:** 0 Recherche · 1 Kommunikation · 2 Physische Handlung · 3 Buchung/Kauf · 4 Vertrag/Finanzen. Pro Person gelten Regeln «auto bis CHF X / fragen / nie» (`/me/policies`); Stufe 4 ist nie automatisch.\n\n**Webhooks:** `POST` an deine Webhook-URL, Header `X-SwissHuman-Signature: t=<unix>,v1=<hex>` = HMAC-SHA256(secret, \"<t>.<body>\"). Events: `task.created`, `task.quoted`, `task.authorized`, `task.assigned`, `task.started`, `task.progress`, `task.update`, `human.question`, `human.answer`, `task.message`, `task.evidence`, `task.delayed`, `task.escalated`, `task.reassigned`, `task.result_submitted`, `task.rework_requested`, `task.completed`, `task.cancelled`, `task.failed`.\n\n**MCP:** `https://ki.nerdag.ch/mcp` (Streamable HTTP) mit den Tools human_create_task, human_get_quote, human_approve_task, human_get_status, human_send_message, human_answer_question, human_confirm_result, human_cancel_task, human_check_availability u.a.\n\n**Skills:** `courier`, `on_board_courier`, `shopping`, `phone_call`, `travel_booking`, `vacation_booking`, `postal_mail`, `laundry`, `invoicing`, `debt_collection`, `job_application`, `physical_errand`, `general_human_task`."},"servers":[{"url":"https://ki.nerdag.ch/v1"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"API-Key (sh_live_…) oder Session-Token"}},"parameters":{"EndUser":{"name":"X-End-User-Id","in":"header","required":false,"schema":{"type":"string"},"description":"Pflicht bei API-Keys: ID der Endkund:in in deinem System"}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}}}}},"Quote":{"type":"object","properties":{"currency":{"type":"string","const":"CHF"},"total":{"type":"number"},"items":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"amount":{"type":"number"}}}},"expenses_note":{"type":"string"},"estimate":{"type":"boolean"},"note":{"type":"string"}}},"Task":{"type":"object","properties":{"id":{"type":"string"},"ref":{"type":"string","examples":["SH-7K3PQ"]},"service":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}}},"title":{"type":"string"},"status":{"type":"string","enum":["draft","searching","assigned","in_progress","submitted","completed","cancelled","failed"]},"status_label":{"type":"string"},"phase":{"type":"string","enum":["NEEDS_INFORMATION","QUOTED","ASSIGNING","ASSIGNED","IN_PROGRESS","WAITING_FOR_CLIENT","WAITING_FOR_HUMAN","RESULT_SUBMITTED","COMPLETED","CANCELLED","FAILED"]},"objective":{"type":["string","null"]},"requirements":{"type":"array","items":{"type":"string"}},"evidence":{"type":"object","properties":{"description":{"type":"string"},"minAttachments":{"type":"integer"}}},"authorization":{"type":"object","properties":{"decision":{"type":"string","enum":["auto","ask","never"]},"reason":{"type":"string"}}},"budget_max_chf":{"type":["number","null"]},"payment_method":{"type":["string","null"],"enum":["credits","invoice",null]},"validation":{"type":["object","null"]},"details":{"type":"object","additionalProperties":true},"due_at":{"type":["string","null"],"format":"date-time"},"quote":{"$ref":"#/components/schemas/Quote"},"missing_fields":{"type":"array","items":{"type":"string"}},"problems":{"type":"array","items":{"type":"string"}},"helper":{"type":["object","null"],"properties":{"name":{"type":"string"},"rating":{"type":"number"}}},"open_questions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"question":{"type":"string"}}}},"result":{"type":["object","null"],"properties":{"summary":{"type":"string"},"expenses_chf":{"type":"number"}}},"events":{"type":"array","items":{"type":"object"}}}},"ChatMessage":{"type":"object","properties":{"id":{"type":"string"},"role":{"type":"string","enum":["user","assistant","event"]},"content":{"type":"string"},"task_id":{"type":["string","null"]},"created_at":{"type":"string"}}},"Details":{"type":"object","additionalProperties":{"type":["string","number","boolean","null"]},"description":"Feld-Keys gemäss /services"}}},"paths":{"/services":{"get":{"operationId":"listServices","summary":"Service-Katalog mit Pflichtfeldern und Preisen","security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/quotes":{"post":{"operationId":"getQuote","summary":"Preis schätzen (ohne Auftrag)","parameters":[{"$ref":"#/components/parameters/EndUser"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["service_id"],"properties":{"service_id":{"type":"string"},"details":{"$ref":"#/components/schemas/Details"},"urgency":{"type":"string","enum":["normal","express"]}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Nicht authentifiziert","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Nicht gefunden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Falscher Status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validierung","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/conversations":{"post":{"operationId":"createConversation","summary":"Neuen KI-Chat starten","parameters":[{"$ref":"#/components/parameters/EndUser"}],"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"}}}}}}}},"get":{"operationId":"listConversations","summary":"Chats der Person","parameters":[{"$ref":"#/components/parameters/EndUser"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/conversations/{id}/messages":{"get":{"operationId":"getMessages","summary":"Chatverlauf (inkl. Status-Meldungen zu Aufträgen)","parameters":[{"$ref":"#/components/parameters/EndUser"},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ChatMessage"}}}}}}}}},"post":{"operationId":"sendMessage","summary":"Nachricht an den Concierge senden – Antwort + betroffene Aufträge","parameters":[{"$ref":"#/components/parameters/EndUser"},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["content"],"properties":{"content":{"type":"string"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"reply":{"$ref":"#/components/schemas/ChatMessage"},"tasks":{"type":"array","items":{"$ref":"#/components/schemas/Task"}}}}}}},"401":{"description":"Nicht authentifiziert","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Nicht gefunden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Falscher Status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validierung","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/skills":{"get":{"operationId":"listSkills","summary":"Skills (Alias von /services)","security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/availability":{"get":{"operationId":"checkAvailability","summary":"Human Availability Graph: wer ist jetzt verfügbar? (anonymisiert)","parameters":[{"$ref":"#/components/parameters/EndUser"},{"name":"skill","in":"query","schema":{"type":"string"}},{"name":"near","in":"query","schema":{"type":"string"},"description":"Ort oder Adresse in der Schweiz"},{"name":"radius_km","in":"query","schema":{"type":"number"}},{"name":"transport","in":"query","schema":{"type":"string","enum":["foot","bike","public_transport","car","van"]}},{"name":"language","in":"query","schema":{"type":"string","enum":["de","fr","it","en"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/me/policies":{"get":{"operationId":"getPolicies","summary":"Freigabe-Regeln pro Skill","parameters":[{"$ref":"#/components/parameters/EndUser"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/me/policies/{service_id}":{"put":{"operationId":"setPolicy","summary":"Freigabe-Regel setzen (auto bis CHF X / ask / never)","parameters":[{"$ref":"#/components/parameters/EndUser"},{"name":"service_id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["mode"],"properties":{"mode":{"type":"string","enum":["auto","ask","never"]},"max_chf":{"type":"number"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Nicht authentifiziert","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Nicht gefunden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Falscher Status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validierung","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/tasks":{"get":{"operationId":"listTasks","summary":"Aufträge auflisten","parameters":[{"$ref":"#/components/parameters/EndUser"},{"name":"status","in":"query","schema":{"type":"string"},"description":"Kommagetrennt"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Task"}}}}}}}}},"post":{"operationId":"createTask","summary":"Auftrag anlegen – per Freitext-objective oder strukturiert","description":"Beispiel: {\"objective\": \"Hole den Laptop in Zürich ab und bringe ihn nach Luzern\", \"deadline\": \"2026-09-20T14:00:00+02:00\", \"budget\": {\"max\": 180, \"currency\": \"CHF\"}}. dispatch: false = Entwurf, true = Person hat bestätigt, \"auto\" = nur wenn Freigabe-Regeln es erlauben.","parameters":[{"$ref":"#/components/parameters/EndUser"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"objective":{"type":"string","description":"Freitext – wir wählen Skill und Felder"},"service_id":{"type":"string","enum":["courier","on_board_courier","shopping","phone_call","travel_booking","vacation_booking","postal_mail","laundry","invoicing","debt_collection","job_application","physical_errand","general_human_task"]},"title":{"type":"string"},"details":{"$ref":"#/components/schemas/Details"},"deadline":{"type":"string","format":"date-time"},"urgency":{"type":"string","enum":["normal","express"]},"priority":{"type":"string","enum":["normal","urgent"]},"budget":{"type":"object","properties":{"max":{"type":"number"},"currency":{"type":"string","const":"CHF"}}},"requirements":{"type":"array","items":{"type":"string"}},"dispatch":{"oneOf":[{"type":"boolean"},{"type":"string","const":"auto"}],"default":false}}}}}},"responses":{"201":{"description":"OK","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Task"},{"type":"object","properties":{"estimated_cost":{"type":"number"},"interpreted_by":{"type":"string"},"dispatch_note":{"type":"string"}}}]}}}},"401":{"description":"Nicht authentifiziert","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Nicht gefunden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Falscher Status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validierung","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/tasks/{id}":{"get":{"operationId":"getTask","summary":"Auftrag mit Verlauf","parameters":[{"$ref":"#/components/parameters/EndUser"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Task-ID oder Referenz (SH-XXXXX)"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Task"}}}},"401":{"description":"Nicht authentifiziert","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Nicht gefunden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Falscher Status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validierung","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"updateTask","summary":"Entwurf ergänzen","parameters":[{"$ref":"#/components/parameters/EndUser"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Task-ID oder Referenz (SH-XXXXX)"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string"},"details":{"$ref":"#/components/schemas/Details"},"due_at":{"type":"string"},"urgency":{"type":"string"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Task"}}}},"401":{"description":"Nicht authentifiziert","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Nicht gefunden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Falscher Status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validierung","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/tasks/{id}/approve":{"post":{"operationId":"approveTask","summary":"Entwurf verbindlich auslösen (nur nach Bestätigung der Person!)","parameters":[{"$ref":"#/components/parameters/EndUser"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Task-ID oder Referenz (SH-XXXXX)"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Task"}}}},"401":{"description":"Nicht authentifiziert","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Nicht gefunden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Falscher Status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validierung","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/tasks/{id}/messages":{"post":{"operationId":"messageHelper","summary":"Zusatzinfo an die Helfer:in","parameters":[{"$ref":"#/components/parameters/EndUser"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Task-ID oder Referenz (SH-XXXXX)"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["text"],"properties":{"text":{"type":"string"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Nicht authentifiziert","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Nicht gefunden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Falscher Status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validierung","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/tasks/{id}/questions/{qid}/answer":{"post":{"operationId":"answerQuestion","summary":"Rückfrage der Helfer:in beantworten","parameters":[{"$ref":"#/components/parameters/EndUser"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Task-ID oder Referenz (SH-XXXXX)"},{"name":"qid","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["answer"],"properties":{"answer":{"type":"string"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Nicht authentifiziert","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Nicht gefunden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Falscher Status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validierung","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/tasks/{id}/complete":{"post":{"operationId":"confirmCompletion","summary":"Ergebnis bestätigen oder Nachbesserung verlangen","parameters":[{"$ref":"#/components/parameters/EndUser"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Task-ID oder Referenz (SH-XXXXX)"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"accepted":{"type":"boolean"},"rating":{"type":"integer","minimum":1,"maximum":5},"feedback":{"type":"string"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Task"}}}},"401":{"description":"Nicht authentifiziert","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Nicht gefunden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Falscher Status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validierung","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/tasks/{id}/cancel":{"post":{"operationId":"cancelTask","summary":"Stornieren","parameters":[{"$ref":"#/components/parameters/EndUser"},{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Task-ID oder Referenz (SH-XXXXX)"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Task"}}}},"401":{"description":"Nicht authentifiziert","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Nicht gefunden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Falscher Status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Validierung","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/stream":{"get":{"operationId":"stream","summary":"Live-Updates (Server-Sent Events). Token alternativ als ?token=","parameters":[{"$ref":"#/components/parameters/EndUser"}],"responses":{"200":{"description":"text/event-stream"}}}}}}