Introduction
The Dbljump API stores and serves structured information about video games, their releases, creators, platforms, places, images, and sources.
The API follows the JSON:API specification for normal resource endpoints. Authentication handoffs and the health endpoint use small, purpose-specific JSON responses.
Base URL
All paths in this reference are relative to:
https://www.dbljump.com
For example:
GET https://www.dbljump.com/games
Use HTTPS for all production requests.
Resource types
JSON:API resource types are singular and camel-cased where necessary. Examples
include game, gameVersion, companyAlias, mediaLicense, and user.
Roles
| Role | Description |
|---|---|
| member | Can authenticate and manage their own user account. |
| editor | Includes member access and can create or edit articles and most article data. |
| admin | Full access, including administrative catalog records and destructive operations. |
Read endpoints are public unless a resource section says otherwise.
Requests and responses
Headers
Typical authenticated request
GET https://www.dbljump.com/games
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json
Authorization: Bearer {token}
Send Accept: application/vnd.api+json. Send
Content-Type: application/vnd.api+json when the request has a JSON:API body.
The old custom version media-type parameter is no longer used.
Authenticated requests use Authorization: Bearer {token}. Do not send an
Authorization header for signed-out requests.
JSON:API document shape
Minimal create request
{
"data": {
"type": "game",
"attributes": {
"displayTitle": "New Game",
"description": "A short description."
}
}
}
Relationship linkage
{
"relationships": {
"holder": {
"data": { "type": "company", "id": "12" }
}
}
}
Create requests use POST; successful responses return 201 Created. Update
requests use PATCH, must include the resource id, and return 200 OK.
Deletes return 204 No Content.
For an update, data.type and data.id must identify the same resource as the
request URL. A mismatch returns 409 Conflict with the error code
RESOURCE_MISMATCH before any attributes or relationships are changed.
Serialized attribute, relationship, filter, sort, and include names use lower camel case. IDs are strings in JSON:API documents.
Collections
All collection endpoints are paginated. The default page size is 30.
| Query | Purpose | Example |
|---|---|---|
page[size] |
Records per page | ?page[size]=20 |
page[number] |
One-based page number | ?page[number]=2 |
sort |
Sort by one or more allowed fields; prefix descending fields with - |
?sort=displayTitle,-originYear |
filter[{field}{predicate}] |
Filter using an allowed field and Ransack predicate | ?filter[slugEq]=pong |
search |
Full-text search on supported collections | ?search=nintendo |
include |
Include related resources | ?include=createdBy,primaryImage |
fields[{type}] |
Sparse fieldset | ?fields[game]=displayTitle,slug |
Collection responses include pagination information under
meta.pagination, including records, current, first, prev, next,
last, and pages when applicable.
Filtering
The most common predicate is Eq, meaning equality. Other Ransack predicates
such as Cont, Gteq, and Lteq can be used with fields listed as queryable
in this reference.
The API accepts camel-case query names and converts them internally. Special relationship filters include:
GET /games?filter[genreIdEq]={id}GET /games?filter[platformIdEq]={id}GET /images?filter[articleIdEq]={id}GET /game-version-releases?filter[gameIdEq]={id}
A collection query using filter[slugEq] returns 404 Not Found rather than
an empty collection when no record matches.
Search
search is supported for articles, games, companies, people, users,
platforms, genres, places, images, and external resources.
Metadata
Most normal resources include createdAt and updatedAt in meta;
extResourceJoin currently returns no timestamp metadata. Article
metadata also includes status, articleType, and keywords. Several
resources add relationship totals under meta.total.
Single-record examples
These examples show the current response shape for representative resources. Exact IDs, timestamps, URLs, relationship counts, and included resources depend on the database and the query parameters.
Game response
GET https://www.dbljump.com/games/pong
{
"data": {
"id": "45",
"type": "game",
"attributes": {
"slug": "pong",
"displayTitle": "Pong",
"description": "Pong is an early table-tennis video game.",
"originDate": "1972-11-29",
"originYear": 1972,
"ended": null,
"thumbnail": "https://www.dbljump.com/uploads/images/87/th_pong.jpg"
},
"relationships": {
"platforms": {
"data": [
{ "id": "4", "type": "platform" }
]
},
"genres": {
"data": [
{ "id": "2", "type": "genre" }
]
},
"versions": {
"data": [
{ "id": "71", "type": "gameVersion" }
]
},
"aliases": {
"data": []
},
"notes": {
"data": []
},
"companyCredits": {
"data": [
{ "id": "108", "type": "companyCredit" }
]
},
"personCredits": {
"data": []
},
"images": {
"data": [
{ "id": "87", "type": "image" }
]
},
"primaryImage": {
"data": { "id": "87", "type": "image" }
},
"headerImage": {
"data": null
},
"createdBy": {
"data": { "id": "1", "type": "user" }
},
"lastUpdatedBy": {
"data": { "id": "1", "type": "user" }
}
},
"meta": {
"status": "published",
"articleType": "game",
"keywords": "Pong, 1972",
"createdAt": "2026-01-12T10:30:00.000Z",
"updatedAt": "2026-07-20T14:15:00.000Z",
"total": {
"images": 1,
"versions": 1,
"notes": 0,
"genres": 1,
"companyCredits": 1,
"personCredits": 0
}
}
}
}
Relationship objects contain resource linkage. Add include, for example
?include=genres,primaryImage, to return the related records in the top-level
included array.
Game-version response
GET https://www.dbljump.com/game-versions/71
{
"data": {
"id": "71",
"type": "gameVersion",
"attributes": {
"status": "extant",
"interfaces": [
"traditional"
],
"audioChannels": 1.0,
"audioSystem": "mono",
"videoFpsTarget": 60,
"videoFpsUnlocked": false,
"videoResW": 640,
"videoResH": 480,
"videoResUnlocked": false,
"videoInterlaced": false,
"videoAspectRatio": "1.333",
"videoHdr": false,
"videoStereoscopic": false,
"videoDynamicScaling": false,
"playLocal": true,
"playersLocalMin": 2,
"playersLocalMax": 2,
"playLocalVs": true,
"playLocalCoOp": false,
"playLocalTeams": false,
"playLan": false,
"playersLanMin": null,
"playersLanMax": null,
"playLanVs": false,
"playLanCoOp": false,
"playLanTeams": false,
"playOnline": false,
"playersOnlineMin": null,
"playersOnlineMax": null,
"playOnlineVs": false,
"playOnlineCoOp": false,
"playOnlineTeams": false
},
"relationships": {
"game": {
"data": { "id": "45", "type": "game" }
},
"platform": {
"data": { "id": "4", "type": "platform" }
},
"releases": {
"data": [
{ "id": "83", "type": "gameVersionRelease" }
]
},
"notes": {
"data": []
}
},
"meta": {
"createdAt": "2026-02-02T09:00:00.000Z",
"updatedAt": "2026-05-18T16:42:00.000Z"
}
}
}
Image response
GET https://www.dbljump.com/images/pong-arcade-screen
{
"data": {
"id": "87",
"type": "image",
"attributes": {
"base64Image": null,
"original": "https://www.dbljump.com/uploads/images/87/pong.jpg",
"thumb": "https://www.dbljump.com/uploads/images/87/th_pong.jpg",
"kind": "screen",
"title": "Pong arcade screen",
"description": "A gameplay screen from the arcade release.",
"height": 1080,
"width": 1920,
"size": "lg",
"year": 1972,
"date": null,
"usageType": "fair",
"attributedName": "Atari",
"attributedUrl": null,
"sourceUrl": "https://example.org/pong",
"slug": "pong-arcade-screen"
},
"relationships": {
"mediaLicense": {
"data": null
},
"place": {
"data": { "id": "840", "type": "place" }
},
"articles": {
"data": [
{ "id": "45", "type": "article" }
]
},
"uploadedBy": {
"data": { "id": "1", "type": "user" }
},
"lastUpdatedBy": {
"data": { "id": "1", "type": "user" }
}
},
"meta": {
"createdAt": "2026-03-10T12:00:00.000Z",
"updatedAt": "2026-03-10T12:00:00.000Z",
"total": {
"articles": 1
}
}
}
}
The base64Image input is never echoed back. Consumers should use original
or thumb.
External-resource response
GET https://www.dbljump.com/ext-resources/204
{
"data": {
"id": "204",
"type": "extResource",
"attributes": {
"kind": "web_article",
"title": "The history of Pong",
"authorNames": [
{
"family": "Example",
"given": "Alex"
}
],
"volumeTitle": "Game History Journal",
"doi": null,
"isbn": null,
"issn": null,
"publisher": "Example Publishing",
"year": 2024,
"date": "2024-06-12",
"sortDate": "2024-06-12",
"urlOriginal": "https://example.org/history-of-pong",
"urlArchived": "https://example.org/archive/history-of-pong",
"lastAccessedAt": "2026-07-28T10:15:00.000Z",
"approvedAt": "2026-07-29T08:00:00.000Z",
"flaggedAt": null,
"pageNumbersBegin": null,
"pageNumbersEnd": null
},
"relationships": {
"createdBy": {
"data": { "id": "1", "type": "user" }
},
"notes": {
"data": [
{ "id": "19", "type": "gameNote" }
]
},
"consumerJoins": {
"data": [
{ "id": "73", "type": "extResourceJoin" }
]
}
},
"meta": {
"createdAt": "2026-07-28T10:15:00.000Z",
"updatedAt": "2026-07-29T08:00:00.000Z"
}
}
}
Create a source with an initial citation
POST https://www.dbljump.com/ext-resources?include=consumerJoins
{
"data": {
"type": "extResource",
"attributes": {
"kind": "book",
"title": "Example book",
"isbn": "9780429771385",
"location": { "type": "pages", "start": "24", "end": "26" }
},
"relationships": {
"notes": {
"data": [ { "type": "gameNote", "id": "19" } ]
}
}
}
}
An editor receives 201 on success. The response’s primary resource is the new
extResource; its attributes do not contain location. The requested
included array contains the new extResourceJoin with the persisted page
location. Both records are rolled back if creation fails.
Cite an existing source
POST https://www.dbljump.com/ext-resource-joins
{
"data": {
"type": "extResourceJoin",
"attributes": {
"location": { "type": "timestamp", "start": 760, "end": 845 }
},
"relationships": {
"extResource": { "data": { "type": "extResource", "id": "206" } },
"consumer": { "data": { "type": "gameNote", "id": "19" } }
}
}
}
Here resource 206 is an existing video source. The request creates a citation for 12:40–14:05 without changing the shared resource. Success returns 201 with the new citation as the primary resource. Repeating the same note/source pair returns 422 and preserves the existing citation.
Citation response
GET https://www.dbljump.com/ext-resource-joins/75
{
"data": {
"id": "75",
"type": "extResourceJoin",
"attributes": {
"location": { "type": "timestamp", "start": 760, "end": 845 }
},
"relationships": {
"extResource": { "data": { "id": "206", "type": "extResource" } },
"consumer": { "data": { "id": "19", "type": "gameNote" } }
}
}
}
Alternatively, request GET /ext-resources/206?include=consumerJoins or
GET /game-notes/19?include=extResourceJoins to read the citation through a
related resource. To include sources with a note’s citations, request
GET /game-notes/19?include=extResourceJoins.extResource.
Edit or clear a citation location
PATCH https://www.dbljump.com/ext-resource-joins/75
{
"data": {
"type": "extResourceJoin",
"id": "75",
"attributes": {
"location": { "type": "timestamp", "start": 900, "end": 915 }
}
}
}
This changes citation 75 to 15:00–15:15, leaving other citations and the shared source unchanged. Success returns 200 with the updated citation.
Clear the location with the same PATCH endpoint
{
"data": {
"type": "extResourceJoin",
"id": "75",
"attributes": { "location": null }
}
}
Omitting location preserves its current value. Explicit null clears the
location and retains the citation. DELETE /ext-resource-joins/75 instead
removes the citation and returns 204, preserving source 206.
Authentication
Sign in
Request
POST https://www.dbljump.com/user-authentications
{
"data": {
"type": "userAuthentication",
"attributes": {
"email": "member@example.com",
"password": "correct horse battery staple",
"rememberMe": true
}
}
}
POST /user-authentications signs in an activated user. On success it returns
200 OK, a small user resource, and an Authorization: Bearer {token}
response header. Store that complete header value and send it with subsequent
authenticated requests.
rememberMe defaults to false and controls the token lifetime.
JWT payload
New tokens use the standard exp expiry claim and include the user’s ID and
role. The server also accepts legacy tokens containing expiry.
An invalid token returns TOKEN_INVALID; an expired token returns
TOKEN_EXPIRED.
Authentication handoff
Authentication handoffs transfer a signed-in session between Dbljump clients without exposing the current JWT in a URL.
Create a handoff
POST /authentication-handoffs
Requires a valid bearer token. Returns 201 Created:
{
"code": "single-use-short-lived-code"
}
Exchange a handoff
Request
POST https://www.dbljump.com/authentication-handoffs/exchange
{
"code": "single-use-short-lived-code"
}
The exchange is unauthenticated. A valid, unused code returns 200 OK:
{
"authHeader": "Bearer {token}",
"data": {
"type": "users",
"id": "42",
"attributes": {
"username": "player",
"avatarThumb": "https://www.dbljump.com/uploads/user_avatar/42/thumb.jpg"
}
}
}
Codes expire after five minutes and can be exchanged only once. Both handoff
responses disable caching. Missing, expired, or reused codes return 401 with
the JSON:API error code AUTHENTICATION_HANDOFF_INVALID.
Articles
Articles provide a combined read-only collection of games, companies, and people.
| Method | Path | Description |
|---|---|---|
| GET | /articles |
List all article types together. |
Use the dedicated /games, /companies, and /people endpoints to fetch or
modify a single typed article.
Attributes
| Attribute | Description |
|---|---|
slug |
URL-friendly identifier generated from the display title. |
displayTitle |
Public title. |
description |
Summary of up to 800 characters. |
originDate |
Exact date of origin, when known. |
originYear |
Origin year; derived from originDate when a date is supplied. |
ended |
Whether the company or person’s activity has ended. |
thumbnail |
Thumbnail URL derived from the primary image. |
Relationships
images, primaryImage, headerImage, createdBy, and lastUpdatedBy.
Queryable fields
id, type, displayTitle, sortTitle, slug, kind, originDate,
originSortDate, originYear, ended, status, createdById,
primaryImageId, headerImageId, createdAt, and updatedAt.
Find a single article by slug through the collection
GET https://www.dbljump.com/articles?filter[slugEq]=pong
Games
Games are the central articles in the database. A game can have multiple platform versions, releases, aliases, notes, images, genres, and credits.
| Method | Path | Authorization |
|---|---|---|
| GET | /games |
Public |
| GET | /games/{id-or-slug} |
Public |
| POST | /games |
Editor |
| PATCH | /games/{id-or-slug} |
Editor |
| DELETE | /games/{id-or-slug} |
Admin, or the editor who created an unpublished game |
The JSON:API type is game.
Writable attributes
| Attribute | Create | Update | Description |
|---|---|---|---|
displayTitle |
Yes | Yes | Required; 1–250 characters. |
description |
Yes | Yes | Optional; maximum 800 characters. |
originDate |
Yes | Yes | Date from 1800 onward. |
originYear |
Yes | Yes | Year from 1800 onward. |
Writable relationships
Updates additionally accept genres, primaryImage, headerImage, and
images. These relationships are intentionally not accepted during creation.
Response relationships
platforms, genres, versions, aliases, notes, companyCredits,
personCredits, images, primaryImage, headerImage, createdBy, and
lastUpdatedBy.
Querying games
Games use the article queryable fields. They also support genreIdEq and
platformIdEq; when both are supplied, only games matching both are returned.
Filter by genre and platform
GET https://www.dbljump.com/games?filter[genreIdEq]=3&filter[platformIdEq]=8
Create a game
POST https://www.dbljump.com/games
{
"data": {
"type": "game",
"attributes": {
"displayTitle": "New Game",
"description": "A concise description of the game.",
"originYear": 2026
}
}
}
New games begin with draft status. Status is returned in article metadata and
is not directly writable by this endpoint.
Companies
Companies describe publishers, developers, technology firms, and other organizations associated with games.
| Method | Path | Authorization |
|---|---|---|
| GET | /companies |
Public |
| GET | /companies/{id-or-slug} |
Public |
| POST | /companies |
Editor |
| PATCH | /companies/{id-or-slug} |
Editor |
| DELETE | /companies/{id-or-slug} |
Admin, or the editor who created an unpublished company |
The JSON:API type is company.
Writable attributes
displayTitle (required, 1–250 characters), description (maximum 800
characters), originDate, originYear, ended, endDate, and endYear.
Dates and years begin at 1800. endDate and endYear describe when the
organization ceased operating.
Writable relationships
originPlace, latestPlace, primaryImage, headerImage, and images.
Response-only fields and relationships
shortName is derived from the newest active styled alias, falling back to
displayTitle.
Relationships include aliases, notes, credits, parentKinships,
childKinships, platforms, originPlace, latestPlace, the common article
image relationships, createdBy, and lastUpdatedBy.
Companies use the article queryable fields plus endDate, endSortDate, and
endYear.
People
People describe individuals credited in the video game industry.
| Method | Path | Authorization |
|---|---|---|
| GET | /people |
Public |
| GET | /people/{id-or-slug} |
Public |
| POST | /people |
Editor |
| PATCH | /people/{id-or-slug} |
Editor |
| DELETE | /people/{id-or-slug} |
Admin, or the editor who created an unpublished person |
The JSON:API type is person.
Writable attributes
| Attribute | Description |
|---|---|
givenNames |
Required on create; maximum 50 characters. |
familyName |
Optional; maximum 50 characters. |
displayTitle |
Accepted; on create it is generated from the supplied names. |
description |
Optional biography summary; maximum 800 characters. |
gender |
Optional free text; maximum 25 characters. |
originDate, originYear |
Birth date or year. |
ended, endDate, endYear |
Whether and when the person’s life ended. |
Writable relationships
originPlace, latestPlace, primaryImage, headerImage, and images.
Response relationships include aliases, notes, credits, the place and
image relationships, createdBy, and lastUpdatedBy.
People use the article queryable fields plus gender, endDate,
endSortDate, and endYear.
Article data
Aliases, notes, credits, and company kinships use independent, non-nested endpoints. Their IDs are numeric. All reads are public; create, update, and delete operations require an editor unless stated otherwise.
Aliases
| Resource | Path | JSON:API type |
|---|---|---|
| Game alias | /game-aliases |
gameAlias |
| Company alias | /company-aliases |
companyAlias |
| Person alias | /person-aliases |
personAlias |
Each supports GET collection, GET /{id}, POST, PATCH /{id}, and
DELETE /{id}.
Common writable fields are displayText, kind, and writingSystem.
writingSystem must be one of Arab, Hang, Hans, Hant, Cyrl, Grek,
Hebr, Jpan, Latn, or Thai.
| Alias | Extra fields | Allowed kind |
|---|---|---|
| Game | gameVersions relationship |
official, working, translated, AKA |
| Company | yearAdopted, dropped, yearDropped |
official, styled, AKA |
| Person | givenNames, familyName, yearAdopted, dropped, yearDropped |
official, full, AKA |
All aliases require an article relationship and may have places.
Queryable fields are id, articleId, displayText, familyName,
givenNames, kind, writingSystem, yearAdopted, yearDropped, dropped,
createdAt, and updatedAt.
Notes
| Resource | Path | JSON:API type |
|---|---|---|
| Game note | /game-notes |
gameNote |
| Company note | /company-notes |
companyNote |
| Person note | /person-notes |
personNote |
Each supports the full CRUD set.
Writable fields are category, heading, body, spoiler, and
displayOrder. Notes require an article relationship. Game notes can also
relate to gameVersions. Notes may be linked to extResources.
The body is Markdown, 5–5000 characters, and is returned both as body and
sanitized bodyHtml. External links are rejected in note Markdown; cite an
external resource through /ext-resource-joins instead. heading is at most 40
characters. If omitted during creation, displayOrder is appended
automatically within its article and category.
Note responses also expose extResourceJoins, the citation joins connecting
that note to its sources. For example,
GET /game-notes/{id}?include=extResourceJoins returns the citation IDs and
their attributes.location in included. To include their shared sources as
well, use include=extResourceJoins.extResource. Use /ext-resource-joins to
add, edit, clear, or remove a note’s individual citation; a location belongs
to that join rather than the note or shared source. See Citations
(external-resource joins) in the Media section for request formats.
| Note type | Allowed categories |
|---|---|
| Game | game, story, development, publishing, visuals, sound, addons, tech, profile, sales, impact |
| Company | history, organization, products, profile, sales, impact |
| Person | bio, education, career, views, profile, impact |
Queryable fields are id, articleId, type, category, heading,
displayOrder, spoiler, extResources, createdById, createdAt, and
updatedAt.
Credits
| Resource | Path | JSON:API type |
|---|---|---|
| Company credit | /company-credits |
companyCredit |
| Person credit | /person-credits |
personCredit |
Both support the full CRUD set. Writable attributes are role, category,
and leading. Required relationships are credited and game; optional
many-valued relationships are places and gameVersions.
Company credit categories are publishing, development, technology,
visuals, sound, language, special, and misc.
Person credit categories are creative, development, technology,
visuals, sound, language, special, and misc.
Queryable fields are id, creditedId, gameId, placeId, role,
category, leading, createdAt, and updatedAt.
Company kinships
/company-kinships uses type companyKinship and supports full CRUD.
Kinships connect a parent company and a different child company.
Writable fields are kind, startYear, and endYear. kind is ownership
or division; years start at 1800 and the end cannot precede the start.
Queryable fields are id, parentId, childId, kind, startYear,
endYear, createdAt, and updatedAt.
Game versions and releases
Game versions
/game-versions uses JSON:API type gameVersion and supports:
| Method | Path | Authorization |
|---|---|---|
| GET | /game-versions |
Public |
| GET | /game-versions/{id} |
Public |
| POST | /game-versions |
Editor |
| PATCH | /game-versions/{id} |
Editor |
| DELETE | /game-versions/{id} |
Editor |
Every version requires one game and one platform. A game can have only one
version per platform.
Writable attributes
| Group | Attributes |
|---|---|
| General | status, interfaces, audioChannels, audioSystem |
| Video | videoFpsTarget, videoFpsUnlocked, videoResW, videoResH, videoResUnlocked, videoInterlaced, videoAspectRatio, videoHdr, videoStereoscopic, videoDynamicScaling |
| Local play | playLocal, playersLocalMin, playersLocalMax, playLocalVs, playLocalCoOp, playLocalTeams |
| LAN play | playLan, playersLanMin, playersLanMax, playLanVs, playLanCoOp, playLanTeams |
| Online play | playOnline, playersOnlineMin, playersOnlineMax, playOnlineVs, playOnlineCoOp, playOnlineTeams |
status is extant, rumored, canceled, or unknown. interfaces accepts
traditional, touch, motion, vision, vr, ar, camera, trackball,
pressure, lightgun, vehicle, custom, or 3d.
Player counts are cleared when their corresponding playLocal, playLan, or
playOnline flag is false. Each maximum must be at least its minimum.
Response relationships are game, platform, releases, and notes.
Queryable fields are id, gameId, platformId, status,
videoFpsTarget, videoFpsUnlocked, videoResW, videoResH,
videoResUnlocked, createdAt, and updatedAt.
Game version releases
/game-version-releases uses type gameVersionRelease and supports the full
CRUD set, with editor authorization for writes.
Writable fields are date, year, physical, and digital. Each release
requires a version relationship and at least one places relationship.
Dates and years may be up to three years in the future. A version cannot have
two releases with the same derived sort date.
Responses include version, game, platform, and places.
Queryable fields are id, versionId, placeId, date, year, physical,
digital, sortDate, createdAt, and updatedAt. Use
filter[gameIdEq] to return releases belonging to any version of a game.
Platforms and genres
Platforms
Platforms represent hardware, operating systems, streaming services, and other environments on which a game version runs.
/platforms uses type platform and supports full CRUD. Reads are public,
editors can create and update, and only admins can delete.
Writable fields are:
| Attribute | Requirements |
|---|---|
name |
Required, unique, maximum 50 characters. |
shortName |
Optional, unique, maximum 18 characters. |
sphere |
arcade, cloud, home, mobile, non-gaming, or portable. |
kind |
add-on, OS, streaming, or system. |
Every platform requires a holder company relationship. Responses also
include games, createdBy, and lastUpdatedBy.
Queryable fields are id, name, shortName, sphere, kind, slug,
holderId, createdById, createdAt, and updatedAt.
Genres
/genres uses type genre and supports full CRUD. Reads are public; only
admins can create, update, or delete genres.
Writable fields are name and shortName. Responses also provide the
generated slug and relationships to games, createdBy, and
lastUpdatedBy.
Queryable fields are id, name, shortName, slug, createdById,
createdAt, and updatedAt.
Places
/places contains geographical regions, countries, subdivisions, and
localities. The JSON:API type is place.
| Method | Path | Authorization |
|---|---|---|
| GET | /places |
Public |
| GET | /places/{id-or-slug} |
Public |
| POST | /places |
Editor for localities; admin for all other kinds |
| PATCH | /places/{id-or-slug} |
Admin, or the editor who created the locality |
| DELETE | /places/{id-or-slug} |
Admin, or the editor who created the locality |
Writable fields
kind is required on create and selects the underlying place type. It must be
region, country, subdivision, or locality; it cannot be changed later.
Other writable attributes are slug, name, latitude, longitude, and
isoCode. Writable relationships are parent, regions, and children.
Responses also include shortName, formatted, createdBy, and
lastUpdatedBy. The retired nested /places/{slug}/children and
/places/{slug}/regions routes have been replaced by these relationships and
collection filters.
Queryable fields are id, name, formatted, type, kind, isoCode,
slug, latitude, longitude, parentId, createdById, createdAt, and
updatedAt.
Media
Images
/images replaces the old /media/images path. Its JSON:API type is image.
Reads are public. Editors can create and update images. Admins can delete any image; an editor can delete an image they uploaded.
Writable attributes
| Attribute | Description |
|---|---|
base64Image |
Required on create; a data:image/...;base64,... string. It cannot be changed later. |
kind |
Required: artwork, boxart, doc, logo, photo, poster, or screen. |
title |
Required; maximum 100 characters. |
description |
Optional; maximum 500 characters. |
year, date |
Image creation date, from 1800 through the present. |
usageType |
free, fair, or licensed. |
attributedName, attributedUrl |
Credit for the image creator or owner. |
sourceUrl |
Original source. |
Writable relationships are mediaLicense, place, articles, games,
companies, and people.
Responses include original, thumb, height, width, size, slug,
uploadedBy, and lastUpdatedBy. base64Image is always returned as null.
Queryable fields are id, kind, title, year, date, sortDate,
usageType, width, height, size, placeId, mediaLicenseId,
uploadedById, slug, createdAt, and updatedAt. Use
filter[articleIdEq] to find images linked to an article.
External resources
/ext-resources stores shared information about material outside Dbljump.
The JSON:API type is extResource. A resource serves as a source when cited;
each citation is a separate extResourceJoin connecting it to a note. The
citation owns its passage location, so different notes can cite different
pages or timestamps in the same source.
| Method | Path | Purpose |
|---|---|---|
| GET | /ext-resources |
List, filter, sort, and paginate resources. |
| GET | /ext-resources/{id} |
Read a shared resource. |
| POST | /ext-resources |
Create a resource, optionally linked to notes. |
| PATCH | /ext-resources/{id} |
Update shared resource details. |
| DELETE | /ext-resources/{id} |
Delete the shared resource and its citation joins. |
Reads are public. Editors can create and update; only admins can delete.
Writable attributes are kind, title, authorNames, volumeTitle, doi, isbn, issn,
publisher, year, date, sortDate, urlOriginal, urlArchived,
pageNumbersBegin, and pageNumbersEnd. title and kind are required.
DOI, ISBN, and ISSN are separate optional strings, with light format checks
described below.
People’s names
authorNames is an optional, ordered array of people’s names. Each entry uses
only given and/or family; at least one must be a nonblank string. The other
name may be omitted, null, or blank. A person with a single given name does
not need a family name. Names may contain Unicode, spaces, and punctuation.
{
"data": {
"type": "extResource",
"attributes": {
"kind": "book",
"title": "Example book",
"authorNames": [
{ "given": "Zoë", "family": "Zed" },
{ "given": "Björk" },
{ "given": "Alex", "family": "Example" }
]
}
}
}
The API stores and returns the submitted spelling, spacing, order, and repeated
entries unchanged. Omitting authorNames on PATCH preserves it; null or []
clears the named authors. Strings containing JSON, bare name objects, non-string
name values other than null, unknown keys, and entries with no nonblank name
return 422 with code invalid at /data/attributes/authorNames.
Company/publication attribution uses the existing publisher and volumeTitle
fields rather than author-name objects. Named authors take precedence; without
them, volumeTitle supplies attribution for web_article, webpage,
print_article, and youtube, while publisher supplies it for book and
website. The resource title is the final fallback. The existing twitter
type has no company/publication fallback.
Identifier formats
These checks catch basic input mistakes. They do not verify checksums, query external registries, enforce uniqueness, or restrict identifiers by resource kind. All three fields may be omitted, null, or blank.
| Field | Accepted shape | Examples |
|---|---|---|
doi |
A 10. numeric prefix and a nonblank suffix separated by /. Older dotted prefixes and punctuation in suffixes are allowed. Optional doi: and http(s)://doi.org/ or http(s)://dx.doi.org/ prefixes are accepted. |
10.1000/182, doi: 10.1000/example, https://doi.org/10.1000/example |
isbn |
10 or 13 digits, with a final X allowed for ISBN-10. Spaces and hyphens are accepted between digits. Optional ISBN, ISBN-10, or ISBN-13 labels are accepted. |
9780429771385, 978-0-429-77138-5, ISBN-10: 0-8044-2957-X |
issn |
Seven digits followed by a digit or X. Spaces and hyphens are accepted between digits, with an optional ISSN label. |
12345678, 1234-5678, ISSN: 2434-561X |
Labels and X are case-insensitive, surrounding whitespace is allowed, and
common Unicode dash separators are accepted in ISBN/ISSN values. Formatting
is checked without rewriting the stored value.
Checks apply to new or changed identifier values. An unchanged older value
does not block unrelated edits. Omitting an identifier on PATCH preserves it;
null or an empty string clears it. Invalid changed values return 422 with
code invalid and a pointer to the identifier, such as /data/attributes/isbn.
Notes and publication details
The to-many notes relationship links the source to notes. Each identifier
must use gameNote, companyNote, or personNote, with an ID belonging to
that declared type. Omitting notes on PATCH preserves the existing links;
supplying it replaces those links, and an empty data array clears them.
Use the citation routes below to edit or remove an individual citation.
kind must be book, print_article, twitter, web_article, webpage,
website, or youtube. urlOriginal is required for every kind except
book and print_article. Page numbers are integers from 1–10000; supplying
only the beginning creates a one-page range.
The shared pageNumbersBegin and pageNumbersEnd fields describe publication
pages. A cited passage uses the separate citation location described below.
Creating a resource with a citation location
POST /ext-resources also accepts attributes.location as a creation-only
input. A non-null location requires exactly one note in relationships.notes.
The API saves the resource and that note’s citation location in one transaction;
if either fails, neither record is created. A resource may be created without
notes when its location is omitted or null.
The input is stored on the citation join. It is never returned as an attribute
of the shared resource. Read consumerJoins, or request
include=consumerJoins, to retrieve the citation IDs and stored locations.
PATCH /ext-resources/{id} rejects attributes.location, including null;
update the individual join instead.
Response and query fields
The response also exposes lastAccessedAt, approvedAt, and flaggedAt,
which are currently response-only, plus the createdBy, notes, and
consumerJoins relationships. A resource’s consumerJoins may also contain
other consumer types; the citation routes below support note consumers only.
Queryable fields are id, kind, title, year, date, sortDate,
urlOriginal, urlArchived, volumeTitle, doi, isbn, issn, publisher,
lastAccessedAt, approvedAt, flaggedAt, createdById, createdAt, and
updatedAt.
Search
GET /ext-resources?search=pong searches the following fields using the same
PostgreSQL search system as other collections. Results use weighted full-text
relevance by default; A is the strongest weight.
| Field | Weight |
|---|---|
title |
A |
authorNames (given/family name values only) |
B |
volumeTitle |
B |
publisher |
C |
urlOriginal |
D |
Title-only trigram matching also supports approximate title searches. Search
works with the existing filters, sorting, pagination, and includes. For example,
GET /ext-resources?search=pong&filter[kindEq]=book&page[size]=20 finds matching
books, including offline sources.
URL matching uses ordinary full-text tokens. A search for ign.com can match
https://ign.com/articles/example, but does not automatically match
www.ign.com or other subdomains; search for that hostname as entered instead.
For substring matching, use filter[urlOriginalCont]=ign.com. This filter is
not restricted to the hostname. Search does not normalize or rewrite URLs.
Use the existing DOI, ISBN, and ISSN filters for identifier lookup; identifiers are not part of this weighted text search. Kind, year, and dates remain filters.
Citations (external-resource joins)
/ext-resource-joins manages individual citations. Its JSON:API type is
extResourceJoin. Reads are public; editors can create, update, and remove
note citations. These joins share the external-resource policy, while deleting
a shared external resource still requires an admin.
| Method | Path | Purpose |
|---|---|---|
| POST | /ext-resource-joins |
Cite an existing resource from a note. |
| GET | /ext-resource-joins/{id} |
Read a citation and its location. |
| PATCH | /ext-resource-joins/{id} |
Change or clear a citation’s location. |
| DELETE | /ext-resource-joins/{id} |
Remove the citation, preserving its source and other citations. |
There is no citation collection GET endpoint. Obtain citation IDs from a
resource’s consumerJoins relationship or a note’s extResourceJoins
relationship. Both support inclusion to retrieve the join records.
Citation requests and responses
Creation requires two to-one relationships:
| Relationship | Type | Meaning |
|---|---|---|
extResource |
extResource |
The existing shared source. |
consumer |
gameNote, companyNote, or personNote |
The note citing it; the ID must belong to the declared type. |
location is the only writable citation attribute and is optional. Responses
return attributes.location and both relationship identifiers. Creating a
second citation from the same note to the same source returns 422 with code
taken and pointer /data/relationships/extResource; it does not replace the
existing citation or location.
PATCH requires data.type: "extResourceJoin" and the citation’s own data.id.
Omitting location preserves it; location: null clears it without removing
the citation. PATCH rejects non-empty relationships: the source and note
cannot be reassigned through this endpoint. Delete the citation and create a
new one to change either relationship.
Citation locations
location is null or one JSON object. Its type selects the following fields;
unknown types and extra fields are rejected. All text values must be nonblank
strings and are plain text rather than HTML or Markdown.
| Type | Example | Rules |
|---|---|---|
pages |
{"type":"pages","start":"24","end":"26"} |
Required string start; optional string end. Labels such as iv or S12 are allowed. When both labels contain only decimal digits, the end cannot precede the start; other labels are not ordered by the API. |
timestamp |
{"type":"timestamp","start":760,"end":845} |
Required integer start; optional integer end. Both are nonnegative whole seconds, and the end cannot precede the start. This example denotes 12:40–14:05. |
chapter |
{"type":"chapter","value":"3"} |
Required string value, containing a number or title. |
section |
{"type":"section","value":"2.1"} |
Required string value, containing a number or title. |
other |
{"type":"other","value":"Table 3"} |
Required string value describing the passage. |
Omit end for a single page or timestamp; do not supply end: null.
Time strings such as "12:40" are not accepted: clients must convert them to
whole seconds. Setting the entire location to null is the way to clear it.
Malformed document structures return 400 with code BAD_REQUEST. Invalid
location objects return 422 with code invalid and pointer
/data/attributes/location. Unsupported note types return 422; an ID not
found within its declared note type returns 404. A mismatched primary type
on POST, or type/ID on PATCH, returns 409 with code RESOURCE_MISMATCH.
Media licenses
/media-licenses replaces /media/licenses and uses type mediaLicense.
Reads are public; only admins can create, update, or delete.
Writable attributes are name (required, unique, maximum 100 characters),
shortName (required, unique, maximum 15 characters), and url (required,
unique, maximum 250 characters). Responses include image totals in metadata.
Users
User resources
/users uses type user.
| Method | Path | Authorization |
|---|---|---|
| GET | /users |
Public |
| GET | /users/{id} |
Public |
| POST | /users |
Public registration |
| PATCH | /users/{id} |
Same user or admin |
| DELETE | /users/{id} |
Same user, or admin deleting a non-admin |
| PATCH | /user-onboarding/{id} |
Same user or admin |
| PATCH | /user-preferences/{id} |
Same user or admin |
Registration
Writable registration fields are email, username, password,
passwordConfirmation, acceptedTerms, and editorRequest.
Email must be valid and unique. Username must be unique, contain only letters, numbers, underscores, or dots, begin and end with a letter or number, and be 2–12 characters. Password must be 8–24 characters. Terms acceptance is required.
Registration returns 201 Created and sends an activation email.
Updating a user
A user or admin can write unconfirmedEmail, username, acceptedTerms,
base64Image, removeAvatar, givenNames, familyName, gender,
birthday, place, password, and passwordConfirmation.
Only admins can also write role and editorRequestApproved. Roles are
member, editor, and admin.
Approving an editor request enrols the user in contributor onboarding and
queues the welcome email that begins the journey. Repeating an approval does
not replace existing progress or send the welcome email again. A user whose
onboardingEmails preference is false is still enrolled but does not receive
the onboarding email.
Email and administrative metadata are returned only to the same user or an
admin. Public responses include username, role, names, gender,
birthday, avatar, avatarThumb, and place.
For the same user or an admin, the response meta also contains the private
onboarding and preferences objects described below. onboarding is null
until the user has been enrolled. Preferences are returned with defaults
applied even when the user has not saved an explicit choice.
Private user state in a
GET /users/{id}response
{
"meta": {
"onboarding": {
"visitEditorComplete": true,
"chooseArticleComplete": false,
"uploadImageComplete": false,
"addCitedTextComplete": false,
"viewContributionsComplete": false,
"journeyComplete": false
},
"preferences": {
"notifications": {
"onboardingEmails": true
},
"editor": {
"showOnboardingReminders": true
}
}
}
}
Queryable fields are id, username, gender, role, placeId,
editorRequestOpen, lastSignedInAt, activatedAt, birthday,
lastActiveAt, createdAt, and updatedAt.
Contributor onboarding
PATCH /user-onboarding/{id} records one or more completed tasks in an active
contributor onboarding journey. Replace {id} with the user ID and use the
same value for data.id. The resource type is userOnboarding.
The endpoint accepts partial updates. Every supplied value must be the JSON
boolean true: completion is permanent and cannot be reset through this
endpoint. Repeating a completed task is safe and returns the unchanged current
state. The response always includes all task flags and journeyComplete, which
becomes true after every task is complete.
The same user or an admin can update the resource. The target user must already
be enrolled in contributor onboarding. The endpoint has no GET, POST, or
DELETE action; clients obtain the current state from GET /users/{id}.
On approval, the API sends the welcome email and schedules a first-step
reminder for one week later. The first successful visitEditorComplete update
schedules a contribution reminder for one week later. Completing the journey
queues its completion email immediately. Before delivery, delayed messages
recheck the user’s contributor role, email preference, and relevant progress;
messages that are no longer applicable are cancelled.
Complete one onboarding task
# PATCH /user-onboarding/5
{
"data": {
"type": "userOnboarding",
"id": "5",
"attributes": {
"visitEditorComplete": true
}
}
}
HTTP 200 response body
{
"data": {
"type": "userOnboarding",
"id": "5",
"attributes": {
"visitEditorComplete": true,
"chooseArticleComplete": false,
"uploadImageComplete": false,
"addCitedTextComplete": false,
"viewContributionsComplete": false,
"journeyComplete": false
}
}
}
| Attribute | Type | Description |
|---|---|---|
visitEditorComplete |
boolean | The contributor has visited the editor. |
chooseArticleComplete |
boolean | The contributor has chosen a game, person, or company article. |
uploadImageComplete |
boolean | The contributor has successfully uploaded an image through the guided article workflow. |
addCitedTextComplete |
boolean | The contributor has successfully added article text with a citation. |
viewContributionsComplete |
boolean | The contributor has viewed their contributions. |
journeyComplete |
boolean | Response-only flag indicating that every onboarding task is complete. |
Contributor onboarding errors
| HTTP status | Error code | Meaning |
|---|---|---|
| 400 | REQUEST_DATA_MISSING |
The JSON:API data or attributes object is missing. |
| 401 | NOT_AUTHORIZED |
Authentication is missing, or the current user cannot update this account. |
| 409 | ONBOARDING_RESOURCE_MISMATCH |
The body type or ID does not identify the resource in the URL. |
| 409 | ONBOARDING_NOT_ACTIVE |
The target user has no active contributor onboarding journey. |
| 422 | ONBOARDING_UPDATE_INVALID |
Attributes are empty or unsupported, or a value is not true. |
| 422 | ONBOARDING_STEP_INVALID |
A task is not part of the active onboarding definition. |
User preferences
PATCH /user-preferences/{id} updates one or more supported preferences.
Replace {id} with the user ID and use the same value for data.id. The
resource type is userPreferences.
Updates are partial and values must be JSON booleans. The response contains all
currently supported preferences with defaults applied. The same user or an
admin can update the resource. The endpoint has no GET, POST, or DELETE
action; clients obtain current preferences from GET /users/{id}.
Disable onboarding email and editor reminders
# PATCH /user-preferences/5
{
"data": {
"type": "userPreferences",
"id": "5",
"attributes": {
"onboardingEmails": false,
"showOnboardingReminders": false
}
}
}
HTTP 200 response body
{
"data": {
"type": "userPreferences",
"id": "5",
"attributes": {
"onboardingEmails": false,
"showOnboardingReminders": false
}
}
}
| Attribute | Type | Default | Description |
|---|---|---|---|
onboardingEmails |
boolean | true |
Whether onboarding emails may be delivered. |
showOnboardingReminders |
boolean | true |
Whether dismissible onboarding reminders appear in the editor. |
User preference errors
| HTTP status | Error code | Meaning |
|---|---|---|
| 400 | REQUEST_DATA_MISSING |
The JSON:API data or attributes object is missing. |
| 401 | NOT_AUTHORIZED |
Authentication is missing, or the current user cannot update this account. |
| 409 | USER_PREFERENCES_RESOURCE_MISMATCH |
The body type or ID does not identify the resource in the URL. |
| 422 | USER_PREFERENCES_UPDATE_INVALID |
Attributes are empty or unsupported, or a value is not a JSON boolean. |
Account activation
POST /user-activations activates an account using email and
activationToken. It returns the activated user with 200 OK.
PATCH /user-activations requests a replacement activation email using
email. It returns 204 No Content.
Both operations are unauthenticated.
Email confirmation
POST /email-confirmations confirms a pending email-address change. Send
unconfirmedEmail and confirmToken in a JSON:API document. The user must
already be activated. Success returns the updated user with 200 OK.
Password reset
POST /user-passwords requests a password-reset email. Send email; success
returns 204 No Content.
PATCH /user-passwords completes the reset. Send email, password, and
passwordResetToken; success returns 204 No Content.
Both password operations are unauthenticated.
Special endpoints
Reorder article notes
PATCH /article-note-orders/{id} atomically reorders every note in one article
category. It requires an editor and returns 204 No Content.
The resource ID is {article-type}-{article-id}-{category}, for example
game-45-development. Article type is game, company, or person.
Reorder all development notes for game 45
PATCH https://www.dbljump.com/article-note-orders/game-45-development
{
"data": {
"type": "article_note_order",
"id": "game-45-development",
"attributes": {
"category": "development"
},
"relationships": {
"article": {
"data": { "type": "game", "id": "45" }
},
"notes": {
"data": [
{ "type": "game_note", "id": "19" },
{ "type": "game_note", "id": "12" }
]
}
}
}
}
Unlike normal serialized resources, this endpoint validates its raw resource identifiers and therefore requires the snake-case types shown above.
The request must contain every note in the category exactly once. IDs must be
unique and must all belong to the specified article and category. An invalid
set returns 422 INVALID_NOTE_ORDER; a mismatched URL or resource identity
returns 409 RESOURCE_MISMATCH.
Health
GET /health is a lightweight service health check. A healthy application
returns 200 OK with an empty body.
Errors
JSON:API errors are returned in an errors array.
Validation error
{
"errors": [
{
"status": "422",
"code": "blank",
"source": {
"pointer": "/data/attributes/displayTitle"
},
"title": "Display title is required."
}
]
}
| Status | Meaning |
|---|---|
| 400 | Malformed or incomplete request data. |
| 401 | Missing/invalid authentication or insufficient authorization. |
| 404 | Record not found. |
| 409 | Request resource identity conflicts with the URL or a creation type does not match the endpoint. |
| 422 | Validation failed or the request is semantically invalid. |
| 500 | Mailer or other server-side operation failed. |
Common application codes include BAD_REQUEST, REQUEST_DATA_MISSING,
NOT_AUTHORIZED, TOKEN_INVALID, TOKEN_EXPIRED,
AUTHENTICATION_HANDOFF_INVALID,
USER_CREDENTIALS_INVALID, USER_ACTIVATION_REQUIRED,
USER_ALREADY_ACTIVATED, INVALID_NOTE_ORDER, RESOURCE_MISMATCH,
ONBOARDING_RESOURCE_MISMATCH, ONBOARDING_UPDATE_INVALID,
ONBOARDING_STEP_INVALID, ONBOARDING_NOT_ACTIVE,
USER_PREFERENCES_RESOURCE_MISMATCH, USER_PREFERENCES_UPDATE_INVALID,
MAILER_ERROR, and SERVER_ERROR.
Validation error pointers use lower camel case and point to either
/data/attributes/{name} or /data/relationships/{name}.
External-resource and citation write endpoints validate document structure
before deserialization. Malformed objects, incorrect relationship cardinality,
and misplaced relationship fields return 400 BAD_REQUEST; the error pointer
identifies the offending document member. Location-value validation returns
422 with code invalid at /data/attributes/location.
A duplicate note/source citation returns 422 with code taken at
/data/relationships/extResource. Unsupported note types return 422; a note
ID that is not found within its declared type returns 404. Creating a resource
or citation with the wrong primary type returns 409 RESOURCE_MISMATCH.