Skip to content

API · v1

API reference

Automate moderation, tickets, announcements, staff and webhooks from your own tools. Open an endpoint and press Try it out to send a real request with your key.

Quick startAuthenticationErrorsWebhooksOpenAPI file

Your API key

Create one under Developer in the dashboard, then paste it here to use “Try it out”. It stays in this browser and is sent only to this site’s API. Requests you send are real: a ban is a ban.

Base address: https://api.rowarden.com/v1. Rate limit per key and minute, by the plan of the person who made it: Free 60, Plus 300, Pro 1000. Every answer carries RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset.

Your key and experiences

Check a key and see what it can reach.

GET/v1/me#

Check your key

The key and, per experience, what it can do right now.

Permissions
Any valid keyA key needs the permission, and so does the person who made it, right now, in that experience.
Limits
Rate limited per key (see the top of the page).

Responses

  • 200OK
    Example value
    {
      "data": {
        "key": {
          "id": "12",
          "name": "Moderation bot",
          "hint": "…a1b2",
          "scopes": [
            "moderation.ban"
          ],
          "created_at": "2026-11-04T10:00:00.000Z",
          "expires_at": "2027-02-02T10:00:00.000Z"
        },
        "experiences": [
          {
            "id": "34",
            "name": "My Game",
            "permissions": [
              "moderation.ban"
            ]
          }
        ]
      }
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

GET/v1/experiences#

List experiences

The experiences this key can act in, with its effective permissions in each.

Permissions
Any valid keyA key needs the permission, and so does the person who made it, right now, in that experience.
Limits
Rate limited per key (see the top of the page).

Responses

  • 200OK
    Example value
    {
      "data": [
        {
          "id": "34",
          "name": "My Game",
          "permissions": [
            "moderation.ban",
            "players.lookup"
          ]
        }
      ],
      "next_cursor": null
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

GET/v1/experiences/{experienceId}#

Get an experience

The experience and the key’s permissions in it.

Permissions
Any valid keyA key needs the permission, and so does the person who made it, right now, in that experience.
Limits
Rate limited per key (see the top of the page).

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.

Responses

  • 200OK
    Example value
    {
      "data": {
        "id": "34",
        "name": "My Game",
        "universe_id": "4242",
        "verification_status": "verified",
        "icon_url": null,
        "permissions": [
          "moderation.ban"
        ]
      }
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 404Not Found: no such player, ticket, form, webhook or other item.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

Players

Look players up and read their stats.

GET/v1/experiences/{experienceId}/players/{robloxUserId}#

Look up a player

Profile, ban status, whether they are in a running server, and recent moderation records (when the key also has moderation.view_history).

Permissions
  • players.lookup Look up players
A key needs the permission, and so does the person who made it, right now, in that experience.
Limits
Rate limited per key (see the top of the page).

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.
robloxUserId*
string (path)
The player’s Roblox user id (digits).

Responses

  • 200OK
    Example value
    {
      "data": {
        "id": "156",
        "username": "Builderman",
        "avatar_url": null,
        "online": false,
        "server": null,
        "ban": {
          "known": true,
          "active": false,
          "expires_at": null,
          "display_reason": null
        },
        "recent_records": []
      }
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 404Not Found: no such player, ticket, form, webhook or other item.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

GET/v1/experiences/{experienceId}/players/{robloxUserId}/stats#

Read a player’s tracked stats

The current saved value of every stat tracked under Datastores. Needs an Open Cloud key with datastore read access on the experience.

Permissions
  • stats.view View player stats
A key needs the permission, and so does the person who made it, right now, in that experience.
Plan
The experience owner’s plan must include Datastores & player stat editing.
Limits
Rate limited per key (see the top of the page).

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.
robloxUserId*
string (path)
The player’s Roblox user id (digits).

Responses

  • 200OK
    Example value
    {
      "data": {
        "player": {
          "id": "156",
          "username": "Builderman"
        },
        "online": false,
        "stats": [
          {
            "name": "gold",
            "label": "Gold",
            "data_store": "PlayerData",
            "state": "ok",
            "value": 50
          }
        ]
      }
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 404Not Found: no such player, ticket, form, webhook or other item.
  • 424Failed Dependency: setup is missing, usually an Open Cloud key with the right permissions on the experience.
  • 502Bad Gateway: Roblox refused or did not answer.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

Moderation

Bans, kicks, warnings and the history.

GET/v1/experiences/{experienceId}/moderation/records#

List moderation records

Bans, unbans, kicks, warnings and notes, newest first.

Permissions
  • moderation.view_history View moderation history
A key needs the permission, and so does the person who made it, right now, in that experience.
Plan
The experience owner’s plan must include Moderation (bans, warnings, history).
Limits
Rate limited per key (see the top of the page).

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.
limit
integer (query)
How many items to return (1-100). min 1, max 100
Default: 25
cursor
string (query)
The next_cursor of the previous page. up to 100 characters
action
string (query)
One of: banunbankickwarnnote
status
string (query)
"active" means bans in force now.
One of: activecompletedqueuedfailed
search
string (query)
Roblox user ID or part of a username. up to 40 characters

Responses

  • 200OK
    Example value
    {
      "data": [
        {
          "id": "9",
          "action": "ban",
          "status": "completed",
          "target": {
            "id": "156",
            "username": "Builderman"
          },
          "reason": "Exploiting",
          "display_reason": null,
          "duration_seconds": 86400,
          "expires_at": "2026-11-05T10:00:00.000Z",
          "issued_by": "ModName",
          "source": "api",
          "created_at": "2026-11-04T10:00:00.000Z"
        }
      ],
      "next_cursor": null
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 422Unprocessable: something in the request is wrong. The message names the field.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

POST/v1/experiences/{experienceId}/moderation/bans#

Ban a player

The result. A permanent ban may wait for a second person’s approval: status "pending_approval", HTTP 202.

Permissions
  • moderation.ban Ban players
A key needs the permission, and so does the person who made it, right now, in that experience.
Plan
The experience owner’s plan must include Moderation (bans, warnings, history).
Limits
Rate limited per key (see the top of the page). Send an Idempotency-Key header to retry safely.

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.
Idempotency-Key
string (header)
Repeat the request safely: the same key and body returns the first answer instead of acting twice. 1-100 characters, kept 24 hours.

Request body (application/json)

NameDescription
target*
string
Roblox user ID or username. up to 32 characters
reason*
string
Why. Shown to other staff and recorded in the history. at least 3 characters, up to 500 characters
display_reason
string
Shown to the player when they try to join. up to 400 characters
duration_seconds
integer or null
Omit or null for a permanent ban.
exclude_alt_accounts
boolean
Do not ban the player’s alternate accounts.
Example value
{
  "target": "Builderman",
  "reason": "Exploiting"
}

Responses

  • 201Created
    Example value
    {
      "data": {
        "status": "completed",
        "message": "Builderman was banned.",
        "record_id": "9",
        "approval_id": null,
        "target": {
          "id": "156",
          "username": "Builderman"
        }
      }
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 409Conflict: the same Idempotency-Key is still running, or the action clashes with the current state.
  • 422Unprocessable: something in the request is wrong. The message names the field.
  • 424Failed Dependency: setup is missing, usually an Open Cloud key with the right permissions on the experience.
  • 502Bad Gateway: Roblox refused or did not answer.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

POST/v1/experiences/{experienceId}/moderation/unbans#

Lift a ban

The result.

Permissions
  • moderation.unban Unban players
A key needs the permission, and so does the person who made it, right now, in that experience.
Plan
The experience owner’s plan must include Moderation (bans, warnings, history).
Limits
Rate limited per key (see the top of the page). Send an Idempotency-Key header to retry safely.

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.
Idempotency-Key
string (header)
Repeat the request safely: the same key and body returns the first answer instead of acting twice. 1-100 characters, kept 24 hours.

Request body (application/json)

NameDescription
target*
string
Roblox user ID or username. up to 32 characters
reason*
string
Why. Shown to other staff and recorded in the history. at least 3 characters, up to 500 characters
Example value
{
  "target": "Builderman",
  "reason": "Exploiting"
}

Responses

  • 201Created
    Example value
    {
      "data": {
        "status": "completed",
        "message": "Builderman was unbanned.",
        "record_id": "10",
        "approval_id": null,
        "target": {
          "id": "156",
          "username": "Builderman"
        }
      }
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 409Conflict: the same Idempotency-Key is still running, or the action clashes with the current state.
  • 422Unprocessable: something in the request is wrong. The message names the field.
  • 424Failed Dependency: setup is missing, usually an Open Cloud key with the right permissions on the experience.
  • 502Bad Gateway: Roblox refused or did not answer.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

POST/v1/experiences/{experienceId}/moderation/kicks#

Kick a player

The result. "queued" until a game server confirms the kick.

Permissions
  • moderation.kick Kick players
A key needs the permission, and so does the person who made it, right now, in that experience.
Plan
The experience owner’s plan must include Moderation (bans, warnings, history).
Limits
Rate limited per key (see the top of the page). Send an Idempotency-Key header to retry safely.

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.
Idempotency-Key
string (header)
Repeat the request safely: the same key and body returns the first answer instead of acting twice. 1-100 characters, kept 24 hours.

Request body (application/json)

NameDescription
target*
string
Roblox user ID or username. up to 32 characters
reason*
string
Why. Shown to other staff and recorded in the history. at least 3 characters, up to 500 characters
Example value
{
  "target": "Builderman",
  "reason": "Exploiting"
}

Responses

  • 201Created
    Example value
    {
      "data": {
        "status": "queued",
        "message": "Kick queued for Builderman.",
        "record_id": "11",
        "approval_id": null,
        "target": {
          "id": "156",
          "username": "Builderman"
        }
      }
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 409Conflict: the same Idempotency-Key is still running, or the action clashes with the current state.
  • 422Unprocessable: something in the request is wrong. The message names the field.
  • 424Failed Dependency: setup is missing, usually an Open Cloud key with the right permissions on the experience.
  • 502Bad Gateway: Roblox refused or did not answer.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

POST/v1/experiences/{experienceId}/moderation/warnings#

Warn a player or add a note

The result.

Permissions
  • moderation.warn Create warnings and notes
A key needs the permission, and so does the person who made it, right now, in that experience.
Plan
The experience owner’s plan must include Moderation (bans, warnings, history).
Limits
Rate limited per key (see the top of the page). Send an Idempotency-Key header to retry safely.

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.
Idempotency-Key
string (header)
Repeat the request safely: the same key and body returns the first answer instead of acting twice. 1-100 characters, kept 24 hours.

Request body (application/json)

NameDescription
target*
string
Roblox user ID or username. up to 32 characters
reason*
string
Why. Shown to other staff and recorded in the history. at least 3 characters, up to 500 characters
kind
string
"warn" counts towards escalation; "note" is only for staff.
One of: warnnote
Default: warn
Example value
{
  "target": "Builderman",
  "reason": "Exploiting"
}

Responses

  • 201Created
    Example value
    {
      "data": {
        "status": "completed",
        "message": "Warning recorded for Builderman.",
        "record_id": "12",
        "approval_id": null,
        "target": {
          "id": "156",
          "username": "Builderman"
        }
      }
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 409Conflict: the same Idempotency-Key is still running, or the action clashes with the current state.
  • 422Unprocessable: something in the request is wrong. The message names the field.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

Servers and announcements

Running servers and in-game announcements.

GET/v1/experiences/{experienceId}/servers#

List running servers

Servers that reported in the last minutes, fullest first.

Permissions
  • players.lookup Look up players
A key needs the permission, and so does the person who made it, right now, in that experience.
Limits
Rate limited per key (see the top of the page).

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.

Responses

  • 200OK
    Example value
    {
      "data": [
        {
          "job_id": "abc-123",
          "place_id": "5000",
          "player_count": 12,
          "player_ids": [
            "156"
          ],
          "started_at": "2026-11-04T09:00:00.000Z",
          "last_seen_at": "2026-11-04T10:00:00.000Z"
        }
      ],
      "next_cursor": null
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

POST/v1/experiences/{experienceId}/announcements#

Announce in every server

Whether it was sent now or queued for the next presence report.

Permissions
  • game.announce Send in-game announcements
A key needs the permission, and so does the person who made it, right now, in that experience.
Plan
The experience owner’s plan must include In-game server integration (kicks, live servers).
Limits
Rate limited per key (see the top of the page). Send an Idempotency-Key header to retry safely.

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.
Idempotency-Key
string (header)
Repeat the request safely: the same key and body returns the first answer instead of acting twice. 1-100 characters, kept 24 hours.

Request body (application/json)

NameDescription
text*
string
Shown in every running server, filtered by Roblox. up to 300 characters
Example value
{
  "text": "The server restarts in 5 minutes."
}

Responses

  • 202Accepted
    Example value
    {
      "data": {
        "status": "sent",
        "text": "Server restarts in 5 minutes",
        "message": "Announcement sent to all servers via MessagingService."
      }
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 409Conflict: the same Idempotency-Key is still running, or the action clashes with the current state.
  • 422Unprocessable: something in the request is wrong. The message names the field.
  • 424Failed Dependency: setup is missing, usually an Open Cloud key with the right permissions on the experience.
  • 502Bad Gateway: Roblox refused or did not answer.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

Tickets

Support tickets and their replies.

GET/v1/experiences/{experienceId}/tickets#

List tickets

Tickets in the categories the key’s role may see, most recently active first, 30 per page.

Permissions
  • tickets.view View tickets
A key needs the permission, and so does the person who made it, right now, in that experience.
Limits
Rate limited per key (see the top of the page).

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.
status
string (query)
One of: openclosedall
Default: open
category_id
integer (query)
max 9007199254740991
awaiting_staff
string (query)
Only tickets waiting for a staff reply.
One of: truefalse
cursor
string (query)
The next_cursor of the previous page. up to 100 characters

Responses

  • 200OK
    Example value
    {
      "data": [
        {
          "id": "8",
          "number": 12,
          "category_id": "2",
          "subject": "Cheater in server",
          "status": "open",
          "awaiting": "staff",
          "player": {
            "roblox_user_id": "156",
            "username": "Builderman",
            "roblox_verified": true,
            "discord_user_id": null,
            "discord_username": null
          },
          "reported_player": {
            "roblox_user_id": "999",
            "username": "Exploiter"
          },
          "assigned_to": null,
          "created_at": "2026-11-04T09:00:00.000Z",
          "updated_at": "2026-11-04T09:05:00.000Z"
        }
      ],
      "next_cursor": null
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 422Unprocessable: something in the request is wrong. The message names the field.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

GET/v1/experiences/{experienceId}/tickets/{ticketId}#

Get a ticket with its messages

The ticket, the player’s answers and every message, including staff-only notes (`internal: true`).

Permissions
  • tickets.view View tickets
A key needs the permission, and so does the person who made it, right now, in that experience.
Limits
Rate limited per key (see the top of the page).

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.
ticketId*
string (path)
The ticket’s id, as returned by the ticket list.

Responses

  • 200OK
    Example value
    {
      "data": {
        "id": "8",
        "number": 12,
        "subject": "Cheater in server",
        "status": "open",
        "awaiting": "staff",
        "answers": [
          {
            "label": "What happened?",
            "value": "Flying"
          }
        ],
        "messages": [
          {
            "id": "30",
            "author_type": "player",
            "author": "Builderman",
            "body": "Someone is flying",
            "internal": false,
            "created_at": "2026-11-04T09:00:00.000Z"
          }
        ]
      }
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 404Not Found: no such player, ticket, form, webhook or other item.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

POST/v1/experiences/{experienceId}/tickets/{ticketId}/replies#

Reply to a ticket

Confirmation. The reply reaches the player like a dashboard reply; `internal: true` keeps it among staff.

Permissions
  • tickets.respond Reply to and close tickets
A key needs the permission, and so does the person who made it, right now, in that experience.
Limits
Rate limited per key (see the top of the page). Send an Idempotency-Key header to retry safely.

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.
ticketId*
string (path)
The ticket’s id, as returned by the ticket list.
Idempotency-Key
string (header)
Repeat the request safely: the same key and body returns the first answer instead of acting twice. 1-100 characters, kept 24 hours.

Request body (application/json)

NameDescription
body*
string
at least 2 characters, up to 4000 characters
internal
boolean
true: a note only staff can see, not sent to the player.
Default: false
Example value
{
  "body": "Thanks for reporting this. We are looking into it."
}

Responses

  • 201Created
    Example value
    {
      "data": {
        "ticket_id": "8",
        "internal": false
      }
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 404Not Found: no such player, ticket, form, webhook or other item.
  • 409Conflict: the same Idempotency-Key is still running, or the action clashes with the current state.
  • 422Unprocessable: something in the request is wrong. The message names the field.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

POST/v1/experiences/{experienceId}/tickets/{ticketId}/status#

Close or reopen a ticket

The new status.

Permissions
  • tickets.respond Reply to and close tickets
A key needs the permission, and so does the person who made it, right now, in that experience.
Limits
Rate limited per key (see the top of the page). Send an Idempotency-Key header to retry safely.

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.
ticketId*
string (path)
The ticket’s id, as returned by the ticket list.
Idempotency-Key
string (header)
Repeat the request safely: the same key and body returns the first answer instead of acting twice. 1-100 characters, kept 24 hours.

Request body (application/json)

NameDescription
status*
string
One of: openclosed
reason
string
up to 500 characters
Example value
{
  "status": "open"
}

Responses

  • 200OK
    Example value
    {
      "data": {
        "ticket_id": "8",
        "status": "closed"
      }
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 404Not Found: no such player, ticket, form, webhook or other item.
  • 409Conflict: the same Idempotency-Key is still running, or the action clashes with the current state.
  • 422Unprocessable: something in the request is wrong. The message names the field.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

Ban appeals

Review and decide appeals.

GET/v1/experiences/{experienceId}/appeals#

List ban appeals

Up to the 50 most recent pending or decided appeals, with the ban they concern.

Permissions
  • moderation.appeals Review ban appeals
A key needs the permission, and so does the person who made it, right now, in that experience.
Limits
Rate limited per key (see the top of the page).

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.
status
string (query)
One of: pendingdecided
Default: pending

Responses

  • 200OK
    Example value
    {
      "data": [
        {
          "id": "4",
          "status": "pending",
          "player": {
            "roblox_user_id": "156",
            "username": "Builderman",
            "discord_user_id": null
          },
          "message": "I was falsely banned.",
          "ban": null,
          "decided_by": null,
          "decision_note": null,
          "decided_at": null,
          "created_at": "2026-11-04T09:00:00.000Z"
        }
      ],
      "next_cursor": null
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 422Unprocessable: something in the request is wrong. The message names the field.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

POST/v1/experiences/{experienceId}/appeals/{appealId}/decision#

Decide an appeal

The decision. Accepting also lifts the ban, which takes the moderation.unban permission as well, and fails (leaving the appeal pending) if Roblox refuses.

Permissions
  • moderation.appeals Review ban appeals
A key needs the permission, and so does the person who made it, right now, in that experience.
Plan
The experience owner’s plan must include Moderation (bans, warnings, history).
Limits
Rate limited per key (see the top of the page). Send an Idempotency-Key header to retry safely.

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.
appealId*
string (path)
The appeal’s id, as returned by the appeal list.
Idempotency-Key
string (header)
Repeat the request safely: the same key and body returns the first answer instead of acting twice. 1-100 characters, kept 24 hours.

Request body (application/json)

NameDescription
accept*
boolean
true lifts the ban.
note
string
up to 1000 characters
Example value
{
  "accept": false
}

Responses

  • 201Created
    Example value
    {
      "data": {
        "appeal_id": "4",
        "decision": "accepted",
        "message": "Appeal accepted: Builderman was unbanned."
      }
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 404Not Found: no such player, ticket, form, webhook or other item.
  • 409Conflict: the same Idempotency-Key is still running, or the action clashes with the current state.
  • 422Unprocessable: something in the request is wrong. The message names the field.
  • 424Failed Dependency: setup is missing, usually an Open Cloud key with the right permissions on the experience.
  • 502Bad Gateway: Roblox refused or did not answer.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

Watchlist

Players staff want to be alerted about.

GET/v1/experiences/{experienceId}/watchlist#

List the watchlist

Watched players and whether they are in a server now.

Permissions
  • players.lookup Look up players
A key needs the permission, and so does the person who made it, right now, in that experience.
Limits
Rate limited per key (see the top of the page).

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.

Responses

  • 200OK
    Example value
    {
      "data": [
        {
          "roblox_user_id": "156",
          "username": "Builderman",
          "reason": "Alt of a banned player",
          "added_by": "ModName",
          "online": false,
          "created_at": "2026-11-04T09:00:00.000Z"
        }
      ],
      "next_cursor": null
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

POST/v1/experiences/{experienceId}/watchlist#

Watch a player

The entry. Staff are alerted when the player joins a server.

Permissions
  • moderation.watchlist Manage the watchlist
A key needs the permission, and so does the person who made it, right now, in that experience.
Limits
Rate limited per key (see the top of the page). Send an Idempotency-Key header to retry safely.

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.
Idempotency-Key
string (header)
Repeat the request safely: the same key and body returns the first answer instead of acting twice. 1-100 characters, kept 24 hours.

Request body (application/json)

NameDescription
target*
string
Roblox user ID or username. up to 32 characters
reason
string
up to 500 characters
Example value
{
  "target": "Builderman"
}

Responses

  • 201Created
    Example value
    {
      "data": {
        "roblox_user_id": "156",
        "username": "Builderman",
        "reason": "Alt of a banned player",
        "added_by": "api:Moderation bot",
        "online": false,
        "created_at": "2026-11-04T09:00:00.000Z"
      }
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 409Conflict: the same Idempotency-Key is still running, or the action clashes with the current state.
  • 422Unprocessable: something in the request is wrong. The message names the field.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

DELETE/v1/experiences/{experienceId}/watchlist/{robloxUserId}#

Stop watching a player

Confirmation.

Permissions
  • moderation.watchlist Manage the watchlist
A key needs the permission, and so does the person who made it, right now, in that experience.
Limits
Rate limited per key (see the top of the page).

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.
robloxUserId*
string (path)
The player’s Roblox user id (digits).

Responses

  • 200OK
    Example value
    {
      "data": {
        "roblox_user_id": "156",
        "removed": true
      }
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 404Not Found: no such player, ticket, form, webhook or other item.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

Forms

Forms and their responses.

GET/v1/experiences/{experienceId}/forms#

List forms

Forms with their response counts (null for forms the key’s role may not read).

Permissions
  • forms.view View form responses
A key needs the permission, and so does the person who made it, right now, in that experience.
Limits
Rate limited per key (see the top of the page).

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.

Responses

  • 200OK
    Example value
    {
      "data": [
        {
          "id": "2",
          "slug": "staff-application",
          "title": "Staff application",
          "description": null,
          "open": true,
          "responses": 14,
          "last_response_at": "2026-11-03T18:00:00.000Z",
          "updated_at": "2026-10-20T12:00:00.000Z"
        }
      ],
      "next_cursor": null
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

GET/v1/experiences/{experienceId}/forms/{formId}/responses#

List form responses

Responses, newest first, 20 per page.

Permissions
  • forms.view View form responses
A key needs the permission, and so does the person who made it, right now, in that experience.
Limits
Rate limited per key (see the top of the page).

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.
formId*
string (path)
The form’s id, as returned by the form list.
q
string (query)
Roblox user ID, Discord ID or part of a username. up to 60 characters
cursor
string (query)
The next_cursor of the previous page. up to 100 characters

Responses

  • 200OK
    Example value
    {
      "data": [
        {
          "id": "31",
          "player": {
            "roblox_user_id": "156",
            "username": "Builderman",
            "roblox_verified": true,
            "discord_user_id": null
          },
          "answers": [
            {
              "label": "Why do you want to join?",
              "value": "I like helping."
            }
          ],
          "created_at": "2026-11-03T18:00:00.000Z"
        }
      ],
      "next_cursor": null
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 404Not Found: no such player, ticket, form, webhook or other item.
  • 422Unprocessable: something in the request is wrong. The message names the field.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

Staff and roles

Who is on the team and what their roles allow.

GET/v1/experiences/{experienceId}/staff#

List staff

Staff by public handle (never emails or account names).

Permissions
  • staff.view View staff
A key needs the permission, and so does the person who made it, right now, in that experience.
Limits
Rate limited per key (see the top of the page).

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.

Responses

  • 200OK
    Example value
    {
      "data": [
        {
          "id": "5",
          "username": "ModName",
          "roblox_user_id": "1000",
          "discord_user_id": "700",
          "is_owner": false,
          "status": "active",
          "roles": [
            "Moderator"
          ],
          "joined_at": "2026-10-01T10:00:00.000Z",
          "expires_at": null,
          "last_active_at": "2026-11-04T09:00:00.000Z"
        }
      ],
      "next_cursor": null
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

GET/v1/experiences/{experienceId}/roles#

List roles

Roles with their permissions and member counts.

Permissions
  • staff.view View staff
A key needs the permission, and so does the person who made it, right now, in that experience.
Limits
Rate limited per key (see the top of the page).

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.

Responses

  • 200OK
    Example value
    {
      "data": [
        {
          "id": "3",
          "name": "Moderator",
          "description": "Standard moderation.",
          "position": 400,
          "is_owner_role": false,
          "permissions": [
            "moderation.ban"
          ],
          "member_count": 4
        }
      ],
      "next_cursor": null
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

Staff management

Modules for running a team: records, activity, sessions, time off, assignments, promotions and orders.

GET/v1/experiences/{experienceId}/staff-records#

List staff records

Warnings, commendations, notes and more kept about staff the key’s role is above. Needs the Staff records module.

Permissions
  • records.view View staff records of staff below you
A key needs the permission, and so does the person who made it, right now, in that experience.
Plan
The experience owner’s plan must include Staff management (teams, activity, sessions, quotas, records, promotions, time off, orders, documents).
Limits
Rate limited per key (see the top of the page).

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.
kind
string (query)
up to 20 characters
q
string (query)
up to 100 characters
member_id
integer (query)
A staff member id from /staff. max 9007199254740991
include_voided
string (query)
One of: truefalse
limit
integer (query)
min 1, max 200
Default: 100

Responses

  • 200OK
    Example value
    {
      "data": [
        {
          "id": "5",
          "member": {
            "id": "7",
            "name": "ModName"
          },
          "kind": "warning",
          "status": "active",
          "title": "Late to shift",
          "reason": null,
          "from_role": null,
          "to_role": null,
          "expires_at": null,
          "until_at": null,
          "voided_at": null,
          "issued_by": "AdminName",
          "source": "web",
          "created_at": "2026-11-01T10:00:00.000Z"
        }
      ],
      "next_cursor": null
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 422Unprocessable: something in the request is wrong. The message names the field.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

GET/v1/experiences/{experienceId}/orders#

List orders

Customer orders, newest first. Needs the Orders module and both permissions.

Permissions
  • orders.view See all orders and order statistics
  • orders.log Log orders and move your own through their steps
A key needs the permission, and so does the person who made it, right now, in that experience.
Plan
The experience owner’s plan must include Staff management (teams, activity, sessions, quotas, records, promotions, time off, orders, documents).
Limits
Rate limited per key (see the top of the page).

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.
status
string (query)
One of: openpreparingreadycompletedcanceled
q
string (query)
up to 60 characters
member_id
integer (query)
max 9007199254740991
limit
integer (query)
min 1, max 300
Default: 100

Responses

  • 200OK
    Example value
    {
      "data": [
        {
          "id": "40",
          "number": 118,
          "status": "open",
          "customer": {
            "roblox_user_id": "156",
            "name": "Builderman"
          },
          "items": [
            {
              "name": "Burger",
              "qty": 2,
              "price": 50
            }
          ],
          "total": 100,
          "note": null,
          "cashier": {
            "id": "7",
            "name": "ModName"
          },
          "assigned_to": null,
          "source": "dashboard",
          "created_at": "2026-11-04T10:00:00.000Z",
          "completed_at": null
        }
      ],
      "next_cursor": null
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 422Unprocessable: something in the request is wrong. The message names the field.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

GET/v1/experiences/{experienceId}/activity#

Staff activity

In-game time and actions per staff member, as member ids and roles (look names up in /staff). Needs the Activity module and both permissions.

Permissions
  • activity.view_all See everyone's activity and the leaderboard
  • staff.view View staff
A key needs the permission, and so does the person who made it, right now, in that experience.
Plan
The experience owner’s plan must include Staff management (teams, activity, sessions, quotas, records, promotions, time off, orders, documents).
Limits
Rate limited per key (see the top of the page).

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.
range
string (query)
Days, or "week" for the current week in the experience’s calendar.
One of: 73090week
Default: 30
sort
string (query)
One of: timeactions
Default: time

Responses

  • 200OK
    Example value
    {
      "data": {
        "from": "2026-10-06",
        "median_in_game_seconds": 7200,
        "median_actions": 12,
        "in_game_time_available": true,
        "board": [
          {
            "rank": 1,
            "member_id": "7",
            "role": "Moderator",
            "in_game_seconds": 18000,
            "actions": 40,
            "measured": true
          }
        ],
        "trend": [
          {
            "week": "2026-10-26",
            "in_game_seconds": 30000,
            "actions": 90
          }
        ]
      }
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 422Unprocessable: something in the request is wrong. The message names the field.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

GET/v1/experiences/{experienceId}/sessions#

List sessions and shifts

Upcoming sessions, then recent past ones, with how many booked and attended. Needs the Sessions module.

Permissions
  • staff.view View staff
A key needs the permission, and so does the person who made it, right now, in that experience.
Plan
The experience owner’s plan must include Staff management (teams, activity, sessions, quotas, records, promotions, time off, orders, documents).
Limits
Rate limited per key (see the top of the page).

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.

Responses

  • 200OK
    Example value
    {
      "data": [
        {
          "id": "6",
          "kind": "training",
          "title": "Moderator training",
          "description": null,
          "status": "scheduled",
          "canceled_reason": null,
          "starts_at": "2026-11-08T18:00:00.000Z",
          "ends_at": "2026-11-08T19:00:00.000Z",
          "host": {
            "id": "7",
            "name": "ModName"
          },
          "capacity": 20,
          "target_attendees": null,
          "booked": 12,
          "attended": 0,
          "absent": 0,
          "series_id": null
        }
      ],
      "next_cursor": null
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

GET/v1/experiences/{experienceId}/time-off#

Time off

Requests waiting for a decision (from staff below the key’s role), and staff on approved leave in the next 30 days. Needs the Time off module.

Permissions
  • timeoff.review Approve or reject time off of staff below you
A key needs the permission, and so does the person who made it, right now, in that experience.
Plan
The experience owner’s plan must include Staff management (teams, activity, sessions, quotas, records, promotions, time off, orders, documents).
Limits
Rate limited per key (see the top of the page).

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.

Responses

  • 200OK
    Example value
    {
      "data": [
        {
          "id": "2",
          "member": {
            "id": "7",
            "name": "ModName"
          },
          "category": "Holiday",
          "status": "approved",
          "starts_on": "2026-11-10",
          "ends_on": "2026-11-17",
          "reason": null,
          "on_leave_now": false,
          "created_at": "2026-11-01T10:00:00.000Z"
        }
      ],
      "next_cursor": null
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

GET/v1/experiences/{experienceId}/assignments#

Assignments and quotas

Every assignment with each member’s progress in the current period. Needs the Assignments module.

Permissions
  • assignments.manage Create assignments and quotas and tick off manual requirements
A key needs the permission, and so does the person who made it, right now, in that experience.
Plan
The experience owner’s plan must include Staff management (teams, activity, sessions, quotas, records, promotions, time off, orders, documents).
Limits
Rate limited per key (see the top of the page).

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.

Responses

  • 200OK
    Example value
    {
      "data": [
        {
          "id": "3",
          "title": "Weekly quota",
          "description": null,
          "period": "weekly",
          "active": true,
          "due_at": null,
          "requirements": [
            {
              "id": "r1",
              "type": "ingame_time",
              "target": 7200,
              "label": null
            }
          ],
          "window": {
            "starts_on": "2026-11-02",
            "ends_on": "2026-11-08"
          },
          "progress": [
            {
              "member": {
                "id": "7",
                "name": "ModName"
              },
              "percent": 60,
              "completed": false,
              "excused": false,
              "behind": false
            }
          ],
          "history": [
            {
              "period_start": "2026-10-26",
              "members": 8,
              "completed": 6,
              "excused": 1
            }
          ]
        }
      ],
      "next_cursor": null
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

GET/v1/experiences/{experienceId}/promotions#

Promotion recommendations

Open recommendations with their votes, then recently decided ones. Needs the Promotions module.

Permissions
  • promotions.vote Vote on promotion recommendations (for staff below you)
A key needs the permission, and so does the person who made it, right now, in that experience.
Plan
The experience owner’s plan must include Staff management (teams, activity, sessions, quotas, records, promotions, time off, orders, documents).
Limits
Rate limited per key (see the top of the page).

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.

Responses

  • 200OK
    Example value
    {
      "data": [
        {
          "id": "9",
          "status": "open",
          "candidate": {
            "id": "7",
            "name": "ModName",
            "current_role": "Moderator"
          },
          "target_role": "Senior Moderator",
          "nominated_by": "AdminName",
          "justification": "Always on time.",
          "votes": [
            {
              "voter": "SeniorName",
              "justification": "Agreed.",
              "created_at": "2026-11-03T10:00:00.000Z"
            }
          ],
          "decided_by": null,
          "decision_note": null,
          "decided_at": null,
          "created_at": "2026-11-02T10:00:00.000Z"
        }
      ],
      "next_cursor": null
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

Analytics and audit log

Player numbers over time, and everything staff and integrations did.

GET/v1/experiences/{experienceId}/analytics#

Player and visit analytics

Live numbers and a time series, limited to the plan’s analytics history.

Permissions
  • analytics.view View analytics
A key needs the permission, and so does the person who made it, right now, in that experience.
Plan
The experience owner’s plan must include Analytics dashboard.
Limits
Rate limited per key (see the top of the page).

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.
range
string (query)
Capped by the plan’s analytics history.
One of: 24h7d30d90d180d365d
Default: 7d

Responses

  • 200OK
    Example value
    {
      "data": {
        "range_days": 7,
        "limited_by_plan": false,
        "bucket": "day",
        "live": {
          "playing": 120,
          "visits": 100000,
          "favorites": 900
        },
        "live_servers": {
          "servers": 8,
          "players": 118
        },
        "current": {
          "avg_playing": 90,
          "peak_playing": 150,
          "visits_gained": 4000,
          "samples": 2000
        },
        "previous": {
          "avg_playing": 80,
          "peak_playing": 140,
          "visits_gained": 3500,
          "samples": 2000
        },
        "series": [
          {
            "time": "2026-11-04T00:00:00.000Z",
            "avg_playing": 90,
            "peak_playing": 150,
            "visits": 100000,
            "favorites": 900
          }
        ]
      }
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 422Unprocessable: something in the request is wrong. The message names the field.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

GET/v1/experiences/{experienceId}/audit-logs#

Read the audit log

Everything staff and integrations did, newest first, as far back as the plan keeps.

Permissions
  • audit.view View audit logs
A key needs the permission, and so does the person who made it, right now, in that experience.
Plan
The experience owner’s plan must include Audit logs.
Limits
Rate limited per key (see the top of the page).

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.
limit
integer (query)
How many items to return (1-100). min 1, max 100
Default: 25
cursor
string (query)
The next_cursor of the previous page. up to 100 characters
action
string (query)
Action prefix, such as "moderation." or "moderation.ban". up to 60 characters
source
string (query)
One of: webdiscordin_gameadminsystemgame_serverstripeapi
from
string (ISO-8601 time) (query)
ISO-8601, such as 2026-11-01T00:00:00Z.
to
string (ISO-8601 time) (query)

Responses

  • 200OK
    Example value
    {
      "data": [
        {
          "id": "77",
          "action": "moderation.ban",
          "result": "success",
          "source": "api",
          "actor": "api:Moderation bot",
          "target": {
            "type": "roblox_user",
            "id": "156"
          },
          "metadata": {
            "reason": "Exploiting"
          },
          "created_at": "2026-11-04T10:00:00.000Z"
        }
      ],
      "next_cursor": null
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 422Unprocessable: something in the request is wrong. The message names the field.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

Webhooks

Receive events at your own address instead of polling.

GET/v1/experiences/{experienceId}/webhooks#

List webhooks

The experience’s webhooks (never their secrets).

Permissions
  • webhooks.manage Manage outgoing webhooks
A key needs the permission, and so does the person who made it, right now, in that experience.
Limits
Rate limited per key (see the top of the page).

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.

Responses

  • 200OK
    Example value
    {
      "data": [
        {
          "id": "3",
          "label": "Ops channel",
          "url": "https://example.com/rowarden",
          "events": [
            "moderation"
          ],
          "status": "active",
          "payload_version": "v1",
          "consecutive_failures": 0,
          "last_error": null,
          "last_success_at": "2026-11-04T10:00:00.000Z",
          "created_at": "2026-11-01T10:00:00.000Z"
        }
      ],
      "next_cursor": null
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

POST/v1/experiences/{experienceId}/webhooks#

Add a webhook

The webhook, with its signing secret in `secret`. The secret is shown this once; it is never kept for an Idempotency-Key replay.

Permissions
  • webhooks.manage Manage outgoing webhooks
A key needs the permission, and so does the person who made it, right now, in that experience.
Limits
Rate limited per key (see the top of the page). Send an Idempotency-Key header to retry safely. The answer holds a secret that is shown only once.

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.
Idempotency-Key
string (header)
Repeat the request safely: the same key and body returns the first answer instead of acting twice. 1-100 characters, kept 24 hours.

Request body (application/json)

NameDescription
label*
string
at least 2 characters, up to 60 characters
url*
string
https only, on a public address. up to 500 characters
events
array of string
Groups or single events to send. Empty or omitted: everything. up to 100 items
Default: []
payload_version
string
"v1" is the documented body; "legacy" the original one.
One of: v1legacy
Default: v1
Example value
{
  "label": "Ops channel",
  "url": "https://example.com/rowarden"
}

Responses

  • 201Created
    Example value
    {
      "data": {
        "id": "3",
        "label": "Ops channel",
        "url": "https://example.com/rowarden",
        "events": [
          "moderation"
        ],
        "status": "active",
        "payload_version": "v1",
        "consecutive_failures": 0,
        "last_error": null,
        "last_success_at": "2026-11-04T10:00:00.000Z",
        "created_at": "2026-11-01T10:00:00.000Z",
        "secret": "whsec_…"
      }
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 409Conflict: the same Idempotency-Key is still running, or the action clashes with the current state.
  • 422Unprocessable: something in the request is wrong. The message names the field.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

PATCH/v1/experiences/{experienceId}/webhooks/{webhookId}#

Change a webhook

The webhook after the change. The address cannot be changed.

Permissions
  • webhooks.manage Manage outgoing webhooks
A key needs the permission, and so does the person who made it, right now, in that experience.
Limits
Rate limited per key (see the top of the page).

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.
webhookId*
string (path)
The webhook’s id, as returned by the webhook list.

Request body (application/json)

NameDescription
label
string
at least 2 characters, up to 60 characters
events
array of string
Groups or single events to send. Empty or omitted: everything. up to 100 items
active
boolean
false pauses it; true resumes one that was paused or switched off.
payload_version
string
"v1" is the documented body; "legacy" the original one.
One of: v1legacy
Example value
{
  "label": "Ops channel"
}

Responses

  • 200OK
    Example value
    {
      "data": {
        "id": "3",
        "label": "Ops channel",
        "url": "https://example.com/rowarden",
        "events": [
          "moderation"
        ],
        "status": "active",
        "payload_version": "v1",
        "consecutive_failures": 0,
        "last_error": null,
        "last_success_at": "2026-11-04T10:00:00.000Z",
        "created_at": "2026-11-01T10:00:00.000Z"
      }
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 404Not Found: no such player, ticket, form, webhook or other item.
  • 422Unprocessable: something in the request is wrong. The message names the field.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

DELETE/v1/experiences/{experienceId}/webhooks/{webhookId}#

Delete a webhook

Confirmation. Its delivery log is deleted too.

Permissions
  • webhooks.manage Manage outgoing webhooks
A key needs the permission, and so does the person who made it, right now, in that experience.
Limits
Rate limited per key (see the top of the page).

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.
webhookId*
string (path)
The webhook’s id, as returned by the webhook list.

Responses

  • 200OK
    Example value
    {
      "data": {
        "id": "3",
        "deleted": true
      }
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 404Not Found: no such player, ticket, form, webhook or other item.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

POST/v1/experiences/{experienceId}/webhooks/{webhookId}/rotate-secret#

Replace the signing secret

The new secret, once. Both secrets sign for 24 hours.

Permissions
  • webhooks.manage Manage outgoing webhooks
A key needs the permission, and so does the person who made it, right now, in that experience.
Limits
Rate limited per key (see the top of the page). Send an Idempotency-Key header to retry safely. The answer holds a secret that is shown only once.

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.
webhookId*
string (path)
The webhook’s id, as returned by the webhook list.
Idempotency-Key
string (header)
Repeat the request safely: the same key and body returns the first answer instead of acting twice. 1-100 characters, kept 24 hours.

Responses

  • 201Created
    Example value
    {
      "data": {
        "id": "3",
        "secret": "whsec_…"
      }
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 404Not Found: no such player, ticket, form, webhook or other item.
  • 409Conflict: the same Idempotency-Key is still running, or the action clashes with the current state.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

POST/v1/experiences/{experienceId}/webhooks/{webhookId}/test#

Send a test event

Confirmation. A `ping` event is delivered within half a minute.

Permissions
  • webhooks.manage Manage outgoing webhooks
A key needs the permission, and so does the person who made it, right now, in that experience.
Limits
Rate limited per key (see the top of the page). Send an Idempotency-Key header to retry safely.

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.
webhookId*
string (path)
The webhook’s id, as returned by the webhook list.
Idempotency-Key
string (header)
Repeat the request safely: the same key and body returns the first answer instead of acting twice. 1-100 characters, kept 24 hours.

Responses

  • 202Accepted
    Example value
    {
      "data": {
        "id": "3",
        "queued": true
      }
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 404Not Found: no such player, ticket, form, webhook or other item.
  • 409Conflict: the same Idempotency-Key is still running, or the action clashes with the current state.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

GET/v1/experiences/{experienceId}/webhooks/{webhookId}/deliveries#

List recent deliveries

Deliveries of the last 14 days, newest first.

Permissions
  • webhooks.manage Manage outgoing webhooks
A key needs the permission, and so does the person who made it, right now, in that experience.
Limits
Rate limited per key (see the top of the page).

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.
webhookId*
string (path)
The webhook’s id, as returned by the webhook list.
limit
integer (query)
min 1, max 100
Default: 50

Responses

  • 200OK
    Example value
    {
      "data": [
        {
          "id": "4812",
          "event": "moderation.ban",
          "status": "delivered",
          "attempts": 1,
          "last_http_status": 200,
          "last_error": null,
          "created_at": "2026-11-04T10:00:00.000Z",
          "delivered_at": "2026-11-04T10:00:01.000Z"
        }
      ],
      "next_cursor": null
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 404Not Found: no such player, ticket, form, webhook or other item.
  • 422Unprocessable: something in the request is wrong. The message names the field.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.

POST/v1/experiences/{experienceId}/webhooks/{webhookId}/deliveries/{deliveryId}/retry#

Retry a failed delivery

Confirmation. Only failed deliveries can be retried.

Permissions
  • webhooks.manage Manage outgoing webhooks
A key needs the permission, and so does the person who made it, right now, in that experience.
Limits
Rate limited per key (see the top of the page). Send an Idempotency-Key header to retry safely.

Parameters

NameDescription
experienceId*
string (path)
The experience’s id, as returned by GET /v1/experiences.
webhookId*
string (path)
The webhook’s id, as returned by the webhook list.
deliveryId*
string (path)
The delivery’s id, as returned by the delivery list.
Idempotency-Key
string (header)
Repeat the request safely: the same key and body returns the first answer instead of acting twice. 1-100 characters, kept 24 hours.

Responses

  • 202Accepted
    Example value
    {
      "data": {
        "id": "4812",
        "queued": true
      }
    }
  • 401Unauthorized: the key is missing, wrong, expired or revoked.
  • 403Forbidden: the key or the person behind it lacks the permission, has no access to that experience, or the owner’s plan does not include this.
  • 404Not Found: no such player, ticket, form, webhook or other item.
  • 409Conflict: the same Idempotency-Key is still running, or the action clashes with the current state.
  • 429Too Many Requests: wait for the Retry-After header’s seconds.
  • 500Internal Server Error: our side. Quote the request_id.

Errors have the shape { "error": { "code", "message", "request_id" } }. The example answer shows the shape; the values come from your own data.