CRM-koppeling — integratiehandleiding
Geschreven voor de IT-afdeling van HOA Energy: hoe jullie eigen CRM leads doorstuurt, gesprekken laat starten en de resultaten automatisch terugkrijgt.
Jullie CRM praat uitsluitend met dit portaal. Het portaal verzorgt zelf het uitbellen via ons AI voice-platform — jullie hoeven daar geen enkele koppeling mee te maken. De koppeling loopt in twee richtingen:
- CRM → portaal: leads aanmelden en gesprekken (laten) starten via REST.
- Portaal → CRM: zodra een gesprek is afgerond sturen wij het resultaat naar jullie webhook-URL.
CRM ──POST /api/public/v1/leads──────────▶ HOA Energy portaal CRM ──POST /api/public/v1/calls/batch───▶ (belt via het voice-platform) CRM ◀──────POST call.completed─────────── HOA Energy portaal
- Vraag de test-API-sleutel op bij Digital AI Agency (begint met
hoa_test_). - Bouw in het CRM een endpoint dat onze callback ontvangt (POST, JSON) en geef ons die URL door — wij zetten hem per omgeving in het portaal.
- Implementeer de calls hieronder en test volledig met de test-sleutel: die belt altijd naar het vaste testnummer, nooit naar een echte klant.
- Na akkoord ontvangen jullie de live-sleutel. Alleen de sleutel wijzigt — de code blijft identiek.
Base URL (live): https://hoaenergy.app
Base URL (test): https://project--e434aff6-3037-4f53-891d-9e14d78ddfc3-dev.lovable.app
Header: x-api-key: <jullie sleutel>
De sleutel bepaalt de omgeving. Een test-sleutel schrijft naar geïsoleerde testdata en belt altijd het vaste testnummer — nooit een echt klantnummer. Rate limit: 60 requests per minuut per sleutel.
401 unauthorized400 invalid_body404 not_found429 rate_limited500 server_error/api/public/v1/leadsLead aanmelden vanuit het CRM. Zet jullie eigen lead-ID in metadata.external_id — die krijgen jullie in de callback terug.
Request
{
"name": "Jan Peeters",
"phone": "+32470112233",
"email": "jan@example.be",
"source": "crm",
"metadata": {
"external_id": "CRM-8842",
"bedrijfsnaam": "Peeters bvba",
"gemeente": "Genk"
}
}Response
201 Created
{
"lead_id": "0c0f…",
"status": "queued",
"environment": "test"
}/api/public/v1/leads/:idHuidige status en gespreksgeschiedenis van een lead opvragen (pull-alternatief op de callback).
Request
(geen body)
Response
200 OK
{
"lead_id": "0c0f…",
"environment": "test",
"name": "Jan Peeters",
"status": "completed",
"outcome": "afspraak geboekt",
"calls": [
{ "id": "9a1…", "agent": "Lien", "status": "completed",
"outcome": "afspraak geboekt", "duration_sec": 143,
"dialed_number": "+32460207122" }
]
}/api/public/v1/calls/triggerEén uitgaand gesprek starten. Agent Lien is de actieve outbound agent.
Request
{ "lead_id": "0c0f…", "agent": "Lien" }Response
202 Accepted
{
"call_id": "9a1…",
"environment": "test",
"dialed_number": "+32460207122",
"number_overridden": true,
"status": "accepted"
}/api/public/v1/calls/batchMeerdere leads in één keer laten bellen (max. 200 per batch) — bijvoorbeeld achter een knop 'Bel selectie' in het CRM.
Request
{ "lead_ids": ["0c0f…", "1d2a…"], "agent": "Lien" }Response
202 Accepted
{
"batch_id": "44b…",
"accepted": [ { "call_id": "9a1…", "lead_id": "0c0f…" } ],
"skipped": []
}Zodra een gesprek is afgerond sturen wij het resultaat naar de URL die per omgeving in het portaal is ingesteld. Bij een fout volgen automatisch 3 pogingen met oplopende wachttijd.
- Antwoord met HTTP 2xx zodra de payload ontvangen is; verwerk daarna asynchroon.
- Gebruik
call_idals idempotency-sleutel — bij een retry komt dezelfde call_id opnieuw binnen. - Bij uitkomst
opt-out: zet de lead in het CRM op niet-bellen. Wij bellen dat nummer ook niet meer.
POST <jullie CRM webhook URL>
Content-Type: application/json
{
"event": "call.completed",
"environment": "test",
"call_id": "9a1…",
"lead_id": "0c0f…",
"agent": "Lien",
"outcome": "warm",
"duration_sec": 143,
"dialed_number": "+32460207122",
"lead": { "id": "0c0f…", "name": "Jan Peeters", "phone": "+32470112233",
"email": null, "status": "completed" },
"completed_at": "2026-09-08T12:00:00.000Z"
}Mogelijke uitkomsten: warm · afspraak geboekt · info-mail gevraagd · niet geïnteresseerd · voicemail · geen gehoor · opt-out.
# 1. lead aanmelden
curl -X POST https://hoaenergy.app/api/public/v1/leads \
-H "x-api-key: hoa_test_…" \
-H "Content-Type: application/json" \
-d '{"name":"Jan Peeters","phone":"+32470112233","source":"crm",
"metadata":{"external_id":"CRM-8842"}}'
# 2. selectie laten bellen
curl -X POST https://hoaenergy.app/api/public/v1/calls/batch \
-H "x-api-key: hoa_test_…" \
-H "Content-Type: application/json" \
-d '{"lead_ids":["0c0f…"],"agent":"Lien"}'- Lead aanmelden (201) en opnieuw ophalen (200).
- Gesprek starten (202) en controleren dat
dialed_numberhet testnummer is. - Callback ontvangen en het resultaat op de juiste lead in het CRM wegschrijven (via
external_id). - Retry-gedrag testen door eenmalig bewust een 500 terug te geven.
- Foutafhandeling testen: verkeerde sleutel (401) en te veel requests (429).
v1.0 — september 2026: eerste publieke versie. Leads aanmelden, gesprek starten, batch starten en de call.completed-callback naar het CRM.