M2C Leads API
Gold Lemon stuurt warme leads naar M2C, één bericht per lead. Vooraf kan Gold Lemon vragen of M2C een bedrijf al kent. Elk verzoek is een POST met JSON over HTTPS, met een sleutel en een handtekening.
De API is van Makershouse, de beheerder van het leadportaal van M2C. Gold Lemon koppelt via Makershouse: sleutels, de testomgeving en vragen over de koppeling lopen via Makershouse.
https://api.m2c.makershouse.nlhttps://api-acc.m2c.makershouse.nlDe testomgeving schrijft naar een nagebootste Teamleader: er komt niets in de echte administratie van M2C. Test en live hebben eigen sleutels.
De volledige specificatie staat als OpenAPI 3.1 op /openapi.json. Daarmee kun je een client genereren of de berichten valideren.
POST /v1/leads # lead of afmelding
POST /v1/klantcheck # bekend of onbekend
# elk verzoek
Authorization: Bearer <sleutel>
Content-Type: application/json
X-Timestamp: <unix-seconden>
X-Signature: sha256=<hex>
Sleutel en handtekening
Elk verzoek heeft twee geheimen. De sleutel gaat mee in Authorization: Bearer. Het signing secret gaat nooit mee; daarmee bereken je de handtekening.
- Neem het verzendmoment in seconden sinds 1970 (UTC). Dat is
X-Timestamp. - Plak het tijdstip, een punt en de ruwe body aan elkaar:
<X-Timestamp>.<body>. - Bereken daarover HMAC-SHA256 met het signing secret, als hexadecimale tekst.
- Stuur die mee als
X-Signature: sha256=<hex>.
Sleutels en signing secrets krijg je van Makershouse via een veilig kanaal, niet per mail. Bewaar ze in een vault, niet in code of logs. Makershouse kan ze altijd intrekken; je krijgt dan een 401 tot er nieuwe zijn.
import hashlib, hmac, json, os, time, requests
body = json.dumps(lead, ensure_ascii=False).encode()
ts = str(int(time.time()))
sig = hmac.new(os.environ["M2C_SIGNING_SECRET"].encode(),
ts.encode() + b"." + body,
hashlib.sha256).hexdigest()
r = requests.post(
"https://api.m2c.makershouse.nl/v1/leads",
data=body,
headers={
"Authorization": f"Bearer {os.environ['M2C_SLEUTEL']}",
"Content-Type": "application/json",
"X-Timestamp": ts,
"X-Signature": f"sha256={sig}",
},
timeout=90,
)
import crypto from 'node:crypto';
const body = JSON.stringify(lead);
const ts = String(Math.floor(Date.now() / 1000));
const sig = crypto
.createHmac('sha256', process.env.M2C_SIGNING_SECRET)
.update(`${ts}.${body}`)
.digest('hex');
const r = await fetch('https://api.m2c.makershouse.nl/v1/leads', {
method: 'POST',
body,
headers: {
Authorization: `Bearer ${process.env.M2C_SLEUTEL}`,
'Content-Type': 'application/json',
'X-Timestamp': ts,
'X-Signature': `sha256=${sig}`,
},
signal: AbortSignal.timeout(90_000),
});
TS=$(date +%s)
SIG=$(printf '%s.%s' "$TS" "$(cat lead.json)" \
| openssl dgst -sha256 -hmac "$M2C_SIGNING_SECRET" -r | cut -d' ' -f1)
curl https://api.m2c.makershouse.nl/v1/leads \
-H "Authorization: Bearer $M2C_SLEUTEL" \
-H 'Content-Type: application/json' \
-H "X-Timestamp: $TS" \
-H "X-Signature: sha256=$SIG" \
--data-binary @lead.json
Lead versturen
Eén lead per verzoek. Een nieuw signaal voor een lead die je al eerder stuurde, gaat met hetzelfde gl_lead_id. M2C bepaalt zelf of het bedrijf al bekend is en antwoordt met 201 (nieuw) of 200 (bekend). Wat M2C daarna met de lead doet, hoort niet bij deze API.
Laat weg wat je niet weet; een lege tekst telt als afwezig. Alle tekst is platte UTF-8, zonder HTML. Onbekende velden worden genegeerd. Lengtes zijn maxima in tekens.
1.0. Een andere hoofdversie geeft 422.2026-11-04T10:12:00+01:00.https://www.linkedin.com/in/…+31612345678.beslisser.https:// en www., bijvoorbeeld voorbeeld.nl.25-50.stairoids, tam_tracker of linkedin._, bijvoorbeeld connectie_geaccepteerd.JJJJ-MM-DD.Cyberbewust.{
"schema_versie": "1.0",
"gl_lead_id": "m2c-2026-000123",
"verstuurd_op": "2026-11-04T10:12:00+01:00",
"contact": {
"voornaam": "Sanne",
"achternaam": "de Vries",
"linkedin_url": "https://www.linkedin.com/in/voorbeeld",
"functie": "Operationeel directeur",
"dmu_rol": "beslisser"
},
"bedrijf": {
"naam": "Voorbeeld Advies BV",
"domein": "voorbeeld.nl",
"plaats": "Heemstede",
"medewerkers": "25-50"
},
"signaal": {
"bron": "linkedin",
"type": "connectie_geaccepteerd",
"datum": "2026-11-03",
"score": 74,
"dienst": "Cyberbewust"
},
"dossier": {
"aanleiding": "Accepteerde gisteren het connectieverzoek van M2C.",
"samenvatting": "Adviesbureau, 30 medewerkers, groeit snel (4 vacatures).",
"gespreksopener": "Jullie team groeit snel. Hoe neem je nieuwe collega's mee in veilig mailen?"
}
}
{ "status": "aangemaakt", "gl_lead_id": "m2c-2026-000123" }
{ "status": "bestaat_al", "gl_lead_id": "m2c-2026-000123" }
Alle namen en gegevens zijn verzonnen.
Afmelding
Wil iemand niet meer benaderd worden, stuur dan een kort bericht naar hetzelfde adres met "afmelding": true. M2C legt vast dat de persoon niet meer benaderd wil worden. Er wordt niets verwijderd.
Verplicht: schema_versie, gl_lead_id, verstuurd_op, afmelding, bedrijf.naam, bedrijf.domein en contact.email of contact.linkedin_url. Andere velden mogen ontbreken.
Het antwoord is 200 afgemeld, of 200 niet_gevonden als er bij M2C niets was om bij te schrijven. Een afmelding telt niet mee voor het dagmaximum.
{
"schema_versie": "1.0",
"gl_lead_id": "m2c-2026-000123",
"verstuurd_op": "2026-11-09T09:30:00+01:00",
"afmelding": true,
"bedrijf": { "naam": "Voorbeeld Advies BV", "domein": "voorbeeld.nl" },
"contact": { "linkedin_url": "https://www.linkedin.com/in/voorbeeld" }
}
{ "status": "afgemeld", "gl_lead_id": "m2c-2026-000123" }
Klantcheck
Vraag vooraf of M2C een bedrijf al kent. Zo heb je geen klantenlijst van M2C nodig. Het antwoord is alleen bekend of onbekend: geen namen, geen klantstatus.
bekend is geen weigering. Een lead van een bekend bedrijf wordt gewoon verwerkt (200 bestaat_al); jij bepaalt of je hem stuurt. onbekend betekent dat M2C het bedrijf op deze gegevens niet vond. Bij het versturen is het antwoord 201 of 200 leidend.
{
"schema_versie": "1.0",
"bedrijf": {
"domein": "voorbeeld.nl",
"naam": "Voorbeeld Advies BV",
"plaats": "Heemstede"
}
}
{ "status": "bekend" }
Antwoorden en fouten
Elk antwoord is JSON met minimaal status. Bij /v1/leads staat ook het gl_lead_id erin, als het bericht er een had.
| Code | status | Wat je doet |
|---|---|---|
| 201 | aangemaakt | Nieuw bedrijf, verwerkt. Klaar. |
| 200 | bestaat_al | Bekend bedrijf, verwerkt. Klaar. |
| 200 | afgemeld / niet_gevonden | Afmelding verwerkt. Klaar. |
| 200 | bekend / onbekend | Antwoord op de klantcheck. |
| 401 | niet_geautoriseerd | Sleutel, tijdstip of handtekening klopt niet. Controleren, niet automatisch herhalen. |
| 404 | niet_gevonden | Onbekend pad. |
| 405 | alleen_post | Gebruik POST. |
| 413 | te_groot | Body groter dan 64 KB. |
| 422 | ongeldig | Zie fouten. Pas opnieuw sturen na correctie. |
| 429 | te_snel | Wacht Retry-After seconden. |
| 429 | daglimiet | Die dag niets meer sturen. |
| 503 | storing | Opnieuw proberen (zie limieten). |
{
"status": "ongeldig",
"gl_lead_id": "m2c-2026-000123",
"fouten": [
{ "veld": "bedrijf.kvk", "reden": "moet uit 8 cijfers bestaan" },
{ "veld": "dossier.samenvatting", "reden": "is langer dan 1500 tekens" }
]
}
Een fout noemt het veld, nooit de waarde die je stuurde.
Limieten en opnieuw proberen
| Wat | Grens |
|---|---|
| Leads en afmeldingen | 10 per minuut, achter elkaar (niet gelijktijdig) |
| Klantchecks | 30 per minuut |
| Leads per dag, eerste week | 10, Nederlandse tijd; afmeldingen tellen niet mee |
| Body | 64 KB |
| Antwoordtijd | binnen 60 seconden; stel je time-out op 90 |
Opnieuw proberen
Bij een time-out, 429 te_snel of 503: opnieuw na 1, 5 en 30 minuten, of na Retry-After als die korter is. Lukt het dan nog niet, meld het aan Makershouse. 401, 413 en 422 herhaal je niet automatisch.
Veilig herhalen
Dezelfde lead opnieuw sturen met hetzelfde gl_lead_id is altijd veilig, ook na een time-out. Het levert nooit een tweede lead op.
Retry-After: 41820
{ "status": "daglimiet", "gl_lead_id": "m2c-2026-000131" }
Retry-After: 5
{ "status": "storing" }
Testen en live gaan
- Makershouse levert de testsleutel en het signing secret voor test, en een bedrijf dat in de testomgeving al bestaat.
- Gold Lemon stuurt vijf verzonnen testleads: een gewone, dezelfde nog eens, een bestaand bedrijf, een ongeldig veld en een afmelding.
- Makershouse en M2C bekijken het resultaat in de testomgeving. Aanpassingen aan de velden worden schema 1.1.
- Makershouse levert de live-sleutel en het signing secret voor live.
- De eerste live lead gaat met een testbedrijf dat Makershouse opgeeft. Daarna de echte stroom, de eerste week met het dagmaximum van 10.
# testlead antwoord
gewoon, nieuw bedrijf 201 aangemaakt
zelfde gl_lead_id nog eens 200 bestaat_al
bedrijf dat al bestaat 200 bestaat_al
bedrijf.kvk van 7 cijfers 422 ongeldig
afmelding van een testlead 200 afgemeld
Privacy en logging
Alleen zakelijke gegevens van zakelijke contactpersonen, op grond van gerechtvaardigd belang. Geen bijzondere persoonsgegevens en geen privéadressen. Leads die de controles van Gold Lemon niet doorstaan, worden niet verstuurd.
M2C bewaart de berichten niet in een verwerkingslog. Logs aan beide kanten bevatten het gl_lead_id en de statuscode, geen namen of e-mailadressen.
Vragen over de koppeling: Makershouse (Kees Romijn).
Wijzigingen
| Schema | Datum | Wat |
|---|---|---|
1.0 | 6 november 2026 | Eerste versie: leads, afmelding en klantcheck. |
Nieuwe optionele velden komen in een 1.x-versie; je bestaande berichten blijven werken. Een 2.0 komt er alleen na afspraak.
De specificatie als OpenAPI 3.1: /openapi.json