One endpoint, every Gemini interaction
Whether you're sending text, an image, a tool call, or a JSON-mode request, you're hitting the same endpoint: generateContent. The streaming variant is streamGenerateContent?alt=sse. Memorize the shape and the rest of Gemini stops feeling like memorization.
Request structure
A request has up to four top-level fields:
contents— the conversation. List of{role, parts}objects. Roles are"user"and"model". There is no"system"role.system_instruction— a separate top-level field for the system prompt. This is where the "you are an X" goes.generationConfig— temperature, top-p, top-k, max output tokens, response MIME type, seed.safetySettings— per-category thresholds for harm filtering.
Parts are the atoms
Inside a content's parts array, each part is one of:
- Text —
{"text": "..."} - Inline data —
{"inline_data": {"mime_type": "image/png", "data": "base64..."}} - File data —
{"file_data": {"file_uri": "files/abc"}}(after upload via the File API) - Function call —
{"function_call": {"name": "...", "args": {...}}}(model output) - Function response —
{"function_response": {"name": "...", "response": {...}}}(your tool result)
One content can hold multiple parts in its parts array — that's how you send "describe this image" + the image itself in a single user turn.
Response shape
The response wraps the model's output in candidates (almost always one) and tells you why generation stopped via finishReason: STOP (clean end), MAX_TOKENS (you ran out of budget), SAFETY (filtered), RECITATION (training data echo), or OTHER (you don't want to see this one).