Version: 1.0 Last Updated: December 13, 2025 Status: Verified by Direct API Testing
Antigravity is Google's Unified Gateway API for accessing multiple AI models (Claude, Gemini, GPT-OSS) through a single, consistent Gemini-style interface. It is NOT the same as Vertex AI's direct model APIs.
- Single API format for all models (Gemini-style)
- Project-based access via Google Cloud authentication
- Internal routing to model backends (Vertex AI for Claude, Gemini API for Gemini)
- Unified response format (
candidates[]structure for all models)
| Environment | URL | Status |
|---|---|---|
| Daily (Sandbox) | https://daily-cloudcode-pa.sandbox.googleapis.com |
✅ Active |
| Production | https://cloudcode-pa.googleapis.com |
✅ Active |
| Autopush (Sandbox) | https://autopush-cloudcode-pa.sandbox.googleapis.com |
❌ Unavailable |
| Action | Path | Description |
|---|---|---|
| Generate Content | /v1internal:generateContent |
Non-streaming request |
| Stream Generate | /v1internal:streamGenerateContent?alt=sse |
Streaming (SSE) request |
| Load Code Assist | /v1internal:loadCodeAssist |
Project discovery |
| Onboard User | /v1internal:onboardUser |
User onboarding |
Authorization URL: https://accounts.google.com/o/oauth2/auth
Token URL: https://oauth2.googleapis.com/token
https://www.googleapis.com/auth/cloud-platform
https://www.googleapis.com/auth/userinfo.email
https://www.googleapis.com/auth/userinfo.profile
https://www.googleapis.com/auth/cclog
https://www.googleapis.com/auth/experimentsandconfigs
Authorization: Bearer {access_token}
Content-Type: application/json
User-Agent: antigravity/1.15.8 windows/amd64
X-Goog-Api-Client: google-cloud-sdk vscode_cloudshelleditor/0.1
Client-Metadata: {"ideType":"ANTIGRAVITY","platform":"MACOS","pluginType":"GEMINI"}For streaming requests, also include:
Accept: text/event-stream| Model Name | Model ID | Type | Status |
|---|---|---|---|
| Claude Sonnet 4.6 | claude-sonnet-4-6 |
Anthropic | ✅ Verified |
| Claude Opus 4.6 Thinking | claude-opus-4-6-thinking |
Anthropic | ✅ Verified |
| Gemini 3 Pro High | gemini-3-pro-high |
✅ Verified | |
| Gemini 3 Pro Low | gemini-3-pro-low |
✅ Verified | |
| GPT-OSS 120B Medium | gpt-oss-120b-medium |
Other | ✅ Verified |
{
"project": "{project_id}",
"model": "{model_id}",
"request": {
"contents": [...],
"generationConfig": {...},
"systemInstruction": {...},
"tools": [...]
},
"userAgent": "antigravity",
"requestId": "{unique_id}"
}messages array is NOT supported.
{
"contents": [
{
"role": "user",
"parts": [
{ "text": "Your message here" }
]
},
{
"role": "model",
"parts": [
{ "text": "Assistant response" }
]
}
]
}user- Human/user messagesmodel- Assistant responses (NOTassistant)
{
"generationConfig": {
"maxOutputTokens": 1000,
"temperature": 0.7,
"topP": 0.95,
"topK": 40,
"stopSequences": ["STOP"],
"thinkingConfig": {
"thinkingBudget": 8000,
"includeThoughts": true
}
}
}| Field | Type | Description |
|---|---|---|
maxOutputTokens |
number | Maximum tokens in response |
temperature |
number | Randomness (0.0 - 2.0) |
topP |
number | Nucleus sampling threshold |
topK |
number | Top-K sampling |
stopSequences |
string[] | Stop generation triggers |
thinkingConfig |
object | Extended thinking config |
parts, NOT a plain string.
// ✅ CORRECT
{
"systemInstruction": {
"parts": [
{ "text": "You are a helpful assistant." }
]
}
}
// ❌ WRONG - Will return 400 error
{
"systemInstruction": "You are a helpful assistant."
}{
"tools": [
{
"functionDeclarations": [
{
"name": "get_weather",
"description": "Get weather for a location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City name"
}
},
"required": ["location"]
}
}
]
}
]
}Gemini models support Google Search grounding, but it cannot be combined with function declarations in the same request. This plugin implements a dedicated google_search tool that makes separate API calls.
The model can call google_search(query, urls?, thinking?) which:
- Makes a separate API call to Antigravity with only
{ googleSearch: {} }(no function declarations) - Parses the
groundingMetadatafrom the response - Returns formatted markdown with sources and citations
Tool Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
query |
string | ✅ | The search query or question |
urls |
string[] | ❌ | URLs to analyze (adds urlContext tool) |
thinking |
boolean | ❌ | Enable deep thinking (default: true) |
Example Response:
## Search Results
Spain won Euro 2024, defeating England 2-1 in the final...
### Sources
- [UEFA Euro 2024](https://uefa.com/...)
- [Al Jazeera](https://aljazeera.com/...)
### Search Queries Used
- "UEFA Euro 2024 winner"The underlying API uses these tool formats:
New API (Gemini 2.0+ / Gemini 3):
{
"tools": [
{ "googleSearch": {} }
]
}Legacy API (Gemini 1.5 only - deprecated):
{
"tools": [
{
"googleSearchRetrieval": {
"dynamicRetrievalConfig": {
"mode": "MODE_DYNAMIC",
"dynamicThreshold": 0.3
}
}
}
]
}Response includes groundingMetadata:
{
"groundingMetadata": {
"webSearchQueries": ["query1", "query2"],
"searchEntryPoint": { "renderedContent": "..." },
"groundingChunks": [{ "web": { "uri": "...", "title": "..." } }],
"groundingSupports": [{ "segment": {...}, "groundingChunkIndices": [...] }]
}
}Important:
googleSearchandurlContexttools cannot be combined withfunctionDeclarationsin the same request. This is why the plugin uses a separate API call.
### Function Name Rules
| Rule | Description |
|------|-------------|
| First character | Must be a letter (a-z, A-Z) or underscore (_) |
| Allowed characters | `a-zA-Z0-9`, underscores (`_`), dots (`.`), colons (`:`), dashes (`-`) |
| Max length | 64 characters |
| Not allowed | Slashes (`/`), spaces, other special characters |
**Examples:**
- ✅ `get_weather` - Valid
- ✅ `mcp:mongodb.query` - Valid (colons and dots allowed)
- ✅ `read-file` - Valid (dashes allowed)
- ❌ `mcp/query` - Invalid (slashes not allowed)
- ❌ `123_tool` - Invalid (must start with letter or underscore)
### JSON Schema Support
| Feature | Status | Notes |
|---------|--------|-------|
| `type` | ✅ Supported | `object`, `string`, `number`, `integer`, `boolean`, `array` |
| `properties` | ✅ Supported | Object properties |
| `required` | ✅ Supported | Required fields array |
| `description` | ✅ Supported | Field descriptions |
| `enum` | ✅ Supported | Enumerated values |
| `items` | ✅ Supported | Array item schema |
| `anyOf` | ✅ Supported | Converted to `any_of` internally |
| `allOf` | ✅ Supported | Converted to `all_of` internally |
| `oneOf` | ✅ Supported | Converted to `one_of` internally |
| `additionalProperties` | ✅ Supported | Additional properties schema |
| `const` | ❌ NOT Supported | Use `enum: [value]` instead |
| `$ref` | ❌ NOT Supported | Inline the schema instead |
| `$defs` / `definitions` | ❌ NOT Supported | Inline definitions instead |
| `$schema` | ❌ NOT Supported | Strip from schema |
| `$id` | ❌ NOT Supported | Strip from schema |
| `default` | ❌ NOT Supported | Strip from schema |
| `examples` | ❌ NOT Supported | Strip from schema |
| `title` (nested) | ⚠️ Caution | May cause issues in nested objects |
**⚠️ IMPORTANT:** The following features will cause a 400 error if sent to the API:
- `const` - Convert to `enum: [value]` instead
- `$ref` / `$defs` - Inline the schema definitions
- `$schema` / `$id` - Strip these metadata fields
- `default` / `examples` - Strip these documentation fields
```json
// ❌ WRONG - Will return 400 error
{ "type": { "const": "email" } }
// ✅ CORRECT - Use enum instead
{ "type": { "enum": ["email"] } }
Note: The plugin automatically handles these conversions via the schema-transform.ts module.
{
"response": {
"candidates": [
{
"content": {
"role": "model",
"parts": [
{ "text": "Response text here" }
]
},
"finishReason": "STOP"
}
],
"usageMetadata": {
"promptTokenCount": 16,
"candidatesTokenCount": 4,
"totalTokenCount": 20
},
"modelVersion": "claude-sonnet-4-6",
"responseId": "msg_vrtx_..."
},
"traceId": "abc123..."
}Content-Type: text/event-stream
data: {"response": {"candidates": [{"content": {"role": "model", "parts": [{"text": "Hello"}]}}], "usageMetadata": {...}, "modelVersion": "...", "responseId": "..."}, "traceId": "..."}
data: {"response": {"candidates": [{"content": {"role": "model", "parts": [{"text": " world"}]}, "finishReason": "STOP"}], "usageMetadata": {...}}, "traceId": "..."}
| Field | Description |
|---|---|
response.candidates |
Array of response candidates |
response.candidates[].content.role |
Always "model" |
response.candidates[].content.parts |
Array of content parts |
response.candidates[].finishReason |
STOP, MAX_TOKENS, OTHER |
response.usageMetadata.promptTokenCount |
Input tokens |
response.usageMetadata.candidatesTokenCount |
Output tokens |
response.usageMetadata.totalTokenCount |
Total tokens |
response.usageMetadata.thoughtsTokenCount |
Thinking tokens (Gemini) |
response.modelVersion |
Actual model used |
response.responseId |
Request ID (format varies by model) |
traceId |
Trace ID for debugging |
| Model Type | Format | Example |
|---|---|---|
| Claude | msg_vrtx_... |
msg_vrtx_01UDKZG8PWPj9mjajje8d7u7 |
| Gemini | Base64-like | ypM9abPqFKWl0-kPvamgqQw |
| GPT-OSS | Base64-like | y5M9aZaSKq6z2roPoJ7pEA |
When the model wants to call a function:
{
"response": {
"candidates": [
{
"content": {
"role": "model",
"parts": [
{
"functionCall": {
"name": "get_weather",
"args": {
"location": "Paris"
},
"id": "toolu_vrtx_01PDbPTJgBJ3AJ8BCnSXvUqk"
}
}
]
},
"finishReason": "OTHER"
}
]
}
}{
"contents": [
{ "role": "user", "parts": [{ "text": "What's the weather?" }] },
{ "role": "model", "parts": [{ "functionCall": { "name": "get_weather", "args": {...}, "id": "..." } }] },
{ "role": "user", "parts": [{ "functionResponse": { "name": "get_weather", "id": "...", "response": { "temperature": "22C" } } }] }
]
}For thinking-capable models (*-thinking), use:
{
"generationConfig": {
"maxOutputTokens": 10000,
"thinkingConfig": {
"thinkingBudget": 8000,
"includeThoughts": true
}
}
}maxOutputTokens must be GREATER than thinkingBudget
Gemini models return thinking with signatures:
{
"parts": [
{
"thoughtSignature": "ErADCq0DAXLI2nx...",
"text": "Let me think about this..."
},
{
"text": "The answer is..."
}
]
}Claude thinking models may include thought: true parts:
{
"parts": [
{
"thought": true,
"text": "Reasoning process...",
"thoughtSignature": "..."
},
{
"text": "Final answer..."
}
]
}{
"error": {
"code": 400,
"message": "Error description",
"status": "INVALID_ARGUMENT",
"details": [...]
}
}| Code | Status | Description |
|---|---|---|
| 400 | INVALID_ARGUMENT |
Invalid request format |
| 401 | UNAUTHENTICATED |
Invalid/expired token |
| 403 | PERMISSION_DENIED |
No access to resource |
| 404 | NOT_FOUND |
Model not found |
| 429 | RESOURCE_EXHAUSTED |
Rate limit exceeded |
{
"error": {
"code": 429,
"message": "You have exhausted your capacity on this model. Your quota will reset after 3s.",
"status": "RESOURCE_EXHAUSTED",
"details": [
{
"@type": "type.googleapis.com/google.rpc.RetryInfo",
"retryDelay": "3.957525076s"
}
]
}
}The following Anthropic/Vertex AI features are NOT supported:
| Feature | Error |
|---|---|
anthropic_version |
Unknown field |
messages array |
Unknown field |
max_tokens |
Unknown field |
Plain string systemInstruction |
Invalid value |
system_instruction (snake_case at root) |
Unknown field |
JSON Schema const |
Unknown field (use enum: [value]) |
JSON Schema $ref |
Not supported (inline instead) |
JSON Schema $defs |
Not supported (inline instead) |
Tool names with / |
Invalid (use _ or : instead) |
| Tool names starting with digit | Invalid (must start with letter/underscore) |
{
"project": "my-project-id",
"model": "claude-sonnet-4-6",
"request": {
"contents": [
{
"role": "user",
"parts": [
{ "text": "Hello, how are you?" }
]
}
],
"systemInstruction": {
"parts": [
{ "text": "You are a helpful assistant." }
]
},
"generationConfig": {
"maxOutputTokens": 1000,
"temperature": 0.7
}
},
"userAgent": "antigravity",
"requestId": "agent-abc123"
}| Header | Description |
|---|---|
x-cloudaicompanion-trace-id |
Trace ID for debugging |
server-timing |
Request duration |
| Feature | Antigravity | Vertex AI Anthropic |
|---|---|---|
| Endpoint | cloudcode-pa.googleapis.com |
aiplatform.googleapis.com |
| Request format | Gemini-style contents |
Anthropic messages |
anthropic_version |
Not used | Required |
| Model names | Simple (claude-sonnet-4-6) |
Versioned (claude-4-5@date) |
| Response format | candidates[] |
Anthropic content[] |
| Multi-model support | Yes (Claude, Gemini, etc.) | Anthropic only |
- 2025-12-14: Added function calling quirks, JSON Schema support matrix, tool name rules
- 2025-12-13: Initial specification based on direct API testing