There are three APIs, and which one you want depends on who is calling.
Base URL: https://api.moddingcommunity.com. All three live on their own
origin, separate from the website.
Public content API
A person scripting what they could already do in the browser: create and edit their own mods, assets, servers, articles, communities, collections and groups with an API key instead of a session.
Integration API
A program — a game server plugin or a game mod — reporting facts about one specific content item: who is in a party, what map is running, what was said in chat.
App API
The desktop client: device authorisation, browsing, installs, downloads and reviews, signed in as a real member.
The APIs live on their own origin
Every path on this page — /api/content, /api/integration/v1, /api/app/v1
and /api/avatar/v1 — is served from api.moddingcommunity.com. Point new
integrations there.
/api/avatar/v1 is the fourth surface and is not one of the three above: it is
two public reads describing the avatar asset
set, and needs no credential at all.
The old website addresses still work
https://moddingcommunity.com/api/… is proxied to the same service, so no
existing key, script, plugin or app has to change today.
It is a proxy and not a redirect, deliberately: a cross-origin redirect
strips the Authorization header — browsers do it per the fetch spec, curl
does it unless you pass --location-trusted, and most Go and C# HTTP clients do
it too — so a redirect would have worked perfectly for anonymous reads and
silently 401ed every keyed call at once.
If a deprecation window is ever opened on the apex paths, it will be announced
here first, with a Sunset header on the responses well before anything stops
answering.
Choosing between them
| You are… | Use | Credential |
|---|---|---|
| A member automating your own uploads | Public content API | tmc_… key, or an Ed25519 keypair |
| A game server or mod reporting play | Integration API | tmci_… token, or an Ed25519 keypair |
| A first-party client acting for a user | App API | OAuth-style device token |
| Anyone, reading a public item | Public content API | None — see below |
The three token namespaces are deliberately distinct so that a credential can never be presented to the wrong surface: a content key sent to the integration API is rejected on its prefix, before anything looks it up.
Reading needs no credential
GET /api/content/<type> and GET /api/content/<type>/<id> answer with no
Authorization header at all, for items that are completely public:
curl "https://api.moddingcommunity.com/api/content/mod/123"
Everything else — every write, every relation, every read of a non-content type — needs a key. See Reading without a key.
What is the same everywhere
Whichever API you are on:
- JSON in, JSON out. There is no form-encoded or XML variant.
- A credential can never exceed what its owner could do in the UI. Every write resolves to the same access check the edit form uses.
- Every request is metered and logged, including the rejected ones.
- Errors have one shape. See Errors.