Cursus
Meerdere API’s van AI-providers beheren wordt al snel overweldigend. Elke provider heeft andere authenticatiemethoden, prijsmodellen en API-specificaties. Ontwikkelaars verspillen talloze uren met schakelen tussen OpenAI, Anthropic, Google en andere platforms, alleen maar om verschillende modellen te kunnen gebruiken.
OpenRouter lost deze complexiteit op met een uniforme API die je verbindt met meer dan 400 modellen van tientallen providers. Je krijgt toegang tot GPT-5, Claude 4, Gemini 2.5 Pro en honderden andere modellen met één API-sleutel en een consistente interface. Het platform regelt automatische fallbacks, kostenbeheer en provider-routing achter de schermen.
In deze tutorial leg ik alles uit wat je moet weten over OpenRouter, van je eerste API-call instellen tot geavanceerde functies zoals gestructureerde outputs. Aan het eind kun je betrouwbare applicaties bouwen die niet vastzitten aan één provider.
Wat is OpenRouter?
OpenRouter is een platform met een uniforme API die je via één endpoint toegang geeft tot meer dan 400 AI-modellen van tientallen providers. In plaats van losse API-sleutels te beheren voor OpenAI, Anthropic, Google, Meta en anderen, gebruik je één sleutel om hun volledige modelcatalogus te bereiken.
Het platform werkt als een intelligente router: het stuurt je verzoeken naar de juiste provider en verzorgt authenticatie, facturatie en foutafhandeling. Deze aanpak lost meerdere hoofdpijndossiers op die komen kijken bij het gebruik van meerdere AI-providers.
Problemen die OpenRouter oplost
Werken met meerdere AI-providers wordt snel rommelig. Elke provider heeft een eigen API-formaat, inlogproces en betaalsysteem. Je eindigt met afzonderlijke code voor elke dienst, wat ontwikkeling vertraagt en het testen van nieuwe modellen lastig maakt.
Het wordt nog erger als providers uitvallen of je tegen rate limits aanloopt. Je app breekt, en je kunt niets doen behalve wachten. Bovendien betekent uitzoeken welke provider de beste prijs biedt voor vergelijkbare modellen dat je kosten handmatig moet bijhouden over verschillende platforms.
Het grootste probleem is vastzitten aan één provider. Als je alles rond hun specifieke API bouwt, wordt later overstappen naar betere of goedkopere opties een groot project.
Hoe OpenRouter dit oplost
OpenRouter pakt deze problemen aan met een set samenhangende functies:
- Eén API-sleutel werkt met 400+ modellen van alle grote providers
- Automatisch overschakelen naar back-upproviders wanneer je eerste keuze faalt
- Prijzen naast elkaar voor alle modellen zodat je kosten direct kunt vergelijken
- Werkt met bestaande OpenAI-code — verander alleen de endpoint-URL
- Realtime monitoring die verzoeken naar de snelste beschikbare provider stuurt
Deze onderdelen werken samen om AI-ontwikkeling soepeler en betrouwbaarder te maken.
Voor wie is OpenRouter?
Verschillende typen gebruikers halen voordeel uit deze uniforme aanpak:
- Ontwikkelaars kunnen nieuwe modellen proberen zonder overal accounts aan te maken, waardoor experimenteren sneller gaat
- Enterprise-teams krijgen de uptime die ze nodig hebben via automatische back-ups wanneer providers falen
- Budgetbewuste gebruikers vinden de goedkoopste optie voor hun behoeften zonder spreadsheetrekensommen
- Onderzoekers krijgen direct toegang tot state-of-the-art modellen zonder account-overhead
Nu je weet wat OpenRouter te bieden heeft, gaan we je eerste API-call opzetten.
Vereisten
Voordat je met OpenRouter aan de slag gaat, moet je een paar dingen op je machine hebben ingesteld. Deze tutorial gaat ervan uit dat je basiskennis van Python-programmeren hebt en eerder met API’s hebt gewerkt. Je hoeft geen expert te zijn, maar je moet concepten begrijpen als HTTP-verzoeken doen en JSON-responses afhandelen.
Je hebt Python 3.7 of later nodig. We gebruiken het openai Python-pakket om met de API van OpenRouter te werken, samen met python-dotenv om omgevingsvariabelen veilig te beheren. Je installeert beide met:
pip install requests openai python-dotenv
Je hebt ook een OpenRouter-account en API-sleutel nodig. Ga naar openrouter.ai om een gratis account aan te maken — je krijgt een kleine krediettoelage om te testen. Zodra je bent ingelogd, ga je naar de sectie API Keys in je accountinstellingen en genereer je een nieuwe sleutel.
Na het ophalen van je API-sleutel maak je een .env-bestand in je projectmap en voeg je je sleutel als volgt toe:
OPENROUTER_API_KEY=your_api_key_here
Zo blijft je API-sleutel veilig en buiten je code. Als je OpenRouter verder wilt gebruiken dan alleen voor testen, moet je via de Credits-pagina tegoed aan je account toevoegen.
Met deze basis ben je klaar om je eerste API-call via OpenRouter te doen.
Je eerste API-call in OpenRouter
Beginnen met OpenRouter is verrassend eenvoudig als je eerder de OpenAI-SDK hebt gebruikt. Je verandert één regel code en hebt ineens toegang tot honderden modellen van verschillende providers.
Je eerste request en setup
Laten we meteen beginnen met een werkend voorbeeld dat de aanpak van OpenRouter laat zien:
import os
from openai import OpenAI
from dotenv import load_dotenv
load_dotenv()
client = OpenAI(
base_url="https://openrouter.ai/api/v1",
api_key=os.getenv("OPENROUTER_API_KEY"),
)
response = client.chat.completions.create(
model="openai/gpt-5-mini",
messages=[
{
"role": "user",
"content": "Write a haiku about debugging code at 2 AM"
}
]
)
print(response.choices[0].message.content)
Night hum, coffee cooled
cursor blinks, bug hides somewhere
I chase ghosts 'til dawn
De magie gebeurt op twee plekken. Ten eerste stuurt de base_url-parameter je verzoeken naar de servers van OpenRouter in plaats van die van OpenAI. Ten tweede volgt de modelnaam het formaat provider/model-name — openai/gpt-5-mini in plaats van alleen gpt-5-mini. Zo geef je aan welke providerversie je wilt, met behoud van de bekende interface. Dit zijn enkele veelgebruikte modellen die je zonder fouten in het bovenstaande voorbeeld kunt gebruiken:
- google/gemini-2.0-flash-001
- google/gemini-2.5-pro
- mistralai/mistral-nemo
- deepseek/deepseek-r1-distill-qwen-32b
Nu je hebt gezien hoe makkelijk het is om met verschillende modellen te werken, vraag je je misschien af: wat gebeurt er als je gekozen model niet beschikbaar is? Hoe bouw je applicaties die betrouwbaar blijven, zelfs als providers problemen hebben? Daar komen OpenRouters routing- en veerkrachtfuncties om de hoek kijken.
Modelrouting voor veerkracht
Betrouwbare AI-applicaties bouwen betekent voorbereid zijn op het onverwachte. Providers hebben downtime, modellen raken rate-limited en soms blokkeert contentmoderatie je verzoeken. Modelrouting is OpenRouters oplossing — het schakelt automatisch tussen verschillende modellen om je applicatie soepel te laten draaien.
Handmatige fallbacks instellen
De eenvoudigste manier om veerkracht toe te voegen is back-upmodellen op te geven. Als je primaire keuze faalt, probeert OpenRouter je alternatieven op volgorde. De extra_body-parameter geeft deze routinginstructies door aan de API van OpenRouter, omdat de OpenAI-SDK deze functie niet native ondersteunt:
response = client.chat.completions.create(
model="moonshotai/kimi-k2", # Primary choice
messages=[
{"role": "user", "content": "Explain quantum computing in simple terms"}
],
extra_body={
"models": ["anthropic/claude-sonnet-4", "deepseek/deepseek-r1"]
}
)
print(f"Response from: {response.model}")
print(response.choices[0].message.content)
Response from: moonshotai/kimi-k2
Imagine a normal computer bit as a tiny light-switch that can only be OFF (0) or ON (1)...
OpenRouter probeert eerst Kimi-K2. Als die niet beschikbaar is, rate-limited is of geblokkeerd, schakelt het automatisch over naar Claude Sonnet 4, en daarna naar DeepSeek R1. Het veld response.model toont welk model daadwerkelijk heeft geantwoord.
Autorouter voor maximaal gemak
Zodra je handmatige fallbacks begrijpt, wordt de autorouter erg aantrekkelijk. Die verzorgt modelkeuze en fallbacks automatisch, aangestuurd door NotDiamond’s evaluatiesysteem:
response = client.chat.completions.create(
model="openrouter/auto",
messages=[
{"role": "user", "content": "Debug this Python code in 3 sentences: def factorial(n): return n * factorial(n-1)"}
]
)
print(f"Auto router selected: {response.model}")
print(response.choices[0].message.content)
Auto router selected: openai/chatgpt-4o-latest
The given code is missing a base case, which causes infinite recursion and eventually a RecursionError. To fix it, add a base case like `if n == 0: return 1` before the recursive call. Here's the corrected version:
\```python
def factorial(n):
if n == 0:
return 1
return n * factorial(n - 1)
\```
De autorouter analyseert je prompt en kiest het beste beschikbare model, met ingebouwde fallbacks als je eerste keuze niet beschikbaar is. Je krijgt veerkracht zonder configuratie. Gebruik de autorouter wel met beleid in gevoelige of zichtbare scenario’s, want hij kan de complexiteit van je probleem onderschatten en daardoor een model met lagere capaciteit kiezen.
Effectieve fallbackstrategieën bouwen
Niet alle modellen zijn goede back-ups voor elkaar. Downtime bij een provider kan alle modellen van dat bedrijf raken, dus kies fallbacks van verschillende providers. Rate limits en kosten verschillen sterk, dus koppel dure modellen ook aan goedkopere alternatieven:
# Goede fallbackketen: verschillende providers, dalende kosten
response = client.chat.completions.create(
model="anthropic/claude-sonnet-4",
messages=[
{"role": "user", "content": "Your prompt here"}
],
extra_body={
"models": [
"x-ai/grok-4", # Vergelijkbare performance
"moonshotai/kimi-k2", # Goedkoper
"deepseek/deepseek-r1:free" # Gratis back-up
]
}
)
Dit geeft je topkwaliteit wanneer beschikbaar, solide prestaties als back-up en gegarandeerde beschikbaarheid als laatste redmiddel. Contentmoderatiebeleid verschilt ook per provider, dus diversifiëren van je keten geeft betere dekking voor gevoelige onderwerpen.
Modellen vinden voor je fallbackketen
De modellenpagina laat je filteren op provider en mogelijkheden om je keten te bouwen. Veel krachtige modellen zoals DeepSeek R1 en Kimi-K2 zijn gratis omdat ze open-source zijn, en zijn uitstekende fallbacks. Gratis modellen hebben limieten van 50 verzoeken per dag voor nieuwe gebruikers, of 1000 verzoeken per dag als je 10 credits hebt gekocht.
Voor dynamische applicaties kun je modellen programmatisch ontdekken:
def get_provider_models(api_key: str, provider: str) -> list[str]:
r = requests.get(
"https://openrouter.ai/api/v1/models",
headers={"Authorization": f"Bearer {api_key}"}
)
return [m["id"] for m in r.json()["data"] if m["id"].startswith(provider)]
# Build fallbacks across providers
openai_models = get_provider_models(api_key, "openai/")
anthropic_models = get_provider_models(api_key, "anthropic/")
Met deze aanpak bouw je robuuste fallbackketens die meebewegen zodra nieuwe modellen beschikbaar komen.
Streaming voor realtime reacties
Bij AI-modellen, zeker bij langere antwoorden, verwachten gebruikers dat de output geleidelijk verschijnt in plaats van te wachten op het volledige antwoord. Streaming lost dit op door antwoordstukjes te sturen zodra ze worden gegenereerd, wat een interactievere ervaring oplevert die lijkt op de interface van ChatGPT.
Basisopzet voor streaming
Om streaming in OpenRouter in te stellen, voeg je stream=True toe aan je request. De response wordt een iterator die chunks oplevert terwijl het model ze genereert:
response = client.chat.completions.create(
model="openai/gpt-5",
messages=[
{"role": "user", "content": "Write a detailed explanation of how neural networks learn"}
],
stream=True
)
for chunk in response:
if chunk.choices[0].delta.content is not None:
print(chunk.choices[0].delta.content, end="")
Elke chunk bevat een klein stukje van het antwoord. Het veld delta.content bevat het nieuwe tekstfragment, en we printen het meteen zonder regeleinde om het streamingeffect te creëren. De parameter end="" voorkomt dat print nieuwe regels tussen chunks toevoegt.
Een betere streaminghandler bouwen
Voor productie-applicaties wil je meer controle over het streamingproces. Hier is een uitgebreidere handler die de volledige response beheert:
def stream_response(model, messages, show_progress=True):
response = client.chat.completions.create(
model=model,
messages=messages,
stream=True
)
complete_response = ""
for chunk in response:
if chunk.choices[0].delta.content is not None:
content = chunk.choices[0].delta.content
complete_response += content
if show_progress:
print(content, end="", flush=True)
if show_progress:
print() # Add final newline
return complete_response
# Use it with different models
result = stream_response(
"anthropic/claude-sonnet-4",
[{"role": "user", "content": "Explain quantum entanglement like I'm 12 years old"}]
)
Deze handler vangt de volledige response terwijl hij voortgang toont, geeft je zowel de streamingervaring als de uiteindelijke tekst en zorgt voor nette outputformattering.
Streaming verandert de gebruikerservaring van “wachten en hopen” naar “voortgang zien”. Hierdoor voelen je AI-applicaties veel responsiever en aantrekkelijker.
Reasoning tokens in OpenRouter gebruiken
Sommige AI-modellen kunnen je hun “denkproces” laten zien voordat ze hun definitieve antwoord geven. Deze reasoning tokens bieden een transparant kijkje in hoe het model complexe problemen benadert en laten de stapsgewijze logica zien die tot de conclusie leidt. Inzicht in deze interne redenering helpt je antwoorden te verifiëren, modelgedrag te debuggen en meer betrouwbare applicaties te bouwen.
Wat zijn reasoning tokens
Reasoning tokens verschijnen in een apart veld reasoning in de response, los van de hoofdinhoud. Verschillende modellen ondersteunen reasoning op verschillende manieren — sommige gebruiken effort levels, andere tokenbudgetten.
Hier is een simpel voorbeeld dat reasoning in actie laat zien:
response = client.chat.completions.create(
model="anthropic/claude-sonnet-4",
messages=[
{"role": "user", "content": "How many 'r's are in the word 'strrawberry'?"}
],
max_tokens=2048,
extra_body={
"reasoning": {
"max_tokens": 512
}
}
)
print("Final answer:")
print(response.choices[0].message.content)
print("\nReasoning process:")
print(response.choices[0].message.reasoning)
Final answer:
To count the 'r's in 'strrawberry', I'll go through each letter:
...
There are **4** 'r's in the word 'strrawberry'.
Reasoning process:
...
Het model laat zowel het eindantwoord zien als de interne redenering die tot die conclusie leidde. Deze dubbele output helpt je begrijpen of het model het probleem correct heeft aangepakt.
De intensiteit van reasoning sturen
Je kunt bepalen hoeveel redeneerinspanning modellen leveren met twee benaderingen. De parameter effort werkt met modellen zoals OpenAI’s o-serie en gebruikt niveaus die overeenkomen met specifieke tokenpercentages op basis van je max_tokens-instelling:
- Hoge inspanning: gebruikt ongeveer 80% van
max_tokensvoor reasoning - Gemiddelde inspanning: gebruikt ongeveer 50% van
max_tokensvoor reasoning - Lage inspanning: gebruikt ongeveer 20% van
max_tokensvoor reasoning
# High effort reasoning for complex problems
response = client.chat.completions.create(
model="deepseek/deepseek-r1",
messages=[
{"role": "user", "content": "Solve this step by step: If a train travels 240 miles in 3 hours, then speeds up by 20 mph for the next 2 hours, how far does it travel total?"}
],
max_tokens=4000, # High effort will use ~3200 tokens for reasoning
extra_body={
"reasoning": {
"effort": "high"
}
}
)
print("Problem solution:")
print(response.choices[0].message.content)
print("\nStep-by-step reasoning:")
print(response.choices[0].message.reasoning)
Voor modellen die directe toekenning van tokens ondersteunen, zoals de modellen van Anthropic, kun je exacte reasoningbudgetten specificeren:
def get_reasoning_response(question, reasoning_budget=2000):
response = client.chat.completions.create(
model="anthropic/claude-sonnet-4",
messages=[{"role": "user", "content": question}],
max_tokens=10000,
extra_body={
"reasoning": {
"max_tokens": reasoning_budget # Exact token allocation
}
}
)
return response
# Compare different reasoning budgets
response = get_reasoning_response(
"What's bigger: 9.9 or 9.11? Explain your reasoning carefully.",
reasoning_budget=3000
)
print("Answer:", response.choices[0].message.content)
print("Detailed reasoning:", response.choices[0].message.reasoning)
Hogere tokenbudgetten leveren over het algemeen grondiger redenering op, terwijl lagere budgetten sneller zijn maar minder gedetailleerd.
Reasoning behouden in gesprekken
Bij het bouwen van gesprekken met meerdere beurten moet je zowel de reasoning als het eindantwoord bewaren om context te behouden. Dit is vooral belangrijk bij complexe discussies waar het denkproces van het model de volgende antwoorden beïnvloedt:
# First message with reasoning
response = client.chat.completions.create(
model="anthropic/claude-sonnet-4",
messages=[
{"role": "user", "content": "Should I invest in renewable energy stocks? Consider both risks and opportunities."}
],
extra_body={
"reasoning": {
"max_tokens": 3000
}
}
)
# Build conversation history with reasoning preserved
messages = [
{"role": "user", "content": "Should I invest in renewable energy stocks? Consider both risks and opportunities."},
{
"role": "assistant",
"content": response.choices[0].message.content,
"reasoning_details": response.choices[0].message.reasoning_details # Preserve reasoning
},
{"role": "user", "content": "What about solar energy specifically? How does that change your analysis?"}
]
# Continue conversation with reasoning context
follow_up = client.chat.completions.create(
model="anthropic/claude-sonnet-4",
messages=messages,
extra_body={
"reasoning": {
"max_tokens": 2000
}
}
)
print("Follow-up answer:")
print(follow_up.choices[0].message.content)
print("\nContinued reasoning:")
print(follow_up.choices[0].message.reasoning)
Het veld reasoning_details bewaart de complete reasoningketen, waardoor het model kan voortbouwen op eerdere analyses bij vervolgvragen. Dat levert samenhangendere en contextbewustere gesprekken op.
Kosten en facturatie
Reasoning tokens worden afgerekend als outputtokens en verhogen dus je gebruikskosten. Vaak verbeteren ze de antwoordkwaliteit echter genoeg om de kosten te rechtvaardigen, vooral bij complexe taken waar nauwkeurigheid belangrijker is dan snelheid. Volgens de documentatie van OpenRouter kunnen reasoning tokens de modelprestaties verbeteren bij uitdagende problemen en tegelijk transparantie bieden in het beslisproces.
Voor kostengevoelige toepassingen kun je de kwaliteit van reasoning tegen de uitgaven afwegen door effortlevels of tokenbudgetten aan te passen op basis van taakcomplexiteit. Simpele vragen hebben misschien geen reasoning nodig, terwijl complexe problemen baat hebben bij high-effort reasoning.
Werken met multimodale modellen in OpenRouter
Tot nu toe heb je met tekst gewerkt, maar wat als je afbeeldingen of documenten moet analyseren? Misschien wil je vragen stellen over een grafiek, informatie uit een PDF halen of beschrijven wat er op een foto gebeurt. Daar komen multimodale modellen van pas — ze begrijpen zowel tekst als visuele content in hetzelfde verzoek.
Multimodale mogelijkheden begrijpen
In plaats van een afbeelding met tekst te proberen te beschrijven, kun je de echte afbeelding meesturen en er direct vragen over stellen. Dat maakt je applicaties veel intuïtiever, omdat het model precies ziet waar je mee werkt. Je hoeft niet te gokken of je tekstbeschrijving alle belangrijke details heeft gevangen.
Je gebruikt multimodale modellen via dezelfde interface als eerder, alleen met een extra parameter attachments om je visuele content mee te sturen. Bestandsbijlagen werken met alle modellen op OpenRouter. Zelfs als een model PDFs of afbeeldingen niet native ondersteunt, parseert OpenRouter deze bestanden intern en geeft de inhoud door aan het model.
Werken met afbeeldingen
Je kunt afbeeldingen meesturen via URL’s of base64-encoding. Als je afbeelding al online staat, is de URL-aanpak het eenvoudigst:
response = client.chat.completions.create(
model="openai/gpt-5-mini",
messages=[
{
"role": "user",
"content": "What's happening in this image? Describe the scene in detail."
}
],
extra_body={
"attachments": [
{
"type": "image/jpeg",
"url": "https://example.com/photo.jpg"
}
]
}
)
print(response.choices[0].message.content)
Voor lokale afbeeldingen kun je base64 gebruiken:
import base64
def encode_image_to_base64(image_path):
with open(image_path, "rb") as image_file:
encoded_string = base64.b64encode(image_file.read()).decode('utf-8')
return encoded_string
# Analyze a local screenshot
encoded_image = encode_image_to_base64("screenshot.png")
response = client.chat.completions.create(
model="openai/gpt-5-mini",
messages=[
{
"role": "user",
"content": "This is a screenshot of a data dashboard. What insights can you extract from the charts and metrics shown?"
}
],
extra_body={
"attachments": [
{
"type": "image/png",
"data": encoded_image
}
]
}
)
print(response.choices[0].message.content)
Het model bekijkt de daadwerkelijke afbeelding en geeft specifieke inzichten over wat het ziet, niet alleen generieke reacties.
PDF-documenten verwerken
PDF-verwerking werkt hetzelfde, maar opent documentanalyse. Je kunt vragen stellen over rapporten, formulieren analyseren of informatie uit complexe documenten halen:
def encode_pdf_to_base64(pdf_path):
with open(pdf_path, "rb") as pdf_file:
encoded_string = base64.b64encode(pdf_file.read()).decode('utf-8')
return encoded_string
# Analyze a research paper
encoded_pdf = encode_pdf_to_base64("research_paper.pdf")
response = client.chat.completions.create(
model="openai/gpt-5-mini",
messages=[
{
"role": "user",
"content": "Summarize the key findings from this research paper. What are the main conclusions and methodology used?"
}
],
extra_body={
"attachments": [
{
"type": "application/pdf",
"data": encoded_pdf
}
]
}
)
print(response.choices[0].message.content)
Dit werkt uitstekend voor financiële rapporten, academische papers, contracten of elke PDF waarbij je AI-analyse van de feitelijke inhoud nodig hebt. Je kunt ook meerdere bijlagen in één verzoek opnemen als je afbeeldingen moet vergelijken of meerdere documenten samen wilt analyseren.
Kosten en modelkeuze
Multimodale verzoeken zijn duurder dan alleen-tekstverzoeken, omdat je extra datatypes verwerkt. Afbeeldingen en PDFs vergen meer rekenkracht, wat terug te zien is in de prijs. Je kunt de specifieke multimodale prijzen per model bekijken op de modellenpagina.
Verschillende modellen hebben verschillende sterke punten bij visuele content. Sommige zijn beter in gedetailleerde beeldanalyse, andere excelleren in documentbegrip. Je zult met verschillende modellen willen experimenteren om te vinden wat het beste werkt voor jouw behoeften en budget.
Gestructureerde outputs gebruiken
Als je echte applicaties bouwt, heb je voorspelbare dataformaten nodig die je code betrouwbaar kan parsen. Vrije-tekstantwoorden zijn prima voor chatinterfaces, maar waardeloos voor applicaties die specifieke informatie moeten extraheren. In plaats van onvoorspelbare tekst terug te krijgen die je met regex moet parsen of hopen dat het model correct heeft geformatteerd, dwingen gestructureerde outputs modellen om gegarandeerde JSON terug te geven met precies de velden en datatypes die je nodig hebt. Dit elimineert parsefouten en maakt je applicatiecode veel eenvoudiger.
Anatomie van gestructureerde output-requests
Gestructureerde outputs gebruiken een parameter response_format met deze basisstructuur:
"response_format": {
"type": "json_schema", # Always this for structured outputs
"json_schema": {
"name": "your_schema_name", # Name for your schema
"strict": True, # Enforce strict compliance
"schema": {
# Your actual JSON schema definition goes here
}
}
}
Voorbeeld sentimentanalyse
Laten we een compleet voorbeeld doorlopen dat sentiment uit tekst haalt. Dit laat zien hoe gestructureerde outputs in de praktijk werken:
response = client.chat.completions.create(
model="openai/gpt-5-mini",
messages=[
{"role": "user", "content": "Analyze the sentiment: 'This movie was absolutely terrible!'"}
],
extra_body={
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "sentiment_analysis",
"strict": True,
"schema": {
"type": "object",
"properties": {
"sentiment": {"type": "string", "enum": ["positive", "negative", "neutral"]},
"confidence": {"type": "number"}
},
"required": ["sentiment", "confidence"]
}
}
}
}
)
import json
result = json.loads(response.choices[0].message.content)
print(result)
{'sentiment': 'negative', 'confidence': 0.98}
Dit gebeurt er in dit schema:
sentiment: Een tekenreeksveld dat is beperkt tot drie specifieke waarden metenum. Het model kan niets anders retourneren dan "positive", "negative" of "neutral"confidence: Een numeriek veld voor de vertrouwensscore van het modelrequired: Beide velden moeten in de response aanwezig zijn — het model kan ze niet overslaanstrict: True: Dwingt strikte naleving van de schemastructuur af
Zonder gestructureerde outputs krijg je mogelijk reacties als “De stemming is erg negatief met hoge zekerheid” of “Negatief (95% zeker)”. Met het schema krijg je altijd parsebare JSON die je direct in je code kunt gebruiken.
Met strict: True wordt het schema rigoureus afgedwongen — het model kan niet afwijken van je structuur. De array required geeft aan welke velden verplicht zijn. Je kunt enum gebruiken om waarden te beperken tot specifieke keuzes, array voor lijsten en geneste object-types voor complexe data.
Modelcompatibiliteit
Niet alle modellen ondersteunen gestructureerde outputs, maar de meeste moderne wel. Je kunt op de modellenpagina de compatibiliteit checken. Als een model gestructureerde outputs niet native ondersteunt, verzorgt OpenRouter de formatting vaak intern.
Gestructureerde outputs veranderen AI-antwoorden van onvoorspelbare tekst in betrouwbare data waar je applicaties op kunnen bouwen. Voor elke productie-usecase waarbij je consistente data-extractie nodig hebt, is deze feature essentieel.
Conclusie
We hebben geleerd hoe je via de uniforme API van OpenRouter toegang krijgt tot honderden AI-modellen, van je eerste request tot functies als streaming, reasoning tokens en gestructureerde outputs.
De automatische fallbacks en modelrouting van het platform zorgen dat je applicaties betrouwbaar blijven, zelfs als individuele providers problemen hebben. Met dezelfde codepatronen kunnen we modellen vergelijken, van provider wisselen en voor elke taak de beste keuze vinden zonder meerdere API-sleutels te beheren.
Begin met simpele requests en probeer gaandeweg meer features naarmate je behoeften groeien. Test verschillende modellen voor verschillende soorten taken — sommige werken beter voor creatief schrijven, andere zijn sterker in data-analyse of redeneerproblemen.
Met de kennis die je hier hebt opgedaan, kun je AI-applicaties bouwen die niet aan één provider vastzitten, zodat je vrij bent om mee te bewegen met nieuwe modellen en mogelijkheden.
Ik ben een contentmaker op het gebied van data science met meer dan 2 jaar ervaring en een van de grootste achterbannen op Medium. Ik schrijf graag diepgaande artikelen over AI en ML met een vleugje sarcasme, want je moet íets doen om ze wat minder droog te maken. Ik heb meer dan 130 artikelen en een DataCamp-cursus gemaakt, met nog een in de maak. Mijn content is door meer dan 5 miljoen ogen bekeken, van wie 20k mij is gaan volgen op zowel Medium als LinkedIn.

