The pointercrate API

This is the documentation for the pointercrate application programming interface (short: API). If you dont know what an API is or have no idea how you even got to this page, this link takes you back to the demonlist. If you rather want to read source code of the implementation directly, head over to the github repository instead. It also contains the markdown files these documentation pages are generated from, so if you find any error here feel free to submit a pull request!

The API can be used to retrieve data about the demonlist and is internally used to manage it. All endpoints described here are located under https://pointercrate.com/api/v1/ unless a different api version is explicitly provided, in which case the v1 part of the URL needs to be amended.

It is always good practice to set the Accept header in requests to application/json (or at least give application/json a higher preference than text/html), so that in case of errors, you receive a JSON response instead of the HTML error page.

All HTTP traffic is automatically redirected to HTTPS. All requests to URLs without a trailing slash are automatically redirected to URLs with one.

Errors

In case of a client or server error, the API returns an error response. Errors that are specific to a given endpoint are always listed in that endpoint's documentation. Following is an exhaustive list of errors that can occur at any endpoint in the API. Note that the errors with status code 500 INTERNAL SERVER ERROR should (obviously) not occur and are only listed for completeness sake. An complete ist of all errors can be found at the bottom on this page.

Status code Error code Description Data
400 40002 A header in the request was malformed and couldn't be processed header: The name of the malformed header
405 40500 405 METHOD NOT ALLOWED error allowed_methods: A list of allowed HTTP methods for this endpoint
409 40900 409 CONFLICT error. The resources you attempted to modify or delete has been concurrently modified by another client. Try again after re-requesting the resource
412 41200 The value provided in the If-Match header doesn't match the current state of the object
418 41800 No If-Match header was provided, although the request needs to be conditional
500 50000 The server encountered an unexpected state and couldn't recover
500 50001 Same as above, but we actually know what happened cause: The cause of the error
500 50003 The database unexpectedly returned an error while accessing the data required to perform the request
500 50005 Failure to connect to the database
503 50300 The requested endpoint is currently down for maintenance

In the case that you do not receive any response at all, or receive a Apache/Nginx error page you can assume that the pointercrate server crashed and couldn't recover. If this is the case all hope is lost.

409 versus 412

The cases in which a 409 CONFLICT error or a 412 PRECONDITION FAILED error is returned are very similar. In fact, handling for both errors should probably be identical. A 409 error is returned if the request you were making contained a valid hash of the object you were trying to access, however the same was true for another concurrent request. Which ever of the requests commits its database level transaction might now receive the CONFLICT error. A 412 error means that a modification to the object you were trying to access happen at some point prior to your current request (or the hash you sent along was invalid in the first place).

Both cases need to be handled the same way: You'll have to re-GET the object to retrieve its updated ETag and retry the request (simply retrying after a 409 error will most likely yield a 412 error directly after)

Authentication

Basic

Some endpoints in the API require you to authenticate using HTTP Basic Authentication. Since all communication with the API is enforced to be done via HTTPS, this is OK.

Access tokens

Pointercrate requires you to have a valid access token to issue requests to most endpoints. An access token for your account can be retrieved via a successful call to the login endpoint.

Pointercrate access tokens are JSON Web Tokens and can be parsed by any standard compliant implementation.

Each access token is valid until you change your password, or is invalidated via a call to invalidate.

When an endpoint requires authentication via an access token, the Authorization header has to be set to the word Bearer followed by a space, followed by your access token.

Cookies

Theoretically, it is possible to authenticate using cookies. Any requests made from your browser through the web interface are authenticated this way. Practically, you cannot use this authentication method (attempting to do so will simply result in a 401 UNAUTHORIZED response)

Errors

These error conditions apply to any endpoint that require authentication and are thus not repeated for every one of them.

Status code Error code Description
401 40100 A generic 401 UNAUTHORIZED error, indicating that authorization failed (e.g. because of a bad username, wrong password, wrong authorization method )

Permissions

Different endpoints require different kinds of privileges to be used. A user's permissions are saved as a bitmask, and by default every user has absolutely no permissions.

Permissions can be granted by other users with special permissions via the PATCH /users/user_id/ endpoint:

  • A user with the ADMINISTRATOR permission can assign the MODERATOR, LIST_ADMINISTRATOR and EXTENDED_ACCESS permissions
  • A user with the LIST_ADMINISTRATOR permission can assign the LIST_HELPER and LIST_MODERATOR permissions.
  • A user with the RESERVED2 permission can assign the RESERVED1 permission

If an endpoints requires special permissions to be accessed, it's documentation will contain a notice similar to this one:

Access Restrictions:
Access to this endpoint requires at least LIST_HELPER permissions.

Available permissions

Permission Bit Description
EXTENDED_ACCESS 0x1 Users that have access to additional data retrieval endpoints
LIST_HELPER 0x2 Users that help out in managing the demonlist by reviewing records
LIST_MODERATOR 0x4 Users that moderate the demonlist and manage the demon placements
LIST_ADMINISTRATOR 0x8 Users that administrate the demonlist.
RESERVED1 0x10 Reserved for future use
RESERVED2 0x20 Reserved for future use
MODERATOR 0x2000 Users that have access to the pointercrate user list
ADMINISTRATOR 0x4000 Users that can manage other users, including granting them permissions
- 0x8000 A permission users cannot have, but is required to assign certain other permissions, effectively preventing those permissions from ever being assigned

Errors

These error conditions can occur at any endpoint expecting requiring specific access permissions and are thus not listed specifically for each of them.

Status code Error code Description Data
403 40301 You do not have the permissions required to perform this request required: A list of permission-bitmasks that would allow you to perform the request

Pagination and Filtering

Some endpoints in the pointercrate API support or require pagination due to the potentially huge amount of data they can return. This mostly applies to the endpoints that return lists of objects, like GET /records/.

Objects returned by endpoints supporting pagination are totally ordered by an ID field, which is specified in the endpoint's documentation.

If an endpoint supports pagination, it's documentation will contain a notice similar to this one:

Pagination:
This endpoint supports pagination and filtering via query parameters. Please see the documentation on pagination for information on the additional request and response headers.

Pagination Query Parameters

Pagination is done via specific query parameters, which tell pointercrate which part of the result set to return.

Note that there is no way to get the total amount of pages, as both page bounds and size can be chosen abitrarily.

Query Parameter Description Default
limit The maximum amount of object to return. Must lie between 1 and 100 50
after The id of the last object on the previous page, thus specifying the start point of the current page The very first item in the result set
before The id of the first object on the next page, thus specifying the end point of the current page The very last item in the result set

Pagination Response Headers

Paginatable endpoints provide the Links header to simply access to the next, previous, first and last page, using the limit set on the request. The header is set to a comma-seperated list of links in the form <[link]>; rel=[page], where page is one of next, prev, first or last.

Note that the next and prev links are only provided if there actually is a next or previous page of results respectively. The first and last links are always provided.

Filtering

Most endpoints that support pagination also support filtering their results beyond simply using the pagination parameters.

If this is supported, the documentation specifies the filterable fields for a given endpoint. It is then possible to specify conditions in the query string, which the returned objects must meet.

There are two ways of filtering the result set:

  • Filtering by equality: The objects returned can be filtered by a specific field's value by specifying the field and a value in the query string, i.e. /api/v1/players/?banned=true
  • Filtering by inequality: The objects returned can be filtered by whether a field is smaller/greater than a specific value by specifying the field, suffixed with either __lt or __gt, and the value to check for inequality against in the query string, i.e. /api/v1/demons/?record_requirement__gt=75. Note that this doesn't work for all fields (since a lexicographical filtering on the record status hardly seems useful)

Multiple conditions can be combined, i.e. /api/v1/records/?after=200&limit=10&status=APPROVED&progress__lt=100. This request would return the first 10 approved records with a record ID greater than 200 and a progress less than 100.

Note that filtering explicitly on the ID field is not possible. You have to use the special before and after parameters for that. You also cannot use equality filtering on the ID field. Use the specific endpoint for retrieving single objects instead.

Errors:

These error conditions can occur at any endpoint supporting pagination and are thus not listed specifically for each of them.

Status code Error code Description
422 42207 The limit parameter is smaller than 1 or greater than 100

External Videos

Valid video formats

Pointercrate only accepts videos from a specific set of hosting services. It further normalizes all videos from a given host into one specific URL format and ensures that every video link actually leads to a valid video. All query parameters, including timestamps on youtube videos, are stripped from URLs.

If a host you want to see supported is missing or a URL format for one of the provided hosts is missing, please open an issue on the GitHub repository.

Please note that pointercrate asynchronously performs HEAD requests to any video URL submitted and discards any that don't return a successful response.

The accepted URL formats are:

Video host URL formats
YouTube http[s]://www.youtube.com/watch?v={id}
YouTube http[s]://m.youtube.com/watch?v={id}
YouTube http[s]://youtube.com/watch?w={id}
YouTube http[s]://youtu.be/{id}
Twitch http[s]://www.twitch.tv/videos/{id}
Twitch http[s]://twitch.tv/videos/{id}
Twitch http[s]://www.twitch.tv/{name}/v/{id}
Twitch http[s]://twitch.tv/{name}/v/{id}
Everyplay http[s]://www.everyplay.com/videos/{id}
Everyplay http[s]://everyplay.com/videos/{id}
Vimeo http[s]://www.vimeo.com/{id}
Vimeo http[s]://vimeo.com/{id}
Bilibili http[s]://www.bilibili.com/video/{id}
Bilibili http[s]://bilibili.com/video/{id}

They are normalized into the following:

Video host URL format
YouTube https://www.youtube.com/watch?v={id}
Twitch https://www.twitch.tv/videos/{id}
Everyplay https://everyplay.com/videos/{id}
Vimeo https://vimeo.com/{id}
Bilibili https://www.bilibili.com/video/{id}

Errors

These error conditions can occur at any endpoint expecting a video URL and are thus not listed specifically for each of them.

Status code Error code Description Data
422 42222 Invalid protocol encountered while processing an URL. Only http and https are supported -
422 42223 Authentication information was discovered while processing an URL -
422 42224 An unknown/unsupported video host has been discovered while processing an URL (no, pornhub is no acceptable host, what is wrong with you people??) -
422 42225 The video URL does not match the expected format for the given host expected: The expected URL format for this host

List of Errors

In generic it is the goal to have the API provide as detailed errors as possible. The generic error variants should be returned as rarely as possible. If you feel like a specific error could be communicated better, feel free to open an issue in the GitHub repository!

Status code Error code Description Data
400 40000 A generic 400 BAD REQUEST error -
400 40001 A 400 BAD REQUEST error with a message stating what went from -
400 40002 A header in the request was malformed and couldn't be processed header: The name of the malformed header
401 40100 A generic 401 UNAUTHORIZED error, indicating that authorization failed (e.g. because of a bad username, wrong password, wrong authorization method ) -
403 40300 A generic 403 FORBIDDEN error -
403 40301 You do not have the permissions required to perform this request required: A list of permission-bitmasks that would allow you to perform the request
403 40304 You have been banned from submitting records -
404 40400 A generic 404 NOT FOUND error -
404 40401 Some object referenced in the request couldn't be found -
405 40500 405 METHOD NOT ALLOWED error allowed_methods: A list of allowed HTTP methods for this endpoint
409 40900 409 CONFLICT error. The resources you attempted to modify or delete has been concurrently modified by another client. Try again after re-requesting the resource -
409 40902 The username you chose is already in use -
409 40904 The demon you tried to add already exists on the list position: The position of the existing demon
411 41100 A generic 411 LENGTH REQUIRED error -
412 41200 412 PRECONDITION FAILED error. The provided If-Match header doesn't match the current state of the object -
413 41300 413 PAYLOAD TOO LARGE error -
415 41500 415 UNSUPPORTED MEDIA TYPE error. Returned if you try to send anything that's not a JSON request body expected: The expected media type. Currently always application/json
422 42200 A generic 422 UNPROCESSABLE ENTITY error -
422 42202 The username provided during registration is shorter than 3 characters or isn't trimmed -
422 42204 The password provided during registration is shorter than 10 characters -
422 42207 The limit pagination parameter is smaller than 1 or greater than 100 -
422 42211 A field in the request that must hold a value was unexpectedly set to null field: The field unexpectedly set to null
422 42212 A demon was attempted to be added with a record requirement outside the interval [0, 100] -
422 42213 A demon was attempted to be added out-of-bounds maximal: The largest position it is acceptable to add a demon at
422 42215 A record with invalid progress was submitted requirement: The record requirement for the demon the record was submitted on
422 42217 A record that's already in the database was submitted status: The status of the existing record
existing: The ID of the existing record
422 42218 The record holder of a submission is banned -
422 42219 A record for a legacy demon was submitted -
422 42220 A non-100% record was submitted for the extended list -
422 42222 Invalid protocol encountered while processing an URL. Only http and https are supported -
422 42223 Authentication information was discovered while processing an URL -
422 42224 An unknown/unsupported video host has been discovered while processing an URL (no, pornhub is no acceptable host, what is wrong with you people??) -
422 42225 The video URL does not match the expected format for the given host expected: The expected URL format for this host
428 42800 Missing If-Match header on a request that's required to be conditional -
500 50000 The server encountered an unexpected state and couldn't recover -
500 50003 The database unexpectedly returned an error while accessing the data required to perform the request -
500 50005 Failure to connect to the database -
503 50300 The requested endpoint is currently down for maintenance -