API Reference
POST JSON for fake images, or GET to look up Discord and Roblox accounts.
base /v1/fake
png default
?format=json for base64
curl
python
javascript
go
php
c#
curl -X POST https://api.vrt.rest/v1/fake/discord/message \
-H "X-API-Key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"username":"alex","msg":"hello","timestamp":"12:56 AM"}' \
--output vrt.png
import requests
r = requests.post(
"https://api.vrt.rest/v1/fake/discord/message",
headers={"X-API-Key": "YOUR_KEY"},
json={
"username": "alex",
"msg": "hello",
"timestamp": "12:56 AM",
},
timeout=60,
)
r.raise_for_status()
open("vrt.png", "wb").write(r.content)
const res = await fetch("https://api.vrt.rest/v1/fake/discord/message", {
method: "POST",
headers: {
"X-API-Key": "YOUR_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
username: "alex",
msg: "hello",
timestamp: "12:56 AM",
}),
});
if (!res.ok) throw new Error(await res.text());
const buf = Buffer.from(await res.arrayBuffer());
require("fs").writeFileSync("vrt.png", buf);
package main
import (
"bytes"
"net/http"
"os"
)
func main() {
body := []byte(`{"username":"alex","msg":"hello","timestamp":"12:56 AM"}`)
req, _ := http.NewRequest("POST", "https://api.vrt.rest/v1/fake/discord/message", bytes.NewReader(body))
req.Header.Set("X-API-Key", "YOUR_KEY")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil { panic(err) }
defer res.Body.Close()
f, _ := os.Create("vrt.png")
defer f.Close()
f.ReadFrom(res.Body)
}
<?php
$ch = curl_init("https://api.vrt.rest/v1/fake/discord/message");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
"X-API-Key: YOUR_KEY",
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode([
"username" => "alex",
"msg" => "hello",
"timestamp" => "12:56 AM",
]),
CURLOPT_RETURNTRANSFER => true,
]);
$png = curl_exec($ch);
file_put_contents("vrt.png", $png);
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "YOUR_KEY");
var json = """{"username":"alex","msg":"hello","timestamp":"12:56 AM"}""";
var res = await client.PostAsync(
"https://api.vrt.rest/v1/fake/discord/message",
new StringContent(json, System.Text.Encoding.UTF8, "application/json"));
res.EnsureSuccessStatusCode();
await File.WriteAllBytesAsync("vrt.png", await res.Content.ReadAsByteArrayAsync());
limits
key required on fake and account routes
20 requests / minute / key
no IP rate limit
~12MB max body (fake routes)
try it
Paste your API key, pick a route, edit the JSON, and send.
api key
route
json body
send request
key stays on this device
response
PNG or error shows here
auth
Send your API key on every request that isn’t a public docs/health page. Treat it like a password. Each key has its own 20/min limit.
headers
X-API-Key: YOUR_KEY
# or
Authorization: Bearer YOUR_KEY
/docs and /health do not require a key.
common fields
Most routes take the same identity fields. Skip avatar fields for a letter avatar.
Name Required Description
usernameyes* Display name
handleno @handle when the template shows one
avatar_urlno Public image URL
avatar_base64no Base64 / data-URL instead of URL
timestampno Time label (format depends on route)
*TikTok routes can use tiktok_username instead of username. Nested rows (users[], messages[], replies[], comments[]) accept the same identity fields.
responses
Default response is raw image/png. Elapsed time is also in the X-Elapsed header.
For JSON, use ?format=json or send Accept: application/json.
JSON body JSON
{
"success": true,
"elapsed": 0.182,
"content_type": "image/png",
"filename": "vrt.png",
"image_base64": "..."
}
errors
Failed calls always return JSON with success: false, even when you asked for a PNG.
error HTTP Description
unauthorized401 Missing or wrong API key
invalid_json400 Body is not a JSON object
bad_request400 Bad / missing fields
not_linked404 No Roblox account linked to that Discord user
not_found404 Roblox user / path not found
unknown_route404 Unknown path
rate_limited429 Too many requests for that key
not_configured503 Account lookup isn’t available right now
lookup_failed502 Account lookup failed
render_failed500 Image render failed
401 unauthorized JSON
{
"success": false,
"elapsed": 0.0012,
"error": "unauthorized",
"message": "Missing or invalid API key. Send X-API-Key or Authorization: Bearer."
}
400 bad_request JSON
{
"success": false,
"elapsed": 0.0041,
"error": "bad_request",
"message": "`msg` is required."
}
400 invalid_json JSON
{
"success": false,
"elapsed": 0.0008,
"error": "invalid_json",
"message": "Body must be JSON."
}
404 unknown_route JSON
{
"success": false,
"elapsed": 0.0006,
"error": "unknown_route",
"message": "Unknown fake route `discord/msg`. See /docs for the list."
}
429 rate_limited JSON
{
"success": false,
"elapsed": 0.0009,
"error": "rate_limited",
"message": "Max 20 requests per 60s per API key."
}
500 render_failed JSON
{
"success": false,
"elapsed": 0.214,
"error": "render_failed",
"message": "Couldn't generate that image. Check your inputs and try again."
}
retries
Each successful POST returns a new PNG. There is no idempotency key, and repeating the same body
is fine: you just get another image.
The API does not send Retry-After. On 429 or 500, wait and retry
the same request. A simple pattern is exponential backoff, for example 1s, then 2s, then 4s, with a small
cap (3 to 5 attempts).
Do not hammer retries on 401, 400, or 404. Fix the key, body, or path first.
Suggested client behavior
status retry? notes
401 / 400 / 404 no fix inputs or auth
429 yes back off; limit is 20/min per key
500 yes transient render failure possible
network timeout yes safe to resend the same JSON
Endpoints
POST
/v1/fake/discord/message
Classic Discord chat message.
Parameters
Name Notes
usernamereq display name
msgreq message text
handleopt @handle if shown; defaults to username
avatar_url / avatar_base64opt profile picture; omit for a letter avatar
themeopt dark, light, onyx, ash
fontopt ggsans, tempo, sakura, jellybean, modern, medieval, eightbit, vampyre
timestampopt e.g. 12:56 AM
hide_clantagsopt bool; hide guild tags when present
image_url / image_base64opt image attachment under the message
reactionsopt string 💀 5, 😭 3 or list of {emoji, count}
Example response image/png
Request body JSON
{
"username": "alex",
"msg": "yo we shipping tonight",
"timestamp": "12:56 AM",
"theme": "dark",
"reactions": "💀 5, 😭 3"
}
POST
/v1/fake/discord/reply
Message with a reply bar above it.
Parameters
Name Notes
usernamereq main message author
msgreq main message text
reply_textreq snippet in the reply bar
reply_usernameopt name in the reply bar
reply_handleopt @handle for the replied-to user
reply_avatar_url / reply_avatar_base64opt avatar in the reply bar; omit for a letter avatar
handleopt @handle for the main author; defaults to username
avatar_url / avatar_base64opt main author avatar; omit for a letter avatar
themeopt dark, light, onyx, ash
fontopt ggsans, tempo, sakura, jellybean, modern, medieval, eightbit, vampyre
timestampopt e.g. 1:02 AM
hide_clantagsopt bool; hide guild tags when present
image_url / image_base64opt image attachment under the main message
reactionsopt string 💀 5, 😭 3 or list of {emoji, count}
mention_highlightopt bool; gold highlight like a pinged reply
Example response image/png
Request body JSON
{
"username": "alex",
"msg": "fair enough",
"reply_username": "feetu",
"reply_text": "you coming?",
"timestamp": "1:02 AM"
}
POST
/v1/fake/discord/vc
Voice channel member list.
Parameters
Name Notes
channelreq voice channel name
usersreq array of members, max 12
users[].usernamereq display name
users[].handleopt @handle; defaults to username
users[].avatar_url / users[].avatar_base64opt profile picture; omit for a letter avatar
users[].statusopt list or string: live, camera, muted, deafened, server_muted, server_deafened, speaking
timeropt call duration, default 12:34
themeopt dark, light, onyx, ash
fontopt ggsans, tempo, sakura, jellybean, modern, medieval, eightbit, vampyre
hide_clantagsopt bool; hide guild tags when present
Example response image/png
Request body JSON
{
"channel": "General",
"timer": "12:34",
"users": [
{"username": "feetu", "status": ["speaking"]},
{"username": "alex", "status": ["muted"]},
{"username": "kai", "status": ["deafened"]}
]
}
POST
/v1/fake/discord/request
Friend request notification card.
Parameters
Name Notes
usernamereq display name on the card
handleopt @handle; defaults to username
avatar_url / avatar_base64opt profile picture; omit for a letter avatar
timestampopt time on the right, default 1m
Example response image/png
Request body JSON
{
"username": "alex",
"timestamp": "1m"
}
POST
/v1/fake/discord/message-request
Pending message request row.
Parameters
Name Notes
usernamereq display name
msgreq preview message text
handleopt @handle; defaults to username
avatar_url / avatar_base64opt profile picture; omit for a letter avatar
timestampopt time after the name, default 1m ago
Example response image/png
Request body JSON
{
"username": "alex",
"msg": "hey can I ask something",
"timestamp": "1m ago"
}
POST
/v1/fake/discord/convo
Multi-message conversation. Same-name rows stack.
Parameters
Name Notes
messagesreq array of messages, max 20
messages[].usernamereq display name
messages[].msgreq message text
messages[].handleopt @handle; defaults to username
messages[].avatar_url / messages[].avatar_base64opt profile picture; omit for a letter avatar
themeopt dark, light, onyx, ash
fontopt ggsans, tempo, sakura, jellybean, modern, medieval, eightbit, vampyre
timestampopt time beside each username, e.g. 12:56 AM
hide_clantagsopt bool; hide guild tags when present
Example response image/png
Request body JSON
{
"messages": [
{"username": "feetu", "msg": "hey"},
{"username": "alex", "msg": "yo"},
{"username": "alex", "msg": "whats up"},
{"username": "feetu", "msg": "shipping the api"}
]
}
POST
/v1/fake/discord/nitro
Nitro gift drop with optional replies.
Parameters
Name Notes
usernamereq gift sender display name
handleopt @handle; defaults to username
avatar_url / avatar_base64opt sender avatar; omit for a letter avatar
themeopt dark, light, onyx, ash
fontopt ggsans, tempo, sakura, jellybean, modern, medieval, eightbit, vampyre
timestampopt e.g. 12:56 AM
hide_clantagsopt bool; hide guild tags when present
repliesopt array max 3; each needs username + msg, optional handle / avatars
Example response image/png
Request body JSON
{
"username": "feetu",
"replies": [
{"username": "alex", "msg": "thanks!"}
]
}
POST
/v1/fake/tiktok/following
Following notification card.
Parameters
Name Notes
tiktok_usernameopt public TikTok handle; fetches real name + avatar
usernamereq* required when not using tiktok_username
avatar_url / avatar_base64opt manual mode only; omit for a letter avatar
verifiedopt bool; verified badge (auto for verified TikTok lookups)
timestampopt e.g. Just now, 1h, Aug 2
Example response image/png
Request body JSON
{
"username": "cooluser",
"timestamp": "Just now",
"verified": true
}
GET
/v1/discord2roblox/{discord_id}
Find the Roblox account linked to a Discord user.
Path
Name Required Description
discord_idyes Discord user ID
Example curl
curl -s "https://api.vrt.rest/v1/discord2roblox/338801162075635733" \
-H "X-API-Key: YOUR_KEY"
Example response JSON
{
"success": true,
"elapsed": 0.12,
"discord_id": 338801162075635733,
"roblox_id": 1,
"username": "Roblox",
"avatar_url": null
}
GET
/v1/roblox2discord/{query}
Find Discord accounts linked to a Roblox user.
Path
Name Required Description
queryyes Roblox username or user ID (URL-encode if needed)
Example curl
curl -s "https://api.vrt.rest/v1/roblox2discord/Roblox" \
-H "X-API-Key: YOUR_KEY"
Example response JSON
{
"success": true,
"elapsed": 0.25,
"roblox": {
"id": 1,
"username": "Roblox",
"display_name": "Roblox",
"profile_url": "https://www.roblox.com/users/1/profile",
"avatar_url": "https://…"
},
"matches": [
{
"discord_id": 338801162075635733,
"display_name": "boohooidc",
"profile_url": "https://discord.com/users/338801162075635733",
"avatar_url": "https://…",
"source": "bloxlink",
"saved_at": 1710000000
}
],
"count": 1
}
GET
/health
Fake Image API status. No API key required.
example response json
{
"success": true,
"service": "fake-api",
"auth_required": true,
"key_rate_per_min": 20
}