2025-12-31 07:07:52 +00:00
2025-12-31 07:07:52 +00:00
2025-12-31 07:07:52 +00:00
2025-12-31 07:07:52 +00:00
2025-12-31 07:07:52 +00:00
2025-12-31 07:07:52 +00:00
2025-12-31 07:07:52 +00:00
2025-12-31 07:07:52 +00:00

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.",
    "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&timestamp=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) or MISS (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: HIT header
  • Cache misses include X-Cache: MISS header
  • 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

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 \n for 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

Description
No description provided
Readme 255 KiB
Languages
JavaScript 75.9%
HTML 23.2%
Dockerfile 0.9%