Operation API

The Operation chat completions API. Grab a key, send a POST, get a reply. That's it.

Base URL

https://ai.vshll.lol/api/public/v1

Authentication

Send your key in the Authorization header:

Authorization: Bearer drc_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Generate keys at /api-keys. Keys are shown once on creation — store them somewhere safe.

POST /v1/chat/completions

Operation chat completions. Streaming and non-streaming supported.

Request body

  • model — model id. Default: google/gemini-3-flash-preview
  • messages — array of { role, content }
  • stream — boolean. SSE when true
  • temperature, max_tokens, tools — optional, passed through

cURL

curl https://ai.vshll.lol/api/public/v1/chat/completions \
  -H "Authorization: Bearer $OPERATION_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google/gemini-3-flash-preview",
    "messages": [
      { "role": "user", "content": "Hello, Operation!" }
    ]
  }'

Python (requests)

import os, requests

resp = requests.post(
    "https://ai.vshll.lol/api/public/v1/chat/completions",
    headers={
        "Authorization": f"Bearer {os.environ['OPERATION_API_KEY']}",
        "Content-Type": "application/json",
    },
    json={
        "model": "google/gemini-3-flash-preview",
        "messages": [{"role": "user", "content": "Hello, Operation!"}],
    },
)
print(resp.json()["choices"][0]["message"]["content"])

Node.js (fetch)

const res = await fetch("https://ai.vshll.lol/api/public/v1/chat/completions", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.OPERATION_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: "google/gemini-3-flash-preview",
    messages: [{ role: "user", content: "Hello, Operation!" }],
  }),
});
const data = await res.json();
console.log(data.choices[0].message.content);

Streaming

Set "stream": true. The response is Server-Sent Events (SSE) with data: {...} chunks terminated by data: [DONE].

Models

  • google/gemini-3-flash-preview — fast, default
  • google/gemini-3-pro-preview — higher quality
  • Any model exposed by the upstream gateway. Pass it in model.

Errors

Errors come back with a consistent JSON envelope:

{ "error": { "message": "…", "type": "invalid_api_key" } }
  • 401 — missing/invalid/revoked key
  • 400 — bad request body
  • 429 — rate limited
  • 402 — workspace credits exhausted

Tool calling

Pass a tools array describing the functions the model can call. If the model decides to use one, the response includes tool_calls. Run them on your side, then send the results back as role: "tool" messages on the next request and the model will continue from there.

Sign in with Operation

Build apps where users sign in with their Operation account, just like "Sign in with Google". The app gets an access token and calls the API on the user's behalf.

1. Register your app

Go to /api-keysOAuth AppsNew app. Add one or more redirect_uris (must be https, or http://localhost for dev). You'll get a client_id and one-time client_secret.

2. Send the user to authorize

Redirect the user's browser to:

https://ai.vshll.lol/oauth/authorize
  ?client_id=YOUR_CLIENT_ID
  &redirect_uri=https://yourapp.com/callback
  &state=RANDOM_STRING

state is optional but recommended — generate a random value, store it, and check it on the redirect back to prevent CSRF.

The user signs in (if needed) and sees: "YourApp wants to access your Operation account." When they click Authorize, they're redirected to:

https://yourapp.com/callback?code=drcode_xxx&state=RANDOM_STRING

3. Exchange the code for a token

On your server (never in browser code — protects your secret):

curl https://ai.vshll.lol/api/public/v1/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "authorization_code",
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET",
    "code": "drcode_xxx",
    "redirect_uri": "https://yourapp.com/callback"
  }'

Response:

{ "access_token": "dro_xxxxxxxx…", "token_type": "Bearer" }

4. Call the API as the user

Use the access token like any other Operation key:

curl https://ai.vshll.lol/api/public/v1/chat/completions \
  -H "Authorization: Bearer dro_xxxxxxxx…" \
  -H "Content-Type: application/json" \
  -d '{ "model": "google/gemini-3-flash-preview", "messages": [{"role":"user","content":"hi"}] }'

Tokens don't expire. Users can revoke an app's access anytime from their API keys page. If they do, the token starts returning 401.

Note

The API follows the widely-used chat-completions JSON format, so any OpenAI-compatible client library will work too if you prefer — just point its base URL at https://ai.vshll.lol/api/public/v1 and use your Operation key.

Ready to build?

Create your first API key in seconds.