Cursussen AI in je bedrijf Week 6 Les 23 / 33

Eigen API-koppelingen

Als no-code niet genoeg is: een klein PHP of Node-scriptje

Er komt een moment waarop no-code niet meer genoeg is. Je workflow loopt dagelijks duizend keer. Je wilt iets doen dat Zapier niet kan. Of je wilt gewoon de controle terug. Dan ga je naar het punt waar veel bouwers vroeg of laat komen: je eigen script dat praat met Claude of GPT-5. In deze les schrijf je dat script, en snap je waarom het simpeler is dan je dacht.

Wat een API-koppeling eigenlijk is

Een AI-API-call klinkt zwaar, maar is in essentie één HTTP-request. Jij stuurt een POST naar Anthropic of OpenAI met wat tekst, zij sturen een antwoord terug. Geen magie, geen SDK-verplichting. Als je cURL kunt, kun je dit.

De verschillen met je gewone API-werk zijn klein maar belangrijk: je stuurt tekst, niet structuren. Je krijgt tekst terug die je zelf moet interpreteren. En je betaalt per token — per stukje tekst dat in en uit gaat.

Een cURL-voorbeeld voor Claude

Onderstaand is een plausibel voorbeeld van hoe je Claude 4.7 aanroept. Gebruik YOUR_API_KEY als placeholder:

curl https://api.anthropic.com/v1/messages \
  -H "x-api-key: YOUR_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-sonnet-4-7",
    "max_tokens": 1024,
    "system": "Je bent een hulpzame assistent die support-mails categoriseert.",
    "messages": [
      {"role": "user", "content": "Hoi, ik kan niet inloggen sinds vanmorgen. Super urgent graag."}
    ]
  }'

Het antwoord is JSON met een content-array waar de tekst in zit. In PHP parse je hem met json_decode. In Node.js is het één await response.json(). Simpeler dan het eruitziet.

System-prompt en user-prompt: het verschil

Twee begrippen die je gaat zien in elke API-call:

System-prompt. De instructie waarin je het model vertelt wie hij is en wat hij moet doen. "Je bent een support-categoriseerder. Antwoord altijd in JSON. Sla geen toelichting vooraf in." Dit deel blijft gelijk over veel aanroepen heen; het is jouw configuratie.

User-prompt. De input die per call verschilt. De mail die je wilt categoriseren. De vraag van de klant. Het is het variabele deel van je aanroep.

Beide samen bepalen wat je terugkrijgt. Een goed gekozen system-prompt zorgt dat je niet telkens dezelfde instructies hoeft te herhalen. Schrijf hem één keer, test hem grondig, en laat hem staan.

✦ De prijs van een fout geformuleerde prompt

Eén slechte system-prompt kan je duizenden euro's per maand kosten. Als je vergeet te zeggen "wees beknopt" en je model antwoord altijd in drie alinea's waar één zin genoeg was, verdrievoudig je je kosten. Schrijf nooit "doe je best" — schrijf "antwoord in maximaal 50 woorden". Wees concreet, altijd.

Structured outputs: de grootste productivity-boost

Het probleem met ouderwetse AI-calls: je krijgt tekst terug. "De urgentie is 4 van de 5, en de categorie is facturatie." Handig voor een mens, onbruikbaar voor een script. Je moet gaan regex'en om er data uit te halen.

Structured outputs — in 2026 standaard bij Claude en GPT-5 — lossen dit op. Je geeft het model een JSON-schema mee en eist dat het antwoord valid JSON is volgens dat schema. Geen gezever meer met parsing.

{
  "type": "object",
  "properties": {
    "categorie": {"type": "string", "enum": ["facturatie", "bug", "feature", "overig"]},
    "urgentie": {"type": "integer", "minimum": 1, "maximum": 5},
    "samenvatting": {"type": "string", "maxLength": 200}
  },
  "required": ["categorie", "urgentie", "samenvatting"]
}

Stuur dit mee, en je krijgt gegarandeerd JSON terug die valideert. Parse met json_decode($body, true), schrijf naar je database, klaar.

Voor een solo-bouwer met PHP/MySQL-achtergrond is dit de meest onderschatte feature van moderne AI-API's. Het maakt het verschil tussen "leuk experiment" en "betrouwbare productie-integratie".

Error handling: niet overslaan

AI-API's falen soms. Rate limits. Timeouts. Ineens een overbelaste server. Zonder foutafhandeling stort je script in bij het minste gekke.

Bouw minimaal deze vier dingen in:

Timeout. Zet een redelijke timeout op je HTTP-client (30 seconden is genoeg voor de meeste calls, max 120 voor lange taken). Hang nooit oneindig.

Retry met exponentiële back-off. Krijg je 429 (rate limit) of 5xx? Wacht 1 seconde, probeer opnieuw. Faalt weer? Wacht 2 seconden. Dan 4. Max 3 retries, dan opgeven.

Fallback. Als Claude down is, probeer GPT-5. Niet netjes, maar het houdt je systeem draaiende. In PHP is dat twintig regels code.

Logging. Elke call die je doet, log hem. Minimum: timestamp, input-hash, gebruikte model, aantal tokens, kosten, response of error. Zonder deze logs kun je nooit achterhalen waar iets misging.

✦ Cache wat niet hoeft te veranderen

Veel AI-calls krijgen dezelfde input en geven dezelfde output. Een product-omschrijving die je door een model haalt verandert niet tot je hem zelf aanpast. Cache het resultaat in Redis of in je MySQL — sleutel is een hash van (prompt + model), waarde is het antwoord, TTL van een maand. Je kosten halveren soms gewoon, puur door niet twee keer hetzelfde te vragen.

Een compleet mini-script in PHP

Stel dat je een support-mail binnenkrijgt via een webhook en die wilt categoriseren. Onder is pseudo-code die je meteen herkent:

<?php
$email_body = $_POST['body']; // de inkomende mail

$payload = [
  'model' => 'claude-sonnet-4-7',
  'max_tokens' => 300,
  'system' => 'Categoriseer support-mails. Antwoord alleen in JSON.',
  'messages' => [
    ['role' => 'user', 'content' => $email_body]
  ],
  // schema hier toevoegen voor structured output
];

$ch = curl_init('https://api.anthropic.com/v1/messages');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
  'x-api-key: ' . getenv('ANTHROPIC_API_KEY'),
  'anthropic-version: 2023-06-01',
  'content-type: application/json'
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));

$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($http_code !== 200) {
  // log error, retry, of fallback naar GPT
  error_log("AI call failed: $http_code");
  exit;
}

$data = json_decode($response, true);
$answer = json_decode($data['content'][0]['text'], true);

// $answer = ['categorie' => 'bug', 'urgentie' => 5, ...]
// sla op in je database
?>

Minder dan dertig regels, en je hebt een werkende AI-integratie. Dit is het patroon dat je overal terugziet — van meeting-samenvattingen tot factuuranalyse. Pas de system-prompt aan, pas het schema aan, en je bouwt elke AI-feature die je wilt.

Wat te doen met de API-key

Nooit in je code. Nooit in je Git-repo. Altijd in een .env-bestand of een environment-variabele op je server. Als je toch een keer per ongeluk je key lekt — wat iedereen overkomt — revoke hem meteen in het dashboard van je provider en maak een nieuwe. Een gelekte key is een dagelijks lopende factuur voor iemand anders.

Drie dingen om mee te nemen

  1. Structured outputs zijn de belangrijkste feature. Laat het model altijd JSON teruggeven dat valideert tegen een schema. Scheelt eindeloos parsen en maakt je integratie robuust.
  2. Error handling is niet optioneel. Timeouts, retries, fallbacks, logging. Zonder gaat je systeem onderuit op de eerste slechte nacht van je provider.
  3. API-keys horen in environment-variabelen. Nooit in code, nooit in Git. Lekkage betekent direct revoken.

In de volgende les — de laatste — kijk je naar de donkere kant. Wat als een agent de verkeerde kant op loopt? Prompt-injectie, budget-runaways, observability. Hoe hou je je AI-automatiseringen onder controle als ze eenmaal 24/7 draaien?

Tot dan. Schrijf klein en test groot.

Cursus
↑ Overzicht