Aan de slag met de Grok 4 API
Voor we onze eerste gebruikersaanvraag doen, hebben we een API-sleutel nodig en een Python-omgeving die verbinding kan maken met de Grok API.
Je API-sleutel aanmaken
Volg deze stappen om een API-sleutel te maken waarmee je de client bij de API kunt authenticeren:
- Bezoek de officiële xAI-documentatiesite.
- Log in met je X-, xAI- of Google-account. Heb je nog geen account, dan kun je een nieuw xAI-account aanmaken.
- Zoek de optie “Create an API key”. Voer een naam in voor je sleutel en klik op “save”.
- Zodra je sleutel verschijnt, kopieer je hem meteen. Je kunt hem later niet opnieuw bekijken, maar je kunt altijd een nieuwe genereren indien nodig.
- Maak in je projectmap een bestand met de naam .env. Plak je API-sleutel erin, in dit formaat:
XAI_API_KEY=<your_api_key_here>
Grok 4 API-prijzen
Hoewel het gebruik van de API goedkoper kan zijn dan een premiumabonnement, is het niet gratis. In tegenstelling tot het SuperGrok-abonnement, dat begint bij $30 per maand voor een vast bedrag, zijn de API-kosten volledig gebaseerd op je verbruik. Wil je echter toegang tot Grok 4 Heavy, dan werkt het anders: je hebt een actief SuperGrok Heavy-abonnement nodig ($300 per maand), ook wanneer je de API gebruikt.
Voor een gedetailleerd kostenoverzicht, bekijk de prijspagina op xAI.

Bron: xAI
De prijs van de Grok API is gebaseerd op gebruik, gemeten per miljoen tokens. Ter referentie: een miljoen tokens staat ongeveer gelijk aan 750.000 Engelse woorden, als input of output. Hoewel de grootte van het contextvenster bijna verdubbeld is ten opzichte van zijn voorganger, is Grok 4 exact even geprijsd als het standaard Grok 3-model. Je betaalt $3 per miljoen inputtokens en $15 per miljoen outputtokens.
Om toegang tot de API te krijgen, moet je credits kopen. Als je net begint, is het verstandig om prepaid credits te gebruiken in plaats van automatische facturatie—zo voorkom je verrassingen op je rekening. Je kunt tokens kopen en je gebruik volgen in de xAI-console, onder Invoices > Credits.
Python-omgeving instellen
Als je je API-sleutel en credits klaar hebt, is de volgende stap je Python-omgeving voorbereiden. Je hebt twee pakketten nodig voor een soepele API-integratie:
python-dotenvom je API-sleutel uit het.env-bestand te laden als omgevingsvariabele.- De
openai-client om met de Grok 4 API te communiceren.
Om je projectafhankelijkheden schoon te houden, is het een goed idee om Anaconda te gebruiken. Na het installeren van Anaconda maak je een nieuwe omgeving grok4 met Python 3.10 met:
conda create -n grok4 python=3.10
conda activate grok4
Met je omgeving actief, installeer je de benodigde pakketten:
pip install python-dotenv openai
Laatste voorbereidingen
Laten we beginnen met het schrijven van ons eerste script. Importeer eerst de benodigde functies uit de geïnstalleerde pakketten, plus os om je API-sleutel te benaderen:
import os
from dotenv import load_dotenv
from openai import OpenAI
Gebruik vervolgens load_dotenv() uit het dotenv-pakket om je omgevingsvariabelen te laden, zodat je API-sleutel beschikbaar is voor het script:
# Load environment variables
load_dotenv()
Initialiseer nu de API-client door je API-sleutel (uit het .env-bestand) en de Grok-server-URL door te geven aan de OpenAI-klasse (we gebruiken in deze tutorial de OpenAI SDK, maar Grok 4 heeft ook een native xAI Python SDK, en is ook compatibel met de SDK van Antrhopic). Wijs dit toe aan de variabele client:
client = OpenAI(
api_key=os.getenv("XAI_API_KEY"),
base_url="https://api.x.ai/v1",
)
Met deze stappen is je script klaar om verzoeken naar Grok 4 te sturen.
Beeldherkenning met Grok 4
Nu we alles hebben klaargezet, testen we beeldherkenning—een van Grok 4's nieuwe features. We laten dit zien door de onderstaande foto van een vegetarische lasagne te uploaden en Grok te vragen de zichtbare ingrediënten te identificeren.

Om een afbeelding te analyseren met de Grok 4 API, sturen we een request met zowel een afbeelding als een prompt. De aanbevolen manier is een OpenAI-compatibele Pythonclient te gebruiken, het model in te stellen op grok-4 en de afbeeldings-URL en je vraag op te nemen in de messages-array. De API retourneert een gedetailleerde beschrijving van de inhoud van de afbeelding, die je uit het response-object kunt halen.
Voordat we het verzoek versturen, moeten we controleren of de afbeelding aan de API-vereisten voldoet. Alleen JPEG- en PNG-formaten worden ondersteund, en de bestandsgrootte mag niet groter zijn dan 20 MB. De afbeelding moet via een directe link toegankelijk zijn en de server moet de juiste Content-Type-header sturen (image/jpeg of image/png).
Na het importeren van de benodigde pakketten, het laden van je omgevingsvariabelen en het instellen van de client, kunnen we onze vraag zo versturen:
# Sending the query
response = client.chat.completions.create(
model="grok-4",
messages=[
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {
"url": "https://shorturl.at/mVDEh",
"detail": "high"
}
},
{
"type": "text",
"text": "Which ingredients do you notice on the picture?"
}
]
}
],
max_tokens=2000,
temperature=0.2, # lower temperature for more deterministic answers
)
# Print the response
print(response.choices[0].message.content)
Based on the picture, it looks like a delicious slice of vegetarian lasagna! Here's what I can clearly see in terms of ingredients (I'm basing this purely on visual cues, so it's not a full recipe—just what's noticeable):
### Main Visible Ingredients:
- **Pasta sheets/lasagna noodles**: The flat, layered pasta that's the base structure of the dish.
- **Tomato sauce**: A red, chunky sauce (likely marinara or similar) that's spread between layers and on top.
- **Cheese**:
- Melted, bubbly cheese on top (probably mozzarella or Parmesan, given the golden-brown spots).
- White, creamy cheese in the filling layers (looks like ricotta or cottage cheese).
- **Spinach (or similar greens)**: Dark green leaves mixed into the layers, giving it a veggie-packed look (this seems like a spinach lasagna variant).
- **Basil leaf**: A fresh green leaf garnishing the top for decoration and flavor.
It doesn't appear to have any meat (like ground beef or sausage), so it's likely a vegetarian version. If this is from a specific recipe or if you have more context, I could refine my observations! What do you think it is? 😊
In dit geval herkende Grok zelfs dat het een vegetarische variant is, puur op basis van de foto—best indrukwekkend!
Redeneren met Grok 4
Grok 4 is ontworpen voor geavanceerd redeneren en kan complexe problemen stap voor stap oplossen. In tegenstelling tot sommige eerdere modellen geeft Grok 4 zijn interne redeneertracering niet prijs, dus je kunt geen gedetailleerd “denkproces” of chain-of-thought als apart veld uit de API-response halen. De output die je ontvangt is het eindantwoord, niet de tussenstappen of ruwe redeneerinhoud.
Daarnaast ondersteunt Grok 4 de parameter reasoning_effort niet meer, zoals bijvoorbeeld in Grok 3 mini (wil je leren hoe je die parameter gebruikt, bekijk dan deze Grok 3 API-tutorial). Je kunt dus niet instellen hoeveel “denktijd” het model neemt voordat het een conclusie trekt. Elke redeneervraag wordt daarom exact hetzelfde opgebouwd als een normale vraag.
Laten we Grok testen met nog een lasagnegerelateerde redeneertaak en het vragen om zijn redenering in de output te tonen.
# Send a basic reasoning query
response = client.chat.completions.create(
model="grok-4",
messages=[
{"role": "user", "content": (
"You want to cook lasagna for a dinner party, but several guests have dietary restrictions. One is vegetarian, one is lactose-intolerant, and another cannot eat gluten. You have six different lasagna recipes (classic, vegetarian, vegan, gluten-free, cheese-heavy, and meat-based). Which recipe or combination of recipes would best satisfy everyone, and what specific ingredient substitutions would you need to make? Explain your reasoning step by step."
)}
],
max_tokens=5000,
temperature=0.2, # lower randomness
)
# Print the final answer
print(response.choices[0].message.content)
Below, I'll explain my reasoning step by step for selecting the best recipe (or combination of recipes) to satisfy all guests at your dinner party, including the vegetarian, the lactose-intolerant person, the gluten-intolerant person, and everyone else (who presumably have no restrictions). I'll base this on logical inferences about what each recipe likely contains, since the problem doesn't provide exact ingredient lists. Then, I'll recommend specific ingredient substitutions and why this approach works.
(...)
### Step 3: Selecting the Best Recipe or Combination
- **Recommended approach**: Use a **combination of the vegan and gluten-free recipes** to create a single modified lasagna that everyone can eat. Start with the vegan recipe as your base (it already handles no meat and no lactose/dairy), then incorporate elements from the gluten-free recipe (e.g., ingredient swaps to eliminate gluten). This results in a **vegan, gluten-free lasagna**.
- Why not multiple lasagnas? Preparing separate dishes (e.g., one vegetarian, one gluten-free) could work but might not fully satisfy everyone in a shared meal—e.g., the lactose-intolerant guest couldn't eat a dairy-based vegetarian version. A single inclusive dish promotes unity at the party and simplifies cooking/serving. If you have time and oven space, you could make a small "classic" version on the side for unrestricted guests who prefer meat and cheese, but the modified vegan/gluten-free one would still be the core option.
- Why this combination over others? Vegan + gluten-free covers all restrictions without needing to add meat or dairy (which would violate rules). Starting with gluten-free and making it vegan would require more substitutions (e.g., removing meat and cheese), while vegan is already "80% there." Other combos (e.g., vegetarian + gluten-free) would still need dairy removals for lactose intolerance, making them less efficient.
This approach ensures:
- The vegetarian can eat it (no meat).
- The lactose-intolerant can eat it (no dairy/lactose).
- The gluten-intolerant can eat it (no gluten).
- Others can eat it (it's still a flavorful lasagna, though it won't have "real" meat or cheese—unrestricted guests might find it less indulgent, but it's a fair compromise).
(...)
Ik heb Groks antwoord ingekort om de kernpunten te benadrukken, maar zelfs in deze kortere versie is duidelijk dat het model zijn werk goed deed. Grok ging stap voor stap te werk om
- De dieetrestricties te begrijpen
- De beschikbare recepten te evalueren
- De beste receptencombinatie te kiezen
- Specifieke ingrediëntvervangers voor te stellen
- Een volledige aangepaste receptopzet te geven
- Terug te koppelen waarom dit iedereen tevredenstelt
- Mogelijke nadelen en alternatieven te bespreken
Function calling met Grok 4
Net als zijn voorganger ondersteunt Grok 4 function calling. Daarmee kan het model direct met externe tools en diensten communiceren. Grok is dus niet beperkt tot het genereren van tekst—het kan ook acties uitvoeren zoals weerupdates ophalen, evenementtijden controleren, databaserijen analyseren of zelfs slimme apparaten bedienen.
Wanneer je een verzoek indient, kan Grok bepalen of het extra data nodig heeft en vragen om een specifieke functie aan te roepen met de juiste parameters. De Pythonclient voert deze functie lokaal uit, stuurt het resultaat terug naar Grok en vervolgens krijg jij een compleet, goed onderbouwd antwoord.
Voorbereiding
Om met function calling te werken, importeren we het pakket json, waarmee we bij de argumentstructuur kunnen van elke functie die Grok aanroept. Daarna definiëren we een callbackfunctie die Grok zal aanroepen wanneer het specifieke data nodig heeft.
In dit voorbeeld is de functie suggest_lasagna_recipe een eenvoudige Pythonfunctie die een vaste receptsuggestie teruggeeft. Deze hardcoded aanpak houdt de demo simpel en voorkomt afhankelijkheid van externe diensten.
import json
# Define the callback function
def suggest_lasagna_recipe(ingredients: list) -> dict:
# Very simplified logic for demo purposes
if "zucchini" in ingredients:
return {"recipe": "Vegetarian Zucchini Lasagna"}
if "beef" in ingredients:
return {"recipe": "Classic Beef Lasagna"}
if "tofu" in ingredients:
return {"recipe": "Vegan Tofu Lasagna"}
return {"recipe": "Basic Cheese Lasagna"}
We moeten ook de tool definiëren die Grok kan aanroepen. Dat houdt in dat je de naam, het doel en de vereiste parameters van de tool specificeert in een JSON-schema. Dit schema stuur je mee met je request, zodat Grok weet dat het deze tool kan gebruiken als er extra informatie nodig is voor de redenering.
# Define the JSON schema for the tool
tools = [
{
"type": "function",
"function": {
"name": "suggest_lasagna_recipe",
"description": "Suggests a lasagna recipe based on available ingredients.",
"parameters": {
"type": "object",
"properties": {
"ingredients": {
"type": "array",
"items": {"type": "string"},
"description": "List of available ingredients"
}
},
"required": ["ingredients"]
}
}
}
]
Tot slot koppelt het woordenboek tools_map de functienamen die Grok gebruikt aan de daadwerkelijke Pythonfuncties in je code. Dankzij deze mapping kan de client de gevraagde functieaanroepen correct uitvoeren.
# link the function names to the functions
tools_map = {
"suggest_lasagna_recipe": suggest_lasagna_recipe
}
Handmatig toolschema’s definiëren werkt prima voor kleine projecten, maar naarmate je project groeit is een datavalidatiebibliotheek zoals Pydantic sterk aan te raden. Pydantic valideert functie-invoer automatisch, verbetert foutafhandeling en resulteert in schonere, beter onderhoudbare code.
Uitvoering
Laten we kijken of Grok onze functie gebruikt wanneer we om een lasagnerecept vragen. Zo verloopt de function-callingworkflow:
- We sturen eerst een gebruikersvraag—“Which lasagna can I make, given my ingredients?”—naar Grok, samen met de beschikbare
tools. - Grok bekijkt vervolgens het verzoek en vraagt, als een functieaanroep nodig is, om het recept door onze lokale functie te triggeren. Als er geen tool call is, gebruiken we gewoon Groks eerste antwoord.
- Wanneer een tool call wordt aangevraagd, draaien we de bijbehorende lokale functie en voegen we het resultaat toe aan de lopende gespreksgeschiedenis.
- Deze bijgewerkte geschiedenis sturen we terug naar Grok, zodat het de redenering kan afronden en een definitief, contextueel antwoord kan geven.
# Step 1: Send the initial user request
messages = [
{"role": "user", "content": "I have beef, ricotta, and tomato sauce. Which lasagna can I make?"}
]
response = client.chat.completions.create(
model="grok-4",
messages=messages,
tools=tools,
tool_choice="auto",
)
# Step 2: Check if a tool call was requested
tool_calls = getattr(response.choices[0].message, "tool_calls", [])
if tool_calls:
for tool_call in tool_calls:
function_name = tool_call.function.name
print(f"{function_name} successfully called")
function_args = json.loads(tool_call.function.arguments)
# Find and call the matching local function
if function_name in tools_map:
function_result = tools_map[function_name](**function_args)
# Step 3: Add the function result back to the message history
messages.append(response.choices[0].message) # Assistant's tool call message
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": json.dumps(function_result)
})
# Step 4: Send a new request including the tool response
final_response = client.chat.completions.create(
model="grok-4",
messages=messages,
tools=tools,
tool_choice="auto"
)
# Print the final answer
print("\nFinal Answer:")
print(final_response.choices[0].message.content)
else:
# No tool call: respond directly
print("\nNo tool call was requested. Final Answer:")
print(response.choices[0].message.content)
suggest_lasagna_recipe successfully called
Final Answer:
Based on your available ingredients (beef, ricotta, and tomato sauce), you can make a **Classic Beef Lasagna**! (...)
Zoals we zien, riep Grok onze functie aan en stelde het bijbehorende recept voor.
Je ziet misschien ook het argument tool_choice in het eerste verzoek. Standaard laat “auto” Grok beslissen of en welke functie wordt aangeroepen. Wil je meer controle, dan kun je een specifieke functieaanroep forceren, exact aangeven welke functie gebruikt moet worden, of function calling helemaal uitschakelen door deze parameter aan te passen.
Gestructureerde output met Grok 4
Net als function calling zijn gestructureerde outputs een feature die met Grok 3 werd geïntroduceerd. Ze laten Grok antwoorden leveren in een strikt formaat zoals JSON in plaats van platte tekst. Dit maakt het veel eenvoudiger om de reacties van het model te parsen, te valideren en te gebruiken in je applicaties of workflows.
Door vooraf een schema op te zetten, weet je zeker dat Groks outputs consistent, machineleesbaar en klaar voor verdere verwerking zijn. Dit is vooral handig wanneer je gestructureerde data uit documenten moet halen of AI-gegenereerde content direct in databases, dashboards of automatiseringstools wilt stoppen, zonder gedoe met onbetrouwbare tekstparsing.
Voor het definiëren van het outputschema gebruiken we Pydantic, wat het structureren van complexe data eenvoudiger en leesbaarder maakt (deze Pydantic-tutorial helpt je op weg). Hiervoor importeer je zowel BaseModel als Field uit pydantic. Omdat onze output een lijst met ingrediënten bevat, importeren we ook List uit de typing-module van Python om het type van elk lijstelement duidelijk te specificeren.
We zouden het schema in puur JSON kunnen opzetten, maar Grok geeft soms output die niet exact overeenkomt met de verwachte structuur. De strekking kan hetzelfde zijn, maar het schema kan afwijken, wat problemen oplevert als je applicatie een specifiek formaat vereist—zeker bij geneste elementen zoals lijsten. Daarom raad ik Pydantic aan: zo wordt de gestructureerde output elke keer betrouwbaar gevalideerd en geparsed.
In ons voorbeeld bevat het schema—Recipe—de naam, het aantal porties en een ingrediëntenlijst. Elk Ingredient wordt gedefinieerd door de naam, de hoeveelheid die het recept nodig heeft, beschikbaarheid, prijs per kilogram, en of het ingrediënt vegetarisch, vegan of glutenvrij is. Het is handig om standaardwaarden in het schema zelf te zetten, zoals we doen voor het aantal porties.
# import additionally needed packages
from pydantic import BaseModel, Field
from typing import List
# Define the schema for the structured output
class Ingredient(BaseModel):
name: str = Field(description="Name of the ingredient")
amount: int = Field(description="Amount in g needed for recipe")
is_at_home: bool = Field(description="Is the item already at home?")
price: float = Field(description="Price of the ingredient in USD per kg")
is_vegetarian: bool = Field(description="Is the ingredient vegetarian?")
is_vegan: bool = Field(description="Is the ingredient vegan?")
is_gluten_free: bool = Field(description="Is the ingredient gluten-free?")
class Recipe(BaseModel):
name: str = Field(description="The name of the recipe")
portions: int = Field(default=4, description="Amount of portions")
ingredients: List[Ingredient] = Field(description="List of ingredients for the recipe")
Houd bij het verzoek doen een paar details in gedachten. In plaats van client.chat.completions.create() gebruiken we client.beta.chat.completions.parse(). Daarmee geef je aan dat we de output in een specifiek formaat verwachten, en ons Recipe-schema wordt meegegeven als het argument response_format.
Het is ook handig om alle kerninstructies voor de taak in de systemprompt te plaatsen. Zo blijft Grok 4 gefocust en consistent gedurende het gesprek. Omdat het schema apart is gedefinieerd, kan de userprompt zich richten op de taak zelf, zonder de vereiste velden voor de JSON-output op te sommen.
Je kunt Grok bijvoorbeeld de rol van Italiaanse chef laten spelen, zodat alle recepten die het oplevert authentiek Italiaans zijn—zo komt er zeker geen ananas op je pizza!
# Send a prompt and request structured output
completion = client.beta.chat.completions.parse(
model="grok-4",
messages=[
{"role": "system", "content": (
"You are a master chef specialized in italian cuisine."
"When asked about recipes, return the output in structured JSON format following the provided schema, without any extra text."
)},
{"role": "user", "content": (
"I have beef, ricotta, and tomato sauce, and want to cook for 4 persons. Which lasagna can I make?"
)}
],
response_format=Recipe,
)
Zodra we Grok 4’s gestructureerde output hebben geparsed, worden de voordelen ten opzichte van platte tekst duidelijk. We kunnen de informatie gemakkelijk herschikken en aanpassen aan onze behoefte, of zelfs specifieke datapunten direct in geautomatiseerde workflows stoppen. In ons voorbeeld betekent dit dat we snel de ingrediëntenprijzen per kilogram kunnen vermenigvuldigen met de benodigde hoeveelheden, kosten kunnen optellen op basis van wat al in de voorraadkast ligt en de uiteindelijke prijs per portie kunnen berekenen in een paar stappen.
# Access the parsed result
recipe = completion.choices[0].message.parsed
price = 0 # initialize price variable
print(f"Recipe: {recipe.name}")
print("Ingredients:")
for i in recipe.ingredients:
print("- " + i.name + " " + str(i.amount) + " g")
if not i.is_at_home:
price += (i.price * i.amount / 1000)
print(f"Price per portion: USD {round((price/recipe.portions), 2)}")
Recipe: Classic Beef Lasagna
Ingredients:
- Ground beef 500 g
- Ricotta cheese 400 g
- Tomato sauce 800 g
- Lasagna noodles 300 g
- Mozzarella cheese 300 g
- Parmesan cheese 100 g
- Onion 200 g
- Garlic 20 g
- Olive oil 30 g
- Egg 50 g
Price per portion: USD 1.7625
Conclusie
Grok 4 brengt nieuwe features zoals een groter contextvenster en betere redeneercapaciteiten. De beeldherkenning en function calling openen interessante mogelijkheden om AI te combineren met real-world data en acties, terwijl gestructureerde output zorgt voor betrouwbare, machineleesbare antwoorden. De API-setup is rechttoe rechtaan, zodat je met slechts een paar dependencies snel kunt integreren in je Pythonprojecten.
En als al die lasagnevoorbeelden je trek hebben gegeven, dan ben je niet de enige—ik ga zelf misschien ook even een stukje pakken!

Vorige week bracht xAI de langverwachte update van Grok uit. Net als in eerdere versies is het hoofdmodel gemakkelijk toegankelijk via de API.
In deze tutorial leg ik uit wat Grok 4 biedt en hoe je aan de slag gaat met de Grok 4 API. We halen het meeste uit de geavanceerde features zoals beeldverwerking, function calling en gestructureerde output.
We houden onze lezers op de hoogte van het laatste AI-nieuws met The Median, onze gratis vrijdagse nieuwsbrief die de belangrijkste verhalen van de week samenvat. Abonneer je en blijf scherp in een paar minuten per week:
Wat is er nieuw aan Grok 4?
Grok 4 is het nieuwste LLM van xAI, ontworpen voor geavanceerd redeneren en probleemoplossing. In tegenstelling tot zijn voorganger werkt Grok 4 uitsluitend als een reasoning-model—er is geen niet-reasoningmodus beschikbaar. De parameter
reasoning_effort, waarmee je eerder kon instellen hoeveel “denktijd” het model nam voor het antwoord, is verwijderd.Er zijn twee hoofdvarianten: Grok 4 en Grok 4 Heavy. Grok 4 Heavy is de high-performance, multi-agentvariant die meerdere AI-agents parallel laat draaien om de nauwkeurigheid te verhogen en hallucinaties te verminderen. Daardoor is het bijzonder krachtig voor complexe analytische taken en kritieke toepassingen. Toegang tot Grok 4 Heavy is beperkt—je hebt een actief SuperGrok Heavy-abonnement nodig om het te gebruiken, ook via de API.
Het contextvenster is bijna verdubbeld, van 131.072 tokens in Grok 3 naar 256.000, waardoor het veel langere documenten en gesprekken kan verwerken en onthouden dan voorheen—geschikt voor veeleisende toepassingen.
Wil je meer lezen over features en benchmarks, dan raad ik deze blog over Grok 4 and the latest on Grok 4.1. Als je liever een video-overzicht bekijkt, check dan zeker deze video: