Quick start
Send JSON to POST /quote/generate. The deployed route is exposed under /quote; the original generator method is /generate.
curl -X POST https://YOUR-DOMAIN/quote/generate \
-H "Content-Type: application/json" \
-d '{
"messages": [{
"from": { "id": 1, "name": "Test User" },
"text": "Hello world!",
"avatar": true
}]
}'botToken; the server also accepts BOT_TOKEN from the environment.Request parameters
Content-Type must be application/json. Only messages is required.
| Field | Type | Required | Description |
|---|---|---|---|
botToken | string | No | Telegram bot token. Falls back to BOT_TOKEN. |
type | string | No | quote, image, or stories. Stories uses 720×1280 output. |
format | string | No | png or webp for quote output. |
ext | string | No | png/webp; selects direct image response handling. |
backgroundColor | string | No | HEX, CSS color name, random, gradient using #111/#222, or // for a transparent variant. |
width | number | No | Layout width before scaling. |
height | number | No | Layout height before scaling. |
scale | number | No | Scaling factor from 1 to 20. Default is 2. |
emojiBrand | string | No | Emoji rendering set, such as apple, google, twitter, joypixels, or blob. |
messages | array | Yes | One or more message objects. |
Message object
Messages can represent one person or a full conversation.
| Field | Type | Description |
|---|---|---|
from | object | Sender: id, first_name, last_name, name, username, and optional photo.url/photo.big_file_id. |
text | string | Message text, up to 4096 characters. |
entities | array | Telegram-style formatting entities. |
avatar | boolean | Whether the avatar is shown. |
replyMessage | object | Quoted/replied message shown above the message. |
media | object|array | Image/sticker/media source. URL or Telegram file ID. |
mediaType | string | sticker for stickers; otherwise text/image. |
mediaCrop | boolean | Crop media to preserve the requested proportions. |
voice | object | Voice message waveform, e.g. { waveform: [0,4,8] }. |
Text entities
Use Telegram entity objects with type, offset, and length. Some entity types also accept extra data.
"entities": [
{ "type": "bold", "offset": 0, "length": 5 },
{ "type": "italic", "offset": 6, "length": 5 },
{ "type": "text_link", "offset": 12, "length": 4, "url": "https://example.com" },
{ "type": "custom_emoji", "offset": 17, "length": 2, "custom_emoji_id": "..." }
]Reply messages
Set replyMessage to display a short quoted message above the current message. It can include name, text, entities, chatId, and optional from sender information.
Media
Media accepts a URL or Telegram file ID. An array can contain multiple files; the generator uses the last file, or the second file when mediaCrop is enabled.
"media": { "url": "https://example.com/image.jpg" }
"media": { "file_id": "AgACAg...", "width": 800, "height": 600 }
"media": [
{ "file_id": "AgACAg...1" },
{ "file_id": "AgACAg...2" }
]Voice messages
Provide waveform samples as numbers. The renderer turns them into a visual waveform.
"voice": {
"waveform": [0, 4, 8, 16, 12, 8, 4, 8, 16, 12, 8, 4, 0]
}Output formats
There are three practical endpoint forms:
/quote/generate— JSON containing the generated image as base64./quote/generate.png— direct PNG response./quote/generate.webp— direct WebP response.
The generated result also reports its actual width, height, type and extension.
Backgrounds & layout
backgroundColor accepts HEX values and CSS color names. Use random for a random background, or two colors separated by a slash for a gradient such as #ff69b4/#6cace4. A value beginning with // creates a semi-transparent variant. Set width, height, and scale to control the render size.
Emoji brands
The bundled emoji sets currently include:
Features at a glance
Errors & limits
Common validation errors include query_empty, messages_empty, and empty_messages. Unknown methods return method not found. The API rate limit is 20 requests per IP per 55-second window; calls matching the configured BOT_TOKEN are whitelisted.
{
"ok": false,
"error": {
"code": 429,
"message": "Rate limit exceeded. See "Retry-After""
}
}Examples
JavaScript
const response = await fetch('https://YOUR-DOMAIN/quote/generate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
backgroundColor: '#f68ac9',
scale: 2,
messages: [{
from: {
id: 1,
name: 'Test User',
photo: { url: 'https://YOUR-DOMAIN/default-avatar.svg' }
},
avatar: true,
text: 'Hello world!'
}]
})
})
const data = await response.json()
const image = Buffer.from(data.result.image, 'base64')Python
import base64, requests
payload = {
'messages': [{
'from': {'id': 1, 'name': 'Test User'},
'text': 'Hello world!',
'avatar': True
}]
}
r = requests.post('https://YOUR-DOMAIN/quote/generate', json=payload)
data = r.json()
image = base64.b64decode(data['result']['image'])
open('quote.png', 'wb').write(image)