• Blog
  • Docs
  • Pricing
  • We’re hiring!
Log inSign up
kamenxrider

kamenxrider

readwise-mastra

Public
Like
readwise-mastra
Home
Code
9
app
1
jobs
1
lib
6
web
3
IMPLEMENTATION_RECAP.md
grounding.md
keyupdates.md
plan.md
tracker.md
Environment variables
6
Branches
1
Pull requests
Remixes
History
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.
Sign up now
Code
/
grounding.md
Code
/
grounding.md
Search
…
grounding.md

Your earlier direction was mostly right (OpenAI-compatible chat completions + Bearer key), but the correct canonical host/endpoint from paste.txt is https://gen.pollinations.ai/v1/chat/completions (and /openai is explicitly marked legacy/deprecated).[1] So Townie should implement Pollinations against gen.pollinations.ai by default, keep the base URL configurable, and add model discovery + fallback selection.[2][1]

Townie: Pollinations integration (corrected)

  1. Set defaults to:
  • POLLINATIONS_BASE_URL = "https://gen.pollinations.ai"[1]
  • POLLINATIONS_CHAT_PATH = "/v1/chat/completions"[1]
  • Authorization: Bearer ${POLLINATIONS_TOKEN} header.[1]
  1. Do not use /openai except as an emergency fallback, because the docs say it’s a legacy endpoint and recommends /v1/chat/completions instead.[1]

  2. Use secret keys (sk_) only on the server side (Val Town env var), because publishable keys are beta and explicitly warned against for production client-side use.[2][1]

Townie: model selection + fallbacks (cheap but good)

Pollinations explicitly supports model discovery endpoints, so Townie should implement runtime discovery and pick models based on capabilities and pricing metadata instead of hardcoding names.[1]

Implement discovery (required)

  • On startup (and daily), call GET https://gen.pollinations.ai/v1/models to get available OpenAI-compatible text models.[1]
  • Also call GET https://gen.pollinations.ai/text/models to get richer model metadata including pricing and capability flags like tools, reasoning, and context_window.[1]
  • For images, call GET https://gen.pollinations.ai/image/models to enumerate image models and pricing.[1]

Default text model + fallbacks (recommended)

Use this ordered list, but only if each model exists in /v1/models (otherwise skip it):[1]

  1. Primary: gemini (cheap/good default).[1]
  2. Fallback 1: openai (broad compatibility baseline per examples).[1]
  3. Fallback 2: gemini-large (use when you need higher quality / harder planning).[1]
  4. Optional: gemini-search only if you intentionally add “web search” features, since it’s described as having google_search enabled.[1]

Townie should store the chosen primary/fallback model IDs in SQLite (or config) after discovery so requests don’t depend on discovery every time.[2][1]

When to use which (simple policy)

  • Inbox triage + tagging suggestions: use primary (gemini) to keep costs low.[1]
  • AI “plan” generation for large batches (projects/apply rules): allow escalation to gemini-large when the task is complex or the first attempt fails validation.[1]
  • If Pollinations returns model errors, automatically retry with the next fallback in order.[1]

Townie: image generation (optional but easy win)

Pollinations supports image generation at GET https://gen.pollinations.ai/image/<prompt>?model=flux with Bearer auth, so Townie can implement a /api/image/cover endpoint (or similar) for project cover images or “visual summaries.”[1] Also implement image model fallback using /image/models rather than hardcoding flux everywhere (but flux is a fine default).[1]

Readwise + Val Town reminders (keep as-is)

Readwise Reader API auth stays Authorization: Token XXX (separate from Pollinations), stored in Val Town env vars.[3][2] Keep Pollinations and Readwise tokens server-side only (Val Town environment variables), because Val Town endpoints are public-by-URL unless you add auth.[2]

If you want, I can give Townie an exact “decision function” (TypeScript) that consumes /text/models and picks the cheapest model that still has tools=true (if you need tool calling) vs tools=false (for pure summarization).[1]

Citations: [1] paste.txt
[2] llms-full-valtown.txt
[3] Reader API

pollinations.ai API

  • OpenAPI Version: 3.1.0
  • API Version: 0.3.0

Documentation for gen.pollinations.ai - the pollinations.ai API gateway.

📝 Edit docs

Quick Start

Get your API key at https://enter.pollinations.ai

Image Generation

curl 'https://gen.pollinations.ai/image/a%20cat?model=flux' \ -H 'Authorization: Bearer YOUR_API_KEY'

Text Generation

curl 'https://gen.pollinations.ai/v1/chat/completions' \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{"model": "openai", "messages": [{"role": "user", "content": "Hello"}]}'

Vision (Image Input)

curl 'https://gen.pollinations.ai/v1/chat/completions' \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{"model": "openai", "messages": [{"role": "user", "content": [{"type": "text", "text": "Describe this image"}, {"type": "image_url", "image_url": {"url": "https://example.com/image.jpg"}}]}]}'

Gemini Tools: gemini, gemini-large have code_execution enabled (can generate images/plots). gemini-search has google_search enabled. Responses may include content_blocks with image_url, text, or thinking types.

Simple Text Endpoint

curl 'https://gen.pollinations.ai/text/hello?key=YOUR_API_KEY'

Streaming

curl 'https://gen.pollinations.ai/v1/chat/completions' \ -H 'Authorization: Bearer YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{"model": "openai", "messages": [{"role": "user", "content": "Write a poem"}], "stream": true}' \ --no-buffer

Model Discovery

Always check available models before testing:

  • Image models: /image/models
  • Text models: /v1/models

Authentication

Two key types (both consume Pollen from your balance):

  • Publishable Keys (pk_): ⚠️ Beta - not yet ready for production use. For client-side apps, IP rate-limited (1 pollen per IP per hour). Warning: Exposing in public code will consume your Pollen if your app gets traffic.
  • Secret Keys (sk_): Server-side only, no rate limits. Keep secret - never expose publicly.

Auth methods:

  1. Header: Authorization: Bearer YOUR_API_KEY
  2. Query param: ?key=YOUR_API_KEY

Account Management

Check your balance and usage:

# Check pollen balance curl 'https://gen.pollinations.ai/account/balance' \ -H 'Authorization: Bearer YOUR_API_KEY' # Get profile info curl 'https://gen.pollinations.ai/account/profile' \ -H 'Authorization: Bearer YOUR_API_KEY' # View usage history curl 'https://gen.pollinations.ai/account/usage' \ -H 'Authorization: Bearer YOUR_API_KEY'

Servers

  • URL: https://gen.pollinations.ai

Operations

GET /account/profile

  • Method: GET
  • Path: /account/profile
  • Tags: gen.pollinations.ai

Get user profile info (name, email, GitHub username, tier, createdAt, nextResetAt). Requires account:profile permission for API keys.

Responses

Status: 200 User profile with name, email, githubUsername, tier, createdAt, nextResetAt
Content-Type: application/json
  • createdAt (required)

    string, format: date-time — Account creation timestamp (ISO 8601)

  • email (required)

    object — User's email address

  • githubUsername (required)

    object — GitHub username if linked

  • name (required)

    object — User's display name

  • nextResetAt (required)

    object — Next daily pollen reset timestamp (ISO 8601)

  • tier (required)

    string, possible values: "anonymous", "spore", "seed", "flower", "nectar", "router" — User's current tier level

Example:

{ "name": "", "email": "", "githubUsername": "", "tier": "anonymous", "createdAt": "", "nextResetAt": "" }
Status: 401 Unauthorized
Status: 403 Permission denied - API key missing `account:profile` permission

GET /account/balance

  • Method: GET
  • Path: /account/balance
  • Tags: gen.pollinations.ai

Get pollen balance. Returns the key's remaining budget if set, otherwise the user's total balance. Requires account:balance permission for API keys.

Responses

Status: 200 Balance (remaining pollen)
Content-Type: application/json
  • balance (required)

    number — Remaining pollen balance (combines tier, pack, and crypto balances)

Example:

{ "balance": 1 }
Status: 401 Unauthorized
Status: 403 Permission denied - API key missing `account:balance` permission

GET /account/usage

  • Method: GET
  • Path: /account/usage
  • Tags: gen.pollinations.ai

Get request history and spending data. Supports JSON and CSV formats. Requires account:usage permission for API keys.

Responses

Status: 200 Usage records with timestamp, model, tokens, cost_usd, etc.
Content-Type: application/json
  • count (required)

    number — Number of records returned

  • usage (required)

    array — Array of usage records

    Items:

    • api_key (required)

      object — API key identifier used (masked)

    • api_key_type (required)

      object — Type of API key ('secret', 'publishable', 'temporary')

    • cost_usd (required)

      number — Cost in USD for this request

    • input_audio_tokens (required)

      number — Number of input audio tokens

    • input_cached_tokens (required)

      number — Number of cached input tokens

    • input_image_tokens (required)

      number — Number of input image tokens

    • input_text_tokens (required)

      number — Number of input text tokens

    • meter_source (required)

      object — Billing source ('tier', 'pack', 'crypto')

    • model (required)

      object — Model used for generation

    • output_audio_tokens (required)

      number — Number of output audio tokens

    • output_image_tokens (required)

      number — Number of output image tokens (1 per image)

    • output_reasoning_tokens (required)

      number — Number of reasoning tokens (for models with chain-of-thought)

    • output_text_tokens (required)

      number — Number of output text tokens

    • response_time_ms (required)

      object — Response time in milliseconds

    • timestamp (required)

      string — Request timestamp (YYYY-MM-DD HH:mm:ss format)

    • type (required)

      string — Request type (e.g., 'generate.image', 'generate.text')

Example:

{ "usage": [ { "timestamp": "", "type": "", "model": "", "api_key": "", "api_key_type": "", "meter_source": "", "input_text_tokens": 1, "input_cached_tokens": 1, "input_audio_tokens": 1, "input_image_tokens": 1, "output_text_tokens": 1, "output_reasoning_tokens": 1, "output_audio_tokens": 1, "output_image_tokens": 1, "cost_usd": 1, "response_time_ms": 1 } ], "count": 1 }
Status: 401 Unauthorized
Status: 403 Permission denied - API key missing `account:usage` permission

GET /v1/models

  • Method: GET
  • Path: /v1/models
  • Tags: gen.pollinations.ai

Get available text models (OpenAI-compatible). If an API key with model restrictions is provided, only allowed models are returned.

Responses

Status: 200 Success
Content-Type: application/json
  • data (required)

    array

    Items:

    • created (required)

      number

    • id (required)

      string

    • object (required)

      string

  • object (required)

    string

Example:

{ "object": "list", "data": [ { "id": "", "object": "model", "created": 1 } ] }
Status: 500 Oh snap, something went wrong on our end. We're on it!
Content-Type: application/json
  • error (required)

    object

    • code (required)

      string

    • details (required)

      object

      • name (required)

        string

      • stack

        string

    • message (required)

      object

    • timestamp (required)

      string

    • cause

      object

    • requestId

      string

  • status (required)

    number

  • success (required)

    boolean

Example:

{ "status": 500, "success": false, "error": { "code": "INTERNAL_ERROR", "message": "Oh snap, something went wrong on our end. We're on it!", "timestamp": "", "details": { "name": "", "stack": "" }, "requestId": "", "cause": null } }

GET /image/models

  • Method: GET
  • Path: /image/models
  • Tags: gen.pollinations.ai

Get a list of available image generation models with pricing, capabilities, and metadata. If an API key with model restrictions is provided, only allowed models are returned.

Responses

Status: 200 Success
Content-Type: application/json

Array of:

  • aliases (required)

    array

    Items:

    string

  • name (required)

    string

  • pricing (required)

    object

  • context_window

    number

  • description

    string

  • input_modalities

    array

    Items:

    string

  • is_specialized

    boolean

  • output_modalities

    array

    Items:

    string

  • reasoning

    boolean

  • tools

    boolean

  • voices

    array

    Items:

    string

Example:

[ { "name": "", "aliases": [ "" ], "pricing": { "propertyName*": 1, "currency": "pollen" }, "description": "", "input_modalities": [ "" ], "output_modalities": [ "" ], "tools": true, "reasoning": true, "context_window": 1, "voices": [ "" ], "is_specialized": true } ]
Status: 500 Oh snap, something went wrong on our end. We're on it!
Content-Type: application/json
  • error (required)

    object

    • code (required)

      string

    • details (required)

      object

      • name (required)

        string

      • stack

        string

    • message (required)

      object

    • timestamp (required)

      string

    • cause

      object

    • requestId

      string

  • status (required)

    number

  • success (required)

    boolean

Example:

{ "status": 500, "success": false, "error": { "code": "INTERNAL_ERROR", "message": "Oh snap, something went wrong on our end. We're on it!", "timestamp": "", "details": { "name": "", "stack": "" }, "requestId": "", "cause": null } }

GET /text/models

  • Method: GET
  • Path: /text/models
  • Tags: gen.pollinations.ai

Get a list of available text generation models with pricing, capabilities, and metadata. If an API key with model restrictions is provided, only allowed models are returned.

Responses

Status: 200 Success
Content-Type: application/json

Array of:

  • aliases (required)

    array

    Items:

    string

  • name (required)

    string

  • pricing (required)

    object

  • context_window

    number

  • description

    string

  • input_modalities

    array

    Items:

    string

  • is_specialized

    boolean

  • output_modalities

    array

    Items:

    string

  • reasoning

    boolean

  • tools

    boolean

  • voices

    array

    Items:

    string

Example:

[ { "name": "", "aliases": [ "" ], "pricing": { "propertyName*": 1, "currency": "pollen" }, "description": "", "input_modalities": [ "" ], "output_modalities": [ "" ], "tools": true, "reasoning": true, "context_window": 1, "voices": [ "" ], "is_specialized": true } ]
Status: 500 Oh snap, something went wrong on our end. We're on it!
Content-Type: application/json
  • error (required)

    object

    • code (required)

      string

    • details (required)

      object

      • name (required)

        string

      • stack

        string

    • message (required)

      object

    • timestamp (required)

      string

    • cause

      object

    • requestId

      string

  • status (required)

    number

  • success (required)

    boolean

Example:

{ "status": 500, "success": false, "error": { "code": "INTERNAL_ERROR", "message": "Oh snap, something went wrong on our end. We're on it!", "timestamp": "", "details": { "name": "", "stack": "" }, "requestId": "", "cause": null } }

POST /v1/chat/completions

  • Method: POST
  • Path: /v1/chat/completions
  • Tags: gen.pollinations.ai

OpenAI-compatible chat completions endpoint.

Legacy endpoint: /openai (deprecated, use /v1/chat/completions instead)

Authentication (Secret Keys Only):

Include your API key in the Authorization header as a Bearer token:

Authorization: Bearer YOUR_API_KEY

API keys can be created from your dashboard at enter.pollinations.ai. Both key types consume Pollen. Secret keys have no rate limits.

Request Body

Content-Type: application/json
  • messages (required)

    array

    Items:

    Any of:

    • content (required)

      object

    • role (required)

      string

    • cache_control

      object

      • type (required)

        string, possible values: "ephemeral"

    • name

      string

    • content (required)

      object

    • role (required)

      string

    • cache_control

      object

      • type (required)

        string, possible values: "ephemeral"

    • name

      string

    • content (required)

      object

    • role (required)

      string

    • name

      string

    • role (required)

      string

    • cache_control

      object

      • type (required)

        string, possible values: "ephemeral"

    • content

      object

    • function_call

      object

    • name

      string

    • tool_calls

      array

      Items:

      • function (required)

        object

        • arguments (required)

          string

        • name (required)

          string

      • id (required)

        string

      • type (required)

        string

    • content (required)

      object

    • role (required)

      string

    • tool_call_id (required)

      string

    • cache_control

      object

      • type (required)

        string, possible values: "ephemeral"

    • content (required)

      object

    • name (required)

      string

    • role (required)

      string

  • audio

    object

    • format (required)

      string, possible values: "wav", "mp3", "flac", "opus", "pcm16"

    • voice (required)

      string, possible values: "alloy", "echo", "fable", "onyx", "shimmer", "coral", "verse", "ballad", "ash", "sage", "amuch", "dan"

  • frequency_penalty

    object, default: 0

  • function_call

    object

  • functions

    array

    Items:

    • name (required)

      string

    • description

      string

    • parameters

      object

  • logit_bias

    object, default: null

  • logprobs

    object, default: false

  • max_tokens

    object

  • modalities

    array

    Items:

    string, possible values: "text", "audio"

  • model

    string, possible values: "openai", "openai-fast", "openai-large", "qwen-coder", "mistral", "openai-audio", "gemini", "gemini-fast", "deepseek", "grok", "gemini-search", "chickytutor", "midijourney", "claude-fast", "claude", "claude-large", "perplexity-fast", "perplexity-reasoning", "kimi", "gemini-large", "nova-fast", "glm", "minimax", "nomnom", default: "openai" — AI model for text generation. See /v1/models for full list.

  • parallel_tool_calls

    boolean, default: true

  • presence_penalty

    object, default: 0

  • reasoning_effort

    string, possible values: "none", "minimal", "low", "medium", "high", "xhigh"

  • repetition_penalty

    object

  • response_format

    object

  • seed

    object

  • stop

    object

  • stream

    object, default: false

  • stream_options

    object

  • temperature

    object, default: 1

  • thinking

    object

  • thinking_budget

    integer

  • tool_choice

    object

  • tools

    array

    Items:

    Any of:

    • function (required)

      object

      • name (required)

        string

      • description

        string

      • parameters

        object

      • strict

        object, default: false

    • type (required)

      string

    • type (required)

      string, possible values: "code_execution", "google_search", "google_maps", "url_context", "computer_use", "file_search"

  • top_logprobs

    object

  • top_p

    object, default: 1

  • user

    string

Example:

{ "messages": [ { "content": "", "role": "system", "name": "", "cache_control": { "type": "ephemeral" } } ], "model": "openai", "modalities": [ "text" ], "audio": { "voice": "alloy", "format": "wav" }, "frequency_penalty": 0, "repetition_penalty": 0, "logit_bias": null, "logprobs": false, "top_logprobs": 0, "max_tokens": 0, "presence_penalty": 0, "response_format": { "type": "text" }, "seed": -1, "stop": "", "stream": false, "stream_options": { "include_usage": true }, "thinking": { "type": "disabled", "budget_tokens": 1 }, "reasoning_effort": "none", "thinking_budget": 0, "temperature": 1, "top_p": 1, "tools": [ { "type": "function", "function": { "description": "", "name": "", "parameters": { "propertyName*": "anything" }, "strict": false } } ], "tool_choice": "none", "parallel_tool_calls": true, "user": "", "function_call": "none", "functions": [ { "description": "", "name": "", "parameters": { "propertyName*": "anything" } } ] }

Responses

Status: 200 Success
Content-Type: application/json
  • choices (required)

    array

    Items:

    • content_filter_results

      object

    • finish_reason

      object

    • index

      integer

    • logprobs

      object

    • message

      object

      • role (required)

        string

      • audio

        object

      • content

        object

      • content_blocks

        object

      • function_call

        object

      • reasoning_content

        object

      • tool_calls

        object

  • created (required)

    integer

  • id (required)

    string

  • model (required)

    string

  • object (required)

    string

  • usage (required)

    object

    • completion_tokens (required)

      integer

    • prompt_tokens (required)

      integer

    • total_tokens (required)

      integer

    • completion_tokens_details

      object

    • prompt_tokens_details

      object

  • citations

    array

    Items:

    string

  • prompt_filter_results

    object

  • system_fingerprint

    object

  • user_tier

    string, possible values: "anonymous", "seed", "flower", "nectar"

Example:

{ "id": "", "choices": [ { "finish_reason": "", "index": 0, "message": { "content": "", "tool_calls": [ { "id": "", "type": "function", "function": { "name": "", "arguments": "" } } ], "role": "assistant", "function_call": { "arguments": "", "name": "" }, "content_blocks": [ { "type": "text", "text": "", "cache_control": { "type": "ephemeral" } } ], "audio": { "transcript": "", "data": "", "id": "", "expires_at": -9007199254740991 }, "reasoning_content": "" }, "logprobs": { "content": [ { "token": "", "logprob": 1, "bytes": [ "[Max Depth Exceeded]" ], "top_logprobs": [ { "token": "[Max Depth Exceeded]", "logprob": "[Max Depth Exceeded]", "bytes": "[Max Depth Exceeded]" } ] } ] }, "content_filter_results": { "hate": { "filtered": true, "severity": "safe" }, "self_harm": { "filtered": true, "severity": "safe" }, "sexual": { "filtered": true, "severity": "safe" }, "violence": { "filtered": true, "severity": "safe" }, "jailbreak": { "filtered": true, "detected": true }, "protected_material_text": { "filtered": true, "detected": true }, "protected_material_code": { "filtered": true, "detected": true } } } ], "prompt_filter_results": [ { "prompt_index": 0, "content_filter_results": { "hate": { "filtered": true, "severity": "safe" }, "self_harm": { "filtered": true, "severity": "safe" }, "sexual": { "filtered": true, "severity": "safe" }, "violence": { "filtered": true, "severity": "safe" }, "jailbreak": { "filtered": true, "detected": true }, "protected_material_text": { "filtered": true, "detected": true }, "protected_material_code": { "filtered": true, "detected": true } } } ], "created": -9007199254740991, "model": "", "system_fingerprint": "", "object": "chat.completion", "usage": { "completion_tokens": 0, "completion_tokens_details": { "accepted_prediction_tokens": 0, "audio_tokens": 0, "reasoning_tokens": 0, "rejected_prediction_tokens": 0 }, "prompt_tokens": 0, "prompt_tokens_details": { "audio_tokens": 0, "cached_tokens": 0 }, "total_tokens": 0 }, "user_tier": "anonymous", "citations": [ "" ] }
Status: 400 Something was wrong with the input data, check the details for more info.
Content-Type: application/json
  • error (required)

    object

    • code (required)

      string

    • details (required)

      object

      • fieldErrors (required)

        object

      • formErrors (required)

        array

        Items:

        string

      • name (required)

        string

      • stack

        string

    • message (required)

      object

    • timestamp (required)

      string

    • cause

      object

    • requestId

      string

  • status (required)

    number

  • success (required)

    boolean

Example:

{ "status": 400, "success": false, "error": { "code": "BAD_REQUEST", "message": "Something was wrong with the input data, check the details for more info.", "timestamp": "", "details": { "name": "", "stack": "", "formErrors": [ "" ], "fieldErrors": { "propertyName*": [ "" ] } }, "requestId": "", "cause": null } }
Status: 401 You need to authenticate by providing a session cookie or Authorization header (Bearer token).
Content-Type: application/json
  • error (required)

    object

    • code (required)

      string

    • details (required)

      object

      • name (required)

        string

      • stack

        string

    • message (required)

      object

    • timestamp (required)

      string

    • cause

      object

    • requestId

      string

  • status (required)

    number

  • success (required)

    boolean

Example:

{ "status": 401, "success": false, "error": { "code": "UNAUTHORIZED", "message": "You need to authenticate by providing a session cookie or Authorization header (Bearer token).", "timestamp": "", "details": { "name": "", "stack": "" }, "requestId": "", "cause": null } }
Status: 500 Oh snap, something went wrong on our end. We're on it!
Content-Type: application/json
  • error (required)

    object

    • code (required)

      string

    • details (required)

      object

      • name (required)

        string

      • stack

        string

    • message (required)

      object

    • timestamp (required)

      string

    • cause

      object

    • requestId

      string

  • status (required)

    number

  • success (required)

    boolean

Example:

{ "status": 500, "success": false, "error": { "code": "INTERNAL_ERROR", "message": "Oh snap, something went wrong on our end. We're on it!", "timestamp": "", "details": { "name": "", "stack": "" }, "requestId": "", "cause": null } }

GET /text/{prompt}

  • Method: GET
  • Path: /text/{prompt}
  • Tags: gen.pollinations.ai

Generates text from text prompts.

Authentication:

Include your API key either:

  • In the Authorization header as a Bearer token: Authorization: Bearer YOUR_API_KEY
  • As a query parameter: ?key=YOUR_API_KEY

API keys can be created from your dashboard at enter.pollinations.ai.

Responses

Status: 200 Generated text response
Content-Type: text/plain

string

Example:

true
Status: 400 Something was wrong with the input data, check the details for more info.
Content-Type: application/json
  • error (required)

    object

    • code (required)

      string

    • details (required)

      object

      • fieldErrors (required)

        object

      • formErrors (required)

        array

        Items:

        string

      • name (required)

        string

      • stack

        string

    • message (required)

      object

    • timestamp (required)

      string

    • cause

      object

    • requestId

      string

  • status (required)

    number

  • success (required)

    boolean

Example:

{ "status": 400, "success": false, "error": { "code": "BAD_REQUEST", "message": "Something was wrong with the input data, check the details for more info.", "timestamp": "", "details": { "name": "", "stack": "", "formErrors": [ "" ], "fieldErrors": { "propertyName*": [ "" ] } }, "requestId": "", "cause": null } }
Status: 401 You need to authenticate by providing a session cookie or Authorization header (Bearer token).
Content-Type: application/json
  • error (required)

    object

    • code (required)

      string

    • details (required)

      object

      • name (required)

        string

      • stack

        string

    • message (required)

      object

    • timestamp (required)

      string

    • cause

      object

    • requestId

      string

  • status (required)

    number

  • success (required)

    boolean

Example:

{ "status": 401, "success": false, "error": { "code": "UNAUTHORIZED", "message": "You need to authenticate by providing a session cookie or Authorization header (Bearer token).", "timestamp": "", "details": { "name": "", "stack": "" }, "requestId": "", "cause": null } }
Status: 500 Oh snap, something went wrong on our end. We're on it!
Content-Type: application/json
  • error (required)

    object

    • code (required)

      string

    • details (required)

      object

      • name (required)

        string

      • stack

        string

    • message (required)

      object

    • timestamp (required)

      string

    • cause

      object

    • requestId

      string

  • status (required)

    number

  • success (required)

    boolean

Example:

{ "status": 500, "success": false, "error": { "code": "INTERNAL_ERROR", "message": "Oh snap, something went wrong on our end. We're on it!", "timestamp": "", "details": { "name": "", "stack": "" }, "requestId": "", "cause": null } }

GET /image/{prompt}

  • Method: GET
  • Path: /image/{prompt}
  • Tags: gen.pollinations.ai

Generate an image or video from a text prompt.

Image Models: flux (default), turbo, gptimage, kontext, seedream, nanobanana, nanobanana-pro

Video Models: veo, seedance

  • veo: Text-to-video only (4-8 seconds)
  • seedance: Text-to-video and image-to-video (2-10 seconds)

Authentication:

Include your API key either:

  • In the Authorization header as a Bearer token: Authorization: Bearer YOUR_API_KEY
  • As a query parameter: ?key=YOUR_API_KEY

API keys can be created from your dashboard at enter.pollinations.ai.

Responses

Status: 200 Success - Returns the generated image or video
Content-Type: image/jpeg

string, format: binary

Example:

{}
Content-Type: image/png

string, format: binary

Example:

{}
Content-Type: video/mp4

string, format: binary

Example:

{}
Status: 400 Something was wrong with the input data, check the details for more info.
Content-Type: application/json
  • error (required)

    object

    • code (required)

      string

    • details (required)

      object

      • fieldErrors (required)

        object

      • formErrors (required)

        array

        Items:

        string

      • name (required)

        string

      • stack

        string

    • message (required)

      object

    • timestamp (required)

      string

    • cause

      object

    • requestId

      string

  • status (required)

    number

  • success (required)

    boolean

Example:

{ "status": 400, "success": false, "error": { "code": "BAD_REQUEST", "message": "Something was wrong with the input data, check the details for more info.", "timestamp": "", "details": { "name": "", "stack": "", "formErrors": [ "" ], "fieldErrors": { "propertyName*": [ "" ] } }, "requestId": "", "cause": null } }
Status: 401 You need to authenticate by providing a session cookie or Authorization header (Bearer token).
Content-Type: application/json
  • error (required)

    object

    • code (required)

      string

    • details (required)

      object

      • name (required)

        string

      • stack

        string

    • message (required)

      object

    • timestamp (required)

      string

    • cause

      object

    • requestId

      string

  • status (required)

    number

  • success (required)

    boolean

Example:

{ "status": 401, "success": false, "error": { "code": "UNAUTHORIZED", "message": "You need to authenticate by providing a session cookie or Authorization header (Bearer token).", "timestamp": "", "details": { "name": "", "stack": "" }, "requestId": "", "cause": null } }
Status: 500 Oh snap, something went wrong on our end. We're on it!
Content-Type: application/json
  • error (required)

    object

    • code (required)

      string

    • details (required)

      object

      • name (required)

        string

      • stack

        string

    • message (required)

      object

    • timestamp (required)

      string

    • cause

      object

    • requestId

      string

  • status (required)

    number

  • success (required)

    boolean

Example:

{ "status": 500, "success": false, "error": { "code": "INTERNAL_ERROR", "message": "Oh snap, something went wrong on our end. We're on it!", "timestamp": "", "details": { "name": "", "stack": "" }, "requestId": "", "cause": null } }

Schemas

ErrorDetails

  • Type: object
  • name (required)

    string

  • stack

    string

Example:

{ "name": "", "stack": "" }

CacheControl

  • Type: object
  • type (required)

    string, possible values: "ephemeral"

Example:

{ "type": "ephemeral" }

ContentFilterSeverity

  • Type: string

Example:

ContentFilterResult

  • Type: object
  • hate

    object

    • filtered (required)

      boolean

    • severity (required)

      string, possible values: "safe", "low", "medium", "high"

  • jailbreak

    object

    • detected (required)

      boolean

    • filtered (required)

      boolean

  • protected_material_code

    object

    • detected (required)

      boolean

    • filtered (required)

      boolean

  • protected_material_text

    object

    • detected (required)

      boolean

    • filtered (required)

      boolean

  • self_harm

    object

    • filtered (required)

      boolean

    • severity (required)

      string, possible values: "safe", "low", "medium", "high"

  • sexual

    object

    • filtered (required)

      boolean

    • severity (required)

      string, possible values: "safe", "low", "medium", "high"

  • violence

    object

    • filtered (required)

      boolean

    • severity (required)

      string, possible values: "safe", "low", "medium", "high"

Example:

{ "hate": { "filtered": true, "severity": "safe" }, "self_harm": { "filtered": true, "severity": "safe" }, "sexual": { "filtered": true, "severity": "safe" }, "violence": { "filtered": true, "severity": "safe" }, "jailbreak": { "filtered": true, "detected": true }, "protected_material_text": { "filtered": true, "detected": true }, "protected_material_code": { "filtered": true, "detected": true } }

CompletionUsage

  • Type: object
  • completion_tokens (required)

    integer

  • prompt_tokens (required)

    integer

  • total_tokens (required)

    integer

  • completion_tokens_details

    object

  • prompt_tokens_details

    object

Example:

{ "completion_tokens": 0, "completion_tokens_details": { "accepted_prediction_tokens": 0, "audio_tokens": 0, "reasoning_tokens": 0, "rejected_prediction_tokens": 0 }, "prompt_tokens": 0, "prompt_tokens_details": { "audio_tokens": 0, "cached_tokens": 0 }, "total_tokens": 0 }

ValidationErrorDetails

  • Type: object
  • fieldErrors (required)

    object

  • formErrors (required)

    array

    Items:

    string

  • name (required)

    string

  • stack

    string

Example:

{ "name": "", "stack": "", "formErrors": [ "" ], "fieldErrors": { "propertyName*": [ "" ] } }

MessageContentPart

  • Type:

Example:

Union type for message content parts. Can be one of:

  • Text content: { type: "text", text: string, cache_control?: CacheControl }
  • Image content: { type: "image_url", image_url: { url: string, detail?: "auto" | "low" | "high", mime_type?: string } }
  • Video content: { type: "video_url", video_url: { url: string, mime_type?: string } }
  • Audio content: { type: "input_audio", input_audio: { data: string, format: "wav" | "mp3" | "flac" | "opus" | "pcm16" }, cache_control?: CacheControl }
  • File content: { type: "file", file: { file_data?: string, file_id?: string, file_name?: string, file_url?: string, mime_type?: string }, cache_control?: CacheControl }
  • Custom types: Any object with a type field for provider-specific extensions

Example (text):

{ "type": "text", "text": "Hello, world!" }

Example (image):

{ "type": "image_url", "image_url": { "url": "https://example.com/image.jpg", "detail": "high" } }

Example (video):

{ "type": "video_url", "video_url": { "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ" } }
FeaturesVersion controlCode intelligenceCLIMCP
Use cases
TeamsAI agentsSlackGTM
DocsShowcaseTemplatesNewestTrendingAPI examplesNPM packages
PricingNewsletterBlogAboutCareers
We’re hiring!
Brandhi@val.townStatus
X (Twitter)
Discord community
GitHub discussions
YouTube channel
Bluesky
Open Source Pledge
Terms of usePrivacy policyAbuse contact
© 2026 Val Town, Inc.