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 -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.

key stays on this device
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.

NameRequiredDescription
usernameyes*Display name
handleno@handle when the template shows one
avatar_urlnoPublic image URL
avatar_base64noBase64 / data-URL instead of URL
timestampnoTime 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 bodyJSON
{
  "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.

errorHTTPDescription
unauthorized401Missing or wrong API key
invalid_json400Body is not a JSON object
bad_request400Bad / missing fields
not_linked404No Roblox account linked to that Discord user
not_found404Roblox user / path not found
unknown_route404Unknown path
rate_limited429Too many requests for that key
not_configured503Account lookup isn’t available right now
lookup_failed502Account lookup failed
render_failed500Image render failed
401 unauthorizedJSON
{
  "success": false,
  "elapsed": 0.0012,
  "error": "unauthorized",
  "message": "Missing or invalid API key. Send X-API-Key or Authorization: Bearer."
}
400 bad_requestJSON
{
  "success": false,
  "elapsed": 0.0041,
  "error": "bad_request",
  "message": "`msg` is required."
}
400 invalid_jsonJSON
{
  "success": false,
  "elapsed": 0.0008,
  "error": "invalid_json",
  "message": "Body must be JSON."
}
404 unknown_routeJSON
{
  "success": false,
  "elapsed": 0.0006,
  "error": "unknown_route",
  "message": "Unknown fake route `discord/msg`. See /docs for the list."
}
429 rate_limitedJSON
{
  "success": false,
  "elapsed": 0.0009,
  "error": "rate_limited",
  "message": "Max 20 requests per 60s per API key."
}
500 render_failedJSON
{
  "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
statusretry?notes
401 / 400 / 404nofix inputs or auth
429yesback off; limit is 20/min per key
500yestransient render failure possible
network timeoutyessafe to resend the same JSON

Endpoints

POST /v1/fake/discord/message

Classic Discord chat message.

Parameters
NameNotes
usernamereqdisplay name
msgreqmessage text
handleopt@handle if shown; defaults to username
avatar_url / avatar_base64optprofile picture; omit for a letter avatar
themeoptdark, light, onyx, ash
fontoptggsans, tempo, sakura, jellybean, modern, medieval, eightbit, vampyre
timestampopte.g. 12:56 AM
hide_clantagsoptbool; hide guild tags when present
image_url / image_base64optimage attachment under the message
reactionsoptstring 💀 5, 😭 3 or list of {emoji, count}
Example responseimage/png
Discord message example
Request bodyJSON
{
  "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
NameNotes
usernamereqmain message author
msgreqmain message text
reply_textreqsnippet in the reply bar
reply_usernameoptname in the reply bar
reply_handleopt@handle for the replied-to user
reply_avatar_url / reply_avatar_base64optavatar in the reply bar; omit for a letter avatar
handleopt@handle for the main author; defaults to username
avatar_url / avatar_base64optmain author avatar; omit for a letter avatar
themeoptdark, light, onyx, ash
fontoptggsans, tempo, sakura, jellybean, modern, medieval, eightbit, vampyre
timestampopte.g. 1:02 AM
hide_clantagsoptbool; hide guild tags when present
image_url / image_base64optimage attachment under the main message
reactionsoptstring 💀 5, 😭 3 or list of {emoji, count}
mention_highlightoptbool; gold highlight like a pinged reply
Example responseimage/png
Discord reply example
Request bodyJSON
{
  "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
NameNotes
channelreqvoice channel name
usersreqarray of members, max 12
users[].usernamereqdisplay name
users[].handleopt@handle; defaults to username
users[].avatar_url / users[].avatar_base64optprofile picture; omit for a letter avatar
users[].statusoptlist or string: live, camera, muted, deafened, server_muted, server_deafened, speaking
timeroptcall duration, default 12:34
themeoptdark, light, onyx, ash
fontoptggsans, tempo, sakura, jellybean, modern, medieval, eightbit, vampyre
hide_clantagsoptbool; hide guild tags when present
Example responseimage/png
Discord VC example
Request bodyJSON
{
  "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
NameNotes
usernamereqdisplay name on the card
handleopt@handle; defaults to username
avatar_url / avatar_base64optprofile picture; omit for a letter avatar
timestampopttime on the right, default 1m
Example responseimage/png
Friend request example
Request bodyJSON
{
  "username": "alex",
  "timestamp": "1m"
}
POST /v1/fake/discord/message-request

Pending message request row.

Parameters
NameNotes
usernamereqdisplay name
msgreqpreview message text
handleopt@handle; defaults to username
avatar_url / avatar_base64optprofile picture; omit for a letter avatar
timestampopttime after the name, default 1m ago
Example responseimage/png
Message request example
Request bodyJSON
{
  "username": "alex",
  "msg": "hey can I ask something",
  "timestamp": "1m ago"
}
POST /v1/fake/discord/convo

Multi-message conversation. Same-name rows stack.

Parameters
NameNotes
messagesreqarray of messages, max 20
messages[].usernamereqdisplay name
messages[].msgreqmessage text
messages[].handleopt@handle; defaults to username
messages[].avatar_url / messages[].avatar_base64optprofile picture; omit for a letter avatar
themeoptdark, light, onyx, ash
fontoptggsans, tempo, sakura, jellybean, modern, medieval, eightbit, vampyre
timestampopttime beside each username, e.g. 12:56 AM
hide_clantagsoptbool; hide guild tags when present
Example responseimage/png
Conversation example
Request bodyJSON
{
  "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
NameNotes
usernamereqgift sender display name
handleopt@handle; defaults to username
avatar_url / avatar_base64optsender avatar; omit for a letter avatar
themeoptdark, light, onyx, ash
fontoptggsans, tempo, sakura, jellybean, modern, medieval, eightbit, vampyre
timestampopte.g. 12:56 AM
hide_clantagsoptbool; hide guild tags when present
repliesoptarray max 3; each needs username + msg, optional handle / avatars
Example responseimage/png
Nitro gift example
Request bodyJSON
{
  "username": "feetu",
  "replies": [
    {"username": "alex", "msg": "thanks!"}
  ]
}
POST /v1/fake/tweet

Single tweet / X post card. Counts auto-fill if omitted.

Parameters
NameNotes
usernamereqdisplay name
msgreqtweet body
handleopt@handle without the @; defaults to username
themeoptlights out, dim, light
avatar_url / avatar_base64optprofile picture; omit for a letter avatar
likes, replies, retweets, bookmarks, viewsoptints; omitted counts are filled automatically
verifiedoptbool; blue verified badge
followoptbool; show Follow button (default true)
timestampopttime under the tweet, e.g. 11:30 PM
dateoptdate under the tweet, e.g. 8/26/26
Example responseimage/png
Tweet example
Request bodyJSON
{
  "username": "alex",
  "handle": "alex",
  "msg": "shipping tonight",
  "likes": 4200,
  "verified": true
}
POST /v1/fake/youtube/comment

YouTube-style comment row.

Parameters
NameNotes
usernamereqdisplay name
msgreqcomment text
avatar_url / avatar_base64optprofile picture; omit for a letter avatar
timestampoptdo not include ago; use 2 hours, 5 minutes, etc.
likesoptlike count (int)
repliesoptreply count (int)
Example responseimage/png
YouTube comment example
Request bodyJSON
{
  "username": "alex",
  "msg": "this goes hard",
  "likes": 128,
  "replies": 4,
  "timestamp": "2 hours"
}
POST /v1/fake/tiktok/following

Following notification card.

Parameters
NameNotes
tiktok_usernameoptpublic TikTok handle; fetches real name + avatar
usernamereq*required when not using tiktok_username
avatar_url / avatar_base64optmanual mode only; omit for a letter avatar
verifiedoptbool; verified badge (auto for verified TikTok lookups)
timestampopte.g. Just now, 1h, Aug 2
Example responseimage/png
TikTok following example
Request bodyJSON
{
  "username": "cooluser",
  "timestamp": "Just now",
  "verified": true
}
POST /v1/fake/tiktok/comment

One comment, or stack up to 3 with comments.

Parameters
NameNotes
commentsoptarray of up to 3 comments; or send one comment at the root
usernamereqdisplay name (per comment) when not using tiktok_username
tiktok_usernameoptpublic TikTok handle; fetches real name + avatar
msgreqcomment text
likesoptlike count string, e.g. 12.5K
repliesoptint; adds a View N replies row when above 0
timestampoptcomment time, e.g. 1m, 2h, 3d
avatar_url / avatar_base64optmanual mode only; omit for a letter avatar
gapoptextra pixels between stacked comment cards
Example responseimage/png
TikTok comment example
Request bodyJSON
{
  "comments": [
    {"username": "cool", "msg": "fire", "likes": "12.5K"},
    {"username": "alex", "msg": "real", "likes": "840"}
  ],
  "gap": 8
}
POST /v1/fake/instagram/comment

Instagram comment card. Send one comment, or stack up to 3 with comments.

Parameters
NameNotes
commentsoptarray of up to 3 comments; or send one comment at the root
usernamereqdisplay name (per comment)
msgreqcomment text
likesoptlike count string, e.g. 48 or 12.5K
repliesoptint; adds a View N more replies row when above 0
timestampopte.g. 2h, 30m, 3d
avatar_url / avatar_base64optprofile picture; omit for a letter avatar
gapoptextra pixels between stacked comment cards
Example responseimage/png
Instagram comment example
Request bodyJSON
{
  "comments": [
    {"username": "alex", "msg": "this is clean", "likes": "48", "timestamp": "2h"}
  ]
}
POST /v1/fake/pornhub/comment

Pornhub-style comment row.

Parameters
NameNotes
usernamereqdisplay name
msgreqcomment text
avatar_url / avatar_base64optprofile picture; omit for a letter avatar
likesoptlike count (int)
timestampoptfull label, e.g. 2 hours ago
Example responseimage/png
Pornhub comment example
Request bodyJSON
{
  "username": "alex",
  "msg": "actually crazy",
  "likes": 12,
  "timestamp": "2 hours ago"
}
GET /v1/discord2roblox/{discord_id}

Find the Roblox account linked to a Discord user.

Path
NameRequiredDescription
discord_idyesDiscord user ID
Examplecurl
curl -s "https://api.vrt.rest/v1/discord2roblox/338801162075635733" \
  -H "X-API-Key: YOUR_KEY"
Example responseJSON
{
  "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
NameRequiredDescription
queryyesRoblox username or user ID (URL-encode if needed)
Examplecurl
curl -s "https://api.vrt.rest/v1/roblox2discord/Roblox" \
  -H "X-API-Key: YOUR_KEY"
Example responseJSON
{
  "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 responsejson
{
  "success": true,
  "service": "fake-api",
  "auth_required": true,
  "key_rate_per_min": 20
}