feat(apiv2): documentation, misc fixes

This commit is contained in:
spiral 2021-10-22 11:20:26 -04:00
parent 2bf1617737
commit 7d36a39a57
No known key found for this signature in database
GPG Key ID: A6059F0CA0E1BD31
9 changed files with 545 additions and 70 deletions

View File

@ -104,6 +104,7 @@ namespace PluralKit.Core
p.Add("description_privacy", system.DescriptionPrivacy.ToJsonString());
p.Add("member_list_privacy", system.MemberListPrivacy.ToJsonString());
p.Add("group_list_privacy", system.GroupListPrivacy.ToJsonString());
p.Add("front_privacy", system.FrontPrivacy.ToJsonString());
p.Add("front_history_privacy", system.FrontHistoryPrivacy.ToJsonString());

View File

@ -110,6 +110,9 @@ namespace PluralKit.Core
if (privacy.ContainsKey("member_list_privacy"))
patch.DescriptionPrivacy = patch.ParsePrivacy(privacy, "member_list_privacy");
if (privacy.ContainsKey("group_list_privacy"))
patch.GroupListPrivacy = patch.ParsePrivacy(privacy, "group_list_privacy");
if (privacy.ContainsKey("front_privacy"))
patch.DescriptionPrivacy = patch.ParsePrivacy(privacy, "front_privacy");

View File

@ -41,7 +41,6 @@ module.exports = {
"/getting-started",
"/user-guide",
"/command-list",
"/api-documentation",
"/privacy-policy",
"/faq",
"/tips-and-tricks"
@ -58,6 +57,19 @@ module.exports = {
"/staff/compatibility",
]
},
{
title: "API Documentation",
collapsable: false,
children: [
"/api/changelog",
"/api/reference",
"/api/endpoints",
"/api/models",
"/api/errors",
// "/api/integrations",
"/api/legacy"
]
},
["https://discord.gg/PczBt78", "Join the support server"],
]
},

View File

@ -0,0 +1,33 @@
---
title: Changelog
permalink: /api/changelog
---
# Version history
* 2020-07-28
* The unversioned API endpoints have been removed.
* 2020-06-17 (v1.1)
* The API now has values for granular member privacy. The new fields are as follows: `visibility`, `name_privacy`, `description_privacy`, `avatar_privacy`, `birthday_privacy`, `pronoun_privacy`, `metadata_privacy`. All are strings and accept the values of `public`, `private` and `null`.
* The `privacy` field has now been deprecated and should not be used. It's still returned (mirroring the `visibility` field), and writing to it will write to *all privacy options*.
* 2020-05-07
* The API (v1) is now formally(ish) defined with OpenAPI v3.0. [The definition file can be found here.](https://github.com/xSke/PluralKit/blob/master/PluralKit.API/openapi.yaml)
* 2020-02-10
* Birthdates with no year can now be stored using `0004` as a year, for better leap year support. Both options remain valid and either may be returned by the API.
* Added privacy set/get support, meaning you will now see privacy values in authed requests and can set them.
* 2020-01-08
* Added privacy support, meaning some responses will now lack information or return 403s, depending on the specific system and member's privacy settings.
* 2019-12-28
* Changed behaviour of missing fields in PATCH responses, will now preserve the old value instead of clearing
* This is technically a breaking change, but not *significantly* so, so I won't bump the version number.
* 2019-10-31
* Added `proxy_tags` field to members
* Added `keep_proxy` field to members
* Deprecated `prefix` and `suffix` member fields, will be removed at some point (tm)
* 2019-07-17
* Added endpoint for querying system by account
* Added endpoint for querying message contents
* 2019-07-10 **(v1)**
* First specified version
* (prehistory)
* Initial release

View File

@ -0,0 +1,261 @@
---
name: Endpoints
permalink: /api/endpoints
---
# Endpoints
The base URL for the PluralKit API is `https://api.pluralkit.me/v2`. Endpoint URLs should be added to the base URL to get a full URL to query.
---
## Systems
*`systemRef` can be a system's short (5-character) ID, a system's UUID, the ID of a Discord account linked to the system, or the string `@me` to refer to the currently authenticated system.*
### Get System
GET `/systems/{systemRef}`
Returns a [system object](/api/models#system-model).
### Update System
PATCH `/systems/{systemRef}`
Takes a partial [system object](/api/models#system-model).
Returns a [system object](/api/models#system-model).
### Get System Guild Settings
GET `/systems/@me/guilds/{guild_id}`
Returns a [system guild settings](/api/models#system-guild-settings) object.
::: note
You must already have updated per-guild settings for your system in the target guild before being able to get or update them from the API.
:::
### Update System Guild Settings
PATCH `/systems/@me/guilds/{guild_id}`
Takes a partial [system guild settings](/api/models#system-guild-settings) object.
Returns a [system guild settings](/api/models#system-guild-settings) object on success.
---
## Members
*`memberRef` can be a member's short (5-character ID) or a member's UUID.*
### Get System Members
GET `/systems/{systemRef}/members`
Returns a list of [member objects](/api/models#member-model).
### Create Member
POST `/members`
Takes a partial [member object](/api/models#member-model) as input. Key `name` is required.
Returns a [member object](/api/models#member-model) on success.
### Get Member
GET `/members/{memberRef}`
Returns a [member object](/api/models#member-model).
### Update Member
PATCH `/members/{memberRef}`
Takes a partial [member object](/api/models#member-model) as input.
Returns a [member object](/api/models#member-model) on success.
### Delete Member
DELETE `/members/{memberRef}`
Returns 204 No Content on success.
### Get Member Groups
GET `/members/{memberRef}/groups`
### Add Member To Groups
PUT `/members/{memberRef}/groups`
::: warn
Not all HTTP implementations support PUT requests with a body. If yours does not, consider using the [Add Member To Group](#add-member-to-group) endpoint instead.
:::
### Remove Member From Groups
DELETE `/members/{memberRef}/groups`
::: warn
Not all HTTP implementations support DELETE requests with a body. If yours does not, consider using the [Remove Member From Group](#remove-member-from-group) endpoint instead.
:::
### Get Member Guild Settings
GET `/members/{memberRef}/guilds/{guild_id}`
Returns a [member guild settings](/api/models#member-guild-settings) object.
::: note
You must already have updated per-guild settings for a member in the target guild before being able to get or update them from the API.
:::
### Update Member Guild Settings
PATCH `/members/{memberRef}/guilds/{guild_id}`
Takes a partial [member guild settings](/api/models#member-guild-settings) object.
Returns a [member guild settings](/api/models#member-guild-settings) object on success.
---
## Groups
*`groupRef` can be a group's short (5-character ID) or a group's UUID.*
### Get System Groups
GET `/systems/{systemRef}/groups`
Returns a list of [group objects](/api/models/#group-model).
### Create Group
POST `/groups`
Takes a partial [group object](/api/models#group-model) as input. Key `name` is required.
Returns a [group object](/api/models#group-model) on success, or an error object on failure.
### Get Group
GET `/groups/{groupRef}`
Returns a [group object](/api/models/#group-model).
### Update Group
PATCH `/groups/{groupRef}`
Takes a partial [group object](/api/models#group-model) as input.
Returns a [group object](/api/models#group-model) on success, or an error object on failure.
### Delete Group
DELETE `/groups/{groupRef}`
Returns 204 No Content on success.
### Get Group Members
GET `/groups/{groupRef}/members`
### Add Member To Group
PUT `/groups/{groupRef}/members/{memberRef}`
### Add Members To Group
PUT `/groups/{groupRef}/members`
::: warn
Not all HTTP implementations support PUT requests with a body. If yours does not, consider using the [Add Member To Group](#add-group-member) endpoint instead.
:::
### Remove Member From Group
DELETE `/groups/{groupRef}/members/{memberRef}`
### Remove Members From Group
DELETE `/groups/{groupRef}/members`
::: warn
Not all HTTP implementations support DELETE requests with a body. If yours does not, consider using the [Remove Member From Group](#remove-member-from-group) endpoint instead.
:::
---
## Switches
*`switchRef` must be a switch's UUID. On POST/PATCH/DELETE endpoints, `systemRef` must be `@me`.*
### Get System Switches
GET `/systems/{systemRef}/switches`
Query String Parameters
|key|type|description|
|---|---|---|
|before|timestamp|date to get latest switch from (inclusive)|
|limit|int|number of switches to get|
Returns a [switch object](/api/models#switch-model) containing a list of IDs.
### Get Current System Fronters
GET `/systems/{systemRef}/fronters`
Returns a [switch object](/api/models#switch-model) containing a list of member objects.
### Create Switch
POST `/systems/{systemRef}/switches`
JSON Body Parameters
|key|type|description|
|---|---|---|
|?timestamp|datetime*|when the switch started|
|members|list of strings**|members present in the switch (or empty list for switch-out)|
* Defaults to "now" when missing.
** Can be short IDs or UUIDs.
### Get Switch
GET `/systems/{systemRef}/switches/{switchRef}`
Returns a [switch object](/api/models#switch-model) containing a list of member objects.
### Update Switch
PATCH `/systems/{systemRef}/switches/{switchRef}`
JSON Body Parameters
|key|type|description|
|---|---|---|
|timestamp|datetime|when the switch started|
Returns a [switch object](/api/models#switch-model) containing a list of member objects on success.
### Update Switch Members
PATCH `/systems/{systemRef}/switches/{switchRef}/members`
Takes a list of member short IDs or UUIDs as input.
Returns a [switch object](/api/models#switch-model) containing a list of member objects on success.
### Delete Switch
DELETE `/systems/{systemRef}/switches/{switchRef}`
Returns 204 No Content on success.

View File

@ -0,0 +1,57 @@
---
title: Errors and Status Codes
permalink: /api/errors
---
# Errors and Status Codes
When something goes wrong, the API will send back a 4xx HTTP status code, along with a JSON object describing the error.
### Error Response Model
|key|type|description|
|---|---|---|
|code|int|numerical error code|
|message|string|description of the error|
|?errors|map of keys to error objects*|details on the error|
|?retry_after|int|if this is a rate limit error, the number of milliseconds after which you can retry the request|
* Only returned for model parsing errors. Values can be individual error objects, or arrays of error objects.
### Error Object
|key|type|description|
|---|---|---|
|message|string|error description|
|?max_length|int|if this is an error indicating a key is too long, the maximum allowed length for the key|
|?actual_length|int|if this is an error indicating a key is too long, the length of the provided value|
## JSON error codes
|code|HTTP response code|meaning|
|---|---|---|
|0|500|Internal server error, try again later|
|0|400|Bad Request (usually invalid JSON)|
|0|401|Missing or invalid Authorization header|
|20001|404|System not found.|
|20002|404|Member not found.|
|20003|404|Group not found.|
|20004|404|Message not found.|
|20005|404|Switch not found.|
|20005|404|Switch not found, switch associated with different system, or unauthorized to view front history.|
|20006|404|No system guild settings found for target guild.|
|20007|404|No member guild settings found for target guild.|
|30001|403|Unauthorized to view member list|
|30002|403|Unauthorized to view group list|
|30003|403|Unauthorized to view group member list|
|30004|403|Unauthorized to view current fronters.|
|30005|403|Unauthorized to view front history.|
|30006|403|Target member is not part of your system.|
|30007|403|Target group is not part of your system.|
|30008|403|$Member '{memberRef}' is not part of your system.|
|30009|403|$Group '{groupRef}' is not part of your system.|
|40002|400|Missing autoproxy member for member-mode autoproxy.|
|40003|400|Duplicate members in member list.|
|40004|400|Member list identical to current fronter list.|
|40005|400|Switch with provided timestamp already exists.|
|40006|400|Invalid switch ID.|

View File

@ -1,47 +1,13 @@
---
title: API documentation
description: PluralKit's API documentation.
permalink: /api
title: Legacy API documentation
permalink: /api/legacy
---
**2020-05-07**: [The PluralKit API is now documented on Swagger.](https://app.swaggerhub.com/apis-docs/xSke/PluralKit/1.1)
Accompanying it is an [OpenAPI v3.0 definition](https://github.com/xSke/PluralKit/blob/master/PluralKit.API/openapi.yaml). It's mostly complete, but is still subject to change - so don't go generating API clients and mock servers with it quite yet. It may still be useful, though :)
# Legacy API documentation
# API documentation
PluralKit has a basic HTTP REST API for querying and modifying your system.
The root endpoint of the API is `https://api.pluralkit.me/v1/`.
#### Authorization header token example
```
Authorization: z865MC7JNhLtZuSq1NXQYVe+FgZJHBfeBCXOPYYRwH4liDCDrsd7zdOuR45mX257
```
Endpoints will always return all fields, using `null` when a value is missing. On `PATCH` endpoints,
missing fields from the JSON request will be ignored and preserved as is, but on `POST` endpoints will
be set to `null` or cleared.
Endpoints taking JSON bodies (eg. most `PATCH` and `PUT` endpoints) require the `Content-Type: application/json` header set.
## Community API Libraries
The following API libraries have been created by members of our community. Please contact the developer of each library if you need support.
- **Python:** *PluralKit.py* ([PyPI](https://pypi.org/project/pluralkit/) | [Docs](https://pluralkit.readthedocs.io/en/latest/source/quickstart.html) | [Source code](https://github.com/almonds0166/pluralkit.py))
- **JavaScript:** *pkapi.js* ([npmjs](https://npmjs.com/package/pkapi.js) | [Docs](https://github.com/greysdawn/pk.js/wiki) | [Source code](https://github.com/greysdawn/pk.js))
- **Golang:** *pkgo* (install: `go get github.com/starshine-sys/pkgo` | [Docs (godoc)](https://godocs.io/github.com/starshine-sys/pkgo) | [Docs (pkg.go.dev)](https://pkg.go.dev/github.com/starshine-sys/pkgo) | [Source code](https://github.com/starshine-sys/pkgo))
Do let us know in the support server if you made a new library and would like to see it listed here!
## Authentication
Authentication is done with a simple "system token". You can get your system token by running `pk;token` using the
Discord bot, either in a channel with the bot or in DMs. Then, pass this token in the `Authorization` HTTP header
on requests that require it. Failure to do so on endpoints that require authentication will return a `401 Unauthorized`.
Some endpoints show information that a given system may have set to private. If this is a specific field
(eg. description), the field will simply contain `null` rather than the true value. If this applies to entire endpoint
responses (eg. fronter, switches, member list), the entire request will return `403 Forbidden`. Authenticating with the
system's token (as described above) will override these privacy settings and show the full information.
::: warning
This is the documentation for v1 of the PluralKit API. Please use v2 going forwards - v1 is deprecated and will be removed eventually.
:::
## Models
The following three models (usually represented in JSON format) represent the various objects in PluralKit's API.
@ -537,31 +503,3 @@ The returned system and member's privacy settings will be respected, and as such
}
}
```
## Version history
* 2020-07-28
* The unversioned API endpoints have been removed.
* 2020-06-17 (v1.1)
* The API now has values for granular member privacy. The new fields are as follows: `visibility`, `name_privacy`, `description_privacy`, `avatar_privacy`, `birthday_privacy`, `pronoun_privacy`, `metadata_privacy`. All are strings and accept the values of `public`, `private` and `null`.
* The `privacy` field has now been deprecated and should not be used. It's still returned (mirroring the `visibility` field), and writing to it will write to *all privacy options*.
* 2020-05-07
* The API (v1) is now formally(ish) defined with OpenAPI v3.0. [The definition file can be found here.](https://github.com/xSke/PluralKit/blob/master/PluralKit.API/openapi.yaml)
* 2020-02-10
* Birthdates with no year can now be stored using `0004` as a year, for better leap year support. Both options remain valid and either may be returned by the API.
* Added privacy set/get support, meaning you will now see privacy values in authed requests and can set them.
* 2020-01-08
* Added privacy support, meaning some responses will now lack information or return 403s, depending on the specific system and member's privacy settings.
* 2019-12-28
* Changed behaviour of missing fields in PATCH responses, will now preserve the old value instead of clearing
* This is technically a breaking change, but not *significantly* so, so I won't bump the version number.
* 2019-10-31
* Added `proxy_tags` field to members
* Added `keep_proxy` field to members
* Deprecated `prefix` and `suffix` member fields, will be removed at some point (tm)
* 2019-07-17
* Added endpoint for querying system by account
* Added endpoint for querying message contents
* 2019-07-10 **(v1)**
* First specified version
* (prehistory)
* Initial release

122
docs/content/api/models.md Normal file
View File

@ -0,0 +1,122 @@
---
title: Models
permalink: /api/models
---
# Models
A question mark (`?`) next to the *key name* means the key is optional - it may be omitted in API responses. A question mark next to the *key type* means the key is nullable - API responses may return `null` for that key, instead of the specified type.
In PATCH endpoints, all keys are optional. However, providing an object with no keys (or no valid keys) will result in 500 internal server error.
Privacy objects (`privacy` key in models) contain values "private" or "public". Patching a privacy value to `null` will set to public. If you do not have access to view the privacy object of the member, the value of the `privacy` key will be null, rather than the values of individual privacy keys.
#### Notes on IDs
Every PluralKit entity has two IDs: a short (5-character) ID and a longer UUID. The short ID is unique across the resource (a member can have the same short ID as a system, for example), while the UUID is consistent for the lifetime of the entity and globally unique across the bot.
### System model
|key|type|notes|
|---|---|---|
|id|string||
|uuid|string||
|name|string|100-character limit|
|description|?string|1000-character limit|
|tag|string||
|avatar_url|?string|256-character limit, must be a publicly-accessible URL|
|banner|?string|256-character limit, must be a publicly-accessible URL|
|color|string|6-character hex code, no `#` at the beginning|
|created|datetime||
|timezone|string|defaults to `UTC`|
|privacy|?system privacy object||
* System privacy keys: `description_privacy`, `member_list_privacy`, `group_list_privacy`, `front_privacy`, `front_history_privacy`
### Member model
|key|type|notes|
|---|---|---|
|id|string||
|uuid|string||
|name|string|100-character limit|
|display_name|?string|100-character limit|
|color|string|6-character hex code, no `#` at the beginning|
|birthday|?string|`YYYY-MM-DD` format, 0004 hides the year|
|pronouns|?string|100-character-limit|
|avatar_url|?string|256-character limit, must be a publicly-accessible URL|
|banner|?string|256-character limit, must be a publicly-accessible URL|
|description|?string|1000-character limit|
|created|?datetime||
|keep_proxy|boolean||
|privacy|?member privacy object||
* Member privacy keys: `visibility`, `name_privacy`, `description_privacy`, `birthday_privacy`, `pronoun_privacy`, `avatar_privacy`, `metadata_privacy`
#### ProxyTag object
| Key | Type |
| ------ | ------- |
| prefix | ?string |
| suffix | ?string |
### Group model
|key|type|notes|
|---|---|---|
|id|string||
|uuid|string||
|name|string|100-character limit|
|display_name|?string|100-character limit|
|description|?string|1000-character limit|
|icon|?string|256-character limit, must be a publicly-accessible URL|
|banner|?string|256-character limit, must be a publicly-accessible URL|
|color|string|6-character hex code, no `#` at the beginning|
|privacy|?group privacy object||
* Group privacy keys: `description_privacy`, `icon_privacy`, `list_privacy`, `visibility`
### Switch model
|key|type|notes|
|---|---|---|
|timestamp|datetime||
| members | list of id/Member | Is sometimes in plain ID list form (eg. `GET /systems/:id/switches`), sometimes includes the full Member model (eg. `GET /systems/:id/fronters`). |
### Message model
|key|type|notes|
|---|---|---|
|timestamp|datetime||
|id|snowflake|The ID of the message sent by the webhook. Encoded as string for precision reasons.|
|original| snowflake|The ID of the (now-deleted) message that triggered the proxy. Encoded as string for precision reasons.|
|sender|snowflake|The user ID of the account that triggered the proxy. Encoded as string for precision reasons.|
|channel|snowflake|The ID of the channel the message was sent in. Encoded as string for precision reasons.|
|system|full System object|The system that proxied the message.|
|member|full Member object|The member that proxied the message.|
### System guild settings model
|key|type|notes|
|---|---|---|
|proxying_enabled|boolean||
|autoproxy_mode|autoproxy mode enum||
|autoproxy_member|?string|must be set if autoproxy_mode is `member`|
|tag|?string|79-character limit|
|tag_enabled|boolean||
#### Autoproxy mode enum
|key|description|
|---|---|
|off|autoproxy is disabled|
|front|autoproxy is set to the first member in the current fronters list, or disabled if the current switch contains no members|
|latch|autoproxy is set to the last member who sent a proxied message in the server|
|member|autoproxy is set to a specific member (see `autoproxy_member` key)|
### Member guild settings model
|key|type|notes|
|---|---|---|
|display_name|?string|100-character limit|
|avatar_url|?string|256-character limit, must be a publicly-accessible URL|

View File

@ -0,0 +1,48 @@
---
title: Reference
permalink: /api/reference
---
# API Reference
PluralKit has a basic HTTP REST API for querying and modifying your system.
The root endpoint of the API is `https://api.pluralkit.me/v2/`.
#### Authorization header token example
```
Authorization: z865MC7JNhLtZuSq1NXQYVe+FgZJHBfeBCXOPYYRwH4liDCDrsd7zdOuR45mX257
```
Endpoints will always return all fields, using `null` when a value is missing. On `PATCH` endpoints,
missing fields from the JSON request will be ignored and preserved as is, but on `POST` endpoints will
be set to `null` or cleared.
For models that have them, the keys `id`, `uuid` and `created` are **not** user-settable.
Endpoints taking JSON bodies (eg. most `PATCH` and `PUT` endpoints) require the `Content-Type: application/json` header set.
## Authentication
Authentication is done with a simple "system token". You can get your system token by running `pk;token` using the
Discord bot, either in a channel with the bot or in DMs. Then, pass this token in the `Authorization` HTTP header
on requests that require it. Failure to do so on endpoints that require authentication will return a `401 Unauthorized`.
Some endpoints show information that a given system may have set to private. If this is a specific field
(eg. description), the field will simply contain `null` rather than the true value. If this applies to entire endpoint
responses (eg. fronter, switches, member list), the entire request will return `403 Forbidden`. Authenticating with the
system's token (as described above) will override these privacy settings and show the full information.
## Rate Limiting
By default, there is a per-IP limit of 2 requests per second across the API. If you exceed this limit, you will get a 429 response code with a [rate limit error](#) body .....
todo: this isn't implemented yet.
## Community API Libraries
The following API libraries have been created by members of our community. Please contact the developer of each library if you need support.
- **Python:** *PluralKit.py* ([PyPI](https://pypi.org/project/pluralkit/) | [Docs](https://pluralkit.readthedocs.io/en/latest/source/quickstart.html) | [Source code](https://github.com/almonds0166/pluralkit.py))
- **JavaScript:** *pkapi.js* ([npmjs](https://npmjs.com/package/pkapi.js) | [Docs](https://github.com/greysdawn/pk.js/wiki) | [Source code](https://github.com/greysdawn/pk.js))
- **Golang:** *pkgo* (install: `go get github.com/starshine-sys/pkgo` | [Docs (godoc)](https://godocs.io/github.com/starshine-sys/pkgo) | [Docs (pkg.go.dev)](https://pkg.go.dev/github.com/starshine-sys/pkgo) | [Source code](https://github.com/starshine-sys/pkgo))
Do let us know in the support server if you made a new library and would like to see it listed here!