Files
opencode-antigravity-auth/docs/ANTIGRAVITY_API_SPEC.md

14 KiB

Antigravity Unified Gateway API Specification

Version: 1.0 Last Updated: December 13, 2025 Status: Verified by Direct API Testing


Overview

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.

Key Characteristics

  • 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)

Endpoints

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

API Actions

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

Authentication

OAuth 2.0 Setup

Authorization URL: https://accounts.google.com/o/oauth2/auth
Token URL: https://oauth2.googleapis.com/token

Required Scopes

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

Required Headers

Authorization: Bearer {access_token}
Content-Type: application/json
User-Agent: antigravity/1.11.5 windows/amd64
X-Goog-Api-Client: google-cloud-sdk vscode_cloudshelleditor/0.1
Client-Metadata: {"ideType":"IDE_UNSPECIFIED","platform":"PLATFORM_UNSPECIFIED","pluginType":"GEMINI"}

For streaming requests, also include:

Accept: text/event-stream

Available Models

Model Name Model ID Type Status
Claude Sonnet 4.5 claude-sonnet-4-5 Anthropic Verified
Claude Sonnet 4.5 Thinking claude-sonnet-4-5-thinking Anthropic Verified
Claude Opus 4.5 Thinking claude-opus-4-5-thinking Anthropic Verified
Gemini 3 Pro High gemini-3-pro-high Google Verified
Gemini 3 Pro Low gemini-3-pro-low Google Verified
GPT-OSS 120B Medium gpt-oss-120b-medium Other Verified

Request Format

Basic Structure

{
  "project": "{project_id}",
  "model": "{model_id}",
  "request": {
    "contents": [...],
    "generationConfig": {...},
    "systemInstruction": {...},
    "tools": [...]
  },
  "userAgent": "antigravity",
  "requestId": "{unique_id}"
}

Contents Array (REQUIRED)

⚠️ IMPORTANT: Must use Gemini-style format. Anthropic-style messages array is NOT supported.

{
  "contents": [
    {
      "role": "user",
      "parts": [
        { "text": "Your message here" }
      ]
    },
    {
      "role": "model",
      "parts": [
        { "text": "Assistant response" }
      ]
    }
  ]
}

Role Values

  • user - Human/user messages
  • model - Assistant responses (NOT assistant)

Generation Config

{
  "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

System Instructions

⚠️ Must be an object with 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 / Function Calling

{
  "tools": [
    {
      "functionDeclarations": [
        {
          "name": "get_weather",
          "description": "Get weather for a location",
          "parameters": {
            "type": "object",
            "properties": {
              "location": {
                "type": "string",
                "description": "City name"
              }
            },
            "required": ["location"]
          }
        }
      ]
    }
  ]
}

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
// ❌ 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 Format

Non-Streaming Response

{
  "response": {
    "candidates": [
      {
        "content": {
          "role": "model",
          "parts": [
            { "text": "Response text here" }
          ]
        },
        "finishReason": "STOP"
      }
    ],
    "usageMetadata": {
      "promptTokenCount": 16,
      "candidatesTokenCount": 4,
      "totalTokenCount": 20
    },
    "modelVersion": "claude-sonnet-4-5",
    "responseId": "msg_vrtx_..."
  },
  "traceId": "abc123..."
}

Streaming Response (SSE)

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": "..."}

Response Fields

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

Response ID Formats

Model Type Format Example
Claude msg_vrtx_... msg_vrtx_01UDKZG8PWPj9mjajje8d7u7
Gemini Base64-like ypM9abPqFKWl0-kPvamgqQw
GPT-OSS Base64-like y5M9aZaSKq6z2roPoJ7pEA

Function Call Response

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"
      }
    ]
  }
}

Providing Function Results

{
  "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" } } }] }
  ]
}

Thinking / Extended Reasoning

Thinking Config

For thinking-capable models (*-thinking), use:

{
  "generationConfig": {
    "maxOutputTokens": 10000,
    "thinkingConfig": {
      "thinkingBudget": 8000,
      "includeThoughts": true
    }
  }
}

⚠️ IMPORTANT: maxOutputTokens must be GREATER than thinkingBudget

Thinking Response (Gemini)

Gemini models return thinking with signatures:

{
  "parts": [
    {
      "thoughtSignature": "ErADCq0DAXLI2nx...",
      "text": "Let me think about this..."
    },
    {
      "text": "The answer is..."
    }
  ]
}

Thinking Response (Claude)

Claude thinking models may include thought: true parts:

{
  "parts": [
    {
      "thought": true,
      "text": "Reasoning process...",
      "thoughtSignature": "..."
    },
    {
      "text": "Final answer..."
    }
  ]
}

Error Responses

Error Structure

{
  "error": {
    "code": 400,
    "message": "Error description",
    "status": "INVALID_ARGUMENT",
    "details": [...]
  }
}

Common Error Codes

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

Rate Limit Response

{
  "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"
      }
    ]
  }
}

NOT Supported

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)

Complete Request Example

{
  "project": "my-project-id",
  "model": "claude-sonnet-4-5",
  "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"
}

Response Headers

Header Description
x-cloudaicompanion-trace-id Trace ID for debugging
server-timing Request duration

Comparison: Antigravity vs Vertex AI Anthropic

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-5) Versioned (claude-4-5@date)
Response format candidates[] Anthropic content[]
Multi-model support Yes (Claude, Gemini, etc.) Anthropic only

Changelog

  • 2025-12-14: Added function calling quirks, JSON Schema support matrix, tool name rules
  • 2025-12-13: Initial specification based on direct API testing