OpenAI & Gemini compatible API • 12x cheaper
1. Get an API key from our Telegram Bot
2. Use OpenAI SDK or Gemini SDK - both work!
3. Pricing: Gemini Chat $0.50/1k requests • Grok Image $0.005/image • Gemini Image $0.02/image • Flow Image $0.03/image • Gemini Voice $0.03/generation
| Model | Type | Description |
|---|---|---|
gemini-flash |
Chat | Fast text generation via Gemini |
grok |
Image | Grok image generation |
gemini-image |
Image | Gemini image generation |
imagen4 |
Image | Flow Image - Imagen 4 |
nanobanana |
Image | Flow Image - NanoBanana |
nanobananapro1k |
Image | Flow Image - NanoBanana Pro 1K |
nanobananapro2k |
Image | Flow Image - NanoBanana Pro 2K |
gemini-voice |
Audio | Gemini Voice Generation (Beta) - $0.03/generation |
| SDK | Base URL |
|---|---|
| OpenAI | https://papaiapi.com/v1 |
| Gemini | https://papaiapi.com/v1beta |
OpenAI style:
Authorization: Bearer sk_live_your_api_key_here
Gemini style:
?key=sk_live_your_api_key_here
# or header:
x-goog-api-key: sk_live_your_api_key_here
Create a chat completion (OpenAI-compatible)
| Parameter | Type | Description |
|---|---|---|
model |
string | required Model to use: gemini-flash |
messages |
array | required Array of message objects with role and content |
stream |
boolean | optional Enable streaming responses (recommended) |
Generate images (OpenAI-compatible). Supports Grok, Gemini Image, and Flow Image models.
| Parameter | Type | Description |
|---|---|---|
prompt |
string | required Text description of the image to generate |
model |
string | optional Model to use: grok (default), gemini-image, imagen4, nanobanana, nanobananapro1k, nanobananapro2k |
n |
integer | optional Number of images (default: 1, currently only 1 supported) |
size |
string | optional Aspect ratio for Flow Image models: 1792x1024 (landscape) or 1024x1792 (portrait). Ignored for Grok/Gemini. |
Generate voice audio from text (OpenAI-compatible TTS). Beta: ~40% success rate.
| Parameter | Type | Description |
|---|---|---|
model |
string | optional Model to use: gemini-voice (default) |
input |
string | required Text to generate audio from |
{
"url": "https://papaiapi.com/temp/abc123.wav"
}
Note: Audio URLs expire after 1 hour. Download files promptly if you need to keep them.
List available models (OpenAI)
Generate content (Gemini-compatible)
| Parameter | Type | Description |
|---|---|---|
contents |
array | required Array of content objects with parts |
generationConfig |
object | optional Generation config (temperature, maxOutputTokens, etc.) |
Stream generate content (Gemini-compatible SSE)
List available models (Gemini)
from openai import OpenAI
client = OpenAI(
base_url="https://papaiapi.com/v1",
api_key="sk_live_your_api_key_here"
)
# Simple request
response = client.chat.completions.create(
model="gemini-flash",
messages=[{"role": "user", "content": "Hello!"}]
)
print(response.choices[0].message.content)
# Streaming
stream = client.chat.completions.create(
model="gemini-flash",
messages=[{"role": "user", "content": "Write a poem"}],
stream=True
)
for chunk in stream:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")
# Simple request
curl -X POST "https://papaiapi.com/v1/chat/completions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk_live_your_api_key_here" \
-d '{
"model": "gemini-flash",
"messages": [{"role": "user", "content": "Hello!"}]
}'
# Streaming
curl -X POST "https://papaiapi.com/v1/chat/completions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk_live_your_api_key_here" \
-d '{
"model": "gemini-flash",
"messages": [{"role": "user", "content": "Hello!"}],
"stream": true
}'
import OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'https://papaiapi.com/v1',
apiKey: 'sk_live_your_api_key_here'
});
// Simple request
const response = await client.chat.completions.create({
model: 'gemini-flash',
messages: [{ role: 'user', content: 'Hello!' }]
});
console.log(response.choices[0].message.content);
// Streaming
const stream = await client.chat.completions.create({
model: 'gemini-flash',
messages: [{ role: 'user', content: 'Write a poem' }],
stream: true
});
for await (const chunk of stream) {
if (chunk.choices[0].delta.content) {
process.stdout.write(chunk.choices[0].delta.content);
}
}
{
"id": "chatcmpl-abc123",
"object": "chat.completion",
"created": 1234567890,
"model": "gemini-flash",
"choices": [{
"index": 0,
"message": {
"role": "assistant",
"content": "Hello! How can I help you?"
},
"finish_reason": "stop"
}],
"usage": {
"prompt_tokens": 0,
"completion_tokens": 0,
"total_tokens": 0
}
}
data: {"id":"chatcmpl-abc","choices":[{"delta":{"role":"assistant"},"index":0}]}
data: {"id":"chatcmpl-abc","choices":[{"delta":{"content":"Hello"},"index":0}]}
data: {"id":"chatcmpl-abc","choices":[{"delta":{"content":"!"},"index":0}]}
data: {"id":"chatcmpl-abc","choices":[{"delta":{},"finish_reason":"stop","index":0}]}
data: [DONE]
{
"created": 1234567890,
"data": [{
"url": "https://papaiapi.com/temp/abc123.jpg",
"revised_prompt": "your original prompt"
}]
}
Note: Image URLs expire after 1 hour. Download images promptly if you need to keep them.
from openai import OpenAI
client = OpenAI(
base_url="https://papaiapi.com/v1",
api_key="sk_live_your_api_key_here"
)
# Grok (default)
response = client.images.generate(
prompt="A cat wearing a tiny hat",
n=1
)
print(response.data[0].url)
# Gemini Image
response = client.images.generate(
model="gemini-image",
prompt="A sunset over mountains"
)
print(response.data[0].url)
# Flow Image (NanoBanana Pro 2K, landscape)
response = client.images.generate(
model="nanobananapro2k",
prompt="A futuristic cityscape",
size="1792x1024"
)
print(response.data[0].url)
# Grok (default)
curl -X POST "https://papaiapi.com/v1/images/generations" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk_live_your_api_key_here" \
-d '{
"prompt": "A cat wearing a tiny hat"
}'
# Gemini Image
curl -X POST "https://papaiapi.com/v1/images/generations" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk_live_your_api_key_here" \
-d '{
"model": "gemini-image",
"prompt": "A sunset over mountains"
}'
# Flow Image (NanoBanana Pro 2K, portrait)
curl -X POST "https://papaiapi.com/v1/images/generations" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk_live_your_api_key_here" \
-d '{
"model": "nanobananapro2k",
"prompt": "A futuristic cityscape",
"size": "1024x1792"
}'
import OpenAI from 'openai';
const client = new OpenAI({
baseURL: 'https://papaiapi.com/v1',
apiKey: 'sk_live_your_api_key_here'
});
// Grok (default)
const response = await client.images.generate({
prompt: 'A cat wearing a tiny hat'
});
console.log(response.data[0].url);
// Gemini Image
const geminiResponse = await client.images.generate({
model: 'gemini-image',
prompt: 'A sunset over mountains'
});
console.log(geminiResponse.data[0].url);
// Flow Image (NanoBanana Pro 2K, landscape)
const flowResponse = await client.images.generate({
model: 'nanobananapro2k',
prompt: 'A futuristic cityscape',
size: '1792x1024'
});
console.log(flowResponse.data[0].url);
import requests
response = requests.post(
"https://papaiapi.com/v1/audio/speech",
headers={
"Authorization": "Bearer sk_live_your_api_key_here",
"Content-Type": "application/json"
},
json={
"model": "gemini-voice",
"input": "Hello, welcome to our podcast!"
}
)
data = response.json()
print(data["url"]) # WAV file URL
# Generate voice audio
curl -X POST "https://papaiapi.com/v1/audio/speech" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk_live_your_api_key_here" \
-d '{
"model": "gemini-voice",
"input": "Hello, welcome to our podcast!"
}'
const response = await fetch('https://papaiapi.com/v1/audio/speech', {
method: 'POST',
headers: {
'Authorization': 'Bearer sk_live_your_api_key_here',
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: 'gemini-voice',
input: 'Hello, welcome to our podcast!'
})
});
const data = await response.json();
console.log(data.url); // WAV file URL
import google.generativeai as genai
genai.configure(
api_key="sk_live_your_api_key_here",
transport="rest",
client_options={"api_endpoint": "papaiapi.com"}
)
model = genai.GenerativeModel('gemini-flash')
response = model.generate_content("Hello!")
print(response.text)
# Generate content
curl -X POST "https://papaiapi.com/v1beta/models/gemini-flash:generateContent?key=sk_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"contents": [{
"parts": [{"text": "Hello!"}]
}]
}'
# Streaming
curl -X POST "https://papaiapi.com/v1beta/models/gemini-flash:streamGenerateContent?key=sk_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"contents": [{
"parts": [{"text": "Write a poem"}]
}]
}'
import { GoogleGenerativeAI } from '@google/generative-ai';
const genAI = new GoogleGenerativeAI('sk_live_your_api_key_here', {
baseUrl: 'https://papaiapi.com/v1beta'
});
const model = genAI.getGenerativeModel({ model: 'gemini-flash' });
const result = await model.generateContent('Hello!');
console.log(result.response.text());
{
"candidates": [{
"content": {
"parts": [{"text": "Hello! How can I help you?"}],
"role": "model"
},
"finishReason": "STOP",
"index": 0
}],
"usageMetadata": {
"promptTokenCount": 0,
"candidatesTokenCount": 0,
"totalTokenCount": 0
}
}
data: {"candidates":[{"content":{"parts":[{"text":"Hello"}],"role":"model"},"index":0}]}
data: {"candidates":[{"content":{"parts":[{"text":"!"}],"role":"model"},"index":0}]}
data: {"candidates":[{"content":{"parts":[{"text":""}],"role":"model"},"finishReason":"STOP","index":0}]}
| Limit | Value |
|---|---|
| Concurrent requests per user | 3 (configurable) |
| Request timeout | 3 minutes (chat), 5 minutes (images) |
| Max prompt length | ~95,000 characters |
| HTTP Code | OpenAI Error | Gemini Error | Description |
|---|---|---|---|
401 |
invalid_api_key | UNAUTHENTICATED | Invalid or missing API key |
402 |
insufficient_balance | FAILED_PRECONDITION | Insufficient balance - top up required |
429 |
rate_limit_exceeded | RESOURCE_EXHAUSTED | Too many concurrent requests |
500 |
internal_error | INTERNAL | Server error - try again |
504 |
timeout | DEADLINE_EXCEEDED | Request timeout |
{
"error": {
"message": "Insufficient balance",
"type": "insufficient_balance",
"code": 402
}
}
{
"error": {
"code": 402,
"message": "Insufficient balance",
"status": "FAILED_PRECONDITION"
}
}
Timeouts: Chat requests may take up to 3 minutes. Use stream: true for better reliability.
Images: Generation may take up to 5 minutes. URLs expire after 1 hour - download promptly.
Voice: Generation may take up to 5 minutes (beta: ~40% success rate). WAV URLs expire after 1 hour.
Retries: Failed requests are automatically retried up to 3 times before returning an error.