5.5 KiB
Quote Generator API
Generate Twitter-style quote images programmatically. Perfect for creating social media content, screenshots, or fake tweets.
Base URL: https://quotes.imbenji.net
Features
- 🎨 Twitter-authentic styling
- 🖼️ Support for images and text-only tweets
- 📸 High-resolution output (3240x3240)
- ⚡ Built-in caching (24-hour TTL)
- 🔒 Base64 image support
- 🐳 Docker-ready
API Endpoints
POST /generate
Generate a quote image using JSON request body.
Request:
curl -X POST https://quotes.imbenji.net/generate \
-H "Content-Type: application/json" \
-d '{
"displayName": "Geoff Marshall",
"username": "@geofftech",
"avatarUrl": "https://example.com/avatar.jpg",
"text": "Does anyone else find it immensely satisfying when you turn a pocket inside out and get rid of the crumbs and fluff stuck in the bottom.",
"imageUrl": null,
"timestamp": 1499766270
}' --output quote.png
GET /generate
Generate a quote image using query parameters.
Request:
curl "https://quotes.imbenji.net/generate?displayName=John%20Doe&username=@johndoe&text=Hello%20World×tamp=1735574400" --output quote.png
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
displayName |
string | No | Display name (defaults to "Anonymous") |
username |
string | No | Twitter handle with @ (defaults to "@anonymous") |
avatarUrl |
string | No | Avatar image URL or base64 data URI |
text |
string | No | Tweet text content |
imageUrl |
string | No | Tweet image URL, base64 data URI, or null |
timestamp |
integer | No | Unix epoch timestamp in seconds |
Response
- Content-Type:
image/png - Headers:
X-Cache:HIT(served from cache) orMISS(newly generated)
Examples
Text-only tweet
fetch('https://quotes.imbenji.net/generate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
displayName: 'John Doe',
username: '@johndoe',
text: 'Just deployed my new API!',
timestamp: Math.floor(Date.now() / 1000)
})
})
.then(res => res.blob())
.then(blob => {
const url = URL.createObjectURL(blob);
document.getElementById('img').src = url;
});
Tweet with image
const response = await fetch('https://quotes.imbenji.net/generate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
displayName: 'Jane Smith',
username: '@janesmith',
avatarUrl: 'https://example.com/avatar.jpg',
text: 'Check out this amazing view! 🌄',
imageUrl: 'https://example.com/photo.jpg',
timestamp: 1735574400
})
});
const blob = await response.blob();
// Save or display the image
Using base64 images
fetch('https://quotes.imbenji.net/generate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
displayName: 'Alice',
username: '@alice',
avatarUrl: 'data:image/png;base64,iVBORw0KGgo...',
text: 'Using base64 images works too!',
imageUrl: 'data:image/jpeg;base64,/9j/4AAQSkZJ...',
timestamp: 1735574400
})
});
Python example
import requests
import time
response = requests.post('https://quotes.imbenji.net/generate', json={
'displayName': 'Python User',
'username': '@pythonista',
'text': 'Making API calls with Python!',
'timestamp': int(time.time())
})
with open('quote.png', 'wb') as f:
f.write(response.content)
cURL with GET
curl -G "https://quotes.imbenji.net/generate" \
--data-urlencode "displayName=Test User" \
--data-urlencode "username=@testuser" \
--data-urlencode "text=This is a test tweet" \
--data-urlencode "timestamp=1735574400" \
--output quote.png
Caching
The API automatically caches generated images for 24 hours from the last request. Identical requests will be served from cache instantly.
- Cache hits include
X-Cache: HITheader - Cache misses include
X-Cache: MISSheader - Cache is cleaned up hourly
- Images are stored based on SHA-256 hash of parameters
Timestamp Format
The timestamp parameter expects a Unix epoch timestamp in seconds (not milliseconds).
JavaScript:
const timestamp = Math.floor(Date.now() / 1000);
Python:
import time
timestamp = int(time.time())
The timestamp will be formatted as: 5:58 PM · Dec 29, 2025
Default Avatar
If no avatarUrl is provided, a default Twitter-style placeholder avatar will be used.
Rate Limiting
Currently, there are no rate limits. Please use responsibly.
Self-Hosting
Docker (Recommended)
git clone <repository>
cd quotegen
docker-compose up -d
The API will be available at http://localhost:3000
Manual Setup
npm install
npm start
Health Check
curl https://quotes.imbenji.net/health
Response:
{
"status": "ok"
}
Technical Details
- Resolution: 3240x3240 (1:1 aspect ratio)
- Format: PNG
- Max tweet width: 450px (auto-scaled to fit)
- Cache TTL: 24 hours from last access
- Cleanup interval: Every hour
Limitations
- Tweet text is not wrapped intelligently (use
\nfor line breaks if needed) - Very long tweets may be cut off
- External image URLs must be publicly accessible
- Base64 images should be reasonably sized
Support
For issues or questions, please contact the maintainer.
Built with: Node.js, Express, node-html-to-image, Puppeteer