This site can embed mod preview images directly from ar-gcp-cdn.bistudio.com (Bohemia Interactive CDN) — without downloading to our servers. Load external content?

API Reference

REST API, JSON responses, standard HTTP codes. All mutating endpoints require authentication.

Base URL:

All list endpoints accept a ?share=<token> query param for public read-only access without authentication.

BadgeMeaning
AuthJWT or API-Key required
OwnerPrimary owner or co-owner
O/COwner, co-owner, or collaborator with sufficient permissions
PrimaryPrimary owner only (not co-owners)
AdminAdmin role required

Authentication

POST /api/v1/auth/login
REQUEST
{ "email": "user@example.com", "password": "..." }
RESPONSE
{ "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)

Note: The API is completely stateless and does not use or set cookies for authentication. You must always provide the Bearer token or API key.
ENDPOINTS
MethodPathNotes
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=.
Users
GET /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" }] }
Settings & Account
MethodPathAuthNotes
PUT /api/v1/settings/display-nameAuth Update display name. Body: { "display_name": "..." }
DELETE /api/v1/settings/accountAuth Permanently deletes account and all associated data.
API Keys
MethodPathAuthNotes
GET /api/v1/api-keysAuth Lists all API keys for the current user.
POST /api/v1/api-keysAuth Generates a new API key. Body: { "name": "..." }

Mods

GET /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 }
GET /api/v1/mods/autocomplete

Fast autocomplete search. Query param: q.

[{ "workshop_id": "...", "name": "...", "image_url": "..." }]
GET /api/v1/mods/:workshopID

Full mod metadata including dependency_ids, tags, image_url, author, summary.

Sub-Resources — /api/v1/mods/:workshopID/...
PathDescription
/metadataLightweight metadata (DB only, no extra tables).
/itemsWeapons, vehicles, gear. Filter: ?type=vehicle|weapon|gear, ?version=
/missionsExtracted scenarios. Filter: ?version=
/depsDependency graph with sizes.
/versionsFull version history & changelogs.
/screenshotsOfficial screenshot gallery.
/item-versionsVersions that have extracted item data available.
/diffItem diff between two versions. Query: ?from=&to=

Mod Lists

CRUD
MethodPathAuthNotes
GET /api/v1/lists Public lists. Add ?public=1. Or /lists/mine (Auth) for your own.
POST /api/v1/listsAuth Body: { "name", "description", "is_public" }
GET /api/v1/lists/:id List detail + items, tags, dependency tree, missing deps.
PUT /api/v1/lists/:idOwner Update name / description / visibility.
DELETE /api/v1/lists/:idPrimary Permanently deletes list, items, versions, audit log.
PATCH /api/v1/lists/:id/communityOwner Assign list to community: {"community_id": "uuid"}
PATCH /api/v1/lists/:id/folderOwner Assign list to folder: {"folder_id": "uuid"}
Mod Management
MethodPathAuthNotes
POST /api/v1/lists/:id/modsO/C Body: { "workshop_id": "..." }. Auto-scrapes unknown mods.
DELETE /api/v1/lists/:id/mods/:workshopIDO/C Remove a mod from the list.
PUT /api/v1/lists/:id/mods/:workshopID/versionO/C Pin/unpin version. Body: { "version": "1.2.3" } or { "version": null }.
POST /api/v1/lists/:id/mods/reorderO/C Save manual sort order. Body: { "order": ["workshopID", ...] }
POST /api/v1/lists/:id/rescrapeO/C Enqueues a background rescrape for all mods in the list.
Templates
MethodPathAuthNotes
GET /api/v1/lists/:id/template-linksO/C Lists templates this list is subscribed to.
DELETE /api/v1/lists/:id/template-links/:templateIDO/C Removes a template subscription.
POST /api/v1/templates/:id/pushOwner Pushes template updates to all subscribed lists.
Collaborators & Co-Owners

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.

COLLABORATORS
MethodPathAuthNotes
GET /api/v1/lists/:id/collaboratorsO/C All collaborators with their permission flags.
POST /api/v1/lists/:id/collaboratorsOwner Add collaborator. Body: { "search": "name_or_email" }
DELETE /api/v1/lists/:id/collaborators/:userIDOwner Remove collaborator.
PUT /api/v1/lists/:id/collaborators/:userID/permissionsOwner Update per-user flags. Body: { "can_add": true, "can_remove": true, "can_deploy": false }
POST /api/v1/lists/:id/share-token/resetOwner Regenerate the public share token. Returns { "share_token": "..." }
POST /api/v1/lists/:id/suggestion-token/resetOwner Regenerate the suggestion link token. Returns { "suggestion_token": "..." }
CO-OWNERS
MethodPathAuthNotes
GET /api/v1/lists/:id/ownersOwner List all co-owners. Returns { "owners": [{ "user_id", "display_name", "added_at" }] }
POST /api/v1/lists/:id/ownersPrimary Add co-owner. Body: { "search": "name_or_email" }
DELETE /api/v1/lists/:id/owners/:userIDPrimary Remove co-owner.
Permission Groups on a List

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.

MethodPathAuthNotes
GET /api/v1/lists/:id/groupsOwner All groups assigned to this list, with their effective permission flags.
POST /api/v1/lists/:id/groupsOwner 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/:groupIDOwner Update per-list permission overrides. Body: same as POST (null = reset to group default).
DELETE /api/v1/lists/:id/groups/:groupIDOwner Remove group from this list. Group members lose access.
Tags

Users manage their own tag library and attach tags to lists for filtering.

MethodPathAuthNotes
GET /api/v1/tags All tags in the system (public).
GET /api/v1/tags/mineAuth Your personal tags.
POST /api/v1/tags/mineAuth Create tag. Body: { "name": "...", "color": "#hex" }
DELETE /api/v1/tags/mine/:tagIDAuth Delete your tag.
GET /api/v1/lists/:id/tags Tags assigned to a list.
POST /api/v1/lists/:id/tagsOwner Assign tag to list. Body: { "tag_id": "..." }
DELETE /api/v1/lists/:id/tags/:tagIDOwner Remove tag from list.
Pins & Templates
PINS
MethodPathAuthNotes
GET /api/v1/lists/pinsAuth Your pinned lists.
POST /api/v1/lists/:id/pinAuth Toggle pin on a list. Returns { "pinned": true|false }
TEMPLATES
MethodPathAuthNotes
GET /api/v1/templates All available starter templates.
POST /api/v1/templatesAuth Create template from an existing list. Body: { "list_id": "...", "name": "..." }
DELETE /api/v1/templates/:idAdmin Delete a template.
POST /api/v1/lists/:id/import-template/:tidO/C Apply a template to a list (adds all template mods).
Deploy Approval

When require_deploy_approval is enabled on a list, collaborators' deployments queue as deploy-requests that an owner must approve or reject.

MethodPathAuthNotes
PUT /api/v1/lists/:id/require-deploy-approvalOwner Enable/disable approval gate. Body: { "require_deploy_approval": true }
GET /api/v1/lists/:id/deploy-requestsOwner Pending and resolved deploy-requests for a list.
PATCH /api/v1/deploy-requests/:idOwner Approve or reject. Body: { "status": "approved"|"rejected", "note": "..." }
Moderation

Block specific users from submitting suggestions to a list.

MethodPathAuthNotes
GET /api/v1/lists/:id/blocksOwner List all blocked users for this list.
POST /api/v1/lists/:id/blocksOwner Block a user. Body: { "user_id": "..." }
DELETE /api/v1/lists/:id/blocks/:userIDOwner Unblock a user.
Import from server.json

Two-step workflow: preview the diff, then apply atomically. Both endpoints accept the same body.

POST /api/v1/lists/:id/import-preview O/C

Query: ?check_order=true to compare and return order changes.

REQUEST — any of these formats
// Full server.json
{ "game": { "mods": [{...}] } }

// Simplified
{ "mods": [{ "modId": "...", "name": "...", "version": "..." }] }

// Fragment
"mods": [{ "modId": "...", ... }]

// Array fragment
[{ "modId": "...", ... }]
RESPONSE
{
  "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" }]
}
POST /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 / Versioning

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.

MethodPathAuthNotes
GET /api/v1/lists/:id/versions All snapshots, newest first. Includes snapshot_json array.
POST /api/v1/lists/:id/versionsO/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/:versionIDO/C Update version_name, tag, notes, is_release.
DELETE /api/v1/lists/:id/versions/:versionIDO/C Delete snapshot permanently.
Snapshot JSON format
[{ "modId": "5965550FD8C7F516", "name": "RHS Status Quo", "version": "0.9.1" }, ...]
Audit Log

Every mutation is logged. Individual entries can be individually undone.

MethodPathAuthNotes
GET /api/v1/lists/:id/auditO/C Last 100 entries, newest first. Each has action, mod_name, old_value, new_value, reverted.
POST /api/v1/lists/:id/audit/:entryID/revertO/C Undo a single entry. Idempotent. Returns { "ok": true }.
Action types
actionold_valuenew_value
add_mod
remove_mod{ "version": "..." }
update_version{ "version": "..." }{ "version": "..." }
import{ "removed": [...], "version_changed": [...] }{ "added": [...], "version_changed": [...] }
Export
MethodPathNotes
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.

Suggestions

Community members can suggest mods to add to a list. Owners review and accept/reject. Voting is open to all logged-in users.

MethodPathAuthNotes
GET /api/v1/lists/:id/suggestionsO/C All pending/reviewed suggestions for a list.
POST /api/v1/lists/:id/suggestionsAuth Suggest a mod. Body: { "workshop_id", "reason", "form_answers": [...] }
POST /api/v1/lists/:id/suggestions/:suggID/voteAuth Upvote or retract vote. Body: { "vote": 1 } (1 = up, 0 = retract).
PATCH /api/v1/lists/:id/suggestions/:suggIDO/C Update suggestion status. Body: { "status": "accepted"|"rejected", "note": "..." }. Accepting immediately adds the mod.
DELETE /api/v1/lists/:id/suggestions/:suggIDO/C Delete a suggestion.
Suggestion Form Fields

Customize the suggestion form with extra questions (text, checkbox, select) shown to users when they submit a suggestion.

MethodPathAuthNotes
GET /api/v1/lists/:id/form-fields All custom fields for the suggestion form.
POST /api/v1/lists/:id/form-fieldsOwner Create field. Body: { "label", "type": "text"|"checkbox"|"select", "required": false, "options": [...] }
PUT /api/v1/lists/:id/form-fields/:fieldIDOwner Update field. Same body as POST.
DELETE /api/v1/lists/:id/form-fields/:fieldIDOwner Delete field.

Organization (Folders & Communities)

FOLDERS
MethodPathAuthNotes
GET /api/v1/foldersAuth Lists all folders for the authenticated user.
POST /api/v1/foldersAuth Creates a new folder. Body: { "name": "..." }
COMMUNITIES
MethodPathAuthNotes
GET /api/v1/communitiesAuth Lists all communities the user is a member of.
POST /api/v1/communitiesAuth Creates a new community. Body: { "name": "...", "description": "..." }

Permission Groups

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.

GROUP CRUD
MethodPathAuthNotes
GET /api/v1/groupsAuth Your groups (primary owner + co-owned). Each object has is_primary_owner: bool.
POST /api/v1/groupsAuth Create group. Body: { "name", "description", "can_add", "can_remove", "can_deploy" }
PUT /api/v1/groups/:groupIDPrimary Update name / description / default permissions. Primary owner only.
DELETE /api/v1/groups/:groupIDPrimary Delete group. Members lose access on all assigned lists.
POST /api/v1/groups/:groupID/assign_communityPrimary Assigns group to community. Body: { "community_id": "uuid" }
GROUP MEMBERS
MethodPathAuthNotes
GET /api/v1/groups/:groupID/membersOwner All members. Returns { "members": [{ "user_id", "display_name", "added_at" }] }
POST /api/v1/groups/:groupID/membersOwner Add member. Body: { "search": "name_or_email" }
DELETE /api/v1/groups/:groupID/members/:userIDOwner Remove member.
GROUP CO-OWNERS
MethodPathAuthNotes
GET /api/v1/groups/:groupID/ownersOwner All co-owners. Returns { "owners": [{ "user_id", "display_name", "added_at" }] }
POST /api/v1/groups/:groupID/ownersPrimary Add co-owner. Body: { "search": "name_or_email" }
DELETE /api/v1/groups/:groupID/owners/:userIDPrimary Remove co-owner. Primary owner only.

Game Servers

Register your Arma Reforger game servers and deploy mod lists via Pterodactyl Panel or SFTP. Credentials are stored AES-256-GCM encrypted.

SERVER CRUD
MethodPathNotes
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.
POST /api/v1/servers/:id/credentials Auth
PTERODACTYL
{
  "panel_url": "https://panel.example.com",
  "api_key": "ptlc_...",
  "server_uuid": "abc123"
}
SFTP
{
  "host": "192.168.1.10",
  "port": 22,
  "username": "root",
  "password": "..."
}
DEPLOYMENT & CONTROL
MethodPathNotes
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).
Deployments run in a dedicated deploy-worker. Status: pendingrunningsuccess | failed.

Webhooks

Receive real-time notifications when mods are added/removed or new versions are available. Supports Discord and custom HTTP endpoints.

MethodPathNotes
GET/api/v1/settings/webhooksYour webhooks.
POST/api/v1/settings/webhooksCreate. Body: { "url", "type": "discord"|"custom", "events": [...], "scope": "global"|"list", "list_id" }
PUT/api/v1/settings/webhooks/:idUpdate URL, events, or scope.
DELETE/api/v1/settings/webhooks/:idDelete webhook.
POST/api/v1/settings/webhooks/:id/testSend a test payload to verify the endpoint.

Notifications

MethodPathNotes
GET/api/v1/notificationsInbox. Query: ?unread=1, ?limit=.
GET/api/v1/notifications/unread-countReturns { "count": N }. Not rate-limited — safe for frequent polling.
PATCH/api/v1/notifications/:id/readMark single notification as read.
POST/api/v1/notifications/read-allMark all as read.
GET/api/v1/settings/notificationsNotification preferences per event type.
PUT/api/v1/settings/notificationsUpdate preferences. Body: { "events": { "mod_updated": true, ... } }

Jobs & Scrapers

Background job management. Most endpoints require Admin role.

MethodPathAuthNotes
POST/api/v1/jobs/scraper/detailScrape a specific mod. Body: { "workshop_id": "..." }. Rate limited: 10/hour per IP.
POST/api/v1/jobs/scraperAuthTrigger full workshop discovery + detail scrape.

Error Codes

StatusMeaningExample body
200OK{ "ok": true }
204No Content — successful delete/update
400Bad Request — invalid input{ "error": "invalid JSON" }
401Unauthorized — missing/expired token{ "error": "unauthorized" }
403Forbidden — valid token, wrong role{ "error": "no permission" }
404Not Found{ "error": "list not found" }
409Conflict — duplicate, limit reached{ "error": "maximum number of mods (1000) reached" }
429Rate Limited{ "error": "rate limit exceeded" }
500Internal Server Error{ "error": "..." }