Generate text, images, video, audio, realtime voice, and embeddings with a single API. OpenAI-compatible — use any OpenAI SDK by changing the base URL.
Also available at https://gen.pollinations.ai/docs
Version: 0.3.0 · OpenAPI: 3.1.0 · Base URL: https://gen.pollinations.ai
1. Get an API key at enter.pollinations.ai. Use the key type for your environment:
sk_*— secret key for backend use. Never ship it in a browser, mobile app, or repository.pk_*App Key — public OAuth client id for BYOP. Use it to obtain a scoped usersk_*; do not use raw publishable keys for new browser generation integrations.
2. Send the key in the Authorization header (or as ?key= query param for GET endpoints):
curl https://gen.pollinations.ai/v1/models \
-H "Authorization: Bearer $POLLINATIONS_KEY"3. Pick an endpoint from the 📑 Contents below.
Integration guides: Connect User Wallets · Publish a Model · Publish an Agent · MCP Server · CLI
- 🚀 Getting Started
- 🔐 Authentication
- 🔓 Sign in with Pollinations (OAuth 2.1)
- 🧪 Use any OpenAI SDK
- 🌊 Streaming chat completions
- 🖼️ Vision: passing images into chat
- 📤 Multipart uploads in depth
- 💡 Tips
- 🛠️ Endpoints
⚠️ Error Responses- 🧩 Schemas
Pollinations recognises two prefixes. Use the right kind of pk_ for the surface you're building.
| Key type | Prefix | Where it goes | What it can do |
|---|---|---|---|
| Secret key | sk_ |
Server-only (env var, secrets manager) | Full account access. Can create child keys, list usage, run any model the account allows. Never ship to a browser, mobile app, or repo. |
| App key (BYOP) | pk_ with redirect URIs |
OAuth client_id for web/mobile/CLI consent |
Users authorize your app; you receive a scoped user sk_. Create at enter.pollinations.ai/keys. This is the supported client path. |
| Raw publishable key | pk_ with no app / OAuth binding |
Legacy only | Existing integrations only. Rate-limited to 1 pollen per IP per hour. Do not mint new raw pk_ keys, and do not embed them in new browser code. |
Both forms accept the same transports:
Authorization: Bearer <key>GET /image/cat?key=<key>The header is preferred for everything except browser flows that can't set custom headers (image/audio GET endpoints and WebSocket realtime sessions).
Endpoints with relaxed auth requirements
| Endpoint | Auth |
|---|---|
GET /{id}, GET /{id}/metadata, HEAD /{id} |
None — media URLs are public reads |
GET /models, GET /v1/models, GET /image/models, GET /text/models, GET /audio/models, GET /embeddings/models |
None — model catalogue is public. Sending a bearer key returns the same data; some endpoints add per-account fields when authenticated. |
| Everything else | Bearer key required unless the endpoint documents ?key= support |
401 UNAUTHORIZED always means key missing or invalid. 402 PAYMENT_REQUIRED means the key authenticated but the account or per-key budget is exhausted — see Error Responses.
Third-party apps can obtain an API key on behalf of a Pollinations user — the OAuth 2.1 authorization-code flow with PKCE (S256) for web apps, or the device flow (RFC 8628) for CLIs. Register a publishable App Key (pk_…) with your redirect URIs at enter.pollinations.ai; the pk_ key is your client_id (public client, no secret), and the issued access token is an opaque sk_ key bound to the budget, expiry, and scopes the user approved.
Endpoints are discoverable via RFC 8414 metadata — resolve them from there rather than hardcoding:
GET https://enter.pollinations.ai/.well-known/oauth-authorization-server
The full integration guide—authorization request, token exchange, device flow, userinfo, scopes, and revocation—is Connect User Wallets.
Pollinations speaks the OpenAI Chat Completions, Images, Embeddings, Audio, and Realtime APIs. Point the SDK at https://gen.pollinations.ai/v1 and pass your sk_… key as the OpenAI key.
Python
from openai import OpenAI
client = OpenAI(
base_url="https://gen.pollinations.ai/v1",
api_key="sk_your_secret_key",
)
response = client.chat.completions.create(
model="openai",
messages=[{"role": "user", "content": "Summarise the theory of relativity in one sentence."}],
)
print(response.choices[0].message.content)Node.js / TypeScript
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://gen.pollinations.ai/v1",
apiKey: process.env.POLLINATIONS_KEY,
});
const response = await client.chat.completions.create({
model: "openai",
messages: [{ role: "user", content: "Summarise the theory of relativity in one sentence." }],
});
console.log(response.choices[0].message.content);Model IDs come from GET /v1/models. Anything openai, claude, mistral, deepseek, etc. routes to the corresponding provider on our side — you don't need separate keys per provider.
Set stream: true to receive Server-Sent Events (SSE) deltas as the model writes. The wire format is byte-for-byte the OpenAI streaming format, so any OpenAI SDK that supports streaming works unchanged.
cURL
curl -N "https://gen.pollinations.ai/v1/chat/completions" \
-H "Authorization: Bearer $POLLINATIONS_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"openai","stream":true,"messages":[{"role":"user","content":"Count to five, one word per line."}]}'-N disables curl's output buffering so deltas appear as they arrive. Each event is a line of the form data: {…} terminated by data: [DONE].
Python (OpenAI SDK)
stream = client.chat.completions.create(
model="openai",
stream=True,
messages=[{"role": "user", "content": "Count to five, one word per line."}],
)
for chunk in stream:
delta = chunk.choices[0].delta.content
if delta:
print(delta, end="", flush=True)When stream: true is set, usage info still arrives on the final chunk (stream_options: { include_usage: true } if your SDK requires opting in).
Models that accept image input (openai, claude, gemini, …) use the standard OpenAI multimodal content shape — an array of typed parts instead of a plain string.
curl "https://gen.pollinations.ai/v1/chat/completions" \
-H "Authorization: Bearer $POLLINATIONS_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai",
"messages": [{
"role": "user",
"content": [
{"type": "text", "text": "What is in this image?"},
{"type": "image_url", "image_url": {"url": "https://example.com/cat.jpg"}}
]
}]
}'image_url.url accepts either a public URL or a data:image/...;base64,… data URI. Use detail: "high" for fine-grained reasoning and "low" for quick takes — see the MessageContentPart schema for every supported part.
For audio or video input, swap in input_audio or video_url parts on models that advertise the matching capability in their /v1/models entry.
Three endpoints accept multipart/form-data request bodies. Each has its own field set.
Transcribe an audio file — Whisper-compatible.
curl -X POST "https://gen.pollinations.ai/v1/audio/transcriptions" \
-H "Authorization: Bearer $POLLINATIONS_KEY" \
-F "file=@./recording.mp3" \
-F "model=openai-audio" \
-F "response_format=verbose_json" \
-F "temperature=0"response_format accepts json (default), verbose_json (adds segment timings), text, srt, vtt. Max file size 25 MB.
Edit an image with a prompt — OpenAI Images Edits-compatible.
curl -X POST "https://gen.pollinations.ai/v1/images/edits" \
-H "Authorization: Bearer $POLLINATIONS_KEY" \
-F "image=@./photo.png" \
-F "prompt=replace the sky with a sunset" \
-F "model=kontext" \
-F "size=1024x1024"Repeat -F "image=@…" to pass multiple reference images on models that accept them (seedream, nanobanana, klein).
Upload arbitrary media to the media store (a separate host: media.pollinations.ai). Returns a https://media.pollinations.ai/<id> URL you can pass anywhere a remote image, audio, or video URL is accepted.
curl -X POST "https://media.pollinations.ai/upload" \
-H "Authorization: Bearer $POLLINATIONS_KEY" \
-F "file=@./asset.png"Each upload gets its own unique id — re-uploading the same bytes yields a new URL. Files use a 30-day lifecycle from upload or the latest refresh. Retrieving the file body refreshes that lifecycle only when the object is at least 15 days old; metadata and HEAD requests do not refresh it. An optional -F "tags=..." field publishes the upload to those tags' public galleries (GET https://media.pollinations.ai/media?tag=...); untagged uploads stay unlisted.
- Do not put raw
pk_keys in browsers. For client apps, register an App Key and use BYOP so users authorize a scopedsk_. Rawpk_keys are legacy and rate-limited (1 pollen/IP/hour). - One key per app. Child keys scope budget and permissions independently — easier to audit, easier to revoke without touching production.
- Retry the same request after a timeout. Keep the endpoint, body, query parameters, and seed unchanged. Your retry waits for the generation already in progress or receives the completed cached result instead of starting another generation.
- Watch
429and503. ARetry-Afterheader tells you how long to back off.502from us means upstream provider — usually transient.
Generate text responses using AI models. Fully compatible with the OpenAI Chat Completions API — use any OpenAI SDK by changing the base URL.
| Endpoint | Best for |
|---|---|
POST /v1/chat/completions |
Full OpenAI compatibility — streaming, tools, vision, structured outputs |
GET /text/{prompt} |
Quick prototyping — simple GET, returns plain text |
Available models: openai, openai-fast, gpt-oss, gpt-5.4, gpt-5.4-mini, openai-large, gpt-5.6-sol, gpt-5.6-terra, gpt-5.6-luna, mercury, command-a-plus, qwen-coder, mistral-small-3.2, mistral, openai-audio, openai-audio-large, gemini-3-flash, gemini, gemini-flash-lite-3.5, gemini-fast, deepseek, gemma, gemma-4-31b, deepseek-pro, grok, grok-large, grok-4.6, gemini-search, midijourney, midijourney-large, claude-fast, claude, claude-sonnet-5, claude-opus-4.6, claude-opus-4.7, claude-large, claude-fable-5, perplexity-fast, perplexity, perplexity-reasoning, kimi, kimi-code, kimi-k3, laguna, longcat, inkling, nemotron, nemotron-3.5-lightning, mimo-v2.5, mimo-v2.5-pro, gemini-large, nova-fast, nova, glm, glm-5.3, llama, llama-maverick, llama-scout, minimax-m2.7, minimax, muse-glimmer, muse-spark-1.2, mistral-large, qwen-coder-large, qwen-large, qwen3.7-max, qwen3.8-2.4t-a95b, qwen3.8-27b, qwen3.8-max, qwen3.7-flash, qwen-vision, qwen-vision-pro, step-flash, step-3.5-flash, qwen-safety
On Gemini, Claude, and Nova models, a large static prompt prefix can be cached so repeat requests bill it at a fraction of the input rate. Mark the end of the static prefix with cache_control on a content block (not on the message); everything before the marker must be byte-identical across requests, everything dynamic goes after. The first request creates the cache (usage reports cache_creation_input_tokens); repeat requests within the TTL report prompt_tokens_details.cached_tokens at the discounted rate.
{
"model": "gemini-fast",
"messages": [
{
"role": "system",
"content": [
{
"type": "text",
"text": "<large static prompt>",
"cache_control": { "type": "ephemeral" }
}
]
},
{ "role": "user", "content": "<dynamic message>" }
]
}Gemini — the prefix must be at least ~2,048 tokens (~4,096 on Gemini 3 models). Requests with tools are not cached — including built-in tools, so gemini, gemini-3-flash, gemini-large, and the search variants only cache when tools are disabled ("tools": []) or a JSON response_format is set; gemini-fast and gemini-flash-lite-3.5 cache by default. Cache creates bill at the standard input rate plus a storage fee for the 1-hour TTL ($1 per 1M cached tokens on Flash models, $4.50 on Pro); hits bill at ~10% of input. The storage fee means caching pays off only when the prefix is reused often — roughly a dozen reuses per hour on the cheapest models.
Claude — all Claude models cache. The prefix must be at least 4,096 tokens (1,024 on claude and claude-fable-5); tools are fine. Cache creates bill at 1.25× the input rate (no storage fee); hits bill at 10% of input. The cache lives ~5 minutes, refreshed on each hit.
Nova — nova and nova-fast cache. The prefix must be at least ~1,000 tokens (up to 20K tokens cacheable). Cache creates are free; hits bill at 25% of input. ~5-minute TTL.
Generate text responses using AI models. Fully compatible with the OpenAI Chat Completions API — use any OpenAI SDK by pointing it to https://gen.pollinations.ai.
Supports streaming, function calling, vision (image input), structured outputs, and reasoning/thinking modes depending on the model.
📥 Request body · application/json
| Field | Type | Description |
|---|---|---|
messages * |
object[] |
— |
model |
string |
AI model for text generation. See /v1/models for full list. · default: "openai" |
modalities |
"text" | "audio"[] |
— |
audio |
object |
— |
audio.voice * |
enum (13) — "alloy", "echo", "fable", … |
— |
audio.format * |
"wav" | "mp3" | "flac" | "opus" | "pcm16" |
— |
frequency_penalty |
number | null |
default: 0 |
repetition_penalty |
number | null |
— |
logit_bias |
object | null |
default: null |
logprobs |
boolean | null |
default: false |
top_logprobs |
integer | null |
— |
max_tokens |
integer | null |
— |
presence_penalty |
number | null |
default: 0 |
response_format |
object |
— |
seed |
integer | null |
— |
stop |
string | null | string[] |
— |
stream |
boolean | null |
default: false |
stream_options |
object | null |
— |
safe |
string | boolean |
Safety features: comma-separated list of privacy, secrets, sexual, violence, shield, true, nsfw. true enables privacy,secrets; nsfw enables sexual,violence. Also accepted in the Pollinations-Safe header. Defaults to off; false and 0 are accepted as off. |
reasoning_effort |
enum (7) — "none", "minimal", "low", … |
Requests reasoning depth for models that support adjustable reasoning. "none" requests no reasoning. |
web_search_options |
object |
Controls Perplexity Sonar search context. Pollinations currently supports low and high. |
web_search_options.search_context_size * |
"low" | "medium" | "high" |
— |
temperature |
number | null |
— |
top_p |
number | null |
— |
tools |
object[] |
— |
tool_choice |
"none" | "auto" | "required" | object |
— |
parallel_tool_calls |
boolean |
default: true |
user |
string |
— |
function_call |
"none" | "auto" | object |
— |
functions |
object[] |
— |
functions[].description |
string |
— |
functions[].name * |
string |
— |
functions[].parameters |
object |
— |
* = required field
📤 Response · 200 · application/json — Success
| Field | Type | Description |
|---|---|---|
id * |
string |
— |
choices * |
object[] |
— |
choices[].finish_reason |
string | null |
— |
choices[].index |
integer |
— |
choices[].message |
object |
— |
choices[].logprobs |
object | null |
— |
choices[].content_filter_results |
ContentFilterResult | null |
— |
prompt_filter_results |
object[] | null |
— |
created * |
integer |
— |
model |
string |
— |
system_fingerprint |
string | null |
— |
object * |
"chat.completion" |
— |
usage |
CompletionUsage |
— |
citations |
string[] |
— |
* = required field
💻 Example
curl -X POST "https://gen.pollinations.ai/v1/chat/completions" \
-H "Authorization: Bearer $POLLINATIONS_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"openai","messages":[{"role":"user","content":"Hello!"}]}'{
"id": "chatcmpl-abc123",
"object": "chat.completion",
"created": 1700000000,
"model": "openai",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Hello! How can I help you today?"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 10,
"completion_tokens": 12,
"total_tokens": 22
}
}Generate text from an OpenAI-style messages array and return the assistant content directly.
Use /v1/chat/completions when you need the full OpenAI-compatible JSON response.
📥 Request body · application/json
| Field | Type | Description |
|---|---|---|
messages * |
object[] |
— |
model |
string |
AI model for text generation. See /v1/models for full list. · default: "openai" |
modalities |
"text" | "audio"[] |
— |
audio |
object |
— |
audio.voice * |
enum (13) — "alloy", "echo", "fable", … |
— |
audio.format * |
"wav" | "mp3" | "flac" | "opus" | "pcm16" |
— |
frequency_penalty |
number | null |
default: 0 |
repetition_penalty |
number | null |
— |
logit_bias |
object | null |
default: null |
logprobs |
boolean | null |
default: false |
top_logprobs |
integer | null |
— |
max_tokens |
integer | null |
— |
presence_penalty |
number | null |
default: 0 |
response_format |
object |
— |
seed |
integer | null |
— |
stop |
string | null | string[] |
— |
stream |
boolean | null |
default: false |
stream_options |
object | null |
— |
safe |
string | boolean |
Safety features: comma-separated list of privacy, secrets, sexual, violence, shield, true, nsfw. true enables privacy,secrets; nsfw enables sexual,violence. Also accepted in the Pollinations-Safe header. Defaults to off; false and 0 are accepted as off. |
reasoning_effort |
enum (7) — "none", "minimal", "low", … |
Requests reasoning depth for models that support adjustable reasoning. "none" requests no reasoning. |
web_search_options |
object |
Controls Perplexity Sonar search context. Pollinations currently supports low and high. |
web_search_options.search_context_size * |
"low" | "medium" | "high" |
— |
temperature |
number | null |
— |
top_p |
number | null |
— |
tools |
object[] |
— |
tool_choice |
"none" | "auto" | "required" | object |
— |
parallel_tool_calls |
boolean |
default: true |
user |
string |
— |
function_call |
"none" | "auto" | object |
— |
functions |
object[] |
— |
functions[].description |
string |
— |
functions[].name * |
string |
— |
functions[].parameters |
object |
— |
* = required field
📤 Response · 200 — Generated text response, audio bytes, JSON message object, or SSE when stream=true
💻 Example
curl -X POST "https://gen.pollinations.ai/text" \
-H "Authorization: Bearer $POLLINATIONS_KEY" \
-H "Content-Type: application/json" \
-d '{"messages":[{"role":"user","content":"Hello!"}],"model":"openai"}'Generate text from a prompt via a simple GET request. Returns plain text.
This is a simplified alternative to the OpenAI-compatible /v1/chat/completions endpoint — ideal for quick prototyping or simple integrations.
⚙️ Parameters
| Param | In | Type | Description |
|---|---|---|---|
prompt * |
path |
string |
Text prompt for generation |
model |
query |
string |
Text model to use. See /v1/models or /text/models for the full list of available models. · default: "openai" |
seed |
query |
integer |
Seed for reproducible results. · default: 0 · min: -1 |
system |
query |
string |
System prompt to set the model's behavior and context. Acts as initial instructions before the user prompt. |
json |
query |
boolean |
When true, the model returns valid JSON. Useful for structured data extraction. |
temperature |
query |
number |
Controls randomness. Lower values (e.g. 0.2) produce more focused output, higher values (e.g. 1.5) produce more creative output. Range: 0.0 to 2.0. |
stream |
query |
boolean |
Stream the response as it's generated, using Server-Sent Events (SSE). Each chunk contains partial text. |
safe |
query |
string | boolean |
Safety features: comma-separated list of privacy, secrets, sexual, violence, shield, true, nsfw. true enables privacy,secrets; nsfw enables sexual,violence. Also accepted in the Pollinations-Safe header. Defaults to off; false and 0 are accepted as off. |
* = required parameter
📤 Response · 200 · text/plain — Generated text response
💻 Example
curl "https://gen.pollinations.ai/text/Write%20a%20haiku%20about%20coding?model=openai&seed=0" \
-H "Authorization: Bearer $POLLINATIONS_KEY"Generate images from text prompts via a simple GET request. Returns JPEG, PNG, or SVG depending on the selected model.
https://gen.pollinations.ai/image/a%20cat%20in%20space?model=flux
Available models: krea, dreamshaper, kontext, nanobanana, nanobanana-2, nanobanana-2-lite, nanobanana-pro, seedream5, seedream5-pro, seedream, seedream-pro, ideogram-v4-turbo, ideogram-v4-balanced, ideogram-v4-quality, gptimage, gptimage-large, gpt-image-2, flux, zimage, zimage-fal, wan-image, wan-image-pro, qwen-image, qwen-image-3, grok-imagine, grok-imagine-pro, grok-imagine-image-2.0, recraft-v4.1-vector, klein, p-image, p-image-edit, nova-canvas
Community image models use an owner/model id and support generation through /image/{prompt} and /v1/images/generations. The registration test adds image input and /v1/images/edits metadata when the registrant's edit endpoint succeeds. OpenAI-compatible responses use b64_json; URL responses are not supported for community models. See /image/models for the live model list and supported endpoints.
Generate an image from a text prompt. Returns JPEG, PNG, or SVG depending on the selected model.
Available models: krea, dreamshaper, kontext, nanobanana, nanobanana-2, nanobanana-2-lite, nanobanana-pro, seedream5, seedream5-pro, seedream, seedream-pro, ideogram-v4-turbo, ideogram-v4-balanced, ideogram-v4-quality, gptimage, gptimage-large, gpt-image-2, flux, zimage, zimage-fal, wan-image, wan-image-pro, qwen-image, qwen-image-3, grok-imagine, grok-imagine-pro, grok-imagine-image-2.0, recraft-v4.1-vector, klein, p-image, p-image-edit, nova-canvas. zimage is the default.
Browse all available models and their capabilities at /image/models.
⚙️ Parameters
| Param | In | Type | Description |
|---|---|---|---|
prompt * |
path |
string |
Text description of the image to generate |
model * |
query |
string |
Model to use. Image: flux, zimage, gptimage, kontext, seedream5, seedream5-pro, nanobanana, nanobanana-pro, klein. Video: veo, seedance-pro, wan, wan-pro, p-video, nova-reel. See /image/models for full list. · default: "zimage" |
width |
query |
integer |
Width in pixels. For images, exact pixels. For video models, used for aspect ratio; use resolution to select a resolution tier. · default: 1024 |
height |
query |
integer |
Height in pixels. For images, exact pixels. For video models, used for aspect ratio; use resolution to select a resolution tier. · default: 1024 |
seed |
query |
integer |
Seed for reproducible results. Supported by: flux, zimage, seedream, klein, seedance, nova-reel. Other models ignore this parameter. · default: 0 · range: -1…2147483647 |
safe |
query |
string | boolean |
Safety features: comma-separated list of privacy, secrets, sexual, violence, shield, true, nsfw. true enables privacy,secrets; nsfw enables sexual,violence. Also accepted in the Pollinations-Safe header. Defaults to off; false and 0 are accepted as off. |
quality |
query |
"low" | "medium" | "high" | "hd" |
Image quality level. Supported by gptimage, gptimage-large, gpt-image-2, and grok-imagine-image-2.0. · default: "medium" |
image |
query |
string |
Reference image URL(s) for image editing or video generation. Separate multiple URLs with | or ,. Image models: Used for editing/style reference (kontext, gptimage, seedream, klein, nanobanana). Video models: image[0] = starting frame (I2V); image[1] = ending frame for first+last-frame interpolation. End-frame supported by veo, the seedance-2.0 family, seedance-2.5, wan-fast, and wan-pro; other video models silently drop image[1]. See video_capabilities on /image/models or /models for per-model support. |
transparent |
query |
boolean |
Generate image with transparent background. Only supported by gptimage and gptimage-large. · default: false |
resolution |
query |
enum (6) — "1k", "2k", "480p", … |
Output resolution for image and video models that advertise resolutions in /models. The first advertised resolution is the default; requested tiers bill at their listed rate. |
* = required parameter
📤 Response · 200 · image/jpeg, image/png, image/svg+xml — Success - Returns the generated image
💻 Example
curl "https://gen.pollinations.ai/image/a%20beautiful%20sunset%20over%20mountains?model=zimage&width=1024" \
-H "Authorization: Bearer $POLLINATIONS_KEY"OpenAI-compatible image generation endpoint.
Generate images from text prompts. Supports response_format: "url" (returns a pollinations.ai URL) or "b64_json" (returns base64-encoded image data, default).
Authentication: Include your API key as Authorization: Bearer YOUR_API_KEY.
📥 Request body · application/json
| Field | Type | Description |
|---|---|---|
prompt * |
string |
A text description of the desired image(s) · length: 1…32000 |
model |
string |
The model to use for image generation · default: "flux" |
n |
integer |
Number of images to generate (currently max 1) · default: 1 · range: 1…1 |
size |
string |
Image size as WIDTHxHEIGHT (e.g., 1024x1024, 512x512) · default: "1024x1024" |
quality |
"standard" | "hd" | "low" | "medium" | "high" |
Image quality. OpenAI 'standard'/'hd' mapped to Pollinations equivalents · default: "medium" |
response_format |
"url" | "b64_json" |
Return format. "url" returns a pollinations.ai URL, "b64_json" returns base64-encoded image data · default: "b64_json" |
user |
string |
End-user identifier for abuse tracking |
image |
string | string[] |
Reference image URL(s) for image-to-image generation (Pollinations extension) |
resolution |
enum (6) — "1k", "2k", "480p", … |
Output resolution for resolution-priced image and video models (Pollinations extension) |
safe |
string | boolean |
Safety features: comma-separated list of privacy, secrets, sexual, violence, shield, true, nsfw. true enables privacy,secrets; nsfw enables sexual,violence. Also accepted in the Pollinations-Safe header. Defaults to off; false and 0 are accepted as off. |
* = required field
📤 Response · 200 · application/json — Success
Returns CreateImageResponse.
💻 Example
curl -X POST "https://gen.pollinations.ai/v1/images/generations" \
-H "Authorization: Bearer $POLLINATIONS_KEY" \
-H "Content-Type: application/json" \
-d '{"prompt":"a serene mountain landscape at sunset","model":"flux","size":"1024x1024"}'OpenAI-compatible image editing endpoint.
Edit images using a text prompt and one or more source images. Accepts JSON with image URLs or multipart/form-data with file uploads. Community image models forward edits to the registrant's OpenAI-compatible endpoint as multipart form data.
Authentication: Include your API key as Authorization: Bearer YOUR_API_KEY.
📤 Response · 200 · application/json — Success
Returns CreateImageResponse.
💻 Example
curl -X POST "https://gen.pollinations.ai/v1/images/edits" \
-H "Authorization: Bearer $POLLINATIONS_KEY" \
-F "image=@./input.png" \
-F "prompt=make the sky a vivid sunset" \
-F "model=kontext"Generate videos from text prompts or reference images. Returns MP4.
https://gen.pollinations.ai/video/sunset%20timelapse?model=veo&duration=4
Available models: veo, seedance-pro, seedance-2.0, seedance-2.0-mini, seedance-2.0-fast, wan, wan-fast, wan-pro, grok-video-pro, grok-imagine-video-1.5, seedance-2.5, happyhorse-1.1, minimax-h3, p-video, nova-reel
Generate a video from a text prompt. Returns MP4.
Available models: veo, seedance-pro, seedance-2.0, seedance-2.0-mini, seedance-2.0-fast, wan, wan-fast, wan-pro, grok-video-pro, grok-imagine-video-1.5, seedance-2.5, happyhorse-1.1, minimax-h3, p-video, nova-reel.
Use duration to set video length, aspectRatio for orientation, and audio where the selected model supports audio output.
You can pass reference images via the image parameter: image[0] is the start frame, and image[1] is the end frame for models with end_frame in video_capabilities.
Browse all available models and their video_capabilities at /image/models.
⚙️ Parameters
| Param | In | Type | Description |
|---|---|---|---|
prompt * |
path |
string |
Text description of the video to generate |
model * |
query |
string |
Model to use. Image: flux, zimage, gptimage, kontext, seedream5, seedream5-pro, nanobanana, nanobanana-pro, klein. Video: veo, seedance-pro, wan, wan-pro, p-video, nova-reel. See /image/models for full list. · default: "veo" |
width |
query |
integer |
Width in pixels. For images, exact pixels. For video models, used for aspect ratio; use resolution to select a resolution tier. · default: 1024 |
height |
query |
integer |
Height in pixels. For images, exact pixels. For video models, used for aspect ratio; use resolution to select a resolution tier. · default: 1024 |
seed |
query |
integer |
Seed for reproducible results. Supported by: flux, zimage, seedream, klein, seedance, nova-reel. Other models ignore this parameter. · default: 0 · range: -1…2147483647 |
safe |
query |
string | boolean |
Safety features: comma-separated list of privacy, secrets, sexual, violence, shield, true, nsfw. true enables privacy,secrets; nsfw enables sexual,violence. Also accepted in the Pollinations-Safe header. Defaults to off; false and 0 are accepted as off. |
image |
query |
string |
Reference image URL(s) for image editing or video generation. Separate multiple URLs with | or ,. Image models: Used for editing/style reference (kontext, gptimage, seedream, klein, nanobanana). Video models: image[0] = starting frame (I2V); image[1] = ending frame for first+last-frame interpolation. End-frame supported by veo, the seedance-2.0 family, seedance-2.5, wan-fast, and wan-pro; other video models silently drop image[1]. See video_capabilities on /image/models or /models for per-model support. |
resolution |
query |
enum (6) — "1k", "2k", "480p", … |
Output resolution for image and video models that advertise resolutions in /models. The first advertised resolution is the default; requested tiers bill at their listed rate. |
duration |
query |
integer |
Video duration in seconds. Only applies to video models. veo: 4, 6, or 8s. seedance-pro: 2-10s. seedance-2.0: 4-15s; Mini: 4-10s; Fast: 4-5s. seedance-2.5: exactly 4s. minimax-h3: exactly 5s. wan: 2-15s. nova-reel: 6-120s (multiples of 6). · range: 1…120 |
aspectRatio |
query |
string |
Video aspect ratio (16:9 or 9:16). Only applies to video models. If not set, determined by explicit width/height; seedance-2.5 otherwise defaults to 16:9. minimax-h3 supports only 16:9. |
audio |
query |
boolean |
Generate audio for the video. Only applies to video models. wan and minimax-h3 always generate audio regardless of this flag. For veo, set to true to enable audio. · default: false |
* = required parameter
📤 Response · 200 · video/mp4 — Success - Returns the generated video
💻 Example
curl "https://gen.pollinations.ai/video/a%20sunset%20timelapse%20over%20the%20ocean?model=veo&width=1024" \
-H "Authorization: Bearer $POLLINATIONS_KEY"Text-to-speech, music generation, and audio transcription.
| Endpoint | Description |
|---|---|
GET /audio/{text} |
Simple URL-based TTS or music generation |
POST /v1/audio/speech |
OpenAI-compatible TTS |
POST /v1/audio/transcriptions |
Speech-to-text transcription |
Audio models: elevenlabs, elevenflash, eleven-multilingual-v2, eleven-dialogue, eleven-voice-changer, eleven-voice-isolator, elevenmusic, lyria-3-clip, eleven-sfx, whisper, gpt-transcribe, scribe, grok-transcribe, grok-tts, universal-2, universal-3.5-pro, stable-audio-3-medium, stable-audio-3-large, fish-audio-s2.1-pro, qwen-tts, qwen-tts-instruct, csm-1b, kokoro
Available voices: alloy, echo, fable, onyx, nova, shimmer, ash, ballad, coral, sage, verse, rachel, domi, bella, elli, charlotte, dorothy, sarah, emily, lily, matilda, adam, antoni, arnold, josh, sam, daniel, charlie, james, fin, callum, liam, george, brian, bill
Transform the speaker identity in an audio file while preserving its words, timing, emotion, and delivery. Accepts preset voice names or custom ElevenLabs voice IDs.
📥 Request body · multipart/form-data
| Field | Type | Description |
|---|---|---|
model |
string |
default: "eleven-voice-changer" |
audio * |
string · binary |
Source audio, up to 50 MB. ElevenLabs supports clips up to five minutes. |
voice |
string |
Target preset voice name or custom ElevenLabs voice ID. · default: "alloy" |
response_format |
"mp3" | "opus" | "aac" | "wav" | "pcm" |
default: "mp3" |
* = required field
📤 Response · 200 · audio/mpeg, audio/opus, audio/aac, audio/wav, audio/pcm — Success - Returns transformed speech
💻 Example
curl -X POST "https://gen.pollinations.ai/v1/audio/voice-changer" \
-H "Authorization: Bearer $POLLINATIONS_KEY" \
-F "audio=@./input.mp3"Remove music, ambient sound, and other background noise from an audio or video file while preserving spoken audio.
📥 Request body · multipart/form-data
| Field | Type | Description |
|---|---|---|
model |
string |
default: "eleven-voice-isolator" |
audio * |
string · binary |
Source audio or video, up to 50 MB and at least 4.6 seconds long. |
* = required field
📤 Response · 200 · audio/mpeg — Success - Returns isolated speech as MP3 audio
💻 Example
curl -X POST "https://gen.pollinations.ai/v1/audio/voice-isolator" \
-H "Authorization: Bearer $POLLINATIONS_KEY" \
-F "audio=@./input.mp3"Generate speech, music, sound effects, or dialogue from text. Compatible with the OpenAI TTS API for JSON requests.
Set model to elevenmusic, lyria-3-clip, stable-audio-3-medium, or stable-audio-3-large to generate music. Lyria returns one fixed 30-second MP3 clip. Pass any publicly accessible audio URL as reference_audio to run audio-to-audio (style transfer) on stable-audio-3-medium or stable-audio-3-large, or reference-audio conditioning on elevenmusic; for ElevenLabs inpainting, pass a composition_plan.
For multi-speaker audio, set model to eleven-dialogue and put one turn per line in input as <voice>: <text>. Voice labels may be preset names or ElevenLabs voice IDs; the top-level voice field is ignored for this model. Dialogue supports up to 10 unique voices and 2,000 total text characters.
Available voices: alloy, echo, fable, onyx, nova, shimmer, ash, ballad, coral, sage, verse, rachel, domi, bella, elli, charlotte, dorothy, sarah, emily, lily, matilda, adam, antoni, arnold, josh, sam, daniel, charlie, james, fin, callum, liam, george, brian, bill, conversational_a, conversational_b, read_speech_a, read_speech_b, read_speech_c, read_speech_d, af_alloy, af_aoede, af_bella, af_heart, af_jessica, af_kore, af_nicole, af_nova, af_river, af_sarah, af_sky, am_adam, am_echo, am_eric, am_fenrir, am_liam, am_michael, am_onyx, am_puck, am_santa, bf_alice, bf_emma, bf_isabella, bf_lily, bm_daniel, bm_fable, bm_george, bm_lewis, ef_dora, em_alex, em_santa, ff_siwis, hf_alpha, hf_beta, hm_omega, hm_psi, if_sara, im_nicola, jf_alpha, jf_gongitsune, jf_nezumi, jf_tebukuro, jm_kumo, pf_dora, pm_alex, pm_santa, zf_xiaobei, zf_xiaoni, zf_xiaoxiao, zf_xiaoyi, zm_yunjian, zm_yunxi, zm_yunxia, zm_yunyang, altair, ara, atlas, aurora, carina, castor, celeste, cosmo, eve, helios, helix, iris, kepler, leo, liora, lumen, luna, lux, naksh, orion, perseus, rex, rigel, sal, sirius, ursa, zagan, zenith
Output formats: mp3 (default), opus, aac, flac, wav, pcm
📥 Request body · application/json
| Field | Type | Description |
|---|---|---|
model |
string |
— |
input * |
string |
Text or prompt to generate. The eleven-dialogue model expects one voice: text turn per line. · length: 1…10000 |
safe |
string | boolean |
Optional safety features; accepts a comma-separated string or boolean shorthand. |
voice |
string |
default: "alloy" |
response_format |
enum (6) — "mp3", "opus", "aac", … |
default: "mp3" |
duration |
number |
range: 0.5…300 |
seconds |
number |
range: 1…380 |
steps |
integer |
range: 1…100 |
negative_prompt |
string |
— |
instrumental |
boolean |
— |
store_for_inpainting |
boolean |
— |
reference_audio |
string · uri |
Public HTTP(S) URL for reference-audio conditioning or audio-to-audio generation. |
conditioning_ref |
object |
— |
composition_plan |
object |
— |
seed |
integer |
max: 4294967295 |
instructions |
string |
— |
loop |
boolean |
— |
prompt_influence |
number |
max: 1 |
* = required field
📤 Response · 200 · audio/mpeg, audio/opus, audio/aac, audio/flac, audio/wav, audio/pcm — Success - Returns audio data
💻 Example
curl -X POST "https://gen.pollinations.ai/v1/audio/speech" \
-H "Authorization: Bearer $POLLINATIONS_KEY" \
-H "Content-Type: application/json" \
-d '{"input":"Hello world","voice":"nova"}'Generate base64-encoded speech with character-level timing for the original and normalized text. Supports the elevenlabs, elevenflash, and eleven-multilingual-v2 models.
📥 Request body · application/json
| Field | Type | Description |
|---|---|---|
model |
"elevenlabs" | "elevenflash" | "eleven-multilingual-v2" |
default: "elevenlabs" |
input * |
string |
Text to synthesize and align. · max length: 10000 |
voice |
string |
Preset voice name or custom ElevenLabs voice ID. · default: "alloy" |
response_format |
"mp3" | "opus" | "aac" | "wav" | "pcm" |
Encoding used for audio_base64. · default: "mp3" |
seed |
integer |
max: 4294967295 |
* = required field
📤 Response · 200 · application/json — Success - Returns base64 audio and character timings
| Field | Type | Description |
|---|---|---|
audio_base64 * |
string |
— |
alignment * |
object |
— |
alignment.characters |
string[] |
— |
alignment.character_start_times_seconds |
number[] |
— |
alignment.character_end_times_seconds |
number[] |
— |
normalized_alignment * |
object |
— |
normalized_alignment.characters |
string[] |
— |
normalized_alignment.character_start_times_seconds |
number[] |
— |
normalized_alignment.character_end_times_seconds |
number[] |
— |
* = required field
💻 Example
curl -X POST "https://gen.pollinations.ai/v1/audio/speech/with-timestamps" \
-H "Authorization: Bearer $POLLINATIONS_KEY" \
-H "Content-Type: application/json" \
-d '{"input":"Hello world","voice":"nova"}'Transcribe audio files to text. Compatible with the OpenAI Whisper API.
Supported audio formats: mp3, mp4, mpeg, mpga, m4a, wav, webm
Models:
whisper-large-v3(default) — OpenAI Whisper via OVHcloudwhisper-1— Alias for whisper-large-v3gpt-transcribe— Fast multilingual speech recognition with prompt contextscribe— ElevenLabs Scribe (90+ languages, word-level timestamps)grok-transcribe— xAI speech recognition with word timestamps, speaker labels, and text formattinguniversal-2— AssemblyAI Universal-2 (99 languages)universal-3.5-pro— AssemblyAI Universal-3.5 Pro (18 languages, code switching, prompting)
📥 Request body · multipart/form-data
| Field | Type | Description |
|---|---|---|
file * |
string · binary |
The audio file to transcribe. Supported formats: mp3, mp4, mpeg, mpga, m4a, wav, webm. |
model |
string |
The model to use. Options: whisper-large-v3, whisper-1, gpt-transcribe, scribe, grok-transcribe, universal-2, universal-3.5-pro. · default: "whisper-large-v3" |
language |
string |
Language of the audio in ISO-639-1 format (e.g. en, fr). Improves accuracy. |
prompt |
string |
Optional text to guide the model's style or continue a previous segment. |
response_format |
enum (6) — "json", "text", "srt", … |
The format of the transcript output. Support is model-dependent: srt and vtt require a model that renders subtitles, and diarized_json a diarization-capable one. Unsupported combinations return 400 naming the formats that model accepts. · default: "json" |
temperature |
number |
Sampling temperature between 0 and 1. Lower is more deterministic. |
speakers_expected |
integer |
Optional provider hint for the number of speakers. Only honored with response_format=diarized_json. · min: 1 |
* = required field
📤 Response · 200 · application/json — Success - Returns transcription
| Field | Type | Description |
|---|---|---|
text |
string |
— |
segments |
object[] |
OpenAI-compatible diarized segments. Present when response_format=diarized_json. |
segments[].type |
"transcript.text.segment" |
— |
segments[].id |
string |
— |
segments[].speaker |
string |
— |
segments[].text |
string |
— |
segments[].start |
number |
— |
segments[].end |
number |
— |
* = required field
💻 Example
curl -X POST "https://gen.pollinations.ai/v1/audio/transcriptions" \
-H "Authorization: Bearer $POLLINATIONS_KEY" \
-F "file=@./audio.mp3" \
-F "model=whisper-large-v3"Generate speech, dialogue, music, or sound effects from text via a simple GET request.
Text-to-speech (default): Returns spoken audio in the selected voice and format.
Known voice presets: alloy, echo, fable, onyx, nova, shimmer, ash, ballad, coral, sage, verse, rachel, domi, bella, elli, charlotte, dorothy, sarah, emily, lily, matilda, adam, antoni, arnold, josh, sam, daniel, charlie, james, fin, callum, liam, george, brian, bill, conversational_a, conversational_b, read_speech_a, read_speech_b, read_speech_c, read_speech_d, af_alloy, af_aoede, af_bella, af_heart, af_jessica, af_kore, af_nicole, af_nova, af_river, af_sarah, af_sky, am_adam, am_echo, am_eric, am_fenrir, am_liam, am_michael, am_onyx, am_puck, am_santa, bf_alice, bf_emma, bf_isabella, bf_lily, bm_daniel, bm_fable, bm_george, bm_lewis, ef_dora, em_alex, em_santa, ff_siwis, hf_alpha, hf_beta, hm_omega, hm_psi, if_sara, im_nicola, jf_alpha, jf_gongitsune, jf_nezumi, jf_tebukuro, jm_kumo, pf_dora, pm_alex, pm_santa, zf_xiaobei, zf_xiaoni, zf_xiaoxiao, zf_xiaoyi, zm_yunjian, zm_yunxi, zm_yunxia, zm_yunyang, altair, ara, atlas, aurora, carina, castor, celeste, cosmo, eve, helios, helix, iris, kepler, leo, liora, lumen, luna, lux, naksh, orion, perseus, rex, rigel, sal, sirius, ursa, zagan, zenith. ElevenLabs models also accept a custom voice ID.
Output formats: mp3 (default), opus, aac, flac, wav, pcm
Dialogue: The eleven-dialogue model expects one <voice>: <text> turn per line.
Music generation: Set model=elevenmusic, lyria-3-clip, stable-audio-3-medium, or stable-audio-3-large to generate music instead of speech. lyria-3-clip returns a fixed 30-second MP3 clip; elevenmusic supports duration (3-300 seconds) and instrumental mode; stable-audio-3-medium/stable-audio-3-large support seconds (1-380), steps, seed, and negative_prompt. Pass any publicly accessible audio URL as reference_audio to POST /v1/audio/speech.
⚙️ Parameters
| Param | In | Type | Description |
|---|---|---|---|
text * |
path |
string |
Text or prompt to generate. The eleven-dialogue model expects one voice: text turn per line. |
voice |
query |
string |
Voice preset or custom provider voice ID. Dialogue voices come from labels in the text. · default: "alloy" |
response_format |
query |
enum (6) — "mp3", "opus", "aac", … |
Audio output format. Grok TTS supports mp3, wav, and pcm; Fish Audio supports mp3 and pcm; CSM and Kokoro support mp3, opus, flac, wav, and pcm; Qwen TTS currently returns WAV regardless of this setting; lyria-3-clip and eleven-sfx support mp3 only. · default: "mp3" |
model |
query |
string |
Audio model for speech, dialogue, music, or sound-effect generation |
duration |
query |
string |
Music duration in seconds (elevenmusic 3-300; lyria-3-clip fixed at 30) |
seconds |
query |
number |
Audio duration in seconds for stable-audio-3-medium/large, 1-380 · range: 1…380 |
steps |
query |
integer |
Sampling steps (stable-audio-3-medium 1-100, stable-audio-3-large 4-8) · range: 1…100 |
negative_prompt |
query |
string |
Negative prompt for stable-audio-3-large |
instrumental |
query |
"true" | "false" |
If true, guarantees instrumental output (elevenmusic only) · default: "false" |
instructions |
query |
string |
Emotion/style instruction (qwen-tts-instruct only) |
loop |
query |
"true" | "false" |
Loop the generated sound effect (eleven-sfx only) |
prompt_influence |
query |
string |
How strictly to follow the prompt, 0-1 (eleven-sfx only) |
seed |
query |
integer |
Seed passed to the model. Same seed + parameters return the same cached result while available. · range: -1…4294967295 |
key |
query |
string |
API key (alternative to Authorization header) |
safe |
query |
string | boolean |
Safety features: comma-separated list of privacy, secrets, sexual, violence, shield, true, nsfw. true enables privacy,secrets; nsfw enables sexual,violence. Also accepted in the Pollinations-Safe header. Defaults to off; false and 0 are accepted as off. |
* = required parameter
📤 Response · 200 · audio/mpeg — Success - Returns audio data
💻 Example
curl "https://gen.pollinations.ai/audio/Hello%2C%20welcome%20to%20Pollinations!?voice=nova&response_format=mp3" \
-H "Authorization: Bearer $POLLINATIONS_KEY"OpenAI-compatible Realtime WebSocket for voice, multimodal, and transcription sessions.
| Endpoint | Description |
|---|---|
GET /realtime |
Pollinations Realtime session (model=gpt-realtime-2.1) |
GET /v1/realtime |
WebSocket Realtime session (model=gpt-realtime-2.1) |
Requires an API key with positive balance. Server clients can use Authorization: Bearer <key>; browser WebSocket clients can use ?key=pk_....
The WebSocket settles one billing event when the session closes. Selecting scribe-realtime creates a transcription session automatically; other realtime models create voice and multimodal sessions.
Events sent and received over both routes use the OpenAI Realtime protocol. See OpenAI's Realtime WebSocket events guide.
import WebSocket from "ws";
// Server: Bearer auth. Browser: append `&key=pk_...` instead (headers aren't settable).
const ws = new WebSocket(
"wss://gen.pollinations.ai/v1/realtime?model=gpt-realtime-2.1",
{ headers: { Authorization: `Bearer ${process.env.POLLINATIONS_API_KEY}` } },
);
ws.on("open", () => ws.send(JSON.stringify({
type: "session.update",
session: { type: "realtime", instructions: "Be concise." },
})));
ws.on("message", (m) => console.log(JSON.parse(m.toString())));Browser audio: play the model's audio through an <audio> element (e.g. a Web Audio MediaStreamDestination set as the element's srcObject), not straight to the Web Audio output. The browser only uses audio-element output as the echo-cancellation reference, so without it the mic re-captures the model's voice and it starts replying to itself. The WebRTC transport handles this automatically; on the WebSocket transport it's the client's responsibility.
Realtime models: gpt-realtime-2.1, gpt-realtime-2.1-mini, gpt-realtime-2, scribe-realtime, gpt-live-transcribe
OpenAI-compatible Realtime WebSocket for voice, multimodal, and transcription sessions.
Connect with wss://gen.pollinations.ai/realtime?model=gpt-realtime-2.1 and send/receive OpenAI Realtime JSON events over the socket. Selecting scribe-realtime creates a transcription session automatically.
Server clients can authenticate with Authorization: Bearer <key>. Browser WebSocket clients can use ?key=pk_... because they cannot set custom authorization headers.
Models: gpt-realtime-2.1, gpt-realtime-2.1-mini, gpt-realtime-2, scribe-realtime, gpt-live-transcribe.
Billing: requires a positive balance and settles one session total when the socket closes.
⚙️ Parameters
| Param | In | Type | Description |
|---|---|---|---|
model |
query |
"gpt-realtime-2.1" | "gpt-realtime-2.1-mini" | "gpt-realtime-2" | "scribe-realtime" | "gpt-live-transcribe" |
Realtime model to use. Supported models: gpt-realtime-2.1, gpt-realtime-2.1-mini, gpt-realtime-2, scribe-realtime, gpt-live-transcribe. · default: "gpt-realtime-2.1" |
key |
query |
string |
Pollinations API key. Useful for browser WebSocket clients that cannot set custom Authorization headers. |
* = required parameter
💻 Example
curl "https://gen.pollinations.ai/realtime?model=gpt-realtime-2.1&key=:key" \
-H "Authorization: Bearer $POLLINATIONS_KEY"OpenAI-compatible Realtime WebSocket for voice, multimodal, and transcription sessions.
Connect with wss://gen.pollinations.ai/v1/realtime?model=gpt-realtime-2.1 and send/receive OpenAI Realtime JSON events over the socket. Selecting scribe-realtime creates a transcription session automatically.
Server clients can authenticate with Authorization: Bearer <key>. Browser WebSocket clients can use ?key=pk_... because they cannot set custom authorization headers.
Models: gpt-realtime-2.1, gpt-realtime-2.1-mini, gpt-realtime-2, scribe-realtime, gpt-live-transcribe.
Billing: requires a positive balance and settles one session total when the socket closes.
⚙️ Parameters
| Param | In | Type | Description |
|---|---|---|---|
model |
query |
"gpt-realtime-2.1" | "gpt-realtime-2.1-mini" | "gpt-realtime-2" | "scribe-realtime" | "gpt-live-transcribe" |
Realtime model to use. Supported models: gpt-realtime-2.1, gpt-realtime-2.1-mini, gpt-realtime-2, scribe-realtime, gpt-live-transcribe. · default: "gpt-realtime-2.1" |
key |
query |
string |
Pollinations API key. Useful for browser WebSocket clients that cannot set custom Authorization headers. |
* = required parameter
💻 Example
curl "https://gen.pollinations.ai/v1/realtime?model=gpt-realtime-2.1&key=:key" \
-H "Authorization: Bearer $POLLINATIONS_KEY"Generate vector embeddings with an OpenAI-compatible response format.
| Endpoint | Description |
|---|---|
POST /v1/embeddings |
OpenAI-compatible embeddings endpoint |
GET /embeddings/models |
Embedding models with pricing and modalities |
gemini-2 supports text, image, audio, and video inputs. cohere-embed-v4 supports text and one image per input. The OpenAI and Qwen embedding models are text-only.
String batch input supports up to 32 items. For retrieval, use task_type with Gemini text input (it is converted to the recommended prompt instruction) or input_type (query or document) with Cohere. Dimensions are model-specific: Cohere supports 256, 512, 1024, or 1536; openai-3-small supports up to 1536; gemini-2 and openai-3-large support up to 3072; qwen3-embedding-8b supports up to 4096.
Gemini task instructions count toward prompt token usage. Cohere requests containing an image expose one combined usage count, so any accompanying text is billed at the image-input rate.
Gemini GA migration: gemini-2 now uses the GA embedding space. Do not mix preview-era and GA vectors; re-embed stored gemini-2 data before comparing it with new results.
Embedding models: gemini-2, openai-3-small, openai-3-large, cohere-embed-v4, qwen3-embedding-8b
Returns available embedding models with pricing, capabilities, and supported input modalities. When authenticated: models are filtered by API key permissions, and paid_only models are hidden if the account has no paid balance. Pass ?community=false to exclude community models or ?community=true to return only community models.
⚙️ Parameters
| Param | In | Type | Description |
|---|---|---|---|
community |
query |
"0" | "1" | "true" | "false" |
Filter by community status: true/1 for community-only, false/0 for official-only. Omit for all models. |
* = required parameter
📤 Response · 200 · application/json — Success
💻 Example
curl "https://gen.pollinations.ai/embeddings/models?community=0" \
-H "Authorization: Bearer $POLLINATIONS_KEY"Generate vector embeddings with an OpenAI-compatible response format.
Models: gemini-2 supports text, image, audio, and video. cohere-embed-v4 supports text and one image. OpenAI and Qwen embedding models are text-only.
Input: Pass a string, an array of up to 32 strings, or supported multimodal content parts (text, image_url, input_audio, video_url) in the input field.
Retrieval roles: Use task_type with Gemini text input; it is converted to the model's recommended prompt instruction. Use input_type (query or document) with Cohere.
Billing: Gemini task instructions count toward prompt token usage. Cohere image requests expose one combined usage count, so text accompanying an image is billed at the image-input rate.
Gemini migration: gemini-2 uses the GA embedding space. Do not mix preview-era and GA vectors; re-embed stored gemini-2 data before comparing it with new results.
Dimensions: Defaults are model-specific. Qwen supports up to 4096; Gemini and OpenAI large up to 3072; OpenAI small up to 1536; Cohere supports 256, 512, 1024, or 1536.
📥 Request body · application/json
| Field | Type | Description |
|---|---|---|
model |
string |
Embedding model to use · default: "openai-3-small" |
input * |
string | string[] | object | object[] |
Input text or content parts to embed. Supports strings, arrays of strings (max 32 inputs), or multimodal content parts (text, image_url, input_audio, video_url). Gemini supports every listed modality; Cohere Embed v4 supports text and one image per input. |
dimensions |
integer |
Output embedding dimensions (128-4096). Model-specific limits apply; Cohere supports 256, 512, 1024, or 1536. · range: 128…4096 |
task_type |
enum (8) — "SEMANTIC_SIMILARITY", "CLASSIFICATION", "CLUSTERING", … |
Gemini text-specific task hint, converted to the model's recommended prompt instruction |
input_type |
"query" | "document" |
Cohere-specific input role for retrieval. Use document when indexing and query when searching. |
encoding_format |
"float" | "base64" |
Output encoding for the embedding vector. base64 packs Float32 little-endian like OpenAI. · default: "float" |
* = required field
📤 Response · 200 · application/json — Success
Returns CreateEmbeddingResponse.
💻 Example
curl -X POST "https://gen.pollinations.ai/v1/embeddings" \
-H "Authorization: Bearer $POLLINATIONS_KEY" \
-H "Content-Type: application/json" \
-d '{"input":"Hello world"}'Discover available models with pricing, capabilities, and metadata. No authentication required.
| Endpoint | Returns |
|---|---|
GET /models |
All models with pricing, capabilities, and metadata |
GET /v1/models |
All models in OpenAI-compatible format ({object: "list", data: [...]}) |
GET /text/models |
Text models with pricing, context window, tool support |
GET /image/models |
Image & video models with capabilities and pricing |
GET /video/models |
Video models with capabilities and pricing |
GET /audio/models |
Audio models with supported voices |
GET /embeddings/models |
Embedding models with supported modalities |
GET /3d/models |
3D Generation models with supported modalities |
All model discovery endpoints accept an optional community query parameter:
| Parameter | Values | Behaviour |
|---|---|---|
| (omitted) | Returns all models (default, backward-compatible) | |
community=false |
false, 0 |
Excludes community models — returns official models only |
community=true |
true, 1 |
Returns community models only |
Any other value (e.g. tru, yes, 2) returns 400 Bad Request.
Example: GET /models?community=false
Rich model endpoints include capabilities for agentic/model traits:
tool_calling, reasoning, web_search, and code_execution.
Modalities, video frame controls, voices, and context length remain separate
structured fields.
Community models use an owner/model id and appear in the same discovery responses as Pollinations-operated models. Use community=true to return only community models or community=false to exclude them.
For registration, publishing, pricing, fallbacks, and health monitoring, see Publish a Model. For ownership endpoints and schemas, see Community Models under Resources.
Returns available models in the OpenAI-compatible format ({object: "list", data: [...]}), with Pollinations pricing and capability extensions. Official models are ordered by modality (text, image, video, 3D, audio, realtime, embedding), with each configured default first, followed by stable and then alpha/preview models from newest to oldest. Community models follow from newest to oldest. Use /models, /text/models, /image/models, /audio/models, or /embeddings/models for richer metadata. When authenticated: the owner's private community models are included, models are filtered by API key permissions, and paid_only models are hidden if the account has no paid balance. Pass ?community=false to exclude community models or ?community=true to return only community models.
⚙️ Parameters
| Param | In | Type | Description |
|---|---|---|---|
community |
query |
"0" | "1" | "true" | "false" |
Filter by community status: true/1 for community-only, false/0 for official-only. Omit for all models. |
* = required parameter
📤 Response · 200 · application/json — Success
| Field | Type | Description |
|---|---|---|
object * |
"list" |
— |
data * |
object[] |
— |
data[].id * |
string |
— |
data[].object * |
"model" |
— |
data[].created * |
number |
— |
data[].input_modalities |
string[] |
— |
data[].output_modalities |
string[] |
— |
data[].supported_endpoints |
string[] |
— |
data[].agent |
boolean |
— |
data[].base_model |
string |
— |
data[].pricing |
object |
— |
data[].capabilities |
string[] |
— |
data[].tools |
boolean |
— |
data[].reasoning |
boolean |
— |
data[].context_length |
number |
— |
data[].per_user_rpm |
number | null |
— |
* = required field
💻 Example
curl "https://gen.pollinations.ai/v1/models?community=0" \
-H "Authorization: Bearer $POLLINATIONS_KEY"{
"object": "list",
"data": [
{
"id": "openai",
"object": "model",
"created": 1700000000,
"owned_by": "pollinations"
},
{
"id": "claude",
"object": "model",
"created": 1700000000,
"owned_by": "pollinations"
},
{
"id": "gemini",
"object": "model",
"created": 1700000000,
"owned_by": "pollinations"
}
]
}Returns all available models with pricing, capabilities, and metadata. Official models are ordered by modality (text, image, video, 3D, audio, realtime, embedding), with each configured default first, followed by stable and then alpha/preview models from newest to oldest. Community models follow from newest to oldest. When authenticated: the owner's private community models are included, models are filtered by API key permissions, and paid_only models are hidden if the account has no paid balance. Pass ?community=false to exclude community models or ?community=true to return only community models.
⚙️ Parameters
| Param | In | Type | Description |
|---|---|---|---|
community |
query |
"0" | "1" | "true" | "false" |
Filter by community status: true/1 for community-only, false/0 for official-only. Omit for all models. |
* = required parameter
📤 Response · 200 · application/json — Success
💻 Example
curl "https://gen.pollinations.ai/models?community=0" \
-H "Authorization: Bearer $POLLINATIONS_KEY"Returns all available 3D model generation models with pricing, capabilities, and metadata. When authenticated: models are filtered by API key permissions, and paid_only models are hidden if the account has no paid balance. Pass ?community=false to exclude community models or ?community=true to return only community models.
⚙️ Parameters
| Param | In | Type | Description |
|---|---|---|---|
community |
query |
"0" | "1" | "true" | "false" |
Filter by community status: true/1 for community-only, false/0 for official-only. Omit for all models. |
* = required parameter
📤 Response · 200 · application/json — Success
💻 Example
curl "https://gen.pollinations.ai/3d/models?community=0" \
-H "Authorization: Bearer $POLLINATIONS_KEY"Returns all available image and video generation models with pricing, capabilities, and metadata. Video models are included here — check the outputModalities field to distinguish image vs video models. When authenticated: models are filtered by API key permissions, and paid_only models are hidden if the account has no paid balance. Pass ?community=false to exclude community models or ?community=true to return only community models.
⚙️ Parameters
| Param | In | Type | Description |
|---|---|---|---|
community |
query |
"0" | "1" | "true" | "false" |
Filter by community status: true/1 for community-only, false/0 for official-only. Omit for all models. |
* = required parameter
📤 Response · 200 · application/json — Success
💻 Example
curl "https://gen.pollinations.ai/image/models?community=0" \
-H "Authorization: Bearer $POLLINATIONS_KEY"Returns all available video generation models with pricing, capabilities, and metadata. When authenticated: models are filtered by API key permissions, and paid_only models are hidden if the account has no paid balance. Pass ?community=false to exclude community models or ?community=true to return only community models.
⚙️ Parameters
| Param | In | Type | Description |
|---|---|---|---|
community |
query |
"0" | "1" | "true" | "false" |
Filter by community status: true/1 for community-only, false/0 for official-only. Omit for all models. |
* = required parameter
📤 Response · 200 · application/json — Success
💻 Example
curl "https://gen.pollinations.ai/video/models?community=0" \
-H "Authorization: Bearer $POLLINATIONS_KEY"Returns all available text generation and community text models with pricing, capabilities, and metadata including context window size, supported modalities, and tool support. When authenticated: the owner's private community models are included, models are filtered by API key permissions, and paid_only models are hidden if the account has no paid balance. Pass ?community=false to exclude community models or ?community=true to return only community models.
⚙️ Parameters
| Param | In | Type | Description |
|---|---|---|---|
community |
query |
"0" | "1" | "true" | "false" |
Filter by community status: true/1 for community-only, false/0 for official-only. Omit for all models. |
* = required parameter
📤 Response · 200 · application/json — Success
💻 Example
curl "https://gen.pollinations.ai/text/models?community=0" \
-H "Authorization: Bearer $POLLINATIONS_KEY"Returns all available audio models (text-to-speech, music generation, and transcription) with pricing, capabilities, and metadata. When authenticated: models are filtered by API key permissions, and paid_only models are hidden if the account has no paid balance. Pass ?community=false to exclude community models or ?community=true to return only community models.
⚙️ Parameters
| Param | In | Type | Description |
|---|---|---|---|
community |
query |
"0" | "1" | "true" | "false" |
Filter by community status: true/1 for community-only, false/0 for official-only. Omit for all models. |
* = required parameter
📤 Response · 200 · application/json — Success
💻 Example
curl "https://gen.pollinations.ai/audio/models?community=0" \
-H "Authorization: Bearer $POLLINATIONS_KEY"Register, test, update, and remove community models owned by the authenticated account.
List private and public community models owned by the authenticated account. API keys require account:keys.
📤 Response · 200 · application/json — Registered community models
| Field | Type | Description |
|---|---|---|
data * |
object[] |
— |
provider * |
object |
— |
provider.name * |
string | null |
— |
provider.url * |
string · uri | null |
— |
* = required field
💻 Example
curl "https://gen.pollinations.ai/account/my-models" \
-H "Authorization: Bearer $POLLINATIONS_KEY"Register a private or public community text, image, or transcription model. Private is the default. Public models require an allowlisted account and may be free or priced. API keys require account:keys. The upstream bearer token is encrypted and never returned.
📥 Request body · application/json
| Field | Type | Description |
|---|---|---|
name * |
string |
length: 1…120 |
title * |
string |
Display name shown in the model catalog. · length: 1…42 |
description |
string |
max length: 160 |
visibility |
"private" | "public" |
"private": owner-only, shown only to the owner, with no owner-set price. "public": anyone and listed in the catalog; it may be free or priced. Publishing requires an allowlisted account. · default: "private" |
baseUrl * |
string · uri |
OpenAI-compatible /v1 base URL or full chat, image generation, or image edit URL. |
bearerToken * |
string |
— |
upstreamModel |
string |
length: 1…253 |
modality |
"text" | "image" | "transcription" |
Upstream API family. "text" uses /v1/chat/completions; "image" uses /v1/images/generations and optionally /v1/images/edits when the endpoint test succeeds; "transcription" uses /v1/audio/transcriptions. · default: "text" |
imagePricing |
"request" | "tokens" |
Image models only. "request": the generated-image price is charged once per generation. "tokens": provider-returned OpenAI image token usage is charged against per-token prices. Detected by the endpoint test. · default: "request" |
inputModalities |
"text" | "image" | "audio"[] |
Input types accepted by the model. Select every supported modality so the model catalog can advertise them accurately. |
advertised |
object |
Owner-declared catalog metadata for text models. |
advertised.capabilities |
"tool_calling" | "reasoning"[] |
— |
advertised.contextLength |
integer |
max: 10000000 |
perUserRpm |
number | null |
Maximum requests per minute for each Pollinations user. Decimals are supported; 0.5 means one request every two minutes. Null means no Pollinations-side limit. |
paidOnly |
boolean |
Restrict callers to spending Paid Pollen on this model. Use it when the upstream bills per use, so Quest Pollen cannot cover the price and leave you paying the inference cost. · default: false |
fallbacks |
string[] |
Community model ids ("/") tried in order when this model's upstream fails, or an empty array to clear them. Each must be another listed community model of the same modality, public or owned by you, and priced at or below this model on every price field. |
promptTextPrice |
number |
Pollen price. Token rates are per token internally (the dashboard displays per 1M); completionImagePrice is per generated image when imagePricing is "request". |
promptCachedPrice |
number |
Pollen price. Token rates are per token internally (the dashboard displays per 1M); completionImagePrice is per generated image when imagePricing is "request". |
promptCacheWritePrice |
number |
Pollen price. Token rates are per token internally (the dashboard displays per 1M); completionImagePrice is per generated image when imagePricing is "request". |
promptAudioPrice |
number |
Pollen price. Token rates are per token internally (the dashboard displays per 1M); completionImagePrice is per generated image when imagePricing is "request". |
promptImagePrice |
number |
Pollen price. Token rates are per token internally (the dashboard displays per 1M); completionImagePrice is per generated image when imagePricing is "request". |
completionTextPrice |
number |
Pollen price. Token rates are per token internally (the dashboard displays per 1M); completionImagePrice is per generated image when imagePricing is "request". |
completionReasoningPrice |
number |
Pollen price. Token rates are per token internally (the dashboard displays per 1M); completionImagePrice is per generated image when imagePricing is "request". |
completionAudioPrice |
number |
Pollen price. Token rates are per token internally (the dashboard displays per 1M); completionImagePrice is per generated image when imagePricing is "request". |
completionImagePrice |
number |
Pollen price. Token rates are per token internally (the dashboard displays per 1M); completionImagePrice is per generated image when imagePricing is "request". |
* = required field
📤 Response · 200 · application/json — Created community model
💻 Example
curl -X POST "https://gen.pollinations.ai/account/my-models" \
-H "Authorization: Bearer $POLLINATIONS_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"my-community-model","baseUrl":"https://api.example.com/v1","bearerToken":"sk-upstream-token"}'{
"visibility": "private",
"modality": "text",
"imagePricing": "request",
"inputModalities": [
"text"
]
}Set the public provider name and HTTPS service link shared by all community models owned by the authenticated account. Send both fields empty to clear the profile. Publishing approval and account:keys are required.
📥 Request body · application/json
| Field | Type | Description |
|---|---|---|
name * |
string |
max length: 42 |
url * |
string |
max length: 2048 |
* = required field
📤 Response · 200 · application/json — Updated community provider profile
| Field | Type | Description |
|---|---|---|
name * |
string | null |
— |
url * |
string · uri | null |
— |
* = required field
💻 Example
curl -X POST "https://gen.pollinations.ai/account/my-models/provider" \
-H "Authorization: Bearer $POLLINATIONS_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"My Provider","url":"https://api.example.com"}'Community models this model may declare as fallbacks: listed, public or owned by you, same modality, and priced at or below it on every price field. Computed with the same rule the update endpoint validates against, so every id listed here is accepted. Eligibility is re-checked when a request is routed, so a target repriced above this model afterwards stops serving without changing the stored list.
⚙️ Parameters
| Param | In | Type | Description |
|---|---|---|---|
id * |
path |
string |
— |
* = required parameter
📤 Response · 200 · application/json — Eligible fallback model ids
| Field | Type | Description |
|---|---|---|
data * |
string[] |
— |
* = required field
💻 Example
curl "https://gen.pollinations.ai/account/my-models/key_abc123/fallback-candidates" \
-H "Authorization: Bearer $POLLINATIONS_KEY"Fetch OpenAI-compatible upstream model IDs from a provider before registering a My Models endpoint. Limited to one probe every 30 seconds per account. API keys require account:keys.
📥 Request body · application/json
| Field | Type | Description |
|---|---|---|
baseUrl * |
string · uri |
— |
bearerToken * |
string |
— |
* = required field
📤 Response · 200 · application/json — Upstream model IDs
| Field | Type | Description |
|---|---|---|
data * |
string[] |
— |
* = required field
💻 Example
curl -X POST "https://gen.pollinations.ai/account/my-models/models" \
-H "Authorization: Bearer $POLLINATIONS_KEY" \
-H "Content-Type: application/json" \
-d '{"baseUrl":"https://api.example.com/v1","bearerToken":"sk-upstream-token"}'Test an OpenAI-compatible upstream model before registering it. Image tests detect the image pricing mode and probe the derived /images/edits endpoint. Limited to one probe every 30 seconds per account. API keys require account:keys.
📥 Request body · application/json
| Field | Type | Description |
|---|---|---|
baseUrl * |
string · uri |
— |
bearerToken * |
string |
— |
model * |
string |
length: 1…253 |
modality |
"text" | "image" | "transcription" |
Upstream API family. "text" uses /v1/chat/completions; "image" uses /v1/images/generations and optionally /v1/images/edits when the endpoint test succeeds; "transcription" uses /v1/audio/transcriptions. · default: "text" |
* = required field
📤 Response · 200 · application/json — Endpoint test result
| Field | Type | Description |
|---|---|---|
ok * |
boolean |
— |
message * |
string |
— |
usage * |
object |
Raw provider usage, or { images: 1 } when an image provider returns no token usage. |
billableUsage * |
object |
Normalized billable usage fields used to reveal applicable prices. |
imagePricing |
"request" | "tokens" |
Image tests only: pricing mode detected from the provider response. |
inputModalities |
"text" | "image" | "audio"[] |
Image tests only: input types detected from generation and edit probes. |
* = required field
💻 Example
curl -X POST "https://gen.pollinations.ai/account/my-models/test" \
-H "Authorization: Bearer $POLLINATIONS_KEY" \
-H "Content-Type: application/json" \
-d '{"baseUrl":"https://api.example.com/v1","bearerToken":"sk-upstream-token","model":"llama-3.3-70b"}'Update a community model owned by the authenticated account. Changing visibility to public publishes it and requires an allowlisted account; public models may be free or priced. API keys require account:keys.
⚙️ Parameters
| Param | In | Type | Description |
|---|---|---|---|
id * |
path |
string |
— |
* = required parameter
📥 Request body · application/json
| Field | Type | Description |
|---|---|---|
name |
string |
length: 1…120 |
title |
string |
Display name shown in the model catalog. · length: 1…42 |
description |
string |
max length: 160 |
visibility |
"private" | "public" |
"private": owner-only, shown only to the owner, with no owner-set price. "public": anyone and listed in the catalog; it may be free or priced. Publishing requires an allowlisted account. |
hidden |
boolean |
— |
baseUrl |
string · uri |
OpenAI-compatible /v1 base URL or full chat, image generation, or image edit URL. |
upstreamModel |
string |
length: 1…253 |
bearerToken |
string |
— |
perUserRpm |
number | null |
Maximum requests per minute for each Pollinations user. Decimals are supported; 0.5 means one request every two minutes. Null means no Pollinations-side limit. |
paidOnly |
boolean |
Restrict callers to spending Paid Pollen on this model. Use it when the upstream bills per use, so Quest Pollen cannot cover the price and leave you paying the inference cost. |
imagePricing |
"request" | "tokens" |
Image models only. "request": the generated-image price is charged once per generation. "tokens": provider-returned OpenAI image token usage is charged against per-token prices. Detected by the endpoint test. |
inputModalities |
"text" | "image" | "audio"[] |
Input types accepted by the model. Select every supported modality so the model catalog can advertise them accurately. |
advertised |
object |
Owner-declared catalog metadata for text models. |
advertised.capabilities |
"tool_calling" | "reasoning"[] |
— |
advertised.contextLength |
integer |
max: 10000000 |
fallbacks |
string[] |
Community model ids ("/") tried in order when this model's upstream fails, or an empty array to clear them. Each must be another listed community model of the same modality, public or owned by you, and priced at or below this model on every price field. |
promptTextPrice |
number |
Pollen price. Token rates are per token internally (the dashboard displays per 1M); completionImagePrice is per generated image when imagePricing is "request". |
promptCachedPrice |
number |
Pollen price. Token rates are per token internally (the dashboard displays per 1M); completionImagePrice is per generated image when imagePricing is "request". |
promptCacheWritePrice |
number |
Pollen price. Token rates are per token internally (the dashboard displays per 1M); completionImagePrice is per generated image when imagePricing is "request". |
promptAudioPrice |
number |
Pollen price. Token rates are per token internally (the dashboard displays per 1M); completionImagePrice is per generated image when imagePricing is "request". |
promptImagePrice |
number |
Pollen price. Token rates are per token internally (the dashboard displays per 1M); completionImagePrice is per generated image when imagePricing is "request". |
completionTextPrice |
number |
Pollen price. Token rates are per token internally (the dashboard displays per 1M); completionImagePrice is per generated image when imagePricing is "request". |
completionReasoningPrice |
number |
Pollen price. Token rates are per token internally (the dashboard displays per 1M); completionImagePrice is per generated image when imagePricing is "request". |
completionAudioPrice |
number |
Pollen price. Token rates are per token internally (the dashboard displays per 1M); completionImagePrice is per generated image when imagePricing is "request". |
completionImagePrice |
number |
Pollen price. Token rates are per token internally (the dashboard displays per 1M); completionImagePrice is per generated image when imagePricing is "request". |
* = required field
📤 Response · 200 · application/json — Updated community model
💻 Example
curl -X POST "https://gen.pollinations.ai/account/my-models/key_abc123/update" \
-H "Authorization: Bearer $POLLINATIONS_KEY" \
-H "Content-Type: application/json" \
-d '{"description":"Updated model description"}'{
"visibility": "private",
"modality": "text",
"imagePricing": "request",
"inputModalities": [
"text"
]
}Delete a community model owned by the authenticated account. API keys require account:keys.
⚙️ Parameters
| Param | In | Type | Description |
|---|---|---|---|
id * |
path |
string |
— |
* = required parameter
📤 Response · 200 · application/json — Deleted community model
| Field | Type | Description |
|---|---|---|
id * |
string |
— |
* = required field
💻 Example
curl -X DELETE "https://gen.pollinations.ai/account/my-models/key_abc123" \
-H "Authorization: Bearer $POLLINATIONS_KEY"Create, inspect, update, and remove managed agents owned by the authenticated account.
List prompt agents owned by the authenticated account. API keys require account:keys.
📤 Response · 200 · application/json — Owned agents
| Field | Type | Description |
|---|---|---|
data * |
object[] |
— |
data[].id * |
string |
— |
data[].name * |
string |
— |
data[].title * |
string |
— |
data[].description * |
string | null |
— |
data[].visibility * |
"private" | "public" |
— |
data[].baseUrl * |
string · uri |
— |
data[].upstreamModel * |
string |
— |
data[].systemPrompt * |
string |
— |
data[].baseModel * |
string |
— |
data[].mcpServers * |
"pollinations"[] |
— |
data[].createdAt * |
string |
— |
data[].updatedAt * |
string |
— |
* = required field
💻 Example
curl "https://gen.pollinations.ai/account/agents" \
-H "Authorization: Bearer $POLLINATIONS_KEY"Create and list a prompt agent in one operation. API keys require account:keys.
📥 Request body · application/json
| Field | Type | Description |
|---|---|---|
systemPrompt * |
string |
length: 1…8000 |
baseModel * |
string |
length: 1…253 |
mcpServers |
"pollinations"[] |
default: [] |
name * |
string |
length: 1…120 |
title * |
string |
length: 1…42 |
description |
string |
default: "" · max length: 160 |
visibility |
"private" | "public" |
default: "private" |
* = required field
📤 Response · 200 · application/json — Created agent
| Field | Type | Description |
|---|---|---|
id * |
string |
— |
name * |
string |
— |
title * |
string |
— |
description * |
string | null |
— |
visibility * |
"private" | "public" |
— |
baseUrl * |
string · uri |
— |
upstreamModel * |
string |
— |
systemPrompt * |
string |
— |
baseModel * |
string |
— |
mcpServers * |
"pollinations"[] |
— |
createdAt * |
string |
— |
updatedAt * |
string |
— |
* = required field
💻 Example
curl -X POST "https://gen.pollinations.ai/account/agents" \
-H "Authorization: Bearer $POLLINATIONS_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"my-agent","title":"My Agent","systemPrompt":"You are a helpful assistant.","baseModel":"openai","mcpServers":["pollinations"]}'Get an agent owned by the authenticated account. API keys require account:keys.
⚙️ Parameters
| Param | In | Type | Description |
|---|---|---|---|
id * |
path |
string |
— |
* = required parameter
📤 Response · 200 · application/json — Owned agent
| Field | Type | Description |
|---|---|---|
id * |
string |
— |
name * |
string |
— |
title * |
string |
— |
description * |
string | null |
— |
visibility * |
"private" | "public" |
— |
baseUrl * |
string · uri |
— |
upstreamModel * |
string |
— |
systemPrompt * |
string |
— |
baseModel * |
string |
— |
mcpServers * |
"pollinations"[] |
— |
createdAt * |
string |
— |
updatedAt * |
string |
— |
* = required field
💻 Example
curl "https://gen.pollinations.ai/account/agents/key_abc123" \
-H "Authorization: Bearer $POLLINATIONS_KEY"Replace an agent configuration and listing in one operation. API keys require account:keys.
⚙️ Parameters
| Param | In | Type | Description |
|---|---|---|---|
id * |
path |
string |
— |
* = required parameter
📥 Request body · application/json
| Field | Type | Description |
|---|---|---|
systemPrompt * |
string |
length: 1…8000 |
baseModel * |
string |
length: 1…253 |
mcpServers |
"pollinations"[] |
default: [] |
name |
string |
length: 1…120 |
title |
string |
length: 1…42 |
description |
string |
max length: 160 |
visibility |
"private" | "public" |
— |
* = required field
📤 Response · 200 · application/json — Updated agent
| Field | Type | Description |
|---|---|---|
id * |
string |
— |
name * |
string |
— |
title * |
string |
— |
description * |
string | null |
— |
visibility * |
"private" | "public" |
— |
baseUrl * |
string · uri |
— |
upstreamModel * |
string |
— |
systemPrompt * |
string |
— |
baseModel * |
string |
— |
mcpServers * |
"pollinations"[] |
— |
createdAt * |
string |
— |
updatedAt * |
string |
— |
* = required field
💻 Example
curl -X PATCH "https://gen.pollinations.ai/account/agents/key_abc123" \
-H "Authorization: Bearer $POLLINATIONS_KEY" \
-H "Content-Type: application/json" \
-d '{"systemPrompt":"You are a concise assistant.","baseModel":"openai","mcpServers":["pollinations"]}'Delete an agent and its model listing. API keys require account:keys.
⚙️ Parameters
| Param | In | Type | Description |
|---|---|---|---|
id * |
path |
string |
— |
* = required parameter
📤 Response · 200 · application/json — Deleted agent
| Field | Type | Description |
|---|---|---|
id * |
string |
— |
* = required field
💻 Example
curl -X DELETE "https://gen.pollinations.ai/account/agents/key_abc123" \
-H "Authorization: Bearer $POLLINATIONS_KEY"Upload images, audio, and video and get back a unique id and URL. Each upload gets its own id (re-uploading the same bytes yields a new one).
Base URL: https://media.pollinations.ai
| Endpoint | Description |
|---|---|
POST /upload |
Upload a file, receive a unique media URL |
GET /{id} |
Retrieve a previously uploaded file |
GET /{id}/metadata |
Get file metadata as JSON |
GET /media?tag={tag} |
List the public gallery for a tag (no auth) |
DELETE /media/{id} |
Delete a published item you own (secret sk_ key) |
Upload requires an API key; retrieval is public. The decoded/file-size limit is 100MB for both upload formats. Files use a 30-day lifecycle from upload or the latest refresh. Retrieving the file body refreshes that lifecycle only when the object is at least 15 days old; metadata and HEAD requests do not refresh it. Two upload formats are accepted:
Multipart form (browsers, files on disk):
curl -X POST "https://media.pollinations.ai/upload" \
-H "Authorization: Bearer YOUR_API_KEY" \
-F file=@path/to/image.pngBase64 JSON (programmatic callers that already hold the bytes):
curl -X POST "https://media.pollinations.ai/upload" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"data": "<base64-or-data-uri>", "contentType": "image/png", "name": "image.png"}'Tags publish (alpha). An optional tags field (comma-separated string, or a JSON array in the JSON format) publishes the upload into each tag's public gallery, where anyone can list it via GET /media?tag={tag}. Untagged uploads stay unlisted — reachable only by their unguessable id URL. Full endpoint reference: https://media.pollinations.ai/openapi.json
Upload an image, audio, or video file via multipart/form-data (field file) or application/json (base64 data). Returns a unique id and its retrieval URL; each upload gets its own id (re-uploading the same bytes yields a new one). Files are retained for 30 days.
Tags publish. An optional tags field publishes the upload into each tag's public gallery (GET /media?tag=…), where anyone can see it. Untagged uploads stay unlisted: reachable only by their unguessable id URL, never listed anywhere. Alpha: the publish tagging is new and may still change.
📥 Request body · application/json
| Field | Type | Description |
|---|---|---|
data * |
string |
Base64-encoded file bytes (with or without a data: prefix). |
contentType |
string |
MIME type; defaults to application/octet-stream. |
name |
string |
Filename; used for the download Content-Disposition. |
tags |
string | string[] |
Tags (publish the upload to those tags' public galleries): a comma-separated string or an array of strings. |
* = required field
📤 Response · 200 · application/json — Upload successful
| Field | Type | Description |
|---|---|---|
id * |
string |
Unique media id (also the retrieval id) |
url * |
string |
Public retrieval URL |
contentType * |
string |
— |
size * |
integer |
File size in bytes |
tags |
string[] |
Tags the upload was published with; present only when tagged |
* = required field
💻 Example
curl -X POST "https://media.pollinations.ai/upload" \
-H "Authorization: Bearer $POLLINATIONS_KEY" \
-F "file=@./image.png"List the public gallery for a tag: every published item carrying that tag, any owner, newest first. Tagging an upload is what publishes it, so galleries are fully public — no API key needed. tag is required.
Items reference storage with a 30-day lifecycle. A GET refreshes the lifecycle once an object is at least 15 days old. An expired item keeps its catalog entry, but its url 404s. Alpha: this endpoint is new and its API may still change.
⚙️ Parameters
| Param | In | Type | Description |
|---|---|---|---|
tag * |
query |
string |
Required. The public gallery to list: items carrying this tag, any owner. |
limit |
query |
integer |
Page size, 1–100. Omitted → 20. · range: 1…100 |
cursor |
query |
string |
Opaque pagination cursor from a previous response's nextCursor. |
* = required parameter
📤 Response · 200 · application/json — Page of media items
| Field | Type | Description |
|---|---|---|
items * |
object[] |
— |
items[].id * |
string |
Catalog item id |
items[].url * |
string |
Public retrieval URL |
items[].contentType * |
string |
— |
items[].size * |
integer | null |
File size in bytes |
items[].tags * |
string[] |
— |
items[].createdAt * |
string |
ISO-8601 timestamp |
nextCursor * |
string | null |
Opaque cursor for the next page, null when exhausted. Treat it as a token: pass it back verbatim as ?cursor= to fetch the next page — do not parse or construct it. |
hasMore * |
boolean |
true when more pages exist (nextCursor is non-null). Loop while hasMore is true. |
* = required field
💻 Example
curl "https://media.pollinations.ai/media?tag=:tag&limit=:limit"Delete a published media item you own: the file, its catalog entry, and all its tags are removed, so it disappears from galleries and its URL 404s. Requires your secret (sk_) API key. Untagged uploads were never published, have no catalog entry, and can't be deleted — they use the same 30-day lifecycle, refreshed by a GET once they are at least 15 days old. Alpha: this endpoint is new and its API may still change.
⚙️ Parameters
| Param | In | Type | Description |
|---|---|---|---|
id * |
path |
string |
Media id (from the upload response or GET /media). |
* = required parameter
📤 Response · 200 · application/json — Item deleted
| Field | Type | Description |
|---|---|---|
deleted * |
"true" |
— |
id * |
string |
Id of the deleted media item |
* = required field
💻 Example
curl -X DELETE "https://media.pollinations.ai/media/550e8400-e29b-41d4-a716-446655440000" \
-H "Authorization: Bearer $POLLINATIONS_KEY"Get a file by its id. Access keeps files from expiring.
⚙️ Parameters
| Param | In | Type | Description |
|---|---|---|---|
id * |
path |
string |
— |
* = required parameter
📤 Response · 200 — File content with appropriate Content-Type
💻 Example
curl "https://media.pollinations.ai/550e8400-e29b-41d4-a716-446655440000"Check existence and metadata without downloading the file.
⚙️ Parameters
| Param | In | Type | Description |
|---|---|---|---|
id * |
path |
string |
— |
* = required parameter
📤 Response · 200 — File exists (headers include Content-Type, Content-Length, X-Content-Id)
💻 Example
curl -X HEAD "https://media.pollinations.ai/550e8400-e29b-41d4-a716-446655440000"Return file metadata (id, content type, size, upload timestamp) as JSON without downloading the file body.
⚙️ Parameters
| Param | In | Type | Description |
|---|---|---|---|
id * |
path |
string |
— |
* = required parameter
📤 Response · 200 · application/json — File metadata
| Field | Type | Description |
|---|---|---|
id * |
string |
Unique media id |
contentType * |
string |
— |
size * |
integer |
File size in bytes |
uploadedAt |
string |
ISO-8601 upload timestamp, when recorded |
* = required field
💻 Example
curl "https://media.pollinations.ai/550e8400-e29b-41d4-a716-446655440000/metadata"Self-service endpoints for the authenticated user. All endpoints require authentication (API key or session). API keys need the relevant account:<scope> permission. Base path: /account.
account:usage is the read-only account-state scope for balances, usage, quests, and earnings. account:keys manages keys and, where enabled, my-models. These permissions are independent; request both when a client needs both. Newly created child keys cannot receive account:keys through this API.
| Endpoint | Description |
|---|---|
GET /account/profile |
GitHub username, image, and community model access |
GET /account/balance |
Current pollen balance |
GET /account/quests |
Read-only quest status |
GET /account/usage |
Per-request usage history with costs (account-wide) |
GET /account/usage/daily |
Daily aggregated usage for dashboards |
GET /account/key/usage |
Usage history for the calling API key only |
/account/agents |
Managed prompt-agent configuration |
/account/my-models |
Private community model registration and allowlisted public publishing |
GET /account/key |
API key validity, type, and permissions |
Returns user profile. githubUsername, image, and communityEndpointsAllowed are always included. name and email are included only when the API key has account:profile.
balance is the amount visible to this caller and is kept stable for existing clients:
- Budgeted API keys always get the key's remaining budget in
balance(no extra scope). - Sessions and unbudgeted keys get the account total (Quest Pollen + paid) in
balance. That path requiresaccount:usagefor API keys.
When the caller can view account usage (dashboard session or account:usage), the response also includes accountBalance: { total, tier, paid } so clients can see Quest Pollen vs paid Pollen. Budgeted keys without account:usage do not receive accountBalance — that would leak the owner's wallet.
Usage history for the API key used in the request. No extra scope — a key can always read its own usage. For account-wide usage across all keys, use GET /account/usage with account:usage.
Returns the quest catalog with account status. completed includes both globally completed quests and quests earned by the account. Requires account:usage. Claiming rewards is dashboard-only.
Per-request usage history: model, token counts, cost, response time. Requires account:usage.
Daily aggregated usage suitable for dashboards. Requires account:usage.
Returns the current API key's validity, type, and permissions.
Create and manage prompt agents and their callable owner/name model listings in one operation. POST /account/agents requires name, title, systemPrompt, and baseModel; description, visibility, and mcpServers are optional. PATCH /account/agents/{id} replaces the runtime configuration and can update listing fields. Managed agents are text-only and free, with no owner-set prices, fallbacks, or per-user request limit. Calls still consume Pollen for the base model and tool generations. API keys require account:keys.
See Publish an Agent for dashboard, CLI, and API examples.
Community text, image, and speech-to-text model management. Any authenticated account can list, create, update, delete, and call its private owner-only models. Text providers expose /v1/chat/completions; image providers expose /v1/images/generations and may also expose /v1/images/edits; transcription providers expose /v1/audio/transcriptions. Image responses use b64_json. The endpoint test detects image-edit support and selects image pricing: valid OpenAI image token usage enables per-1M-token pricing, otherwise a fixed Pollen price is charged once per successful generated image.
Public publishing requires communityEndpointsAllowed: true; request account-level publisher access with the allowlist form. Inspecting and testing an upstream endpoint is open to every account, limited to one probe every 30 seconds. The form does not register individual models. API keys require account:keys. The dashboard, Account API, and polli my-models support text, image, and transcription registration. See Publish a Model for setup, publishing, pricing, fallbacks, and health monitoring.
Returns your account profile. GitHub username, profile image, and community model access are always returned. Name and email are returned only when the API key has account:profile.
📤 Response · 200 · application/json — User profile
| Field | Type | Description |
|---|---|---|
githubUsername * |
string | null |
GitHub username if linked |
image * |
string | null |
Profile picture URL (e.g. GitHub avatar) |
communityEndpointsAllowed * |
boolean |
Whether the account is allowed to manage community endpoints. |
name |
string | null |
User's display name (only returned when the key has account:profile or account:keys) |
email |
string · email | null |
User's email address (only returned when the key has account:profile or account:keys) |
* = required field
💻 Example
curl "https://gen.pollinations.ai/account/profile" \
-H "Authorization: Bearer $POLLINATIONS_KEY"{
"githubUsername": "janedeveloper",
"image": "https://avatars.example.com/jane.jpg",
"communityEndpointsAllowed": false,
"name": "Jane Developer",
"email": "jane@example.com"
}Returns the quest catalog with the authenticated account's read-only status. Globally completed quests and quests earned by the account are both returned as completed. API keys require the read-only account:usage permission. Claiming rewards remains dashboard-only.
📤 Response · 200 · application/json — Quest status for the authenticated account
| Field | Type | Description |
|---|---|---|
quests * |
object[] |
— |
quests[].id * |
string |
— |
quests[].title * |
string |
— |
quests[].description * |
string |
— |
quests[].category * |
enum (6) — "setup", "grow", "build", … |
— |
quests[].state * |
"available" | "completed" | "coming_soon" |
— |
quests[].status * |
"open" | "completed" | "coming_soon" |
— |
quests[].rewardAmount * |
number |
— |
quests[].balanceBucket * |
"tier" | "pack" |
— |
quests[].url * |
string | null |
— |
quests[].reward * |
object | null |
— |
* = required field
💻 Example
curl "https://gen.pollinations.ai/account/quests" \
-H "Authorization: Bearer $POLLINATIONS_KEY"Returns the pollen balance visible to the caller. API keys with a budget always see their remaining budget in balance (no scope needed). When the caller can view account usage (account:usage or a dashboard session), the response also includes accountBalance: { total, tier, paid }. Unbudgeted keys without account:usage get 403. Key-scoped usage is GET /account/key/usage; account-wide usage is GET /account/usage.
📤 Response · 200 · application/json — Pollen balance
| Field | Type | Description |
|---|---|---|
balance * |
number |
Pollen remaining for this caller. Budgeted API keys see the key's remaining budget here, not the account total. Sessions and unbudgeted keys see the account total (Quest Pollen + paid). |
accountBalance |
object |
Full account balances. Included only when the caller can view account usage (dashboard session or account:usage). Omitted for budgeted keys that lack that permission so the account wallet is not leaked. |
accountBalance.total * |
number |
Quest Pollen + paid Pollen the account can spend on a regular model. Paid-only models spend paid alone, so use that field for them rather than this total. |
accountBalance.tier * |
number |
Quest Pollen remaining, never below 0 |
accountBalance.paid * |
number |
Paid Pollen remaining, never below 0 |
* = required field
💻 Example
curl "https://gen.pollinations.ai/account/balance" \
-H "Authorization: Bearer $POLLINATIONS_KEY"Returns your request history with per-request details: model used, token counts, cost, and response time. Defaults to the last 30 days, supports up to 90 days via days, or exact day/week/month periods via granularity and period. Supports JSON and CSV export. Each response is capped at 50,000 rows. Use before with before_event_id for stable cursor-based pagination. API keys require the read-only account:usage permission.
⚙️ Parameters
| Param | In | Type | Description |
|---|---|---|---|
format |
query |
"json" | "csv" |
default: "json" |
limit |
query |
number |
default: 100 · range: 1…50000 |
before |
query |
string |
— |
before_event_id |
query |
string |
— |
days |
query |
integer |
default: 30 · range: 1…90 |
granularity |
query |
"day" | "week" | "month" |
— |
period |
query |
string |
— |
api_key_ids |
query |
string |
— |
models |
query |
string |
— |
* = required parameter
📤 Response · 200 · application/json — Usage records
| Field | Type | Description |
|---|---|---|
usage * |
object[] |
Array of usage records |
usage[].timestamp * |
string |
Request timestamp (YYYY-MM-DD HH:mm:ss format) |
usage[].cursor_event_id * |
string |
Event id used with before_event_id for stable pagination |
usage[].type * |
string |
Request type (e.g., 'generate.image', 'generate.text') |
usage[].model * |
string | null |
Model used for generation |
usage[].api_key_id * |
string | null |
API key id used for generation |
usage[].api_key * |
string | null |
API key display name |
usage[].api_key_type * |
string | null |
Type of API key ('secret', 'publishable') |
usage[].meter_source * |
string | null |
Billing source: 'tier' = Quest Pollen balance, 'pack' = paid balance |
usage[].input_text_tokens * |
number |
Number of input text tokens |
usage[].input_cached_tokens * |
number |
Number of cached input tokens |
usage[].input_audio_tokens * |
number |
Number of input audio tokens |
usage[].input_audio_seconds * |
number |
Duration of input audio in seconds (for transcription/STT) |
usage[].input_image_tokens * |
number |
Number of input image tokens |
usage[].output_text_tokens * |
number |
Number of output text tokens |
usage[].output_reasoning_tokens * |
number |
Number of reasoning tokens (for models with chain-of-thought) |
usage[].output_audio_tokens * |
number |
Number of output audio tokens |
usage[].output_audio_seconds * |
number |
Duration of output audio in seconds (for TTS/music generation) |
usage[].output_image_tokens * |
number |
Number of output image tokens (1 per image) |
usage[].output_video_seconds * |
number |
Duration of output video in seconds |
usage[].cost_usd * |
number |
Cost in USD for this request |
usage[].response_time_ms * |
number | null |
Response time in milliseconds |
count * |
number |
Number of records returned |
* = required field
💻 Example
curl "https://gen.pollinations.ai/account/usage?format=json&limit=100" \
-H "Authorization: Bearer $POLLINATIONS_KEY"Returns aggregated usage for the requested time window, grouped by date, API key, model, and billing source. Use days for rolling windows or granularity and period for exact day/week/month periods. Useful for dashboards and spending analysis. Supports JSON and CSV export. Requires account:usage permission when using API keys.
⚙️ Parameters
| Param | In | Type | Description |
|---|---|---|---|
format |
query |
"json" | "csv" |
default: "json" |
days |
query |
integer |
default: 90 · range: 1…90 |
granularity |
query |
"day" | "week" | "month" |
— |
period |
query |
string |
— |
api_key_ids |
query |
string |
— |
* = required parameter
📤 Response · 200 · application/json — Usage records aggregated by date/API key/model/source
| Field | Type | Description |
|---|---|---|
usage * |
object[] |
Array of daily usage records |
usage[].date * |
string |
Date (YYYY-MM-DD format) |
usage[].api_key_id * |
string |
API key id used for these requests |
usage[].api_key * |
string | null |
API key name used for these requests |
usage[].model * |
string | null |
Model used |
usage[].meter_source * |
string | null |
Billing source: 'tier' = Quest Pollen balance, 'pack' = paid balance |
usage[].requests * |
number |
Number of requests |
usage[].cost_usd * |
number |
Total cost in USD |
count * |
number |
Number of records returned |
* = required field
💻 Example
curl "https://gen.pollinations.ai/account/usage/daily?format=json&days=90" \
-H "Authorization: Bearer $POLLINATIONS_KEY"Returns recent per-request earnings transactions, newest first. Requires account:usage permission when using API keys.
⚙️ Parameters
| Param | In | Type | Description |
|---|---|---|---|
limit |
query |
number |
default: 100 · range: 1…50000 |
days |
query |
integer |
default: 30 · range: 1…90 |
granularity |
query |
"day" | "week" | "month" |
— |
period |
query |
string |
— |
* = required parameter
📤 Response · 200 · application/json — Earnings transaction records
| Field | Type | Description |
|---|---|---|
transactions * |
object[] |
Earning transaction records |
transactions[].timestamp * |
string |
Request timestamp (YYYY-MM-DD HH:mm:ss format) |
transactions[].cursor_event_id * |
string |
Stable event id |
transactions[].entity_name * |
string |
Earning entity display name |
transactions[].model * |
string | null |
Model used for generation |
transactions[].meter_source * |
string | null |
Billing source: 'tier' = tier balance, 'pack' = paid balance |
transactions[].pollen_earned * |
number |
Developer credit earned |
count * |
number |
Number of records returned |
* = required field
💻 Example
curl "https://gen.pollinations.ai/account/earnings/transactions?limit=100&days=30" \
-H "Authorization: Bearer $POLLINATIONS_KEY"Returns developer earnings in one response: per-(date, entity) buckets and per-entity rollups across BYOP apps and community models. Rows include requests, baseline_price, reward basis cost_usd, and reward_rate. Use days for rolling windows or granularity and period for exact day/week/month periods. API keys require the read-only account:usage permission.
⚙️ Parameters
| Param | In | Type | Description |
|---|---|---|---|
format |
query |
"json" | "csv" |
default: "json" |
days |
query |
integer |
default: 90 · range: 1…90 |
granularity |
query |
"day" | "week" | "month" |
— |
period |
query |
string |
— |
* = required parameter
📤 Response · 200 · application/json — Earnings buckets and additive totals
| Field | Type | Description |
|---|---|---|
daily * |
object[] |
Per-(date, earning entity) buckets for the period |
daily[].date * |
string |
Date bucket (YYYY-MM-DD or hourly); empty string on rollup rows |
daily[].entity_id * |
string |
Earning entity id (BYOP app key or community model) |
daily[].entity_name * |
string |
Earning entity display name |
daily[].source * |
"byop_markup" | "community_model" |
Reward source, such as byop_markup or community_model |
daily[].requests * |
number |
Number of billed requests |
daily[].paid_requests * |
number |
Billed requests paid from paid balance |
daily[].tier_requests * |
number |
Billed requests paid from tier balance |
daily[].baseline_price * |
number |
Model cost before markup (sum over the bucket) |
daily[].pollen_earned * |
number |
Developer credit earned over the bucket |
daily[].paid_earned * |
number |
Developer credit earned from paid-balance spend |
daily[].tier_earned * |
number |
Developer credit earned from Quest Pollen spend |
daily[].cost_usd * |
number |
Reward basis total for the bucket; BYOP rows use payer charge, community model rows use model price |
daily[].reward_rate * |
number |
Average reward or markup rate applied |
perEntity * |
object[] |
Per-earning-entity rollups for the period |
perEntity[].date * |
string |
Date bucket (YYYY-MM-DD or hourly); empty string on rollup rows |
perEntity[].entity_id * |
string |
Earning entity id (BYOP app key or community model) |
perEntity[].entity_name * |
string |
Earning entity display name |
perEntity[].source * |
"byop_markup" | "community_model" |
Reward source, such as byop_markup or community_model |
perEntity[].requests * |
number |
Number of billed requests |
perEntity[].paid_requests * |
number |
Billed requests paid from paid balance |
perEntity[].tier_requests * |
number |
Billed requests paid from tier balance |
perEntity[].baseline_price * |
number |
Model cost before markup (sum over the bucket) |
perEntity[].pollen_earned * |
number |
Developer credit earned over the bucket |
perEntity[].paid_earned * |
number |
Developer credit earned from paid-balance spend |
perEntity[].tier_earned * |
number |
Developer credit earned from Quest Pollen spend |
perEntity[].cost_usd * |
number |
Reward basis total for the bucket; BYOP rows use payer charge, community model rows use model price |
perEntity[].reward_rate * |
number |
Average reward or markup rate applied |
* = required field
💻 Example
curl "https://gen.pollinations.ai/account/earnings?format=json&days=90" \
-H "Authorization: Bearer $POLLINATIONS_KEY"{
"daily": [
{
"source": "byop_markup"
}
],
"perEntity": [
{
"source": "byop_markup"
}
]
}List all API keys for the current user. Requires account:keys permission when using API keys. Secret key values are never returned.
📤 Response · 200 — List of API keys
💻 Example
curl "https://gen.pollinations.ai/account/keys" \
-H "Authorization: Bearer $POLLINATIONS_KEY"Create a new API key. To create an app key, use type: "publishable" with redirectUris. Publishable app keys default developer earnings off; send earningsEnabled: true to opt in. Requires account:keys permission when using API keys. The full key value is returned only once in the response. The keys account permission is automatically stripped from child keys to prevent escalation.
📥 Request body · application/json
| Field | Type | Description |
|---|---|---|
name * |
string |
Name for the API key · length: 1…253 |
type |
"secret" | "publishable" |
Key type: secret (sk_) or publishable app key (pk_). Use publishable to create an app key. · default: "secret" |
expiresIn |
integer |
Expiry in seconds from now (max 365 days) · max: 31536000 |
allowedModels |
string[] | null |
Model IDs this key can access. null = all models |
pollenBudget |
number | null |
Pollen budget cap. Publishable keys accept only null, omission, or 0 and always use 0; secret keys use null for unlimited |
accountPermissions |
string[] | null |
Account permissions (e.g. ["usage"]). "keys" is auto-stripped. |
redirectUris |
string[] |
Allowed OAuth redirect URIs for publishable app keys. Required for OAuth app flows. Must be https:// except http:// loopback URIs for local apps. Matching pins scheme, host, port, and path; one trailing slash is ignored. If the registered URI has no query, incoming query params are allowed; if it has a query, the query must match exactly. Loopback ports are matched port-agnostically. |
earningsEnabled |
boolean |
Enable developer earnings for publishable app keys. Defaults to false; send true to opt in. |
* = required field
📤 Response · 200 — Created API key with full secret
💻 Example
curl -X POST "https://gen.pollinations.ai/account/keys" \
-H "Authorization: Bearer $POLLINATIONS_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"my-app-backend","type":"secret","allowedModels":["openai","flux"],"pollenBudget":100}'Delete/revoke an API key. Requires account:keys permission when using API keys. Cannot revoke the key used to authenticate the request.
⚙️ Parameters
| Param | In | Type | Description |
|---|---|---|---|
id * |
path |
string |
— |
* = required parameter
📤 Response · 200 — Key revoked
💻 Example
curl -X DELETE "https://gen.pollinations.ai/account/keys/key_abc123" \
-H "Authorization: Bearer $POLLINATIONS_KEY"Returns information about the API key used in the request: validity, type (secret/publishable), expiry, permissions, and remaining budget. Useful for validating keys without making generation requests.
📤 Response · 200 · application/json — API key status and information
| Field | Type | Description |
|---|---|---|
valid * |
boolean |
Whether the API key is valid and active |
type * |
"publishable" | "secret" |
Type of API key |
name * |
string | null |
Display name of the API key |
expiresAt * |
string | null |
Expiry timestamp in ISO 8601 format, null if never expires |
expiresIn * |
number | null |
Seconds until expiry, null if never expires |
permissions * |
object |
API key permissions |
permissions.models * |
string[] | null |
List of allowed model IDs, null = all models allowed |
permissions.account * |
string[] | null |
List of account permissions, null = no account access |
pollenBudget * |
number | null |
Remaining pollen budget for this key, null = unlimited (uses user balance) |
rateLimitEnabled * |
boolean |
Whether rate limiting is enabled for this key |
userId * |
string | null |
Stable id of the user that owns this key — server-attested. |
byopApp * |
object | null |
BYOP app attribution for keys minted through the BYOP authorize flow. Server-attested; null for non-BYOP keys. |
* = required field
💻 Example
curl "https://gen.pollinations.ai/account/key" \
-H "Authorization: Bearer $POLLINATIONS_KEY"{
"valid": true,
"type": "secret",
"name": "my-bot",
"expiresAt": null,
"expiresIn": null,
"permissions": {
"models": null,
"account": [
"usage"
]
},
"pollenBudget": null,
"rateLimitEnabled": false
}Returns usage history for the API key used in the request. No scope required — a key can always read its own usage. Use before with before_event_id for stable cursor-based pagination. For account-wide usage across all keys, use /account/usage with account:usage.
⚙️ Parameters
| Param | In | Type | Description |
|---|---|---|---|
format |
query |
"json" | "csv" |
default: "json" |
limit |
query |
number |
default: 100 · range: 1…50000 |
before |
query |
string |
— |
before_event_id |
query |
string |
— |
days |
query |
integer |
default: 30 · range: 1…90 |
granularity |
query |
"day" | "week" | "month" |
— |
period |
query |
string |
— |
api_key_ids |
query |
string |
— |
models |
query |
string |
— |
* = required parameter
📤 Response · 200 · application/json — Usage records for this key
| Field | Type | Description |
|---|---|---|
usage * |
object[] |
Array of usage records |
usage[].timestamp * |
string |
Request timestamp (YYYY-MM-DD HH:mm:ss format) |
usage[].cursor_event_id * |
string |
Event id used with before_event_id for stable pagination |
usage[].type * |
string |
Request type (e.g., 'generate.image', 'generate.text') |
usage[].model * |
string | null |
Model used for generation |
usage[].api_key_id * |
string | null |
API key id used for generation |
usage[].api_key * |
string | null |
API key display name |
usage[].api_key_type * |
string | null |
Type of API key ('secret', 'publishable') |
usage[].meter_source * |
string | null |
Billing source: 'tier' = Quest Pollen balance, 'pack' = paid balance |
usage[].input_text_tokens * |
number |
Number of input text tokens |
usage[].input_cached_tokens * |
number |
Number of cached input tokens |
usage[].input_audio_tokens * |
number |
Number of input audio tokens |
usage[].input_audio_seconds * |
number |
Duration of input audio in seconds (for transcription/STT) |
usage[].input_image_tokens * |
number |
Number of input image tokens |
usage[].output_text_tokens * |
number |
Number of output text tokens |
usage[].output_reasoning_tokens * |
number |
Number of reasoning tokens (for models with chain-of-thought) |
usage[].output_audio_tokens * |
number |
Number of output audio tokens |
usage[].output_audio_seconds * |
number |
Duration of output audio in seconds (for TTS/music generation) |
usage[].output_image_tokens * |
number |
Number of output image tokens (1 per image) |
usage[].output_video_seconds * |
number |
Duration of output video in seconds |
usage[].cost_usd * |
number |
Cost in USD for this request |
usage[].response_time_ms * |
number | null |
Response time in milliseconds |
count * |
number |
Number of records returned |
* = required field
💻 Example
curl "https://gen.pollinations.ai/account/key/usage?format=json&limit=100" \
-H "Authorization: Bearer $POLLINATIONS_KEY"Public quest catalog and available rewards.
Returns product quests and GitHub issue quest instances in one list.
📤 Response · 200 · application/json — Quest catalog
| Field | Type | Description |
|---|---|---|
quests * |
object[] |
— |
quests[].id * |
string |
— |
quests[].title * |
string |
— |
quests[].description * |
string |
— |
quests[].category * |
enum (6) — "setup", "grow", "build", … |
— |
quests[].state * |
"available" | "completed" | "coming_soon" |
— |
quests[].rewardAmount * |
number |
— |
quests[].balanceBucket * |
"tier" | "pack" |
— |
quests[].goal |
object |
— |
quests[].url * |
string | null |
— |
* = required field
💻 Example
curl "https://gen.pollinations.ai/quests/catalog"Returns raw model health rows from the public Tinybird model_health pipe.
The optional minutes query parameter controls the rolling window and must be an integer between 1 and 10080.
The X-Model-Status-Timestamp response header reports when the data was fetched from Tinybird; X-Model-Status-Stale is set when stale data is returned during an upstream failure.
📤 Response · 200 · application/json — Success
💻 Example
curl "https://gen.pollinations.ai/v1/models/status" \
-H "Authorization: Bearer $POLLINATIONS_KEY"Generate 3D models from text prompts and images via a simple GET request. Returns glTF Binary in GLB format. Depending on the model, certain models ignore text inputs — any text prompt passed to the Trellis 2 family will be ignored; only the image URL is used.
Available models: trellis-2, hyper3d-rodin
Note:
hyper3d-rodinrequires Paid Pollen.trellis-2(the default) supportslow,medium, andhighresolution and works with Quest Pollen.
Generate a 3D model from a text prompt or reference image(s). Returns GLB by default.
Available models: trellis-2, hyper3d-rodin. trellis-2 is the default.
Pass reference image URL(s) via the image parameter for image-to-3D models (trellis-2). Separate multiple URLs with | or ,. hyper3d-rodin accepts both images and a text prompt.
Browse all available models and their input requirements at /3d/models.
⚙️ Parameters
| Param | In | Type | Description |
|---|---|---|---|
prompt * |
path |
string |
Text description of the 3D model to generate (required for text-to-3D models such as Hyper3D Rodin; ignored by image-only models such as Trellis 2) |
model * |
query |
enum (6) — "trellis-2", "hyper3d-rodin", "trellis-2-low", … |
Model to use. See /3d/models for the full list and per-model input requirements. · default: "trellis-2" |
resolution |
query |
"low" | "medium" | "high" |
Output detail for trellis-2. Defaults to low. |
image |
query |
string |
Reference image URL(s) for image-to-3D generation. Separate multiple URLs with | or ,. Required for image-only models (e.g. trellis, triposr, sf3d). |
seed |
query |
integer |
Seed for varied generations. Passed through to models that support it (hyper3d-rodin); otherwise only affects the media-cache key, so a new seed forces a fresh generation for the same prompt/image. |
safe |
query |
string | boolean |
Safety features: comma-separated list of privacy, secrets, sexual, violence, shield, true, nsfw. true enables privacy,secrets; nsfw enables sexual,violence. Also accepted in the Pollinations-Safe header. Defaults to off; false and 0 are accepted as off. |
* = required parameter
📤 Response · 200 · model/gltf-binary — Success - Returns the generated 3D model
💻 Example
curl "https://gen.pollinations.ai/3d/a%20low-poly%20treasure%20chest?model=trellis-2&resolution=low" \
-H "Authorization: Bearer $POLLINATIONS_KEY"Generate a 3D model from a text prompt or reference image using JSON parameters. trellis-2 supports low, medium, and high resolution with variable pricing.
⚙️ Parameters
| Param | In | Type | Description |
|---|---|---|---|
prompt * |
path |
string |
Text description of the 3D model to generate (required for text-to-3D models; ignored by image-only models) |
key |
query |
string |
API key (alternative to Authorization header) |
safe |
query |
string | boolean |
Safety features: comma-separated list of privacy, secrets, sexual, violence, shield, true, nsfw. true enables privacy,secrets; nsfw enables sexual,violence. Also accepted in the Pollinations-Safe header. Defaults to off; false and 0 are accepted as off. |
* = required parameter
📥 Request body · application/json
| Field | Type | Description |
|---|---|---|
model |
enum (6) — "trellis-2", "hyper3d-rodin", "trellis-2-low", … |
Model to use for 3D generation. See /3d/models for the full list and per-model input requirements. · default: "trellis-2" |
image |
string | string[] |
Reference image URL or array of URLs for image-to-3D generation, optionally guided by the path prompt on supported models. A string is treated as one complete URL. |
resolution |
"low" | "medium" | "high" |
Output voxel-grid resolution for trellis-2: low (512³), medium (1024³), or high (1536³). Higher resolutions add detail, take longer, and cost more. · default: "low" |
seed |
integer |
Seed for varied generations. Passed to models that support it. |
* = required field
📤 Response · 200 · model/gltf-binary — Success - Returns the generated 3D model
💻 Example
curl -X POST "https://gen.pollinations.ai/3d/a%20low-poly%20treasure%20chest?key=:key&safe=:safe" \
-H "Authorization: Bearer $POLLINATIONS_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"hyper3d-rodin"}'All endpoints return errors in this envelope:
{
"status": 400,
"success": false,
"error": {
"code": "BAD_REQUEST",
"message": "Description of what went wrong",
"timestamp": "2026-01-01T00:00:00.000Z",
"details": { "name": "ValidationError" },
"requestId": "req_abc123"
}
}| Status | Code | Description |
|---|---|---|
400 |
BAD_REQUEST |
Invalid input. details includes formErrors and fieldErrors for validation failures. |
400 |
invalid_image_url |
A supplied image URL is malformed, not HTTP(S), points at a private or credentialed host, or redirects. Provide a direct public image URL. |
400 |
failed_to_download_image |
A supplied image URL could not be downloaded — host unreachable, DNS failure, a non-2xx response from the image host, or a body that ended mid-read. The host's status is reported in details.upstreamStatus. |
400 |
image_too_large |
A supplied image exceeds the per-image size cap, or the request exceeds the per-request image size or count cap. |
400 |
unsupported_image_media_type |
A supplied image declares no media type and could not be recognized from its content. A declared media type is forwarded to the provider as-is, so whether a given format is usable is answered by the provider, not here. |
401 |
UNAUTHORIZED |
Missing or invalid API key. Provide via Authorization: Bearer <key> header or ?key=<key> query param. |
402 |
PAYMENT_REQUIRED |
Insufficient pollen balance or API key budget exhausted. |
403 |
FORBIDDEN |
Access denied — insufficient permissions or paid-model access for this model. |
404 |
NOT_FOUND |
Resource not found. |
405 |
METHOD_NOT_ALLOWED |
HTTP method not supported on this route. |
409 |
CONFLICT |
Request conflicts with current resource state (e.g. duplicate key name). |
422 |
UNPROCESSABLE_ENTITY |
Request was well-formed but semantically invalid — typically a model rejection or unsupported parameter combination. |
422 |
content_policy_violation |
Prompt, input, or generated content was blocked by content moderation. Adjust the input and retry. |
429 |
RATE_LIMITED |
Too many requests. Slow down. |
500 |
INTERNAL_ERROR |
Server error. We're on it. |
502 |
BAD_GATEWAY |
Upstream provider returned an unexpected error (auth, billing). |
503 |
SERVICE_UNAVAILABLE |
Temporarily unavailable — usually the safety/balance check service is degraded. Retry with backoff. |
Reusable request/response objects referenced from the endpoints above.
Marks the end of a static prompt prefix to cache (Gemini, Claude, and Nova models). Place on the final content block of the prefix; repeat requests bill the cached prefix at ~10% of the input rate. See Text Generation → Prompt caching.
| Field | Type | Description |
|---|---|---|
type * |
"ephemeral" |
— |
* = required field
| Field | Type | Description |
|---|---|---|
cached_input_tokens |
integer | null |
— |
cache_creation_input_tokens |
integer | null |
— |
cache_read_input_tokens |
integer | null |
— |
completion_tokens * |
integer |
— |
completion_tokens_details |
object | null |
— |
prompt_tokens * |
integer |
— |
prompt_tokens_details |
object | null |
— |
reasoning_tokens |
integer | null |
— |
total_tokens * |
integer |
— |
* = required field
| Field | Type | Description |
|---|---|---|
hate |
object |
— |
hate.filtered * |
boolean |
— |
hate.severity * |
ContentFilterSeverity |
— |
self_harm |
object |
— |
self_harm.filtered * |
boolean |
— |
self_harm.severity * |
ContentFilterSeverity |
— |
sexual |
object |
— |
sexual.filtered * |
boolean |
— |
sexual.severity * |
ContentFilterSeverity |
— |
violence |
object |
— |
violence.filtered * |
boolean |
— |
violence.severity * |
ContentFilterSeverity |
— |
jailbreak |
object |
— |
jailbreak.filtered * |
boolean |
— |
jailbreak.detected * |
boolean |
— |
protected_material_text |
object |
— |
protected_material_text.filtered * |
boolean |
— |
protected_material_text.detected * |
boolean |
— |
protected_material_code |
object |
— |
protected_material_code.filtered * |
boolean |
— |
protected_material_code.detected * |
boolean |
— |
* = required field
Type: "safe" | "low" | "medium" | "high"
| Field | Type | Description |
|---|---|---|
model |
string |
Embedding model to use · default: "openai-3-small" |
input * |
string | string[] | object | object[] |
Input text or content parts to embed. Supports strings, arrays of strings (max 32 inputs), or multimodal content parts (text, image_url, input_audio, video_url). Gemini supports every listed modality; Cohere Embed v4 supports text and one image per input. |
dimensions |
integer |
Output embedding dimensions (128-4096). Model-specific limits apply; Cohere supports 256, 512, 1024, or 1536. · range: 128…4096 |
task_type |
enum (8) — "SEMANTIC_SIMILARITY", "CLASSIFICATION", "CLUSTERING", … |
Gemini text-specific task hint, converted to the model's recommended prompt instruction |
input_type |
"query" | "document" |
Cohere-specific input role for retrieval. Use document when indexing and query when searching. |
encoding_format |
"float" | "base64" |
Output encoding for the embedding vector. base64 packs Float32 little-endian like OpenAI. · default: "float" |
* = required field
| Field | Type | Description |
|---|---|---|
object * |
"list" |
— |
data * |
object[] |
— |
data[].object * |
"embedding" |
— |
data[].embedding * |
number[] | string |
Embedding vector — array of floats, or base64-encoded Float32 (little-endian) when encoding_format=base64. |
data[].index * |
integer |
Index of the embedding in the list |
model * |
string |
— |
usage * |
object |
— |
usage.prompt_tokens * |
integer |
— |
usage.total_tokens * |
integer |
— |
* = required field
| Field | Type | Description |
|---|---|---|
prompt * |
string |
A text description of the desired image(s) · length: 1…32000 |
model |
string |
The model to use for image generation · default: "flux" |
n |
integer |
Number of images to generate (currently max 1) · default: 1 · range: 1…1 |
size |
string |
Image size as WIDTHxHEIGHT (e.g., 1024x1024, 512x512) · default: "1024x1024" |
quality |
"standard" | "hd" | "low" | "medium" | "high" |
Image quality. OpenAI 'standard'/'hd' mapped to Pollinations equivalents · default: "medium" |
response_format |
"url" | "b64_json" |
Return format. "url" returns a pollinations.ai URL, "b64_json" returns base64-encoded image data · default: "b64_json" |
user |
string |
End-user identifier for abuse tracking |
image |
string | string[] |
Reference image URL(s) for image-to-image generation (Pollinations extension) |
resolution |
enum (6) — "1k", "2k", "480p", … |
Output resolution for resolution-priced image and video models (Pollinations extension) |
safe |
string | boolean |
Safety features: comma-separated list of privacy, secrets, sexual, violence, shield, true, nsfw. true enables privacy,secrets; nsfw enables sexual,violence. Also accepted in the Pollinations-Safe header. Defaults to off; false and 0 are accepted as off. |
* = required field
| Field | Type | Description |
|---|---|---|
created * |
integer |
— |
data * |
object[] |
— |
data[].url |
string |
— |
data[].b64_json |
string |
— |
data[].media_type |
string |
MIME type for non-raster output such as image/svg+xml |
data[].revised_prompt |
string |
— |
usage * |
object |
— |
usage.input_tokens * |
integer |
— |
usage.output_tokens * |
integer |
— |
usage.total_tokens * |
integer |
— |
usage.input_tokens_details * |
object |
— |
* = required field
| Field | Type | Description |
|---|---|---|
name * |
string |
— |
upstreamStatus |
integer |
— |
upstreamHost |
string |
— |
upstreamBody |
string |
— |
* = required field
Union type. One of:
type: "text"— fields:text,cache_controltype: "image_url"— fields:image_urltype: "video_url"— fields:video_urltype: "input_audio"— fields:input_audio,cache_controltype: "file"— fields:file,cache_controlobject
| Field | Type | Description |
|---|---|---|
name * |
string |
— |
formErrors * |
string[] |
— |
fieldErrors * |
object |
— |
* = required field