OpenAI-compatible REST API in pure PHP (built-in web server + cURL)
Base URL: http://localhost:3000This is a pure-PHP rewrite of the veoaifree.com proxy with no Composer dependencies. A single index.php acts as both the router and the front controller: it serves the static frontend from public/ and exposes an OpenAI-compatible /v1 API.
| Model ID | Display name | Provider |
|---|---|---|
claude-sonnet | Claude Sonnet 5 | Anthropic |
gpt-terra | GPT-5.6 Terra | OpenAI |
gemini | Gemini 3.1 Pro | |
gemini_pro | Gemini 3.7 Flash | |
kimi | Kimi K3 | Moonshot |
glm | GLM 5.2 | Zhipu |
grok | Grok 4.5 | xAI |
nemotron | Nemotron 3 Ultra | NVIDIA |
Requirements: PHP 8+ with the cURL extension enabled.
# 1. Copy the example config
cp .env.example .env # fill in VEO_EMAIL / VEO_PASSWORD (optional) and API_KEY (optional)
# 2. Boot the built-in PHP web server
php -S localhost:3000 index.php
Open http://localhost:3000 for the chat UI, or http://localhost:3000/docs.html for this page.
Optional, controlled by the API_KEY in .env.
# If API_KEY is set, every /v1 request needs this header:
Authorization: Bearer your_secret_api_key
Lists all available model IDs.
{ "object": "list", "data": [{ "id": "claude-sonnet", "object": "model", "created": 1788084659, "owned_by": "veoaifree" }] }
Generate a reply with the selected model. Supports streaming and non-streaming.
| Field | Type | Required | Description |
|---|---|---|---|
model | string | optional | Model ID. Defaults to gpt-terra. |
messages | array | yes | {role, content}; roles user/assistant. |
stream | boolean | optional | true for SSE streaming. |
web_search | boolean | optional | Deep Search. Defaults to true; set false to disable. |
curl -X POST http://localhost:3000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet",
"messages": [{ "role": "user", "content": "Hello!" }],
"stream": false
}'
{
"id": "chatcmpl-abc123",
"object": "chat.completion",
"created": 1788084712,
"model": "claude-sonnet",
"choices": [{ "index": 0, "message": { "role": "assistant", "content": "Hi!" }, "finish_reason": "stop" }]
}
Set stream: true to receive a Server-Sent Events stream ending in [DONE].
data: {"id":"chatcmpl-x","object":"chat.completion.chunk","created":1788,"model":"gemini_pro","choices":[{"index":0,"delta":{"content":"A "},"finish_reason":null}]}
data: {"id":"chatcmpl-x","object":"chat.completion.chunk","created":1788,"model":"gemini_pro","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
data: [DONE]
Deep Search is on by default. Pass web_search: false to disable per request.
Log in to veoaifree.com with your credentials. The session cookie is stored in data/cookies.txt and used for all proxied requests. Also runs automatically on startup/requests when VEO_EMAIL/VEO_PASSWORD are set.
curl -X POST http://localhost:3000/v1/auth/login \
-H "Content-Type: application/json" \
-d '{ "email": "you@example.com", "password": "secret" }'
Returns whether a logged-in session is active.
{ "loggedIn": true }
{ "error": { "message": "Description of the error" } }
| Status | Meaning |
|---|---|
400 | Invalid request / login failed / image not supported |
401 | Missing or incorrect API key |
500 | Upstream / internal error |
Point opencode's veo provider at this PHP server. Fresh opencode.json:
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"veo": {
"api": "openai",
"name": "Veo AI Free",
"options": {
"apiKey": "dummy",
"baseURL": "http://localhost:3000/v1"
},
"models": {
"claude-sonnet": { "id": "claude-sonnet", "name": "Claude Sonnet 5", "tool_call": true, "reasoning": false },
"gpt-terra": { "id": "gpt-terra", "name": "GPT-5.6 Terra", "tool_call": true, "reasoning": false },
"gemini": { "id": "gemini", "name": "Gemini 3.1 Pro", "tool_call": true, "reasoning": false },
"gemini_pro": { "id": "gemini_pro", "name": "Gemini 3.7 Flash", "tool_call": true, "reasoning": false },
"grok": { "id": "grok", "name": "Grok 4.5", "tool_call": true, "reasoning": false },
"kimi": { "id": "kimi", "name": "Kimi K3", "tool_call": true, "reasoning": false },
"glm": { "id": "glm", "name": "GLM 5.2", "tool_call": true, "reasoning": false },
"nemotron": { "id": "nemotron", "name": "Nemotron 3 Ultra", "tool_call": true, "reasoning": false }
}
}
},
"model": "veo/claude-sonnet"
}