{"openapi":"3.1.0","info":{"title":"Sjel Provider API","version":"1.0.0","description":"API voor aangesloten dienstverleners om opdrachten, statussen, documenten, klantfacturen en webhooks te beheren."},"servers":[{"url":"https:\/\/sjel.nl\/api\/v1","description":"Production"}],"security":[{"ProviderApiKey":[]}],"paths":{"\/provider\/assignments":{"get":{"summary":"Lijst provideropdrachten","parameters":[{"$ref":"#\/components\/parameters\/StatusFilter"},{"$ref":"#\/components\/parameters\/LimitFilter"}],"responses":{"200":{"$ref":"#\/components\/responses\/AssignmentList"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/provider\/assignments\/{id}":{"get":{"summary":"Details van \u00e9\u00e9n opdracht","parameters":[{"$ref":"#\/components\/parameters\/AssignmentId"}],"responses":{"200":{"$ref":"#\/components\/responses\/AssignmentDetail"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}},"\/provider\/assignments\/{id}\/offer":{"post":{"summary":"Opdracht accepteren of weigeren","description":"Gebruik dit endpoint zodra een opdracht aan je dienstprofiel is aangeboden. Bij weigeren is een korte reden verplicht.","parameters":[{"$ref":"#\/components\/parameters\/AssignmentId"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/OfferResponseRequest"},"examples":{"accept":{"summary":"Opdracht accepteren","value":{"action":"accepted","note":"Wij nemen contact op om een afspraak te plannen."}},"decline":{"summary":"Opdracht weigeren","value":{"action":"declined","decline_reason":"Buiten ons werkgebied","note":"Deze postcode valt niet binnen onze planning."}}}}}},"responses":{"200":{"$ref":"#\/components\/responses\/AssignmentDetail"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/provider\/assignments\/{id}\/status":{"patch":{"summary":"Opdrachtstatus bijwerken","description":"Werk de operationele status van een opdracht bij. Gebruik scheduled_at alleen wanneer de status een afspraak bevestigt.","parameters":[{"$ref":"#\/components\/parameters\/AssignmentId"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/AssignmentStatusUpdateRequest"},"examples":{"site_visit_done":{"summary":"Opname afgerond","value":{"status":"site_visit_done","note":"Opname is uitgevoerd. Label wordt verwerkt."}},"appointment_confirmed":{"summary":"Afspraak bevestigd","value":{"status":"appointment_confirmed","scheduled_at":"2026-06-18T09:30:00+02:00","note":"Afspraak bevestigd met de klant."}}}}}},"responses":{"200":{"$ref":"#\/components\/responses\/AssignmentDetail"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/provider\/assignments\/{id}\/appointments":{"post":{"summary":"Afspraakmomenten voorstellen","description":"Stel maximaal vijf toekomstige afspraakmomenten voor. Sjel maakt per starttijd een keuzeoptie voor de klant aan. Tijden moeten ISO 8601 datum\/tijd strings zijn, inclusief timezone.","parameters":[{"$ref":"#\/components\/parameters\/AssignmentId"}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/AppointmentProposalRequest"},"examples":{"multiple_options":{"summary":"Meerdere afspraakopties","value":{"starts_at":["2026-06-18T09:30:00+02:00","2026-06-18T13:00:00+02:00","2026-06-19T10:00:00+02:00"],"duration_minutes":60,"note":"Kies een moment dat het beste past. De opname duurt ongeveer een uur."}}}}}},"responses":{"200":{"$ref":"#\/components\/responses\/AssignmentDetail"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/provider\/assignments\/{id}\/documents":{"post":{"summary":"Resultaatdocument uploaden","description":"Upload het resultaatdocument bij de opdracht. Toegestaan: pdf, jpg, jpeg, png of webp tot 20 MB.","parameters":[{"$ref":"#\/components\/parameters\/AssignmentId"}],"requestBody":{"required":true,"content":{"multipart\/form-data":{"schema":{"$ref":"#\/components\/schemas\/DocumentUploadRequest"}}}},"responses":{"201":{"$ref":"#\/components\/responses\/DocumentUploaded"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/provider\/assignments\/{id}\/customer-invoice":{"post":{"summary":"Klantfactuur uploaden","description":"Upload de factuur die de dienstverlener aan de klant heeft gestuurd. Dit is verplicht bij marketplace-diensten waar de dienstverlener de formele leverancier is.","parameters":[{"$ref":"#\/components\/parameters\/AssignmentId"}],"requestBody":{"required":true,"content":{"multipart\/form-data":{"schema":{"$ref":"#\/components\/schemas\/CustomerInvoiceUploadRequest"}}}},"responses":{"201":{"$ref":"#\/components\/responses\/CustomerInvoiceUploaded"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/provider\/webhook-endpoints":{"get":{"summary":"Webhook endpoints tonen","responses":{"200":{"$ref":"#\/components\/responses\/WebhookEndpointList"},"401":{"$ref":"#\/components\/responses\/Unauthorized"}}},"post":{"summary":"Webhook endpoint registreren","description":"Registreer een HTTPS endpoint voor provider-webhooks. Als events leeg blijft, gebruikt Sjel de standaard events.","requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/WebhookEndpointCreateRequest"},"examples":{"default_events":{"summary":"Endpoint met standaard events","value":{"url":"https:\/\/provider.example.com\/sjel\/webhooks"}},"specific_events":{"summary":"Endpoint met specifieke events","value":{"url":"https:\/\/provider.example.com\/sjel\/webhooks","events":["assignment.updated","document.uploaded"]}}}}}},"responses":{"201":{"$ref":"#\/components\/responses\/WebhookEndpointCreated"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"422":{"$ref":"#\/components\/responses\/ValidationError"}}}},"\/provider\/webhook-endpoints\/{endpoint}":{"delete":{"summary":"Webhook endpoint uitschakelen","parameters":[{"name":"endpoint","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"$ref":"#\/components\/responses\/WebhookEndpointCreated"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"404":{"$ref":"#\/components\/responses\/NotFound"}}}}},"components":{"securitySchemes":{"ProviderApiKey":{"type":"http","scheme":"bearer","bearerFormat":"Sjel provider API key"}},"parameters":{"AssignmentId":{"name":"id","in":"path","required":true,"schema":{"type":"integer"}},"StatusFilter":{"name":"status","in":"query","required":false,"schema":{"type":"string"}},"LimitFilter":{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":25,"maximum":100}}},"schemas":{"Assignment":{"type":"object","properties":{"id":{"type":"integer"},"service_type":{"type":"string"},"status":{"type":"string"},"status_label":{"type":"string"},"customer_status":{"type":"string"},"customer_status_label":{"type":"string"},"workflow":{"$ref":"#\/components\/schemas\/AssignmentWorkflow"},"property":{"$ref":"#\/components\/schemas\/AssignmentProperty"},"scheduled_at":{"type":"string","format":"date-time","nullable":true},"partner_action_due_at":{"type":"string","format":"date-time","nullable":true},"updated_at":{"type":"string","format":"date-time","nullable":true},"events":{"type":"array","items":{"$ref":"#\/components\/schemas\/AssignmentEvent"},"description":"Alleen aanwezig bij detail endpoints."}}},"AssignmentWorkflow":{"type":"object","properties":{"id":{"type":"integer","nullable":true},"number":{"type":"string","nullable":true,"example":"EL-2026-000001"},"type":{"type":"string","nullable":true,"example":"energielabel"}}},"AssignmentProperty":{"type":"object","properties":{"id":{"type":"integer","nullable":true},"title":{"type":"string","nullable":true},"address":{"type":"string","nullable":true},"city":{"type":"string","nullable":true},"postal_code":{"type":"string","nullable":true}}},"AssignmentEvent":{"type":"object","properties":{"event":{"type":"string"},"source":{"type":"string"},"note":{"type":"string","nullable":true},"occurred_at":{"type":"string","format":"date-time","nullable":true}}},"DocumentUploadResponse":{"type":"object","properties":{"id":{"type":"integer"},"status":{"type":"string"},"filename":{"type":"string","nullable":true},"uploaded_at":{"type":"string","format":"date-time","nullable":true}}},"CustomerInvoiceUploadResponse":{"type":"object","properties":{"id":{"type":"integer"},"status":{"type":"string"},"invoice_number":{"type":"string","nullable":true},"uploaded_at":{"type":"string","format":"date-time","nullable":true}}},"WebhookEndpoint":{"type":"object","properties":{"id":{"type":"integer"},"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string"}},"status":{"type":"string"},"secret_hint":{"type":"string","nullable":true},"signing_secret":{"type":"string","nullable":true,"description":"Alleen zichtbaar bij aanmaken."},"last_success_at":{"type":"string","format":"date-time","nullable":true},"last_failure_at":{"type":"string","format":"date-time","nullable":true},"created_at":{"type":"string","format":"date-time","nullable":true}}},"Error":{"type":"object","properties":{"message":{"type":"string"}}},"ValidationError":{"type":"object","properties":{"message":{"type":"string","example":"The starts_at field is required."},"errors":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}}}}},"OfferResponseRequest":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["accepted","declined"]},"decline_reason":{"type":"string","nullable":true,"maxLength":120,"description":"Verplicht als action=declined."},"note":{"type":"string","nullable":true,"maxLength":3000}}},"AssignmentStatusUpdateRequest":{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["appointment_proposed","appointment_confirmed","site_visit_done","completed"]},"scheduled_at":{"type":"string","format":"date-time","nullable":true},"note":{"type":"string","nullable":true,"maxLength":3000}}},"AppointmentProposalRequest":{"type":"object","required":["starts_at"],"properties":{"starts_at":{"type":"array","minItems":1,"maxItems":5,"items":{"type":"string","format":"date-time"},"description":"Toekomstige ISO 8601 startmomenten met timezone, bijvoorbeeld 2026-06-18T09:30:00+02:00."},"duration_minutes":{"type":"integer","minimum":15,"maximum":240,"default":60},"note":{"type":"string","nullable":true,"maxLength":3000}}},"DocumentUploadRequest":{"type":"object","required":["document"],"properties":{"document":{"type":"string","format":"binary","description":"PDF\/afbeelding, maximaal 20 MB."},"note":{"type":"string","nullable":true,"maxLength":3000}}},"CustomerInvoiceUploadRequest":{"type":"object","required":["invoice"],"properties":{"invoice":{"type":"string","format":"binary","description":"PDF\/afbeelding, maximaal 20 MB."},"invoice_number":{"type":"string","nullable":true,"maxLength":120}}},"WebhookEndpointCreateRequest":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri","maxLength":1000},"events":{"type":"array","maxItems":20,"items":{"type":"string","maxLength":120},"description":"Bijvoorbeeld assignment.updated, assignment.completed, document.uploaded, payout.updated of *."}}}},"responses":{"AssignmentList":{"description":"Opdrachtenlijst","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#\/components\/schemas\/Assignment"}},"meta":{"type":"object","properties":{"limit":{"type":"integer"},"provider":{"type":"integer"}}}}}}}},"AssignmentDetail":{"description":"Opdracht","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#\/components\/schemas\/Assignment"}}}}}},"DocumentUploaded":{"description":"Document geupload","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#\/components\/schemas\/DocumentUploadResponse"}}}}}},"CustomerInvoiceUploaded":{"description":"Klantfactuur geupload","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#\/components\/schemas\/CustomerInvoiceUploadResponse"}}}}}},"WebhookEndpointList":{"description":"Webhook endpoints","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#\/components\/schemas\/WebhookEndpoint"}}}}}}},"WebhookEndpointCreated":{"description":"Webhook endpoint","content":{"application\/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#\/components\/schemas\/WebhookEndpoint"}}}}}},"Unauthorized":{"description":"API key ontbreekt of is ongeldig","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"Forbidden":{"description":"Geen toegang tot deze opdracht","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"NotFound":{"description":"Niet gevonden","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Error"}}}},"ValidationError":{"description":"Validatiefout","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ValidationError"}}}}}}}