Getting Started with the Gemini API in Vertex AI with cURL / REST API

Source notebook

Repo path: gemini/getting-started/intro_gemini_curl.ipynb · Open on GitHub · intro

Uses cURL to call Gemini 3.5 Flash on Vertex AI for text, chat, tools, multimodal, and JSON output.

Summary

This notebook teaches how to call the Vertex AI Gemini REST API directly with cURL. It walks through project setup, endpoint construction, text generation, streaming, model parameters, chat, function calling, multimodal image and video prompts, controlled JSON generation, Google Search grounding, and code execution.

Key code patterns

REST endpoint setup

MODEL_ID = "gemini-3.5-flash"
api_host = "aiplatform.googleapis.com"
if LOCATION != "global":
    api_host = f"{LOCATION}-aiplatform.googleapis.com"
API_ENDPOINT = f"{api_host}/v1/projects/{PROJECT_ID}/locations/{LOCATION}/publishers/google/models/{MODEL_ID}"

Builds the Vertex AI model endpoint for global or regional locations.

Text generation

curl -X POST \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H "Content-Type: application/json" \
  https://${API_ENDPOINT}:generateContent \
  -d '{"contents":{"role":"USER","parts":{"text":"Why is the sky blue?"}}}'

Shows the minimal REST request pattern for Gemini text output.

Streaming generation

curl -X POST \
  -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  -H "Content-Type: application/json" \
  https://${API_ENDPOINT}:streamGenerateContent \
  -d '{"contents":{"role":"USER","parts":{"text":"Why is the sky blue?"}}}'

Uses streamGenerateContent so response fragments can be processed before completion.

Function declarations

"tools": [{
  "function_declarations": [{
    "name": "find_theaters",
    "description": "find theaters based on location and optionally movie title",
    "parameters": {"type": "object", "properties": {"location": {"type": "string"}}}
  }]
}]

Passes function schemas so Gemini can return a functionCall.

Multimodal file input

"parts": [
  {"text": "Describe this image"},
  {"file_data": {
    "mime_type": "image/png",
    "file_uri": "gs://cloud-samples-data/generative-ai/image/320px-Felis_catus-cat_on_snow.jpg"
  }}
]

References Cloud Storage media with mime_type for image or video prompts.

Controlled JSON output

"generationConfig": {
  "response_mime_type": "application/json",
  "response_schema": {
    "type": "object",
    "properties": {"recipe_name": {"type": "string"}}
  }
}

Constrains model output to a declared JSON schema.

Google Search tool

"tools": {
  "google_search": {}
},
"generationConfig": {
  "response_modalities": "TEXT"
}

Lets Gemini decide when to use Google Search and returns grounding metadata.

Code execution tool

"contents": {
  "role": "user",
  "parts": {"text": "Calculate 20th fibonacci number. Then find the nearest palindrome to it."}
},
"tools": [{"code_execution": {}}]

Enables Gemini to generate and run Python code iteratively.

Models & APIs used

  • Models: gemini-3.5-flash
  • APIs / services: Vertex AI, Cloud Storage, Google Search

When to use this

Use this pattern when you need direct REST or cURL examples for Gemini on Vertex AI without a client SDK.

Gotchas & caveats

  • Requires an existing Google Cloud project with the Vertex AI API enabled.
  • Colab requires google.colab auth.authenticate_user; Vertex AI Workbench does not.
  • Requests use gcloud auth print-access-token for bearer authentication.
  • The notebook installs jq to parse REST responses.
  • Cloud Storage files used in prompts must be in the same Google Cloud project sending the request.
  • Inline image input requires base64 encoding and the correct mime_type.
  • Base64 flags differ between macOS and Linux.
  • The tutorial uses billable Vertex AI components.

Best practices

  • Set GOOGLE_CLOUD_PROJECT and GOOGLE_CLOUD_REGION before building the API endpoint.
  • Use the global aiplatform.googleapis.com host unless a regional location is configured.
  • Set generation parameters such as temperature, top_p, top_k, max_output_tokens, candidate_count, and stop_sequences deliberately.
  • Use safety_settings to configure harm blocking thresholds.
  • Specify role values for multi-turn chat content.
  • Provide explicit function names, descriptions, parameters, and required fields for function calling.
  • Specify mime_type for inline_data and file_data multimodal inputs.
  • Use response_schema with application/json for controlled generation.