API reference
Custom games
Create a customs session, add signed-up players, then dispatch: Zyron's bot pool friends each player in Fortnite and enters the match key in their party — no key ever posted in chat.
All paths are relative to https://api.zyron.pro/api/v1/guilds/:guildId.
How it works
A customs session represents one custom-game lobby: a host, a match key, and a list of signed-up players. The key is never shared publicly — when you dispatch, Zyron's bot pool delivers it to each player inside Fortnite. Players must have a linked Epic account so the bots know whom to friend.
Config
/guilds/:guildId/customs/config/guilds/:guildId/customs/configGuild-wide customs settings. PATCH is a partial update and returns the full config.
| Field | Type | Description |
|---|---|---|
hostRoleIds | string[] | Roles allowed to host customs from Discord. |
cooldownMinutes | number | Minimum minutes between sessions per host. |
minAccountAgeDays | number | Minimum Discord account age for players to sign up. |
requiredRoleIds | string[] | Roles a player must have to sign up (empty = anyone). |
defaultChannelId | string | Default channel for session announcements. |
maxActiveSessions | number | How many sessions may be live at once. |
{
"hostRoleIds": ["987654321098765432"],
"cooldownMinutes": 30,
"minAccountAgeDays": 7,
"requiredRoleIds": [],
"defaultChannelId": "333333333333333333",
"maxActiveSessions": 2
}Presets
/guilds/:guildId/customs/presets/guilds/:guildId/customs/presets/guilds/:guildId/customs/presets/:presetId/guilds/:guildId/customs/presets/:presetIdPresets are saved session templates (title, game mode, region, playlist, team size, signup cap, and lifecycle messages including missedSignup for post-dispatch late sign-ups). Pass a presetId when creating a session to prefill it — explicit body fields override preset values. POST returns 201 with the created preset.
List sessions
/guilds/:guildId/customs/sessions| Field | Type | Description |
|---|---|---|
status | string | Query parameter — filter by status, e.g. open, dispatched, cancelled. |
page | number | Query parameter — 1-based page number. |
limit | number | Query parameter — results per page. |
Create a session
/guilds/:guildId/customs/sessions| Field | Type | Description |
|---|---|---|
hostDiscordIdrequired | string | The Discord member hosting the match. They are DM'd as host with the session details and key. |
title | string | Display title for the session. |
gameModerequired | string | Game mode, e.g. Battle Royale or Zero Build. |
region | string | Server region, e.g. EU, NAC. |
playlist | string | Playlist / island identifier. |
teamSize | number | Players per team (1 = solos). |
channelId | string | Announcement channel. Defaults to the config's defaultChannelId. |
signupCap | number | Maximum number of signed-up players. |
presetId | string | Prefill from a preset; explicit fields override it. |
curl -X POST https://api.zyron.pro/api/v1/guilds/123456789012345678/customs/sessions \
-H "Authorization: Bearer zyr_your_guild_key" \
-H "Content-Type: application/json" \
-d '{
"hostDiscordId": "222222222222222222",
"title": "Friday Night Customs",
"gameMode": "Battle Royale",
"region": "EU",
"teamSize": 2,
"signupCap": 100
}'Returns 201 Created:
{
"session": {
"sessionId": "cs_9f2c1ab34d",
"title": "Friday Night Customs",
"gameMode": "Battle Royale",
"region": "EU",
"teamSize": 2,
"signupCap": 100,
"status": "open",
"hostDiscordId": "222222222222222222",
"players": [],
"createdAt": "2026-07-10T17:00:12.000Z"
},
"key": "duos-eu-4821"
}The key is returned once
key is included only in this 201 response. Store it securely if your integration needs it — later reads require the dedicated GET .../key endpoint, and the key is never shown in session objects.Get session & key
/guilds/:guildId/customs/sessions/:sessionIdReturns the session with its status and player list — without the key.
/guilds/:guildId/customs/sessions/:sessionId/keyReturns { "key": "duos-eu-4821" }. Treat this endpoint as sensitive — anyone with the key can join the match.
Players
/guilds/:guildId/customs/sessions/:sessionId/playersAdds a player to the session — call this when someone signs up in your own bot. The player must have a linked Epic account; otherwise the request fails with 409 conflict and a message explaining the reason (no link, blocklisted, account too new, already signed up, or the cap is reached).
Sign-ups normally require status open. When the session's messages.missedSignup stage is enabled ("keep sign-up open after dispatch"), the endpoint also accepts sign-ups while the session is closed, dispatching or ready — the key is then delivered to the late player immediately. Once the game is started or cancelled the endpoint returns 409 again.
| Field | Type | Description |
|---|---|---|
discordIdrequired | string | The Discord member signing up. |
memberRoleIds | string[] | The member's role IDs, used to evaluate requiredRoleIds without a Discord lookup. |
createdTimestamp | number | The member's Discord account creation time (ms), used to evaluate minAccountAgeDays. |
curl -X POST https://api.zyron.pro/api/v1/guilds/123456789012345678/customs/sessions/cs_9f2c1ab34d/players \
-H "Authorization: Bearer zyr_your_guild_key" \
-H "Content-Type: application/json" \
-d '{ "discordId": "555555555555555555" }'/guilds/:guildId/customs/sessions/:sessionId/players/:discordIdRemoves a player from the session (e.g. they un-signed-up).
Dispatch — deliver the key in-game
/guilds/:guildId/customs/sessions/:sessionId/dispatchThe key-distribution action. Zyron's bot pool friends each signed-up player in Fortnite and enters the match key in their party — players never see the key in Discord. Dispatch runs asynchronously; listen for the customs.dispatch.completed webhook to learn when it finishes and how many deliveries succeeded.
With the preset's messages.missedSignup stage enabled, dispatch also posts a "Missed sign up?" embed with a late sign-up button in the session channel — players who missed the window can still join and get a key until the game is started or cancelled (the button then deactivates).
curl -X POST https://api.zyron.pro/api/v1/guilds/123456789012345678/customs/sessions/cs_9f2c1ab34d/dispatch \
-H "Authorization: Bearer zyr_your_guild_key"Cancel & retry
/guilds/:guildId/customs/sessions/:sessionId/cancelCancels the session and fires the customs.session.cancelled webhook.
/guilds/:guildId/customs/sessions/:sessionId/retry/:discordIdRetries key delivery for a single player whose dispatch failed (e.g. their friend request expired or their party was full).
Leaderboards & scoring
Custom games are scored automatically from replay uploads. When players run the Zyron Client during a hosted custom game, each replay is correlated to the session by the recorder's Epic id on the roster, and every game is scored (placement + eliminations against the session's point system) into a per-game result.
- Per-lobby leaderboard — per-player standings aggregated across all games of one session, plus each game's full scoreboard and killfeed.
- Server-wide ladder — an all-time, per-player leaderboard aggregating every custom game the server has hosted (points, wins, eliminations, games played).
Standings are per player
/guilds/:guildId/customs/leaderboardThe server-wide, all-time ladder for the guild (per player).
/guilds/:guildId/customs/sessions/:sessionId/leaderboardThe per-lobby leaderboard for one session, aggregated across its scored games. Public (no-auth) shareable pages also exist at zyron.pro/leaderboard/customs/<sessionId> and zyron.pro/leaderboard/customs/guild/<guildId>.
Build your own customs bot
The intended integration: your bot owns the Discord UX (signup buttons, embeds, reminders); Zyron owns Epic-side delivery. The flow:
- 1. Create the session —
POST /customs/sessionswith your host'shostDiscordId. Zyron DMs the host; you storesessionId(and the once-onlykeyif you need it). - 2. Add players as they sign up — each time someone clicks your bot's signup button, call
POST .../players. Surface any409message back to the user (e.g. "link your Epic account first"). - 3. Dispatch — when the lobby is ready, call
POST .../dispatch. Zyron's bots friend every player and enter the key in their parties. - 4. Listen for completion — handle the
customs.dispatch.completedwebhook (doneCount,failedCount,cause). UsePOST .../retry/:discordIdfor any stragglers.
Verified links are the prerequisite