The Veritas API
Uncensored, OpenAI-compatible inference for chat, images, voice, and video, behind one key. No content filters, no KYC. Agents can also pay per call in USDC over x402, with no key at all.
Veritas mirrors the OpenAI API, so anything written for it works here by changing two things: the base URL and the key. Point your client at the endpoint below, send a vrt_ key as a bearer token, and use a Veritas model.
Base URL https://www.veritas.guru/api/v1
Auth Authorization: Bearer vrt_your_key
Format OpenAI Chat Completions
Quickstart
Generate a free key on the key page, then make your first request.
cURL
curl https://www.veritas.guru/api/v1/chat/completions \
-H "Authorization: Bearer vrt_your_key" \
-H "Content-Type: application/json" \
-d '{
"model": "veritas-uncensored",
"messages": [{"role": "user", "content": "Hello"}]
}'
Python
from openai import OpenAI
client = OpenAI(api_key="vrt_your_key", base_url="https://www.veritas.guru/api/v1")
resp = client.chat.completions.create(
model="veritas-uncensored",
messages=[{"role": "user", "content": "Hello"}],
)
print(resp.choices[0].message.content)
JavaScript
const res = await fetch("https://www.veritas.guru/api/v1/chat/completions", {
method: "POST",
headers: {
"Authorization": "Bearer vrt_your_key",
"Content-Type": "application/json"
},
body: JSON.stringify({
model: "veritas-uncensored",
messages: [{ role: "user", content: "Hello" }]
})
});
const data = await res.json();
console.log(data.choices[0].message.content);
Authentication
Every request is authenticated with your key in the Authorization header as a bearer token.
Authorization: Bearer vrt_your_key
Keys begin with vrt_. Each request counts once against your monthly plan limit. Keep keys server-side where you can; you can regenerate a key any time from your account, which immediately revokes the old one.
Models
Pass a model id in the model field. Standard OpenAI names such as gpt-4o are also accepted and route to the uncensored chat model, so existing code runs without edits.
| Model | Type | Notes |
|---|---|---|
| veritas-uncensored | Chat | Default chat model. No content filters. |
| veritas-roleplay | Chat | Tuned for character and roleplay. |
| veritas-private | Chat | End-to-end encrypted inference. |
| veritas-image | Image | Default image generation. No watermark. |
| veritas-image-nsfw | Image | Unfiltered image generation. |
| veritas-video | Video | Text to video. |
| veritas-voice | Voice | Text to speech. |
List them programmatically:
curl https://www.veritas.guru/api/v1/models \
-H "Authorization: Bearer vrt_your_key"
Chat completions
POST/chat/completions
Send a list of messages and receive a model reply. The request and response shapes match the OpenAI Chat Completions API.
| Field | Type | Description |
|---|---|---|
| model | string | A Veritas model id, or an OpenAI name. |
| messages | array | Messages with role and content. |
| temperature | number | Sampling temperature. Optional. |
| max_tokens | integer | Maximum tokens to generate. Optional. |
| stream | boolean | Stream the response as SSE. Optional. |
| tools | array | Function definitions. Optional. |
| tool_choice | string | auto, required, or a named function. |
Example response:
{
"id": "chatcmpl-...",
"object": "chat.completion",
"model": "veritas-uncensored",
"choices": [{
"index": 0,
"message": { "role": "assistant", "content": "Hello. How can I help?" },
"finish_reason": "stop"
}],
"usage": { "prompt_tokens": 9, "completion_tokens": 7, "total_tokens": 16 }
}
Tool calling
Define functions in the tools array and the model can return structured calls for your code to run.
curl https://www.veritas.guru/api/v1/chat/completions \
-H "Authorization: Bearer vrt_your_key" \
-H "Content-Type: application/json" \
-d '{
"model": "veritas-uncensored",
"messages": [{"role": "user", "content": "Weather in Tokyo?"}],
"tools": [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the weather for a city",
"parameters": {
"type": "object",
"properties": { "city": {"type": "string"} },
"required": ["city"]
}
}
}],
"tool_choice": "required"
}'
The reply contains a tool_calls array with the function name and JSON arguments, and finish_reason: "tool_calls".
Streaming
Set stream: true to receive the response as Server-Sent Events. Each event is a chat.completion.chunk, ending with data: [DONE]. Streaming works with the standard OpenAI SDKs.
stream = client.chat.completions.create(
model="veritas-uncensored",
messages=[{"role": "user", "content": "Count to five"}],
stream=True,
)
for chunk in stream:
print(chunk.choices[0].delta.content or "", end="")
Images
POST/image/generate
Generate an image from a prompt. Output has no watermark, and generation is unfiltered by default. Use veritas-image-nsfw for the unrestricted model.
curl https://www.veritas.guru/api/v1/image/generate \
-H "Authorization: Bearer vrt_your_key" \
-H "Content-Type: application/json" \
-d '{
"model": "veritas-image",
"prompt": "a lighthouse in a storm, oil painting",
"width": 1024,
"height": 1024
}'
Voice
POST/audio/speech
Convert text to speech. Returns audio bytes.
curl https://www.veritas.guru/api/v1/audio/speech \
-H "Authorization: Bearer vrt_your_key" \
-H "Content-Type: application/json" \
-d '{
"model": "veritas-voice",
"input": "Hello from Veritas.",
"voice": "af_sky"
}' --output speech.mp3
Transcription
POST/audio/transcriptions
Transcribe an audio file to text. Send the file as multipart form data, the same shape as the OpenAI transcription endpoint.
curl https://www.veritas.guru/api/v1/audio/transcriptions \
-H "Authorization: Bearer vrt_your_key" \
-F file=@audio.mp3
Video
POST/video/queue POST/video/retrieve
Video generation is asynchronous. Queue a job, then poll for the result.
# 1. Queue
curl https://www.veritas.guru/api/v1/video/queue \
-H "Authorization: Bearer vrt_your_key" \
-H "Content-Type: application/json" \
-d '{ "model": "veritas-video", "prompt": "aerial drift over a calm ocean at sunset" }'
# 2. Retrieve with the returned id
curl https://www.veritas.guru/api/v1/video/retrieve \
-H "Authorization: Bearer vrt_your_key" \
-H "Content-Type: application/json" \
-d '{ "id": "the_job_id" }'
Embeddings
POST/embeddings
Generate vector embeddings for retrieval and search.
curl https://www.veritas.guru/api/v1/embeddings \
-H "Authorization: Bearer vrt_your_key" \
-H "Content-Type: application/json" \
-d '{ "model": "veritas-uncensored", "input": "text to embed" }'
Agents
Because Veritas is OpenAI-compatible, agent frameworks work by setting the base URL and key. Chat, streaming, and tool calling are all supported.
LangChain
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="veritas-uncensored",
api_key="vrt_your_key",
base_url="https://www.veritas.guru/api/v1",
)
print(llm.invoke("Hello").content)
CrewAI
from crewai import LLM
llm = LLM(
model="openai/veritas-uncensored",
base_url="https://www.veritas.guru/api/v1",
api_key="vrt_your_key",
)
MCP server
Veritas runs a native Model Context Protocol server over Streamable HTTP, so MCP-native clients (Cursor, Claude, custom agents) connect directly and call Veritas as tools. Discovery is open; tool calls require your key.
Endpoint https://www.veritas.guru/mcp
Auth Authorization: Bearer vrt_your_key
Transport Streamable HTTP (JSON-RPC)
Tools
| Tool | Description |
|---|---|
| veritas_chat | Uncensored chat. Set web_search for current information. |
| veritas_generate_image | Generate an image from a prompt. |
| veritas_text_to_speech | Convert text to spoken audio. |
| veritas_generate_video | Queue a text-to-video job. |
| veritas_get_video | Retrieve a queued video by its job id. |
Connect a client
Add it to any MCP client. Example for Cursor (mcp.json):
{
"mcpServers": {
"veritas": {
"url": "https://www.veritas.guru/mcp",
"headers": { "Authorization": "Bearer vrt_your_key" }
}
}
}
Quick check
List the available tools (no key required for discovery):
curl https://www.veritas.guru/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
Pay-per-call (x402)
Two endpoints let an agent pay for a single call in USDC on Base using the x402 protocol, with no account and no API key. The wallet signs a payment for each request, the call clears, and nothing is stored. This is built for autonomous agents that hold funds and spend them directly.
| Endpoint | Does | Default price |
|---|---|---|
| POST /x402/chat | OpenAI-compatible chat completion | $0.002 / call |
| POST /x402/image | Image generation, returns a URL | $0.02 / image |
How it works
Standard x402 flow over HTTP's 402 Payment Required:
- POST without an X-PAYMENT header returns 402 with the payment requirements: amount, asset (USDC), network (Base), and the pay-to address.
- The client signs a payment authorization for that amount and retries the request with an X-PAYMENT header.
- On success you get the result, plus an X-PAYMENT-RESPONSE header containing the settlement transaction.
Request bodies: /x402/chat takes { messages, model? }; /x402/image takes { prompt, width?, height? }.
With x402-fetch
The x402-fetch client handles the 402 handshake and signs each payment from a wallet automatically.
import { wrapFetchWithPayment } from "x402-fetch";
import { createWalletClient, http } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { base } from "viem/chains";
const account = privateKeyToAccount(process.env.PRIVATE_KEY);
const wallet = createWalletClient({ account, chain: base, transport: http() });
const pay = wrapFetchWithPayment(fetch, wallet);
const res = await pay("https://www.veritas.guru/x402/image", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ prompt: "a lighthouse in a storm, oil painting" })
});
const { url } = await res.json();
Rate limits
Limits are counted per calendar month and reset on the first. Each request counts as one.
| Plan | Requests / month |
|---|---|
| Free | 100 |
| Pro | 5,000 |
| Ultra | 50,000 |
Responses include X-Veritas-Plan and X-Veritas-Requests-Remaining headers. Upgrade to Pro or Ultra from the upgrade page, paying in USDC on Base, in $VERITAS tokens, or by staking $VERITAS to unlock a plan while your tokens stay yours. See staking for the tiers.
Errors
Errors return a JSON body with an error field and a standard HTTP status.
| Status | Meaning |
|---|---|
| 401 | Missing, invalid, or revoked key. |
| 404 | Unknown endpoint. |
| 413 | Request body too large. |
| 429 | Monthly request limit reached. |
| 502 | Upstream request failed. Retry. |
Privacy
We do not log the content of your requests. Prompts and responses are not stored on our servers, and your data is never used for training.
In the web app, conversations stay in your browser by default. If you enable sync, history is encrypted on your device with a key only you hold, so what we store is text we cannot read.