ar-gcp-cdn.bistudio.com
(Bohemia Interactive CDN) — without downloading to our servers.
Load external content?
REST API, JSON responses, standard HTTP codes. All mutating endpoints require authentication.
All list endpoints accept a ?share=<token> query param for public read-only access without authentication.
| Badge | Meaning |
|---|---|
| Auth | JWT or API-Key required |
| Owner | Primary owner or co-owner |
| O/C | Owner, co-owner, or collaborator with sufficient permissions |
| Primary | Primary owner only (not co-owners) |
| Admin | Admin role required |
/api/v1/auth/login
{ "email": "user@example.com", "password": "..." }
{ "token": "eyJ...", "user": { "user_id": "...", "display_name": "Ghost" } }
Include the token: Authorization: Bearer <token>
Or use a long-lived API Key: X-API-Key: <key> (manage in Settings → API Keys)
| Method | Path | Notes |
|---|---|---|
| GET | /api/v1/auth/me |
Current user info: id, email, display_name, role, is_approved. |
| POST | /api/v1/auth/magic |
Request a magic-link login email. Body: { "email": "..." }. |
| GET | /api/v1/auth/magic/verify |
Verify magic link token from email. Query: ?token=. Returns JWT. |
| GET | /api/v1/auth/discord |
Redirect to Discord OAuth2 login flow. |
| GET | /api/v1/auth/discord/callback |
Discord OAuth2 callback. Returns JWT on success. |
| GET | /api/v1/auth/email-verify |
Verify a new email address. Query: ?token=. |
/api/v1/users/search
Auth
Live user search for autocomplete (collaborator/co-owner/group-member pickers). Query: ?q= (min 2 chars).
{ "users": [{ "id": "...", "display_name": "Ghost" }] }
| Method | Path | Auth | Notes |
|---|---|---|---|
| PUT | /api/v1/settings/display-name | Auth | Update display name. Body: { "display_name": "..." } |
| DELETE | /api/v1/settings/account | Auth | Permanently deletes account and all associated data. |
| Method | Path | Auth | Notes |
|---|---|---|---|
| GET | /api/v1/api-keys | Auth | Lists all API keys for the current user. |
| POST | /api/v1/api-keys | Auth | Generates a new API key. Body: { "name": "..." } |
/api/v1/mods
Browse the mod catalog. Query params: search, tag, sort (name_asc, name_desc, size_desc, updated_desc), page, limit (max 100).
{ "mods": [{...}], "total": 1250, "pages": 63 }
/api/v1/mods/autocomplete
Fast autocomplete search. Query param: q.
[{ "workshop_id": "...", "name": "...", "image_url": "..." }]
/api/v1/mods/:workshopID
Full mod metadata including dependency_ids, tags, image_url, author, summary.
/api/v1/mods/:workshopID/...| Path | Description |
|---|---|
/metadata | Lightweight metadata (DB only, no extra tables). |
/items | Weapons, vehicles, gear. Filter: ?type=vehicle|weapon|gear, ?version= |
/missions | Extracted scenarios. Filter: ?version= |
/deps | Dependency graph with sizes. |
/versions | Full version history & changelogs. |
/screenshots | Official screenshot gallery. |
/item-versions | Versions that have extracted item data available. |
/diff | Item diff between two versions. Query: ?from=&to= |
| Method | Path | Auth | Notes |
|---|---|---|---|
| GET | /api/v1/lists | — | Public lists. Add ?public=1. Or /lists/mine (Auth) for your own. |
| POST | /api/v1/lists | Auth | Body: { "name", "description", "is_public" } |
| GET | /api/v1/lists/:id | — | List detail + items, tags, dependency tree, missing deps. |
| PUT | /api/v1/lists/:id | Owner | Update name / description / visibility. |
| DELETE | /api/v1/lists/:id | Primary | Permanently deletes list, items, versions, audit log. |
| PATCH | /api/v1/lists/:id/community | Owner | Assign list to community: {"community_id": "uuid"} |
| PATCH | /api/v1/lists/:id/folder | Owner | Assign list to folder: {"folder_id": "uuid"} |
| Method | Path | Auth | Notes |
|---|---|---|---|
| POST | /api/v1/lists/:id/mods | O/C | Body: { "workshop_id": "..." }. Auto-scrapes unknown mods. |
| DELETE | /api/v1/lists/:id/mods/:workshopID | O/C | Remove a mod from the list. |
| PUT | /api/v1/lists/:id/mods/:workshopID/version | O/C | Pin/unpin version. Body: { "version": "1.2.3" } or { "version": null }. |
| POST | /api/v1/lists/:id/mods/reorder | O/C | Save manual sort order. Body: { "order": ["workshopID", ...] } |
| POST | /api/v1/lists/:id/rescrape | O/C | Enqueues a background rescrape for all mods in the list. |
| Method | Path | Auth | Notes |
|---|---|---|---|
| GET | /api/v1/lists/:id/template-links | O/C | Lists templates this list is subscribed to. |
| DELETE | /api/v1/lists/:id/template-links/:templateID | O/C | Removes a template subscription. |
| POST | /api/v1/templates/:id/push | Owner | Pushes template updates to all subscribed lists. |
Collaborators can add/remove mods based on their per-list permissions. Co-owners have full management rights (same as the primary owner), except they cannot delete the list or add/remove other co-owners.
| Method | Path | Auth | Notes |
|---|---|---|---|
| GET | /api/v1/lists/:id/collaborators | O/C | All collaborators with their permission flags. |
| POST | /api/v1/lists/:id/collaborators | Owner | Add collaborator. Body: { "search": "name_or_email" } |
| DELETE | /api/v1/lists/:id/collaborators/:userID | Owner | Remove collaborator. |
| PUT | /api/v1/lists/:id/collaborators/:userID/permissions | Owner | Update per-user flags. Body: { "can_add": true, "can_remove": true, "can_deploy": false } |
| POST | /api/v1/lists/:id/share-token/reset | Owner | Regenerate the public share token. Returns { "share_token": "..." } |
| POST | /api/v1/lists/:id/suggestion-token/reset | Owner | Regenerate the suggestion link token. Returns { "suggestion_token": "..." } |
| Method | Path | Auth | Notes |
|---|---|---|---|
| GET | /api/v1/lists/:id/owners | Owner | List all co-owners. Returns { "owners": [{ "user_id", "display_name", "added_at" }] } |
| POST | /api/v1/lists/:id/owners | Primary | Add co-owner. Body: { "search": "name_or_email" } |
| DELETE | /api/v1/lists/:id/owners/:userID | Primary | Remove co-owner. |
Assign a permission group to a list so all group members gain access. Per-list overrides can be set to differ from the group's defaults.
| Method | Path | Auth | Notes |
|---|---|---|---|
| GET | /api/v1/lists/:id/groups | Owner | All groups assigned to this list, with their effective permission flags. |
| POST | /api/v1/lists/:id/groups | Owner | Assign a group. Body: { "group_id": "...", "can_add": null, "can_remove": null, "can_deploy": null } — null means inherit from group defaults. |
| PATCH | /api/v1/lists/:id/groups/:groupID | Owner | Update per-list permission overrides. Body: same as POST (null = reset to group default). |
| DELETE | /api/v1/lists/:id/groups/:groupID | Owner | Remove group from this list. Group members lose access. |
| Method | Path | Auth | Notes |
|---|---|---|---|
| GET | /api/v1/lists/pins | Auth | Your pinned lists. |
| POST | /api/v1/lists/:id/pin | Auth | Toggle pin on a list. Returns { "pinned": true|false } |
| Method | Path | Auth | Notes |
|---|---|---|---|
| GET | /api/v1/templates | — | All available starter templates. |
| POST | /api/v1/templates | Auth | Create template from an existing list. Body: { "list_id": "...", "name": "..." } |
| DELETE | /api/v1/templates/:id | Admin | Delete a template. |
| POST | /api/v1/lists/:id/import-template/:tid | O/C | Apply a template to a list (adds all template mods). |
When require_deploy_approval is enabled on a list, collaborators' deployments queue as deploy-requests that an owner must approve or reject.
| Method | Path | Auth | Notes |
|---|---|---|---|
| PUT | /api/v1/lists/:id/require-deploy-approval | Owner | Enable/disable approval gate. Body: { "require_deploy_approval": true } |
| GET | /api/v1/lists/:id/deploy-requests | Owner | Pending and resolved deploy-requests for a list. |
| PATCH | /api/v1/deploy-requests/:id | Owner | Approve or reject. Body: { "status": "approved"|"rejected", "note": "..." } |
Block specific users from submitting suggestions to a list.
| Method | Path | Auth | Notes |
|---|---|---|---|
| GET | /api/v1/lists/:id/blocks | Owner | List all blocked users for this list. |
| POST | /api/v1/lists/:id/blocks | Owner | Block a user. Body: { "user_id": "..." } |
| DELETE | /api/v1/lists/:id/blocks/:userID | Owner | Unblock a user. |
Two-step workflow: preview the diff, then apply atomically. Both endpoints accept the same body.
/api/v1/lists/:id/import-preview
O/C
Query: ?check_order=true to compare and return order changes.
// Full server.json
{ "game": { "mods": [{...}] } }
// Simplified
{ "mods": [{ "modId": "...", "name": "...", "version": "..." }] }
// Fragment
"mods": [{ "modId": "...", ... }]
// Array fragment
[{ "modId": "...", ... }]
{
"added": [{ "workshop_id", "name", "version", "size_bytes", "in_catalog" }],
"removed": [{ "workshop_id", "name" }],
"version_changed": [{ "workshop_id", "name", "old_version", "new_version" }],
"order_changed": [{ "workshop_id", "name", "old_index", "new_index" }],
"unchanged": [...],
"not_in_catalog": [{ "mod_id", "name", "version" }]
}
/api/v1/lists/:id/import-apply
O/C
Same body as import-preview. Applies all changes atomically and records one audit log entry for the entire import. Pass ?check_order=true to also reorder the mods based on the JSON array.
{ "ok": true, "added": 5, "removed": 2, "version_changed": 1 }
Snapshots are named point-in-time copies of the full mod list. They can be diffed against each other or against the current live state.
| Method | Path | Auth | Notes |
|---|---|---|---|
| GET | /api/v1/lists/:id/versions | — | All snapshots, newest first. Includes snapshot_json array. |
| POST | /api/v1/lists/:id/versions | O/C | Create snapshot. Body: { "version_name", "tag", "notes", "is_release" } — all optional. |
| GET | /api/v1/lists/:id/versions/live | — | Current list as a snapshot object (for diff comparison). |
| GET | /api/v1/lists/:id/versions/:versionID | — | Single snapshot detail. |
| PATCH | /api/v1/lists/:id/versions/:versionID | O/C | Update version_name, tag, notes, is_release. |
| DELETE | /api/v1/lists/:id/versions/:versionID | O/C | Delete snapshot permanently. |
[{ "modId": "5965550FD8C7F516", "name": "RHS Status Quo", "version": "0.9.1" }, ...]
Every mutation is logged. Individual entries can be individually undone.
| Method | Path | Auth | Notes |
|---|---|---|---|
| GET | /api/v1/lists/:id/audit | O/C | Last 100 entries, newest first. Each has action, mod_name, old_value, new_value, reverted. |
| POST | /api/v1/lists/:id/audit/:entryID/revert | O/C | Undo a single entry. Idempotent. Returns { "ok": true }. |
| action | old_value | new_value |
|---|---|---|
add_mod | — | — |
remove_mod | { "version": "..." } | — |
update_version | { "version": "..." } | { "version": "..." } |
import | { "removed": [...], "version_changed": [...] } | { "added": [...], "version_changed": [...] } |
| Method | Path | Notes |
|---|---|---|
| GET | /api/v1/lists/:id/export?type=fixed |
Download server.json with pinned versions. type=latest uses latest available. |
| GET | /api/v1/lists/:id/export/arma?type=fixed |
Export in native Arma Reforger server.json format. |
Community members can suggest mods to add to a list. Owners review and accept/reject. Voting is open to all logged-in users.
| Method | Path | Auth | Notes |
|---|---|---|---|
| GET | /api/v1/lists/:id/suggestions | O/C | All pending/reviewed suggestions for a list. |
| POST | /api/v1/lists/:id/suggestions | Auth | Suggest a mod. Body: { "workshop_id", "reason", "form_answers": [...] } |
| POST | /api/v1/lists/:id/suggestions/:suggID/vote | Auth | Upvote or retract vote. Body: { "vote": 1 } (1 = up, 0 = retract). |
| PATCH | /api/v1/lists/:id/suggestions/:suggID | O/C | Update suggestion status. Body: { "status": "accepted"|"rejected", "note": "..." }. Accepting immediately adds the mod. |
| DELETE | /api/v1/lists/:id/suggestions/:suggID | O/C | Delete a suggestion. |
Customize the suggestion form with extra questions (text, checkbox, select) shown to users when they submit a suggestion.
| Method | Path | Auth | Notes |
|---|---|---|---|
| GET | /api/v1/lists/:id/form-fields | — | All custom fields for the suggestion form. |
| POST | /api/v1/lists/:id/form-fields | Owner | Create field. Body: { "label", "type": "text"|"checkbox"|"select", "required": false, "options": [...] } |
| PUT | /api/v1/lists/:id/form-fields/:fieldID | Owner | Update field. Same body as POST. |
| DELETE | /api/v1/lists/:id/form-fields/:fieldID | Owner | Delete field. |
| Method | Path | Auth | Notes |
|---|---|---|---|
| GET | /api/v1/folders | Auth | Lists all folders for the authenticated user. |
| POST | /api/v1/folders | Auth | Creates a new folder. Body: { "name": "..." } |
| Method | Path | Auth | Notes |
|---|---|---|---|
| GET | /api/v1/communities | Auth | Lists all communities the user is a member of. |
| POST | /api/v1/communities | Auth | Creates a new community. Body: { "name": "...", "description": "..." } |
Permission groups let you manage collaborator access across multiple lists at once. Create a group, add members, then assign it to any list. Co-owners of a group can add and remove members. Only the primary group owner can rename the group or manage co-owners.
| Method | Path | Auth | Notes |
|---|---|---|---|
| GET | /api/v1/groups | Auth | Your groups (primary owner + co-owned). Each object has is_primary_owner: bool. |
| POST | /api/v1/groups | Auth | Create group. Body: { "name", "description", "can_add", "can_remove", "can_deploy" } |
| PUT | /api/v1/groups/:groupID | Primary | Update name / description / default permissions. Primary owner only. |
| DELETE | /api/v1/groups/:groupID | Primary | Delete group. Members lose access on all assigned lists. |
| POST | /api/v1/groups/:groupID/assign_community | Primary | Assigns group to community. Body: { "community_id": "uuid" } |
| Method | Path | Auth | Notes |
|---|---|---|---|
| GET | /api/v1/groups/:groupID/members | Owner | All members. Returns { "members": [{ "user_id", "display_name", "added_at" }] } |
| POST | /api/v1/groups/:groupID/members | Owner | Add member. Body: { "search": "name_or_email" } |
| DELETE | /api/v1/groups/:groupID/members/:userID | Owner | Remove member. |
| Method | Path | Auth | Notes |
|---|---|---|---|
| GET | /api/v1/groups/:groupID/owners | Owner | All co-owners. Returns { "owners": [{ "user_id", "display_name", "added_at" }] } |
| POST | /api/v1/groups/:groupID/owners | Primary | Add co-owner. Body: { "search": "name_or_email" } |
| DELETE | /api/v1/groups/:groupID/owners/:userID | Primary | Remove co-owner. Primary owner only. |
Register your Arma Reforger game servers and deploy mod lists via Pterodactyl Panel or SFTP. Credentials are stored AES-256-GCM encrypted.
| Method | Path | Notes |
|---|---|---|
| GET | /api/v1/servers |
Your registered game servers. |
| POST | /api/v1/servers |
Register. Body: { "name", "connection_type": "pterodactyl"|"sftp", "file_path", "linked_list_id", "auto_deploy" } |
| GET | /api/v1/servers/:id |
Server detail + last test status. |
| PUT | /api/v1/servers/:id |
Update name / file path / linked list / auto-deploy. |
| DELETE | /api/v1/servers/:id |
Delete server + credentials. |
/api/v1/servers/:id/credentials
Auth
{
"panel_url": "https://panel.example.com",
"api_key": "ptlc_...",
"server_uuid": "abc123"
}
{
"host": "192.168.1.10",
"port": 22,
"username": "root",
"password": "..."
}
| Method | Path | Notes |
|---|---|---|
| POST | /api/v1/servers/:id/test |
Queue a connection test. Returns { "deployment_id" }. Poll /deployments for result. |
| POST | /api/v1/servers/:id/deploy |
Trigger deployment of the linked list. Body: { "list_id": "..." } (optional override). |
| POST | /api/v1/servers/:id/deploy-request |
Submit a deploy-request (if the list has approval gate enabled). Returns { "request_id" }. |
| GET | /api/v1/servers/:id/deployments |
Deployment history. Each entry: status, item_count, snapshot_json, error_message. |
| GET | /api/v1/servers/:id/status |
Live server resource usage and process state (Pterodactyl only). Returns memory/CPU utilization. |
| POST | /api/v1/servers/:id/power |
Send power signal (Pterodactyl only). Body: { "signal": "start"|"stop"|"restart"|"kill" } |
| GET | /api/v1/servers/:id/console/token |
Refresh WebSocket console token (Pterodactyl only). Returns { "token", "socket" }. |
| GET | /api/v1/servers/:id/console/ws |
WebSocket proxy to the Pterodactyl console. Upgrade: ?token= (from /console/token). |
pending → running → success | failed.
Receive real-time notifications when mods are added/removed or new versions are available. Supports Discord and custom HTTP endpoints.
| Method | Path | Notes |
|---|---|---|
| GET | /api/v1/settings/webhooks | Your webhooks. |
| POST | /api/v1/settings/webhooks | Create. Body: { "url", "type": "discord"|"custom", "events": [...], "scope": "global"|"list", "list_id" } |
| PUT | /api/v1/settings/webhooks/:id | Update URL, events, or scope. |
| DELETE | /api/v1/settings/webhooks/:id | Delete webhook. |
| POST | /api/v1/settings/webhooks/:id/test | Send a test payload to verify the endpoint. |
| Method | Path | Notes |
|---|---|---|
| GET | /api/v1/notifications | Inbox. Query: ?unread=1, ?limit=. |
| GET | /api/v1/notifications/unread-count | Returns { "count": N }. Not rate-limited — safe for frequent polling. |
| PATCH | /api/v1/notifications/:id/read | Mark single notification as read. |
| POST | /api/v1/notifications/read-all | Mark all as read. |
| GET | /api/v1/settings/notifications | Notification preferences per event type. |
| PUT | /api/v1/settings/notifications | Update preferences. Body: { "events": { "mod_updated": true, ... } } |
Background job management. Most endpoints require Admin role.
| Method | Path | Auth | Notes |
|---|---|---|---|
| POST | /api/v1/jobs/scraper/detail | — | Scrape a specific mod. Body: { "workshop_id": "..." }. Rate limited: 10/hour per IP. |
| POST | /api/v1/jobs/scraper | Auth | Trigger full workshop discovery + detail scrape. |
| Status | Meaning | Example body |
|---|---|---|
200 | OK | { "ok": true } |
204 | No Content — successful delete/update | — |
400 | Bad Request — invalid input | { "error": "invalid JSON" } |
401 | Unauthorized — missing/expired token | { "error": "unauthorized" } |
403 | Forbidden — valid token, wrong role | { "error": "no permission" } |
404 | Not Found | { "error": "list not found" } |
409 | Conflict — duplicate, limit reached | { "error": "maximum number of mods (1000) reached" } |
429 | Rate Limited | { "error": "rate limit exceeded" } |
500 | Internal Server Error | { "error": "..." } |