Skip to main content
Glama

Storyden

by Southclaws
Mozilla Public License 2.0
227
openapi.yaml228 kB
openapi: 3.1.0 # # ╓███, # ▄██▀"███▄ # ╚█▀ `▀██▄ # ,, ╓███, ▀██▌_ # ╓███ ▄██▀"███▄ ╙███_ # ▐██" ▄██▀ `▀██▄ ╙██ # ▐██ ╙██▄ ╫██Γ ██─ # ▐██ ▀██▄ ,▓██▀ ██─ # ▐██ ╙█████▀ ██─ # ▐██ ╓█████_ ██─ # ▐██ ▄██▀` ╙███╥ ██─ # └███████▀ `▀██ ██ # info: contact: name: Barnaby Keene description: > Storyden social API for building community driven platforms. The Storyden API does not adhere to semantic versioning but instead applies a rolling strategy with deprecations and minimal breaking changes. This has been done mainly for a simpler development process and it may be changed to a more fixed versioning strategy in the future. Ultimately, the primary way Storyden tracks versions is dates, there are no set release tags currently. title: storyden version: "v1.25.8-canary" servers: - url: "/api" description: > The HTTP interface that this document describes is mounted on the `/api/` path and any requests outside of the base path will not be covered by the API specification and will be used for experimental features and plugins. # All endpoints are by default accessible via a browser session cookie or an API # key for either human accounts or bot accounts unless explicitly specified. security: - browser: [] - access_key: [] x-types: cache_response_headers: &cache_response_headers Cache-Control: { $ref: "#/components/headers/Cache-Control" } Last-Modified: { $ref: "#/components/headers/Last-Modified" } ETag: { $ref: "#/components/headers/ETag" } tags: - name: misc description: General metadata for the instance and uncategorised routes. - name: admin description: Administration and configuration settings. - name: roles description: Roles for permissions and aesthetics. - name: auth description: Authentication resources. - name: accounts description: User accounts. - name: invitations description: Account invitations. - name: notifications description: Event notifications. - name: reports description: Content and user reports. - name: profiles description: Public profiles. - name: categories description: Thread categories. - name: tags description: Organisational tags for discussion posts and library nodes. - name: posts description: Any operations for any kind of Post resource. - name: threads description: Forum threads. - name: replies description: Posts within a specific thread. - name: assets description: File uploads and downloads. - name: likes description: Likes/votes for posts and library nodes. - name: collections description: User curated collections of posts and library nodes. - name: nodes description: Structured knowledgebase content tree. - name: links description: Social bookmarks. - name: datagraph description: Content graph (posts, nodes, links) APIs. - name: events description: Event scheduling, invites and management. # # 8888888b. d8888 88888888888 888 888 .d8888b. # 888 Y88b d88888 888 888 888 d88P Y88b # 888 888 d88P888 888 888 888 Y88b. # 888 d88P d88P 888 888 8888888888 "Y888b. # 8888888P" d88P 888 888 888 888 "Y88b. # 888 d88P 888 888 888 888 "888 # 888 d8888888888 888 888 888 Y88b d88P # 888 d88P 888 888 888 888 "Y8888P" # paths: # # d8b # Y8P # # 88888b.d88b. 888 .d8888b .d8888b # 888 "888 "88b 888 88K d88P" # 888 888 888 888 "Y8888b. 888 # 888 888 888 888 X88 Y88b. # 888 888 888 888 88888P' "Y8888P # /version: get: operationId: GetVersion summary: Get the software version string. description: | The version number includes the date and time of the release build as well as a short representation of the Git commit hash. security: [] # TODO: Maybe remove from public access? tags: [misc] responses: default: { $ref: "#/components/responses/InternalServerError" } "200": description: OK content: text/plain: schema: type: string /openapi.json: get: operationId: GetSpec summary: OpenAPI specification description: | This endpoint returns the OpenAPI specification for the Storyden API in JSON format. This is useful for clients that want to dynamically load the API specification for documentation or code generation. security: [] # TODO: Remove this from default public access, add a perm. tags: [misc] responses: default: { $ref: "#/components/responses/InternalServerError" } "200": description: OK content: application/vnd.oai.openapi+json;version=3.1.0: schema: type: object /docs: get: operationId: GetDocs summary: API documentation description: | This endpoint returns the OpenAPI documentation for the Storyden API in an interactive HTML format. This is useful for developers who want to explore the API and test endpoints without writing code. security: [] # TODO: Remove this from default public access, add a perm. tags: [misc] responses: default: { $ref: "#/components/responses/InternalServerError" } "200": description: OK content: text/html: schema: type: string /info: get: operationId: GetInfo description: | Get the basic forum installation info such as title, description, etc. This is a fully public endpoint as it drives the ability to render stuff like OpenGraph metadata, favicon, titles, descriptions, for crawlers. security: [] tags: [misc] responses: default: { $ref: "#/components/responses/InternalServerError" } "200": { $ref: "#/components/responses/GetInfoOK" } /info/icon/{icon_size}: get: operationId: IconGet description: Get the logo icon image. security: [] tags: [misc] parameters: [{ $ref: "#/components/parameters/IconSize" }] responses: default: { $ref: "#/components/responses/InternalServerError" } "200": { $ref: "#/components/responses/AssetGetOK" } /info/icon: post: operationId: IconUpload description: Upload and process the installation's logo image. tags: [misc] requestBody: { $ref: "#/components/requestBodies/AssetUpload" } responses: default: { $ref: "#/components/responses/InternalServerError" } "401": { $ref: "#/components/responses/Unauthorised" } "200": description: OK /info/banner: get: operationId: BannerGet description: Get the banner image. security: [] tags: [misc] responses: default: { $ref: "#/components/responses/InternalServerError" } "200": { $ref: "#/components/responses/AssetGetOK" } post: operationId: BannerUpload description: Upload and process the installation's banner image. tags: [misc] requestBody: { $ref: "#/components/requestBodies/AssetUpload" } responses: default: { $ref: "#/components/responses/InternalServerError" } "401": { $ref: "#/components/responses/Unauthorised" } "200": description: OK /beacon: post: operationId: SendBeacon description: | A catch-all endpoint for tracking read states and other things that are not critical to the functioning of the platform. This endpoint is fire and forget and does not return any meaningful data. It is designed to be used with the `navigator.sendBeacon` API in browsers to mark things such as how far down a thread a member has read, or whether or not a Library Page has been visited recently. It may queue the work for later processing and is not guaranteed to be processed immediately or at all. security: [] tags: [misc] requestBody: { $ref: "#/components/requestBodies/Beacon" } responses: default: { $ref: "#/components/responses/InternalServerError" } "202": description: Accepted # # 888 d8b # 888 Y8P # 888 # 8888b. .d88888 88888b.d88b. 888 88888b. # "88b d88" 888 888 "888 "88b 888 888 "88b # .d888888 888 888 888 888 888 888 888 888 # 888 888 Y88b 888 888 888 888 888 888 888 # "Y888888 "Y88888 888 888 888 888 888 888 # /admin: patch: operationId: AdminSettingsUpdate description: Update non-env configuration settings for installation. tags: [admin] requestBody: { $ref: "#/components/requestBodies/AdminSettingsUpdate" } responses: default: { $ref: "#/components/responses/InternalServerError" } "400": { $ref: "#/components/responses/BadRequest" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/AdminSettingsUpdateOK" } /admin/bans/{account_handle}: post: operationId: AdminAccountBanCreate description: | Suspend an account - soft delete. This disables the ability for the account owner to log in and use the platform. It keeps the account on record for linkage to content so UI doesn't break. It does not change anything else about the account such as the avatar, name, etc. tags: [admin] parameters: [$ref: "#/components/parameters/AccountHandleParam"] responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/AccountGetOK" } delete: operationId: AdminAccountBanRemove description: Given the account is suspended, remove the suspended state. tags: [admin] parameters: [$ref: "#/components/parameters/AccountHandleParam"] responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/AccountGetOK" } /admin/access-keys: get: operationId: AdminAccessKeyList description: | List all access keys for the entire instance. This is only available to admin accounts and is used to manage access keys from other accounts. tags: [admin] responses: default: { $ref: "#/components/responses/InternalServerError" } "400": { $ref: "#/components/responses/BadRequest" } "403": { $ref: "#/components/responses/Forbidden" } "200": { $ref: "#/components/responses/AdminAccessKeyListOK" } /admin/access-keys/{access_key_id}: delete: operationId: AdminAccessKeyDelete description: | Revoke an access key. This will immediately invalidate the key and it will no longer be usable for authentication. tags: [admin] parameters: [{ $ref: "#/components/parameters/AccessKeyIDParam" }] responses: default: { $ref: "#/components/responses/InternalServerError" } "400": { $ref: "#/components/responses/BadRequest" } "403": { $ref: "#/components/responses/Forbidden" } "204": { $ref: "#/components/responses/NoContent" } # # 888 # 888 # 888 # 888d888 .d88b. 888 .d88b. .d8888b # 888P" d88""88b 888 d8P Y8b 88K # 888 888 888 888 88888888 "Y8888b. # 888 Y88..88P 888 Y8b. X88 # 888 "Y88P" 888 "Y8888 88888P' # /roles: post: operationId: RoleCreate description: Creates a role with the specified permissions granted. tags: [roles] requestBody: { $ref: "#/components/requestBodies/RoleCreate" } responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/RoleCreateOK" } get: operationId: RoleList description: List all roles and their permissions. tags: [roles] responses: default: { $ref: "#/components/responses/InternalServerError" } "200": { $ref: "#/components/responses/RoleListOK" } /roles/{role_id}: get: operationId: RoleGet description: Retreives a role and all its permissions. tags: [roles] parameters: [{ $ref: "#/components/parameters/RoleIDParam" }] responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/RoleGetOK" } patch: operationId: RoleUpdate description: Updates a role's attributes. tags: [roles] parameters: [{ $ref: "#/components/parameters/RoleIDParam" }] requestBody: { $ref: "#/components/requestBodies/RoleUpdate" } responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/RoleGetOK" } delete: operationId: RoleDelete description: Deletes a role. tags: [roles] parameters: [{ $ref: "#/components/parameters/RoleIDParam" }] responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { description: OK } # # 888 888 # 888 888 # 888 888 # 8888b. 888 888 888888 88888b. # "88b 888 888 888 888 "88b # .d888888 888 888 888 888 888 # 888 888 Y88b 888 Y88b. 888 888 # "Y888888 "Y88888 "Y888 888 888 # /auth: get: operationId: AuthProviderList description: | Retrieve a list of authentication providers. Storyden supports a few ways to authenticate, from simple passwords to OAuth and WebAuthn. This endpoint tells a client which auth capabilities are enabled. tags: [auth] responses: default: { $ref: "#/components/responses/InternalServerError" } "400": { $ref: "#/components/responses/BadRequest" } "200": { $ref: "#/components/responses/AuthProviderListOK" } /auth/password/signup: post: operationId: AuthPasswordSignup description: Register a new account with a username and password. tags: [auth] parameters: [$ref: "#/components/parameters/InvitationIDQueryParam"] requestBody: { $ref: "#/components/requestBodies/AuthPassword" } responses: default: { $ref: "#/components/responses/InternalServerError" } "400": { $ref: "#/components/responses/BadRequest" } "200": { $ref: "#/components/responses/AuthSuccessOK" } /auth/password/signin: post: operationId: AuthPasswordSignin description: Sign in to an existing account with a username and password. tags: [auth] requestBody: { $ref: "#/components/requestBodies/AuthPassword" } responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/AuthSuccessOK" } /auth/password: post: operationId: AuthPasswordCreate description: | Given the requesting account does not have a password authentication, add a password authentication method to it with the given password. tags: [auth] security: [browser: []] requestBody: { $ref: "#/components/requestBodies/AuthPasswordCreate" } responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/AuthSuccessOK" } patch: operationId: AuthPasswordUpdate description: | Given the requesting account has a password authentication, update the password on file. tags: [auth] security: [browser: []] requestBody: { $ref: "#/components/requestBodies/AuthPasswordUpdate" } responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/AuthSuccessOK" } /auth/password/reset: post: operationId: AuthPasswordReset description: | Complete a password-reset flow using a token that was provided to the member via a reset request operation such as `AuthEmailPasswordReset`. tags: [auth] requestBody: { $ref: "#/components/requestBodies/AuthPasswordReset" } responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/AuthSuccessOK" } /auth/email-password/signup: post: operationId: AuthEmailPasswordSignup description: Register a new account with a email and password. tags: [auth] parameters: [$ref: "#/components/parameters/InvitationIDQueryParam"] requestBody: { $ref: "#/components/requestBodies/AuthEmailPassword" } responses: default: { $ref: "#/components/responses/InternalServerError" } "400": { $ref: "#/components/responses/BadRequest" } "200": { $ref: "#/components/responses/AuthSuccessOK" } /auth/email-password/signin: post: operationId: AuthEmailPasswordSignin description: Sign in to an existing account with a email and password. tags: [auth] requestBody: { $ref: "#/components/requestBodies/AuthEmailPassword" } responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/AuthSuccessOK" } /auth/email-password/reset: post: operationId: AuthPasswordResetRequestEmail description: | Request password reset email to be sent to the specified email address. tags: [auth] requestBody: { $ref: "#/components/requestBodies/AuthEmailPasswordReset" } responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { description: OK } /auth/email/signup: post: operationId: AuthEmailSignup description: | Register a new account with an email and optional password. The password requirement is dependent on how the instance is configured for account authentication with email addresses (password vs magic link.) When the email address has not been registered, this endpoint will send a verification email however it will also return a session cookie to facilitate pre-verification usage of the platform. If the email address already exists, no session cookie will be returned in order to prevent arbitrary account control by a malicious actor. In this case, the email will be sent again with the same OTP for the case where the user has cleared their cookies or switched device but hasn't yet verified due to missing the email or a delivery failure. In this sense, the endpoint can act as a "resend verification email" operation as well as registration. In the first case, a 200 response is provided with the session cookie, in the second case, a 422 response is provided without a session cookie. Given that this is an unauthenticated endpoint that triggers an email to be sent to any public address, it MUST be heavily rate limited. tags: [auth] parameters: [$ref: "#/components/parameters/InvitationIDQueryParam"] requestBody: { $ref: "#/components/requestBodies/AuthEmail" } responses: default: { $ref: "#/components/responses/InternalServerError" } "400": { $ref: "#/components/responses/BadRequest" } "422": description: Verification email sent but no session will be provided. "200": { $ref: "#/components/responses/AuthSuccessOK" } /auth/email/signin: post: operationId: AuthEmailSignin description: | Sign in to an existing account with an email and optional password. The behaviour of this endpoint depends on how the instance is configured. If email+password is the preferred method, a cookie is returned on success but if magic links are preferred, the endpoint will start the code flow. tags: [auth] requestBody: { $ref: "#/components/requestBodies/AuthEmail" } responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/AuthSuccessOK" } /auth/email/verify: post: operationId: AuthEmailVerify description: | Verify an email address using a token that was emailed to one of the account's email addresses either set via sign up or added later. tags: [auth] requestBody: { $ref: "#/components/requestBodies/AuthEmailVerify" } responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/AuthSuccessOK" } /auth/oauth/{oauth_provider}/callback: post: operationId: OAuthProviderCallback description: OAuth2 callback. tags: [auth] parameters: [$ref: "#/components/parameters/OAuthProvider"] requestBody: { $ref: "#/components/requestBodies/OAuthProviderCallback" } responses: default: { $ref: "#/components/responses/InternalServerError" } "401": { $ref: "#/components/responses/Unauthorised" } "404": { $ref: "#/components/responses/NotFound" } "200": { $ref: "#/components/responses/AuthSuccessOK" } /auth/webauthn/make/{account_handle}: get: operationId: WebAuthnRequestCredential description: | Start the WebAuthn registration process by requesting a credential. tags: [auth] parameters: [$ref: "#/components/parameters/AccountHandleParam"] responses: default: { $ref: "#/components/responses/InternalServerError" } "400": { $ref: "#/components/responses/BadRequest" } "200": { $ref: "#/components/responses/WebAuthnRequestCredentialOK" } /auth/webauthn/make: post: operationId: WebAuthnMakeCredential description: Complete WebAuthn registration by creating a new credential. tags: [auth] security: [webauthn: []] parameters: [$ref: "#/components/parameters/InvitationIDQueryParam"] requestBody: { $ref: "#/components/requestBodies/WebAuthnMakeCredential" } responses: default: { $ref: "#/components/responses/InternalServerError" } "400": { $ref: "#/components/responses/BadRequest" } "200": { $ref: "#/components/responses/AuthSuccessOK" } /auth/webauthn/assert/{account_handle}: get: operationId: WebAuthnGetAssertion description: Start the WebAuthn assertion for an existing account. tags: [auth] parameters: [$ref: "#/components/parameters/AccountHandleParam"] responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": $ref: "#/components/responses/WebAuthnGetAssertionOK" /auth/webauthn/assert: post: operationId: WebAuthnMakeAssertion description: Complete the credential assertion and sign in to an account. tags: [auth] security: [webauthn: []] requestBody: { $ref: "#/components/requestBodies/WebAuthnMakeAssertion" } responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/AuthSuccessOK" } /auth/phone: post: operationId: PhoneRequestCode description: | Start the authentication flow with a phone number. The handler will send a one-time code to the provided phone number which must then be sent to the other phone endpoint to verify the number and validate the account. tags: [auth] parameters: [$ref: "#/components/parameters/InvitationIDQueryParam"] requestBody: { $ref: "#/components/requestBodies/PhoneRequestCode" } responses: default: { $ref: "#/components/responses/InternalServerError" } "400": { $ref: "#/components/responses/BadRequest" } "200": { $ref: "#/components/responses/AuthSuccessOK" } /auth/phone/{account_handle}: put: operationId: PhoneSubmitCode description: | Complete the phone number authentication flow by submitting the one-time code that was sent to the user's phone. tags: [auth] parameters: [$ref: "#/components/parameters/AccountHandleParam"] requestBody: { $ref: "#/components/requestBodies/PhoneSubmitCode" } responses: default: { $ref: "#/components/responses/InternalServerError" } "400": { $ref: "#/components/responses/BadRequest" } "200": { $ref: "#/components/responses/AuthSuccessOK" } /auth/access-keys: get: operationId: AccessKeyList description: | List all access keys for the authenticated account or all access keys that have been issued for the entire instance if and only if the request parameters specify all keys and the requesting account is an admin. tags: [auth] responses: default: { $ref: "#/components/responses/InternalServerError" } "400": { $ref: "#/components/responses/BadRequest" } "403": { $ref: "#/components/responses/Forbidden" } "200": { $ref: "#/components/responses/AccessKeyListOK" } post: operationId: AccessKeyCreate description: | Create a new access key for the authenticated account. Access keys are used to authenticate API requests on behalf of the account in a more granular and service-friendly way than a session cookie. Access keys share the same roles and permissions as the owning account and only provide a way to use an `Authorization` header as an way of interacting with the Storyden API. Access keys also allow an expiry date to be set to limit how long a key can be used to authenticate against the API. tags: [auth] security: [browser: []] requestBody: { $ref: "#/components/requestBodies/AccessKeyCreate" } responses: default: { $ref: "#/components/responses/InternalServerError" } "400": { $ref: "#/components/responses/BadRequest" } "403": { $ref: "#/components/responses/Forbidden" } "200": { $ref: "#/components/responses/AccessKeyCreateOK" } /auth/access-keys/{access_key_id}: delete: operationId: AccessKeyDelete description: | Revoke an access key. This will immediately invalidate the key and it will no longer be usable for authentication. tags: [auth] parameters: [{ $ref: "#/components/parameters/AccessKeyIDParam" }] responses: default: { $ref: "#/components/responses/InternalServerError" } "400": { $ref: "#/components/responses/BadRequest" } "403": { $ref: "#/components/responses/Forbidden" } "204": { $ref: "#/components/responses/NoContent" } /auth/logout: get: operationId: AuthProviderLogout description: | Performs a HTTP logout by clearing the session cookie and redirecting to to the requested path at the frontend's `WEB_ADDRESS`. Typically this may be a secondary logout route on the frontend implementation that can handle any frontend-specific logout tasks. This is necessary in cases where the frontend is running on a different origin to the API service such as api.site.com vs site.com because Clear-Site-Data and other headers are same-origin compliant and won't work cross-origin. tags: [auth] security: [browser: []] parameters: - name: redirect in: query description: | Path relative to the `WEB_ADDRESS` to redirect to. Note that this is a path only and not a full URL to prevent cross-origin or cross-site redirects. If not provided, redirects to `WEB_ADDRESS` index page. required: false schema: type: string responses: "302": description: Redirect to specified URL or home page headers: Set-Cookie: { schema: { type: string } } Clear-Site-Data: { schema: { type: string } } Cache-Control: { schema: { type: string } } Location: { schema: { type: string } } # # 888 # 888 # 888 # 8888b. .d8888b .d8888b .d88b. 888 888 88888b. 888888 .d8888b # "88b d88P" d88P" d88""88b 888 888 888 "88b 888 88K # .d888888 888 888 888 888 888 888 888 888 888 "Y8888b. # 888 888 Y88b. Y88b. Y88..88P Y88b 888 888 888 Y88b. X88 # "Y888888 "Y8888P "Y8888P "Y88P" "Y88888 888 888 "Y888 88888P' # /accounts: get: operationId: AccountGet description: Get the information for the currently authenticated account. tags: [accounts] responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/AccountGetOK" } "304": { $ref: "#/components/responses/NotModified" } patch: operationId: AccountUpdate description: Update the information for the currently authenticated account. tags: [accounts] requestBody: { $ref: "#/components/requestBodies/AccountUpdate" } responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/AccountUpdateOK" } /accounts/{account_id}: get: operationId: AccountView description: | Get detailed account information by ID. Requires either the permissions VIEW_ACCOUNTS or ADMINISTRATOR. Users with VIEW_ACCOUNTS can view any account that is not ADMINISTRATOR including those with VIEW_ACCOUNTS. Only members with ADMINISTRATOR can view other ADMINISTRATOR accounts. tags: [accounts] parameters: [{ $ref: "#/components/parameters/AccountIDParam" }] responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "403": { $ref: "#/components/responses/Forbidden" } "200": { $ref: "#/components/responses/AccountGetOK" } /accounts/self/auth-methods: get: operationId: AccountAuthProviderList description: | Retrieve a list of authentication providers with a flag indicating which ones are active for the currently authenticated account. tags: [accounts] responses: default: { $ref: "#/components/responses/InternalServerError" } "400": { $ref: "#/components/responses/BadRequest" } "200": { $ref: "#/components/responses/AccountAuthProviderListOK" } /accounts/self/auth-methods/{auth_method_id}: delete: operationId: AccountAuthMethodDelete description: | Deletes the specified authentication method from the account. This is irreversible however if this authentication method is the only remaining method for the account, this operation will fail with a 400 bad request. tags: [accounts] parameters: - name: auth_method_id required: true in: path schema: type: string responses: default: { $ref: "#/components/responses/InternalServerError" } "400": { $ref: "#/components/responses/BadRequest" } "200": { $ref: "#/components/responses/AccountAuthProviderListOK" } /accounts/self/emails: post: operationId: AccountEmailAdd description: Add an email address to the authenticated account. tags: [accounts] requestBody: { $ref: "#/components/requestBodies/AccountEmailAdd" } responses: default: { $ref: "#/components/responses/InternalServerError" } "400": { $ref: "#/components/responses/BadRequest" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/AccountEmailUpdateOK" } /accounts/self/emails/{email_address_id}: delete: operationId: AccountEmailRemove description: Remove an email address from the authenticated account. tags: [accounts] parameters: [{ $ref: "#/components/parameters/EmailAddressIDParam" }] responses: default: { $ref: "#/components/responses/InternalServerError" } "400": { $ref: "#/components/responses/BadRequest" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { description: OK } /accounts/self/avatar: post: operationId: AccountSetAvatar description: Upload an avatar for the authenticated account. tags: [accounts] requestBody: { $ref: "#/components/requestBodies/AccountSetAvatar" } parameters: [$ref: "#/components/parameters/ContentLength"] responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { description: "OK" } /accounts/{account_handle}/avatar: get: operationId: AccountGetAvatar description: Get an avatar for the specified account. tags: [accounts] parameters: [$ref: "#/components/parameters/AccountHandleParam"] responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/AccountGetAvatar" } /accounts/{account_handle}/roles/{role_id}: put: operationId: AccountAddRole description: | Adds a role to an account. Members without the MANAGE_ROLES permission cannot use this operation. tags: [accounts] parameters: - $ref: "#/components/parameters/RoleIDParam" - $ref: "#/components/parameters/AccountHandleParam" responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/AccountUpdateOK" } delete: operationId: AccountRemoveRole description: | Removes a role from an account. Members without the MANAGE_ROLES cannot use this operation. Admins cannot remove the admin role from themselves. tags: [accounts] parameters: - $ref: "#/components/parameters/RoleIDParam" - $ref: "#/components/parameters/AccountHandleParam" responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/AccountUpdateOK" } /accounts/{account_handle}/roles/{role_id}/badge: put: operationId: AccountRoleSetBadge description: | Desgiantes the specified role as a badge for the profile. Only one role may be set as a badge for the profile. Setting a role as a badge is entirely aesthetic and does not grant any additional permissions. Roles may be created without any permissions in order to be used as badges. tags: [accounts] parameters: - $ref: "#/components/parameters/RoleIDParam" - $ref: "#/components/parameters/AccountHandleParam" responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/AccountUpdateOK" } delete: operationId: AccountRoleRemoveBadge description: | Removes the badge from the profile. This does not remove the role from the account, only the visual badge-status representation of the role. tags: [accounts] parameters: - $ref: "#/components/parameters/RoleIDParam" - $ref: "#/components/parameters/AccountHandleParam" responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/AccountUpdateOK" } # # d8b d8b 888 888 d8b # Y8P Y8P 888 888 Y8P # 888 888 # 888 88888b. 888 888 888 888888 8888b. 888888 888 .d88b. 88888b. .d8888b # 888 888 "88b 888 888 888 888 "88b 888 888 d88""88b 888 "88b 88K # 888 888 888 Y88 88P 888 888 .d888888 888 888 888 888 888 888 "Y8888b. # 888 888 888 Y8bd8P 888 Y88b. 888 888 Y88b. 888 Y88..88P 888 888 X88 # 888 888 888 Y88P 888 "Y888 "Y888888 "Y888 888 "Y88P" 888 888 88888P' # /invitations: get: operationId: InvitationList description: | Retrieve all invitations for the authenticated account. This endpoint is useful for showing the user which invitations they have sent out and which ones have been accepted. If the requesting account is not an admin, the account_id query param must be equal to the ID of the requesting session account's ID. If the requesting account is an admin, the account_id query param may be used to retrieve invitations for a specific account. Otherwise, the endpoint will return all invitations for all accounts. tags: [invitations] parameters: - { $ref: "#/components/parameters/AccountIDQueryParam" } responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/InvitationListOK" } post: operationId: InvitationCreate description: | Create an invitation for the authenticated account. Responds with the invitation data which can be used to construct a public vendor-specific registration URL using the invitation's identifier which can be used in calls to registration operations to indicate the account was invited. tags: [invitations] requestBody: { $ref: "#/components/requestBodies/InvitationCreate" } responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/InvitationCreateOK" } /invitations/{invitation_id}: get: operationId: InvitationGet description: | Retrieve the details of an invitation by its identifier. This endpoint is publicly accessible and can be used to show invitation details before the client's registration flow. tags: [invitations] parameters: [{ $ref: "#/components/parameters/InvitationIDParam" }] responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/InvitationGetOK" } delete: operationId: InvitationDelete description: Delete an invitation. After deletion, it cannot be used. tags: [invitations] parameters: [{ $ref: "#/components/parameters/InvitationIDParam" }] responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { description: "OK" } # # 888 d8b .d888 d8b 888 d8b # 888 Y8P d88P" Y8P 888 Y8P # 888 888 888 # 88888b. .d88b. 888888 888 888888 888 .d8888b 8888b. 888888 888 .d88b. 88888b. .d8888b # 888 "88b d88""88b 888 888 888 888 d88P" "88b 888 888 d88""88b 888 "88b 88K # 888 888 888 888 888 888 888 888 888 .d888888 888 888 888 888 888 888 "Y8888b. # 888 888 Y88..88P Y88b. 888 888 888 Y88b. 888 888 Y88b. 888 Y88..88P 888 888 X88 # 888 888 "Y88P" "Y888 888 888 888 "Y8888P "Y888888 "Y888 888 "Y88P" 888 888 88888P' # /notifications: get: operationId: NotificationList description: Retreive all notifications. tags: [notifications] parameters: - $ref: "#/components/parameters/PaginationQuery" - $ref: "#/components/parameters/NotificationStatusQuery" responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/NotificationListOK" } /notifications/{notification_id}: patch: operationId: NotificationUpdate description: Change the read status for a notification. tags: [notifications] parameters: [$ref: "#/components/parameters/NotificationIDParam"] requestBody: { $ref: "#/components/requestBodies/NotificationUpdate" } responses: default: { $ref: "#/components/responses/InternalServerError" } "400": { $ref: "#/components/responses/BadRequest" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/NotificationUpdateOK" } # # 888 # 888 # 888 # 888d888 .d88b. 88888b. .d88b. 888d888 888888 .d8888b # 888P" d8P Y8b 888 "88b d88""88b 888P" 888 88K # 888 88888888 888 888 888 888 888 888 "Y8888b. # 888 Y8b. 888 d88P Y88..88P 888 Y88b. X88 # 888 "Y8888 88888P" "Y88P" 888 "Y888 88888P' # 888 # 888 # 888 # /reports: post: operationId: ReportCreate description: | Create a new report for content or user violations. Reports can be against any kind of user-generated content as well as members themselves. The kind of report is specified in the request body which dictates which resource the `id` field refers to. tags: [reports] requestBody: { $ref: "#/components/requestBodies/ReportCreate" } responses: default: { $ref: "#/components/responses/InternalServerError" } "400": { $ref: "#/components/responses/BadRequest" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/ReportCreateOK" } get: operationId: ReportList description: | List reports. Regular members see only their own reports. Members with `MANAGE_REPORTS` permission will see all submitted reports. Reports can be filtered by status. By default filters open and acknowledged reports. Returns a list ordered by most recently updated. tags: [reports] parameters: - $ref: "#/components/parameters/PaginationQuery" - $ref: "#/components/parameters/ReportStatusQuery" - $ref: "#/components/parameters/ReportKindQuery" responses: default: { $ref: "#/components/responses/InternalServerError" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/ReportListOK" } /reports/{report_id}: patch: operationId: ReportUpdate description: | Update a report's status and optionally assign handler. Requires the `MANAGE_REPORTS` permission to set the status to anything other than closed. In other words, regular members can only close their own reports while "moderators" can acknowledge, assign and resolve reports. tags: [reports] parameters: [$ref: "#/components/parameters/ReportIDParam"] requestBody: { $ref: "#/components/requestBodies/ReportUpdate" } responses: default: { $ref: "#/components/responses/InternalServerError" } "400": { $ref: "#/components/responses/BadRequest" } "401": { $ref: "#/components/responses/Unauthorised" } "403": { $ref: "#/components/responses/Forbidden" } "404": { $ref: "#/components/responses/NotFound" } "200": { $ref: "#/components/responses/ReportUpdateOK" } # # .d888 d8b 888 # d88P" Y8P 888 # 888 888 # 88888b. 888d888 .d88b. 888888 888 888 .d88b. .d8888b # 888 "88b 888P" d88""88b 888 888 888 d8P Y8b 88K # 888 888 888 888 888 888 888 888 88888888 "Y8888b. # 888 d88P 888 Y88..88P 888 888 888 Y8b. X88 # 88888P" 888 "Y88P" 888 888 888 "Y8888 88888P' # 888 # 888 # 888 # /profiles: get: operationId: ProfileList description: Query and search profiles. tags: [profiles] parameters: - $ref: "#/components/parameters/SearchQuery" - $ref: "#/components/parameters/PaginationQuery" responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/ProfileListOK" } /profiles/{account_handle}: get: operationId: ProfileGet description: Get a public profile by ID. tags: [profiles] parameters: [$ref: "#/components/parameters/AccountHandleParam"] responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/ProfileGetOK" } "304": { $ref: "#/components/responses/NotModified" } /profiles/{account_handle}/followers: get: operationId: ProfileFollowersGet description: Get the followers and following details for a profile. tags: [profiles] parameters: - $ref: "#/components/parameters/PaginationQuery" - $ref: "#/components/parameters/AccountHandleParam" responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/ProfileFollowersGetOK" } put: operationId: ProfileFollowersAdd description: Follow the specified profile as the authenticated account. tags: [profiles] parameters: [$ref: "#/components/parameters/AccountHandleParam"] responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { description: OK } delete: operationId: ProfileFollowersRemove description: Unfollow the specified profile as the authenticated account. tags: [profiles] parameters: [$ref: "#/components/parameters/AccountHandleParam"] responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { description: OK } /profiles/{account_handle}/following: get: operationId: ProfileFollowingGet description: Get the profiles that this account is following. tags: [profiles] parameters: - $ref: "#/components/parameters/PaginationQuery" - $ref: "#/components/parameters/AccountHandleParam" responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/ProfileFollowingGetOK" } "304": { $ref: "#/components/responses/NotModified" } # # 888 d8b # 888 Y8P # 888 # .d8888b 8888b. 888888 .d88b. .d88b. .d88b. 888d888 888 .d88b. .d8888b # d88P" "88b 888 d8P Y8b d88P"88b d88""88b 888P" 888 d8P Y8b 88K # 888 .d888888 888 88888888 888 888 888 888 888 888 88888888 "Y8888b. # Y88b. 888 888 Y88b. Y8b. Y88b 888 Y88..88P 888 888 Y8b. X88 # "Y8888P "Y888888 "Y888 "Y8888 "Y88888 "Y88P" 888 888 "Y8888 88888P' # 888 # Y8b d88P # "Y88P" # /categories: post: operationId: CategoryCreate description: Create a category for organising posts. tags: [categories] requestBody: { $ref: "#/components/requestBodies/CategoryCreate" } responses: default: { $ref: "#/components/responses/InternalServerError" } "400": { $ref: "#/components/responses/BadRequest" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/CategoryCreateOK" } get: operationId: CategoryList description: Get a list of all categories on the site. tags: [categories] responses: default: { $ref: "#/components/responses/InternalServerError" } "200": { $ref: "#/components/responses/CategoryListOK" } /categories/{category_slug}: get: operationId: CategoryGet description: Get information about a category. tags: [categories] parameters: [{ $ref: "#/components/parameters/CategorySlugParam" }] responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "200": { $ref: "#/components/responses/CategoryGetOK" } patch: operationId: CategoryUpdate description: Update a category's information. tags: [categories] parameters: [$ref: "#/components/parameters/CategorySlugParam"] requestBody: { $ref: "#/components/requestBodies/CategoryUpdate" } responses: default: { $ref: "#/components/responses/InternalServerError" } "400": { $ref: "#/components/responses/BadRequest" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/CategoryUpdateOK" } delete: operationId: CategoryDelete description: Delete a category. All posts in this category will be moved to the specified target category. tags: [categories] parameters: [$ref: "#/components/parameters/CategorySlugParam"] requestBody: { $ref: "#/components/requestBodies/CategoryDelete" } responses: default: { $ref: "#/components/responses/InternalServerError" } "400": { $ref: "#/components/responses/BadRequest" } "401": { $ref: "#/components/responses/Unauthorised" } "404": { $ref: "#/components/responses/NotFound" } "200": { $ref: "#/components/responses/CategoryDeleteOK" } /categories/{category_slug}/position: patch: operationId: CategoryUpdatePosition description: | Update the category's position in the tree. You may change the parent using `parent`, and/or reposition the category among its siblings using either `before` or `after`. Use this operation for drag-and-drop interfaces. tags: [categories] parameters: [$ref: "#/components/parameters/CategorySlugParam"] requestBody: { $ref: "#/components/requestBodies/CategoryUpdatePosition" } responses: default: { $ref: "#/components/responses/InternalServerError" } "400": { $ref: "#/components/responses/BadRequest" } "401": { $ref: "#/components/responses/Unauthorised" } "404": { $ref: "#/components/responses/NotFound" } "200": { $ref: "#/components/responses/CategoryListOK" } # # 888 # 888 # 888 # 888888 8888b. .d88b. .d8888b # 888 "88b d88P"88b 88K # 888 .d888888 888 888 "Y8888b. # Y88b. 888 888 Y88b 888 X88 # "Y888 "Y888888 "Y88888 88888P' # 888 # Y8b d88P # "Y88P" # /tags: get: operationId: TagList description: Get a list of all tags on the site. tags: [tags] parameters: [$ref: "#/components/parameters/SearchQuery"] responses: default: { $ref: "#/components/responses/InternalServerError" } "200": { $ref: "#/components/responses/TagListOK" } /tags/{tag_name}: get: operationId: TagGet description: Get information about a tag. tags: [tags] parameters: [{ $ref: "#/components/parameters/TagNameParam" }] responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "200": { $ref: "#/components/responses/TagGetOK" } # # 888 888 888 # 888 888 888 # 888 888 888 # 888888 88888b. 888d888 .d88b. 8888b. .d88888 .d8888b # 888 888 "88b 888P" d8P Y8b "88b d88" 888 88K # 888 888 888 888 88888888 .d888888 888 888 "Y8888b. # Y88b. 888 888 888 Y8b. 888 888 Y88b 888 X88 # "Y888 888 888 888 "Y8888 "Y888888 "Y88888 88888P' # /threads: post: operationId: ThreadCreate description: Create a new thread within the specified category. tags: [threads] requestBody: { $ref: "#/components/requestBodies/ThreadCreate" } responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/ThreadCreateOK" } get: operationId: ThreadList description: Get a list of all threads. tags: [threads] parameters: - $ref: "#/components/parameters/SearchQuery" - $ref: "#/components/parameters/PaginationQuery" - name: author description: Show only results creeated by this user. required: false in: query schema: { $ref: "#/components/schemas/AccountHandle" } - $ref: "#/components/parameters/VisibilityParam" - name: tags description: Show only results with these tags required: false in: query schema: { $ref: "#/components/schemas/TagListIDs" } - $ref: "#/components/parameters/CategorySlugListQuery" responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/ThreadListOK" } /threads/{thread_mark}: get: operationId: ThreadGet summary: Get information about a thread and the posts within the thread. description: | Get information about a thread such as its title, author, when it was created as well as a list of the posts within the thread. tags: [threads] parameters: - $ref: "#/components/parameters/ThreadMarkParam" - $ref: "#/components/parameters/PaginationQuery" responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/ThreadGet" } "304": { $ref: "#/components/responses/NotModified" } patch: operationId: ThreadUpdate description: Publish changes to a thread. tags: [threads] parameters: [$ref: "#/components/parameters/ThreadMarkParam"] requestBody: { $ref: "#/components/requestBodies/ThreadUpdate" } responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/ThreadUpdateOK" } delete: operationId: ThreadDelete description: Archive a thread using soft-delete. tags: [threads] parameters: [$ref: "#/components/parameters/ThreadMarkParam"] responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { description: OK } # # 888 d8b # 888 Y8P # 888 # 888d888 .d88b. 88888b. 888 888 .d88b. .d8888b # 888P" d8P Y8b 888 "88b 888 888 d8P Y8b 88K # 888 88888888 888 888 888 888 88888888 "Y8888b. # 888 Y8b. 888 d88P 888 888 Y8b. X88 # 888 "Y8888 88888P" 888 888 "Y8888 88888P' # 888 # 888 # 888 # /threads/{thread_mark}/replies: post: operationId: ReplyCreate description: Create a new post within a thread. tags: [replies] parameters: [$ref: "#/components/parameters/ThreadMarkParam"] requestBody: { $ref: "#/components/requestBodies/ReplyCreate" } responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/ReplyCreateOK" } # # 888 # 888 # 888 # 88888b. .d88b. .d8888b 888888 .d8888b # 888 "88b d88""88b 88K 888 88K # 888 888 888 888 "Y8888b. 888 "Y8888b. # 888 d88P Y88..88P X88 Y88b. X88 # 88888P" "Y88P" 88888P' "Y888 88888P' # 888 # 888 # 888 # /posts/{post_id}: patch: operationId: PostUpdate description: Publish changes to a single post. tags: [posts] parameters: [$ref: "#/components/parameters/PostIDParam"] requestBody: { $ref: "#/components/requestBodies/PostUpdate" } responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/PostUpdateOK" } delete: operationId: PostDelete description: Archive a post using soft-delete. tags: [posts] parameters: [$ref: "#/components/parameters/PostIDParam"] responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { description: OK } /posts/{post_id}/reacts: put: operationId: PostReactAdd description: Add a reaction to a post. tags: [posts] parameters: [$ref: "#/components/parameters/PostIDParam"] requestBody: { $ref: "#/components/requestBodies/PostReactAdd" } responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/PostReactAddOK" } /posts/{post_id}/reacts/{react_id}: delete: operationId: PostReactRemove description: Remove a reaction from a post. tags: [posts] parameters: - $ref: "#/components/parameters/PostIDParam" - $ref: "#/components/parameters/ReactIDParam" responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { description: OK } # # 888 # 888 # 888 # 8888b. .d8888b .d8888b .d88b. 888888 .d8888b # "88b 88K 88K d8P Y8b 888 88K # .d888888 "Y8888b. "Y8888b. 88888888 888 "Y8888b. # 888 888 X88 X88 Y8b. Y88b. X88 # "Y888888 88888P' 88888P' "Y8888 "Y888 88888P' # /assets: post: operationId: AssetUpload description: Upload and process a media file. tags: [assets] requestBody: { $ref: "#/components/requestBodies/AssetUpload" } parameters: - $ref: "#/components/parameters/ContentLength" - $ref: "#/components/parameters/AssetNameQuery" - $ref: "#/components/parameters/ParentAssetIDQuery" responses: default: { $ref: "#/components/responses/InternalServerError" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/AssetUploadOK" } /assets/{asset_filename}: get: operationId: AssetGet description: Download an asset by its ID. tags: [assets] parameters: [$ref: "#/components/parameters/AssetPathParam"] responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/AssetGetOK" } # # 888 d8b 888 # 888 Y8P 888 # 888 888 # 888 888 888 888 .d88b. .d8888b # 888 888 888 .88P d8P Y8b 88K # 888 888 888888K 88888888 "Y8888b. # 888 888 888 "88b Y8b. X88 # 888 888 888 888 "Y8888 88888P' # /likes/posts/{post_id}: get: operationId: LikePostGet description: Retreives all likes for the given post. Not paginated (yet.) tags: [likes] parameters: - $ref: "#/components/parameters/PostIDParam" responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/LikePostGetOK" } put: operationId: LikePostAdd description: | Add a like/vote to a post. A "like" is pretty much what you'd expect for any modern social platform, it will inform the feed algorithm and the account's recommendations as well as listing the post on their profile. Idempotent operation where repeated use will do nothing. tags: [likes] parameters: - $ref: "#/components/parameters/PostIDParam" responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { description: OK } delete: operationId: LikePostRemove description: | Removes a like/vote from the authenticated account for the post. It will perform the inverse of any changes to the account's algorithm. Also is idempotent, so repeated use will do nothing after being actioned once. tags: [likes] parameters: - $ref: "#/components/parameters/PostIDParam" responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { description: OK } /likes/profiles/{account_handle}: get: operationId: LikeProfileGet description: Retreives all the likes that the given profile has given. tags: [likes] parameters: - $ref: "#/components/parameters/AccountHandleParam" - $ref: "#/components/parameters/PaginationQuery" responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/LikeProfileGetOK" } # # 888 888 888 d8b # 888 888 888 Y8P # 888 888 888 # .d8888b .d88b. 888 888 .d88b. .d8888b 888888 888 .d88b. 88888b. .d8888b # d88P" d88""88b 888 888 d8P Y8b d88P" 888 888 d88""88b 888 "88b 88K # 888 888 888 888 888 88888888 888 888 888 888 888 888 888 "Y8888b. # Y88b. Y88..88P 888 888 Y8b. Y88b. Y88b. 888 Y88..88P 888 888 X88 # "Y8888P "Y88P" 888 888 "Y8888 "Y8888P "Y888 888 "Y88P" 888 888 88888P' # /collections: post: operationId: CollectionCreate description: | Create a collection for curating posts under the authenticated account. tags: [collections] requestBody: { $ref: "#/components/requestBodies/CollectionCreate" } responses: default: { $ref: "#/components/responses/InternalServerError" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/CollectionCreateOK" } get: operationId: CollectionList description: List all collections using the filtering options. tags: [collections] parameters: - { $ref: "#/components/parameters/AccountHandleQueryParam" } - { $ref: "#/components/parameters/CollectionHasItemQueryParam" } responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "200": { $ref: "#/components/responses/CollectionListOK" } /collections/{collection_mark}: get: operationId: CollectionGet description: | Get a collection by its ID. Collections can be public or private so the response will depend on which account is making the request and if the target collection is public, private, owned or not owned by the account. tags: [collections] parameters: [$ref: "#/components/parameters/CollectionMarkParam"] responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/CollectionGetOK" } patch: operationId: CollectionUpdate description: Update a collection owned by the authenticated account. tags: [collections] parameters: [$ref: "#/components/parameters/CollectionMarkParam"] requestBody: { $ref: "#/components/requestBodies/CollectionUpdate" } responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/CollectionUpdateOK" } delete: operationId: CollectionDelete description: Delete a collection owned by the authenticated account. tags: [collections] parameters: [$ref: "#/components/parameters/CollectionMarkParam"] responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { description: OK } /collections/{collection_mark}/posts/{post_id}: put: operationId: CollectionAddPost description: | Add a post to a collection. The collection must be owned by the account making the request. The post can be any published post of any kind. tags: [collections] parameters: - $ref: "#/components/parameters/CollectionMarkParam" - $ref: "#/components/parameters/PostIDParam" responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/CollectionAddPostOK" } delete: operationId: CollectionRemovePost description: | Remove a post from a collection. The collection must be owned by the account making the request. tags: [collections] parameters: - $ref: "#/components/parameters/CollectionMarkParam" - $ref: "#/components/parameters/PostIDParam" responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/CollectionRemovePostOK" } /collections/{collection_mark}/nodes/{node_id}: put: operationId: CollectionAddNode description: | Add a node to a collection. The collection must be owned by the account making the request. The node can be any published node or any node not published but owned by the collection owner. tags: [collections] parameters: - $ref: "#/components/parameters/CollectionMarkParam" - $ref: "#/components/parameters/NodeIDParam" responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/CollectionAddNodeOK" } delete: operationId: CollectionRemoveNode description: | Remove a node from a collection. The collection must be owned by the account making the request. tags: [collections] parameters: - $ref: "#/components/parameters/CollectionMarkParam" - $ref: "#/components/parameters/NodeIDParam" responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/CollectionRemoveNodeOK" } # # 888 # 888 # 888 # 88888b. .d88b. .d88888 .d88b. .d8888b # 888 "88b d88""88b d88" 888 d8P Y8b 88K # 888 888 888 888 888 888 88888888 "Y8888b. # 888 888 Y88..88P Y88b 888 Y8b. X88 # 888 888 "Y88P" "Y88888 "Y8888 88888P' # /nodes: post: operationId: NodeCreate description: | Create a node for curating structured knowledge together. tags: [nodes] requestBody: { $ref: "#/components/requestBodies/NodeCreate" } responses: default: { $ref: "#/components/responses/InternalServerError" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/NodeCreateOK" } get: operationId: NodeList description: | List nodes using the given filters. Can be used to get a full tree. tags: [nodes] parameters: - $ref: "#/components/parameters/SearchQuery" - $ref: "#/components/parameters/PaginationQuery" - name: node_id description: List this node and all child nodes. required: false in: query schema: { $ref: "#/components/schemas/Identifier" } - name: author description: Show only results owned by this account. required: false in: query schema: { $ref: "#/components/schemas/AccountHandle" } - $ref: "#/components/parameters/VisibilityParam" - $ref: "#/components/parameters/TreeDepthParam" - $ref: "#/components/parameters/NodeListFormatParam" responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "200": { $ref: "#/components/responses/NodeListOK" } /nodes/{node_slug}: get: operationId: NodeGet description: Get a node by its URL slug. tags: [nodes] parameters: - $ref: "#/components/parameters/NodeSlugParam" - $ref: "#/components/parameters/NodeChildrenSortParam" - $ref: "#/components/parameters/PaginationQuery" responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/NodeGetOK" } patch: operationId: NodeUpdate description: Update a node. tags: [nodes] parameters: - $ref: "#/components/parameters/NodeSlugParam" requestBody: { $ref: "#/components/requestBodies/NodeUpdate" } responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/NodeUpdateOK" } delete: operationId: NodeDelete description: Delete a node and move all children to its parent or root. tags: [nodes] parameters: - $ref: "#/components/parameters/NodeSlugParam" - $ref: "#/components/parameters/TargetNodeSlugQuery" responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/NodeDeleteOK" } /nodes/{node_slug}/title: post: operationId: NodeGenerateTitle description: | Generate a proposed title for the specified node. Will not actually mutate the specified node, instead will return a proposal based on the output from a language model call. tags: [nodes] parameters: [$ref: "#/components/parameters/NodeSlugParam"] requestBody: { $ref: "#/components/requestBodies/NodeGenerateTitle" } responses: default: { $ref: "#/components/responses/InternalServerError" } "501": { $ref: "#/components/responses/NotImplemented" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "400": { $ref: "#/components/responses/BadRequest" } "200": { $ref: "#/components/responses/NodeGenerateTitleOK" } /nodes/{node_slug}/tags: post: operationId: NodeGenerateTags description: | Generate proposed tags for the specified node. Will not actually mutate the specified node, instead will return a proposal based on the output from a language model call. tags: [nodes] parameters: [$ref: "#/components/parameters/NodeSlugParam"] requestBody: { $ref: "#/components/requestBodies/NodeGenerateTags" } responses: default: { $ref: "#/components/responses/InternalServerError" } "501": { $ref: "#/components/responses/NotImplemented" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "400": { $ref: "#/components/responses/BadRequest" } "200": { $ref: "#/components/responses/NodeGenerateTagsOK" } /nodes/{node_slug}/content: post: operationId: NodeGenerateContent description: | Generate proposed content for the specified node. Will not actually mutate the specified node, instead will return a proposal based on the output from a language model call. tags: [nodes] parameters: [$ref: "#/components/parameters/NodeSlugParam"] requestBody: { $ref: "#/components/requestBodies/NodeGenerateContent" } responses: default: { $ref: "#/components/responses/InternalServerError" } "501": { $ref: "#/components/responses/NotImplemented" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "400": { $ref: "#/components/responses/BadRequest" } "200": { $ref: "#/components/responses/NodeGenerateContentOK" } /nodes/{node_slug}/children: get: operationId: NodeListChildren description: | Get all the children of a given node using the provided filters and page parameters. This can be used for rendering the child nodes of the given node as an interactive table where properties can be used as columns. tags: [nodes] parameters: - $ref: "#/components/parameters/NodeSlugParam" - $ref: "#/components/parameters/NodeChildrenSortParam" - $ref: "#/components/parameters/PaginationQuery" - $ref: "#/components/parameters/SearchQuery" - $ref: "#/components/parameters/TagNameListQueryParam" responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/NodeListOK" } /nodes/{node_slug}/children/property-schema: patch: operationId: NodeUpdateChildrenPropertySchema description: | Updates the property schema of the children of this node. All children of a node use the same schema for properties resulting in a table-like structure and behaviour. See also: NodeUpdatePropertySchema tags: [nodes] parameters: [$ref: "#/components/parameters/NodeSlugParam"] requestBody: { $ref: "#/components/requestBodies/NodeUpdatePropertySchema" } responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": $ref: "#/components/responses/NodeUpdatePropertySchemaOK" /nodes/{node_slug}/property-schema: patch: operationId: NodeUpdatePropertySchema description: | Updates the property schema of this node and its siblings. All children of a node use the same schema for properties resulting in a table-like structure and behaviour. Property schemas are loosely structured and can automatically cast their values sometimes. A failed cast will not change data and instead just yield an empty value when reading however changing the schema back to the original type (or a type compatible with what the type was before changing) will retain the original data upon next read. This permits clients to undo changes to the schema easily while allowing quick schema changes without the need to remove or update values before. tags: [nodes] parameters: [$ref: "#/components/parameters/NodeSlugParam"] requestBody: { $ref: "#/components/requestBodies/NodeUpdatePropertySchema" } responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": $ref: "#/components/responses/NodeUpdatePropertySchemaOK" /nodes/{node_slug}/properties: patch: operationId: NodeUpdateProperties description: | Update the properties of a node. New schema fields will result in the schema of the node being updated before values are assigned. This will also propagate to all sibling nodes as they all share the same schema. tags: [nodes] parameters: [$ref: "#/components/parameters/NodeSlugParam"] requestBody: { $ref: "#/components/requestBodies/NodeUpdateProperties" } responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "400": { $ref: "#/components/responses/BadRequest" } "200": { $ref: "#/components/responses/NodeUpdatePropertiesOK" } /nodes/{node_slug}/visibility: patch: operationId: NodeUpdateVisibility description: | Update the visibility of a node. When changed, this may trigger other operations such as notifications/newsletters. Changing the visibility of anything to "published" is often accompanied by some other side effects. tags: [nodes] parameters: [$ref: "#/components/parameters/NodeSlugParam"] requestBody: { $ref: "#/components/requestBodies/VisibilityUpdate" } responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/NodeUpdateOK" } /nodes/{node_slug}/assets/{asset_id}: put: operationId: NodeAddAsset description: Add an asset to a node. tags: [nodes] parameters: - $ref: "#/components/parameters/NodeSlugParam" - $ref: "#/components/parameters/AssetIDParam" responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/NodeUpdateOK" } delete: operationId: NodeRemoveAsset description: Remove an asset from a node. tags: [nodes] parameters: - $ref: "#/components/parameters/NodeSlugParam" - $ref: "#/components/parameters/AssetIDParam" responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/NodeUpdateOK" } /nodes/{node_slug}/nodes/{node_slug_child}: put: operationId: NodeAddNode description: Set a node's parent to the specified node tags: [nodes] parameters: - $ref: "#/components/parameters/NodeSlugParam" - $ref: "#/components/parameters/NodeSlugChildParam" responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/NodeAddChildOK" } delete: operationId: NodeRemoveNode description: | Remove a node from its parent node and back to the top level. tags: [nodes] parameters: - $ref: "#/components/parameters/NodeSlugParam" - $ref: "#/components/parameters/NodeSlugChildParam" responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/NodeRemoveChildOK" } /nodes/{node_slug}/position: patch: operationId: NodeUpdatePosition description: | Update the node's position in the tree, which optionally allows for changing the node's parent either to another node or to `null` which severs the parent and moves the node to the root. This endpoint also allows for moving the node's sort position within either its current parent, or when moving it to a new parent. Use this operation for a draggable tree interface or a table interface. tags: [nodes] parameters: [$ref: "#/components/parameters/NodeSlugParam"] requestBody: { $ref: "#/components/requestBodies/NodeUpdatePosition" } responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "400": { $ref: "#/components/responses/BadRequest" } "200": { $ref: "#/components/responses/NodeUpdateOK" } # # 888 d8b 888 # 888 Y8P 888 # 888 888 # 888 888 88888b. 888 888 .d8888b # 888 888 888 "88b 888 .88P 88K # 888 888 888 888 888888K "Y8888b. # 888 888 888 888 888 "88b X88 # 888 888 888 888 888 888 88888P' # /links: post: operationId: LinkCreate description: | Add a link to the community bookmarks. This will also scrape the content at the site the link points to, if possible. If the submitted link is an invalid link for whatever reason (invalid URL structure or page is dead) then the API will fail. The metadata for the link is indexed on success. If the submitted link already exists it will be an idempotent operation, unless the body contains additional metadata. In these cases, the link's metadata will be updated with the new metadata and the URL is unchanged. When a link is submitted, it is first "cleaned" to remove any fragments. tags: [links] requestBody: { $ref: "#/components/requestBodies/LinkCreate" } responses: default: { $ref: "#/components/responses/InternalServerError" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/LinkCreateOK" } get: operationId: LinkList description: List all links using the filtering options. tags: [links] parameters: - $ref: "#/components/parameters/SearchQuery" - $ref: "#/components/parameters/PaginationQuery" responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "200": { $ref: "#/components/responses/LinkListOK" } /links/{link_slug}: get: operationId: LinkGet description: | Get the details for a specific link. Such as where it's been posted, which resources it's linked to and how many times it's been opened. tags: [links] parameters: [{ $ref: "#/components/parameters/LinkSlugParam" }] responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "200": { $ref: "#/components/responses/LinkGetOK" } # # 888 888 888 # 888 888 888 # 888 888 888 # .d88888 8888b. 888888 8888b. .d88b. 888d888 8888b. 88888b. 88888b. # d88" 888 "88b 888 "88b d88P"88b 888P" "88b 888 "88b 888 "88b # 888 888 .d888888 888 .d888888 888 888 888 .d888888 888 888 888 888 # Y88b 888 888 888 Y88b. 888 888 Y88b 888 888 888 888 888 d88P 888 888 # "Y88888 "Y888888 "Y888 "Y888888 "Y88888 888 "Y888888 88888P" 888 888 # 888 888 # Y8b d88P 888 # "Y88P" 888 # /datagraph: get: operationId: DatagraphSearch description: Query and search content. tags: [datagraph] parameters: - $ref: "#/components/parameters/RequiredSearchQuery" - $ref: "#/components/parameters/DatagraphKindQuery" - $ref: "#/components/parameters/PaginationQuery" responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/DatagraphSearchOK" } /datagraph/ask: get: operationId: DatagraphAsk description: Ask questions about the community's content. tags: [datagraph] parameters: - $ref: "#/components/parameters/RequiredSearchQuery" - $ref: "#/components/parameters/ParentQuestionID" responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/DatagraphAskOK" } # # 888 # 888 # 888 # .d88b. 888 888 .d88b. 88888b. 888888 .d8888b # d8P Y8b 888 888 d8P Y8b 888 "88b 888 88K # 88888888 Y88 88P 88888888 888 888 888 "Y8888b. # Y8b. Y8bd8P Y8b. 888 888 Y88b. X88 # "Y8888 Y88P "Y8888 888 888 "Y888 88888P' # /events: get: operationId: EventList description: List all events using the filtering options. tags: [events] parameters: - $ref: "#/components/parameters/SearchQuery" - $ref: "#/components/parameters/PaginationQuery" responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "200": { $ref: "#/components/responses/EventListOK" } post: operationId: EventCreate description: | Create a new event. When an event is created, a thread is also created which provides the means for discussion via the thread and reply APIs. tags: [events] requestBody: { $ref: "#/components/requestBodies/EventCreate" } responses: default: { $ref: "#/components/responses/InternalServerError" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/EventCreateOK" } /events/{event_mark}: get: operationId: EventGet description: Get an event by its ID. tags: [events] parameters: [$ref: "#/components/parameters/EventMarkParam"] responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/EventGetOK" } patch: operationId: EventUpdate description: | Update an event. If the content field is updated, this is stored on the thread associated with the event, rather than the event itself. It's possible to update that thread directly using `threads` operations. tags: [events] parameters: [$ref: "#/components/parameters/EventMarkParam"] requestBody: { $ref: "#/components/requestBodies/EventUpdate" } responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { $ref: "#/components/responses/EventUpdateOK" } delete: operationId: EventDelete description: Delete an event. tags: [events] parameters: [$ref: "#/components/parameters/EventMarkParam"] responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { description: OK } /events/{event_mark}/participants/{account_id}: put: operationId: EventParticipantUpdate description: | Add a participant to an event or change an existing participant's state. If the requesting account is an admin or holds MANAGE_EVENTS permission, they can change the participation properties of any account. Otherwise, they can only change their own participation properties. For non-managing members (i.e. not an admin and not a host) this will follow a stricter state machine for the participation status. If the participation status is not set (no participation record is present) or set to "declined", the member may only set their status to "requested" if the event policy is set to "invite_only". Otherwise, they may set it to "attending". If the member is already set to one of these states, they may change it to "declined". A non-managing member cannot change their role and the default is "attendee", only managing members can change participant roles. If the event participation policy is set to "invite_only" then members can only set their status to "requested" or delete their participation. If the event participation policy is set to "closed", it's a no-op. Requests to this resource are idempotent given identical request bodies. It acts as a create-or-update action as participation is account-unique. tags: [events] parameters: - $ref: "#/components/parameters/EventMarkParam" - $ref: "#/components/parameters/AccountIDParam" requestBody: { $ref: "#/components/requestBodies/EventParticipantUpdate" } responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { description: OK } delete: operationId: EventParticipantRemove description: | Remove a participant from an event. Same rules as EventParticipantUpdate where non-managing members may only remove themselves. Not soft-delete. tags: [events] parameters: - $ref: "#/components/parameters/EventMarkParam" - $ref: "#/components/parameters/AccountIDParam" responses: default: { $ref: "#/components/responses/InternalServerError" } "404": { $ref: "#/components/responses/NotFound" } "401": { $ref: "#/components/responses/Unauthorised" } "200": { description: OK } components: # # 8888888b. d8888 8888888b. d8888 888b d888 8888888888 88888888888 8888888888 8888888b. .d8888b. # 888 Y88b d88888 888 Y88b d88888 8888b d8888 888 888 888 888 Y88b d88P Y88b # 888 888 d88P888 888 888 d88P888 88888b.d88888 888 888 888 888 888 Y88b. # 888 d88P d88P 888 888 d88P d88P 888 888Y88888P888 8888888 888 8888888 888 d88P "Y888b. # 8888888P" d88P 888 8888888P" d88P 888 888 Y888P 888 888 888 888 8888888P" "Y88b. # 888 d88P 888 888 T88b d88P 888 888 Y8P 888 888 888 888 888 T88b "888 # 888 d8888888888 888 T88b d8888888888 888 " 888 888 888 888 888 T88b Y88b d88P # 888 d88P 888 888 T88b d88P 888 888 888 8888888888 888 8888888888 888 T88b "Y8888P" # parameters: IconSize: description: Icon sizes. example: "512x512" name: icon_size in: path required: true schema: type: string enum: - 512x512 # Generic big icon - 32x32 # Generic small icon - 180x180 # iOS high DPI - 120x120 # iOS low DPI - 167x167 # iPad OS - 152x152 # iPad Mini ContentLength: description: Body content length in bytes. name: Content-Length in: header required: true schema: type: integer x-go-type: int64 RoleIDParam: description: Role ID in: path name: role_id required: true schema: $ref: "#/components/schemas/Identifier" AccessKeyIDParam: description: Access key ID. in: path name: access_key_id required: true schema: $ref: "#/components/schemas/Identifier" AccountIDParam: description: Account ID. name: account_id in: path required: true schema: $ref: "#/components/schemas/Identifier" AccountHandleParam: description: Account handle. example: southclaws name: account_handle in: path required: true schema: $ref: "#/components/schemas/AccountHandle" AccountHandleQueryParam: description: Account handle. example: southclaws name: account_handle in: query required: false schema: $ref: "#/components/schemas/AccountHandle" AccountIDQueryParam: description: Account ID. name: account_id in: query required: false schema: $ref: "#/components/schemas/Identifier" EmailAddressIDParam: description: An email address ID associated with the requesting account. name: email_address_id in: path required: true schema: $ref: "#/components/schemas/Identifier" InvitationIDParam: description: Unique invitation ID. name: invitation_id in: path required: true schema: $ref: "#/components/schemas/Identifier" InvitationIDQueryParam: description: Unique invitation ID. name: invitation_id in: query required: false schema: $ref: "#/components/schemas/Identifier" NotificationStatusQuery: description: Notification status. name: status in: query required: false schema: $ref: "#/components/schemas/NotificationStatusList" NotificationIDParam: description: Unique notification ID. name: notification_id in: path required: true schema: $ref: "#/components/schemas/Identifier" ReportIDParam: description: Unique report ID. name: report_id in: path required: true schema: $ref: "#/components/schemas/Identifier" ReportStatusQuery: description: Report status filter. name: status in: query required: false schema: $ref: "#/components/schemas/ReportStatus" ReportKindQuery: description: Report target kind filter. name: kind in: query required: false schema: type: string ThreadMarkParam: description: Thread unique and permanent identifier. name: thread_mark in: path required: true schema: $ref: "#/components/schemas/ThreadMark" PostIDParam: description: Unique post ID. name: post_id in: path required: true schema: $ref: "#/components/schemas/Identifier" ReactIDParam: description: Unique react ID. name: react_id in: path required: true schema: $ref: "#/components/schemas/Identifier" NodeIDParam: description: Unique node ID. name: node_id in: path required: true schema: $ref: "#/components/schemas/Identifier" OAuthProvider: description: The identifier for an OAuth2 provider such as "twitter". name: oauth_provider in: path required: true example: twitter schema: type: string SearchQuery: description: Search query string. name: q in: query required: false allowEmptyValue: true schema: type: string minLength: 0 RequiredSearchQuery: description: Search query string. name: q in: query required: true allowEmptyValue: true schema: type: string minLength: 0 ParentQuestionID: description: If a follow-up question, the parent question ID. name: parent_question_id in: query required: false allowEmptyValue: true schema: type: string DatagraphKindQuery: description: Datagraph item kind query. name: kind in: query required: false allowEmptyValue: true explode: true schema: type: array items: { $ref: "#/components/schemas/DatagraphItemKind" } PaginationQuery: description: Pagination query parameters. name: page in: query required: false schema: type: string AssetPathParam: description: Asset ID. name: asset_filename in: path required: true schema: type: string AssetIDParam: description: Asset ID. name: asset_id in: path required: true schema: type: string ParentAssetIDQuery: description: | For uploading new versions of an existing asset, set this parameter to the asset ID of the parent asset. This must be an ID and not a filename. This feature is used for situations where you want to replace an asset in its usage context, but retain the original with a way to reference it for features such as editable/croppable images or file version history. name: parent_asset_id in: query required: false schema: type: string AssetNameQuery: description: The client-provided file name for the asset. name: filename in: query required: false schema: type: string CategorySlugParam: description: Unique category URL slug. name: category_slug in: path required: true schema: type: string CategorySlugListQuery: name: categories description: | Category slugs to filter by. Multiple instances of this parameter can be used to filter by many categories. If not provided, no filtering will be applied and all threads will be returned. If ANY of the provided values is set to the exact value of "null" then only uncategorised threads will be returned. When filtering for uncategorised threads, all other values will be ignored, only the value containing "null" will be considered. required: false in: query schema: $ref: "#/components/schemas/CategorySlugList" TagNameParam: description: Tag name. name: tag_name in: path required: true schema: type: string TagNameListQueryParam: description: Tags to filter by. name: tags in: query required: false schema: { $ref: "#/components/schemas/TagNameList" } CollectionMarkParam: description: | Either: - The unique collection ID. - A string of the form <id>-<slug> name: collection_mark in: path required: true schema: $ref: "#/components/schemas/Mark" CollectionHasItemQueryParam: description: | When specified, will include a field in the response indicating whether or not the specified item is present in the collection. This saves you needing to make two queries to check if an item is in a collection. name: has_item in: query required: false schema: $ref: "#/components/schemas/Identifier" NodeSlugParam: description: Unique node Slug. name: node_slug in: path required: true schema: $ref: "#/components/schemas/Identifier" NodeSlugChildParam: description: Unique node Slug. name: node_slug_child in: path required: true schema: $ref: "#/components/schemas/Identifier" NodeChildrenSortParam: description: | The field (either in schema or in property schema) to sort by. name: children_sort in: query required: false schema: type: string TargetNodeSlugQuery: description: | If set, child nodes will be moved to the target node. If not set, child nodes will be moved to the root. name: target_node in: query required: false schema: type: string LinkSlugParam: description: Unique link Slug. name: link_slug in: path required: true schema: type: string VisibilityParam: name: visibility description: | Filter content with specific visibility values. Note that by default, only published items are returned. When 'draft' is specified, only drafts owned by the requesting account are included. When 'review' is specified, the request will fail if the requesting account does not have the necessary permission to view in-review items. required: false in: query explode: true schema: type: array items: { $ref: "#/components/schemas/Visibility" } TreeDepthParam: name: depth description: | When set to a positive value, the nodes in the response will include all child nodes up to the specified depth. When set to zero, then if the request includes a node ID only that node will be returned, otherwise only top-level (root) nodes will be returned. required: false in: query schema: type: string NodeListFormatParam: name: format description: | List format, either a tree where each item contains a children array or flat where children items contain an ID that references their parent. required: false in: query schema: default: tree type: string enum: [tree, flat] EventMarkParam: description: | Either: - The unique event ID. - The unique event slug. - A string of the form <id>-<slug> name: event_mark in: path required: true schema: $ref: "#/components/schemas/Mark" # # 8888888b. 8888888888 .d88888b. 888 888 8888888888 .d8888b. 88888888888 .d8888b. # 888 Y88b 888 d88P" "Y88b 888 888 888 d88P Y88b 888 d88P Y88b # 888 888 888 888 888 888 888 888 Y88b. 888 Y88b. # 888 d88P 8888888 888 888 888 888 8888888 "Y888b. 888 "Y888b. # 8888888P" 888 888 888 888 888 888 "Y88b. 888 "Y88b. # 888 T88b 888 888 Y8b 888 888 888 888 "888 888 "888 # 888 T88b 888 Y88b.Y8b88P Y88b. .d88P 888 Y88b d88P 888 Y88b d88P # 888 T88b 8888888888 "Y888888" "Y88888P" 8888888888 "Y8888P" 888 "Y8888P" # Y8b # requestBodies: Beacon: content: text/plain: schema: { $ref: "#/components/schemas/BeaconProps" } AdminSettingsUpdate: content: application/json: schema: { $ref: "#/components/schemas/AdminSettingsMutableProps" } RoleCreate: content: application/json: schema: { $ref: "#/components/schemas/RoleInitialProps" } RoleUpdate: content: application/json: schema: { $ref: "#/components/schemas/RoleMutableProps" } AuthPassword: content: application/json: schema: { $ref: "#/components/schemas/AuthPair" } AuthEmailPassword: content: application/json: schema: { $ref: "#/components/schemas/AuthEmailPasswordInitialProps" } AuthEmailPasswordReset: content: application/json: schema: { $ref: "#/components/schemas/AuthEmailPasswordReset" } AuthEmail: content: application/json: schema: { $ref: "#/components/schemas/AuthEmailInitialProps" } AuthEmailVerify: content: application/json: schema: { $ref: "#/components/schemas/AuthEmailVerifyProps" } AuthPasswordCreate: content: application/json: schema: { $ref: "#/components/schemas/AuthPasswordInitialProps" } AuthPasswordUpdate: content: application/json: schema: { $ref: "#/components/schemas/AuthPasswordMutableProps" } AuthPasswordReset: content: application/json: schema: { $ref: "#/components/schemas/AuthPasswordResetProps" } OAuthProviderCallback: content: application/json: schema: { $ref: "#/components/schemas/OAuthCallback" } WebAuthnMakeCredential: content: application/json: schema: { $ref: "#/components/schemas/PublicKeyCredential" } WebAuthnMakeAssertion: content: application/json: schema: { $ref: "#/components/schemas/PublicKeyCredential" } PhoneRequestCode: content: application/json: schema: { $ref: "#/components/schemas/PhoneRequestCodeProps" } PhoneSubmitCode: content: application/json: schema: { $ref: "#/components/schemas/PhoneSubmitCodeProps" } AccessKeyCreate: content: application/json: schema: { $ref: "#/components/schemas/AccessKeyInitialProps" } AccountUpdate: content: application/json: schema: { $ref: "#/components/schemas/AccountMutableProps" } AccountEmailAdd: content: application/json: schema: { $ref: "#/components/schemas/AccountEmailInitialProps" } AccountSetAvatar: content: application/octet-stream: schema: type: string format: binary InvitationCreate: content: application/json: schema: { $ref: "#/components/schemas/InvitationInitialProps" } NotificationUpdate: content: application/json: schema: { $ref: "#/components/schemas/NotificationMutableProps" } ReportCreate: content: application/json: schema: { $ref: "#/components/schemas/ReportInitialProps" } ReportUpdate: content: application/json: schema: { $ref: "#/components/schemas/ReportMutableProps" } CategoryCreate: content: application/json: schema: { $ref: "#/components/schemas/CategoryInitialProps" } CategoryUpdate: content: application/json: schema: { $ref: "#/components/schemas/CategoryMutableProps" } CategoryUpdatePosition: content: application/json: schema: { $ref: "#/components/schemas/CategoryPositionMutableProps" } CategoryDelete: content: application/json: schema: { $ref: "#/components/schemas/CategoryDeleteProps" } ThreadCreate: content: application/json: schema: { $ref: "#/components/schemas/ThreadInitialProps" } ThreadUpdate: content: application/json: schema: { $ref: "#/components/schemas/ThreadMutableProps" } ReplyCreate: description: Create a reply, which is a post within a thread. content: application/json: schema: { $ref: "#/components/schemas/ReplyInitialProps" } PostUpdate: description: Create a post within a thread. content: application/json: schema: { $ref: "#/components/schemas/PostMutableProps" } PostReactAdd: description: Add a reaction to a post. content: application/json: schema: { $ref: "#/components/schemas/ReactInitialProps" } AssetUpload: description: Upload a file. content: application/octet-stream: schema: type: string format: binary CollectionCreate: content: application/json: schema: { $ref: "#/components/schemas/CollectionInitialProps" } CollectionUpdate: content: application/json: schema: { $ref: "#/components/schemas/CollectionMutableProps" } NodeCreate: content: application/json: schema: { $ref: "#/components/schemas/NodeInitialProps" } NodeUpdate: content: application/json: schema: { $ref: "#/components/schemas/NodeMutableProps" } NodeGenerateTitle: content: application/json: schema: { $ref: "#/components/schemas/NodeGenerateTitleRequest" } NodeGenerateTags: content: application/json: schema: { $ref: "#/components/schemas/NodeGenerateTagsRequest" } NodeGenerateContent: content: application/json: schema: { $ref: "#/components/schemas/NodeGenerateContentRequest" } NodeUpdateProperties: content: application/json: schema: { $ref: "#/components/schemas/PropertyMutableProps" } NodeUpdatePropertySchema: content: application/json: schema: type: array items: { $ref: "#/components/schemas/PropertySchemaMutableProps" } NodeUpdatePosition: content: application/json: schema: { $ref: "#/components/schemas/NodePositionMutableProps" } LinkCreate: content: application/json: schema: { $ref: "#/components/schemas/LinkInitialProps" } VisibilityUpdate: content: application/json: schema: { $ref: "#/components/schemas/VisibilityMutationProps" } EventCreate: content: application/json: schema: { $ref: "#/components/schemas/EventInitialProps" } EventUpdate: content: application/json: schema: { $ref: "#/components/schemas/EventMutableProps" } EventParticipantUpdate: content: application/json: schema: { $ref: "#/components/schemas/EventParticipantMutableProps" } # # 8888888b. 8888888888 .d8888b. 8888888b. .d88888b. 888b 888 .d8888b. 8888888888 .d8888b. # 888 Y88b 888 d88P Y88b 888 Y88b d88P" "Y88b 8888b 888 d88P Y88b 888 d88P Y88b # 888 888 888 Y88b. 888 888 888 888 88888b 888 Y88b. 888 Y88b. # 888 d88P 8888888 "Y888b. 888 d88P 888 888 888Y88b 888 "Y888b. 8888888 "Y888b. # 8888888P" 888 "Y88b. 8888888P" 888 888 888 Y88b888 "Y88b. 888 "Y88b. # 888 T88b 888 "888 888 888 888 888 Y88888 "888 888 "888 # 888 T88b 888 Y88b d88P 888 Y88b. .d88P 888 Y8888 Y88b d88P 888 Y88b d88P # 888 T88b 8888888888 "Y8888P" 888 "Y88888P" 888 Y888 "Y8888P" 8888888888 "Y8888P" # responses: NotImplemented: description: Not implemented NotModified: description: Not modified headers: { <<: *cache_response_headers } BadRequest: description: Bad request NotFound: description: Not found Unauthorised: description: Unauthorized Forbidden: description: Forbidden NoContent: description: No content InternalServerError: description: Internal Server Error content: application/json: schema: $ref: "#/components/schemas/APIError" GetInfoOK: description: OK content: application/json: schema: $ref: "#/components/schemas/Info" AdminSettingsUpdateOK: description: OK content: application/json: schema: $ref: "#/components/schemas/AdminSettingsProps" RoleCreateOK: description: OK content: application/json: schema: $ref: "#/components/schemas/Role" RoleListOK: description: OK content: application/json: schema: $ref: "#/components/schemas/RoleListResult" RoleGetOK: description: OK content: application/json: schema: $ref: "#/components/schemas/Role" AuthSuccessOK: description: OK headers: "Set-Cookie": schema: type: string content: application/json: schema: $ref: "#/components/schemas/AuthSuccess" AuthProviderListOK: description: OK content: application/json: schema: type: object required: [providers, mode] properties: providers: { $ref: "#/components/schemas/AuthProviderList" } mode: { $ref: "#/components/schemas/AuthMode" } WebAuthnRequestCredentialOK: description: OK headers: "Set-Cookie": schema: type: string content: application/json: schema: { $ref: "#/components/schemas/WebAuthnPublicKeyCreationOptions" } WebAuthnGetAssertionOK: description: OK headers: "Set-Cookie": schema: type: string content: application/json: schema: $ref: "#/components/schemas/CredentialRequestOptions" AccessKeyCreateOK: description: OK content: application/json: schema: $ref: "#/components/schemas/AccessKeyIssued" AdminAccessKeyListOK: description: OK content: application/json: schema: $ref: "#/components/schemas/OwnedAccessKeyListResult" AccessKeyListOK: description: OK content: application/json: schema: $ref: "#/components/schemas/AccessKeyListResult" AccountGetOK: description: OK headers: { <<: *cache_response_headers } content: application/json: schema: $ref: "#/components/schemas/Account" AccountUpdateOK: description: OK content: application/json: schema: $ref: "#/components/schemas/Account" AccountEmailUpdateOK: description: OK content: application/json: schema: $ref: "#/components/schemas/AccountEmailAddress" AccountAuthProviderListOK: description: OK content: application/json: schema: $ref: "#/components/schemas/AccountAuthMethods" AccountGetAvatar: description: OK headers: { <<: *cache_response_headers } content: image/png: schema: type: string format: binary InvitationListOK: description: OK content: application/json: schema: $ref: "#/components/schemas/InvitationListResult" InvitationCreateOK: description: OK content: application/json: schema: $ref: "#/components/schemas/Invitation" InvitationGetOK: description: OK content: application/json: schema: $ref: "#/components/schemas/Invitation" NotificationListOK: description: OK content: application/json: schema: $ref: "#/components/schemas/NotificationListResult" NotificationUpdateOK: description: OK content: application/json: schema: $ref: "#/components/schemas/Notification" ReportCreateOK: description: OK content: application/json: schema: $ref: "#/components/schemas/Report" ReportListOK: description: OK content: application/json: schema: $ref: "#/components/schemas/ReportListResult" ReportUpdateOK: description: OK content: application/json: schema: $ref: "#/components/schemas/Report" ProfileListOK: description: OK content: application/json: schema: $ref: "#/components/schemas/PublicProfileListResult" ProfileGetOK: description: OK headers: { <<: *cache_response_headers } content: application/json: schema: $ref: "#/components/schemas/PublicProfile" ProfileFollowersGetOK: description: OK content: application/json: schema: $ref: "#/components/schemas/PublicProfileFollowersResult" ProfileFollowingGetOK: description: OK content: application/json: schema: $ref: "#/components/schemas/PublicProfileFollowingResult" CategoryCreateOK: description: OK content: application/json: schema: $ref: "#/components/schemas/Category" CategoryGetOK: description: OK content: application/json: schema: $ref: "#/components/schemas/Category" CategoryUpdateOK: description: OK content: application/json: schema: $ref: "#/components/schemas/Category" CategoryDeleteOK: description: OK content: application/json: schema: $ref: "#/components/schemas/Category" CategoryListOK: description: OK content: application/json: schema: $ref: "#/components/schemas/CategoryListResult" TagListOK: description: OK content: application/json: schema: $ref: "#/components/schemas/TagListResult" TagGetOK: description: OK content: application/json: schema: $ref: "#/components/schemas/Tag" ThreadCreateOK: description: Thread created. content: application/json: schema: $ref: "#/components/schemas/Thread" ThreadUpdateOK: description: Thread updated. content: application/json: schema: $ref: "#/components/schemas/Thread" ThreadListOK: description: List of all threads. headers: { <<: *cache_response_headers } content: application/json: schema: { $ref: "#/components/schemas/ThreadListResult" } ThreadGet: description: The information about a thread and its posts. headers: { <<: *cache_response_headers } content: application/json: schema: { $ref: "#/components/schemas/Thread" } ReplyCreateOK: description: Thread reply created successfully. content: application/json: schema: $ref: "#/components/schemas/Reply" PostUpdateOK: description: Post updated successfully. content: application/json: schema: $ref: "#/components/schemas/Post" PostReactAddOK: description: Post reaction added. content: application/json: schema: $ref: "#/components/schemas/React" AssetUploadOK: description: The new URL of an uploaded file. content: application/json: schema: $ref: "#/components/schemas/Asset" AssetGetOK: description: The new URL of an uploaded file. headers: { <<: *cache_response_headers } content: "*/*": schema: type: string format: binary LikePostGetOK: description: All likes for a post. content: application/json: schema: type: object required: [likes] properties: likes: { $ref: "#/components/schemas/ItemLikeList" } LikeProfileGetOK: description: Likes that an account has given. content: application/json: schema: $ref: "#/components/schemas/ProfileLikeListResult" CollectionCreateOK: description: Collection created. content: application/json: schema: $ref: "#/components/schemas/Collection" CollectionListOK: description: Collection list. content: application/json: schema: type: object required: [collections] properties: collections: { $ref: "#/components/schemas/CollectionList" } CollectionGetOK: description: Collection information and content. content: application/json: schema: $ref: "#/components/schemas/CollectionWithItems" CollectionUpdateOK: description: Collection updated. content: application/json: schema: $ref: "#/components/schemas/Collection" CollectionAddPostOK: description: Collection content added. content: application/json: schema: $ref: "#/components/schemas/CollectionWithItems" CollectionRemovePostOK: description: Collection content added. content: application/json: schema: $ref: "#/components/schemas/CollectionWithItems" CollectionAddNodeOK: description: Collection content added. content: application/json: schema: $ref: "#/components/schemas/CollectionWithItems" CollectionRemoveNodeOK: description: Collection content added. content: application/json: schema: $ref: "#/components/schemas/CollectionWithItems" NodeCreateOK: description: Node created. content: application/json: schema: $ref: "#/components/schemas/Node" NodeListOK: description: Node list. content: application/json: schema: { $ref: "#/components/schemas/NodeListResult" } NodeGetOK: description: Node information and content. content: application/json: schema: $ref: "#/components/schemas/NodeWithChildren" NodeUpdateOK: description: Node updated. content: application/json: schema: $ref: "#/components/schemas/NodeWithChildren" NodeGenerateTitleOK: description: Node title generated. content: application/json: schema: { $ref: "#/components/schemas/NodeGenerateTitleResult" } NodeGenerateTagsOK: description: Node tags generated. content: application/json: schema: { $ref: "#/components/schemas/NodeGenerateTagsResult" } NodeGenerateContentOK: description: Node content generated. content: application/json: schema: { $ref: "#/components/schemas/NodeGenerateContentResult" } NodeUpdatePropertiesOK: description: Node properties updated. content: application/json: schema: type: object required: [properties] properties: properties: $ref: "#/components/schemas/PropertyList" NodeUpdatePropertySchemaOK: description: Node children schema updated. content: application/json: schema: type: object required: [properties] properties: properties: $ref: "#/components/schemas/PropertySchemaList" NodeDeleteOK: description: Node deleted. content: application/json: schema: type: object properties: destination: $ref: "#/components/schemas/Node" NodeAddChildOK: description: Node child added. Returns parent node. content: application/json: schema: $ref: "#/components/schemas/Node" NodeRemoveChildOK: description: Node child removed. Returns parent node. content: application/json: schema: $ref: "#/components/schemas/Node" LinkCreateOK: description: Link indexed content: application/json: schema: $ref: "#/components/schemas/LinkReference" LinkListOK: description: Link list. content: application/json: schema: { $ref: "#/components/schemas/LinkListResult" } LinkGetOK: description: Link data. content: application/json: schema: $ref: "#/components/schemas/Link" DatagraphSearchOK: description: Search results. content: application/json: schema: { $ref: "#/components/schemas/DatagraphSearchResult" } DatagraphAskOK: description: Search results. content: text/event-stream: schema: type: string EventListOK: description: Event list. content: application/json: schema: { $ref: "#/components/schemas/EventListResult" } EventCreateOK: description: Event create. content: application/json: schema: { $ref: "#/components/schemas/Event" } EventGetOK: description: Event get. content: application/json: schema: { $ref: "#/components/schemas/Event" } EventUpdateOK: description: Event update. content: application/json: schema: { $ref: "#/components/schemas/Event" } # # .d8888b. .d8888b. 888 888 8888888888 888b d888 d8888 .d8888b. # d88P Y88b d88P Y88b 888 888 888 8888b d8888 d88888 d88P Y88b # Y88b. 888 888 888 888 888 88888b.d88888 d88P888 Y88b. # "Y888b. 888 8888888888 8888888 888Y88888P888 d88P 888 "Y888b. # "Y88b. 888 888 888 888 888 Y888P 888 d88P 888 "Y88b. # "888 888 888 888 888 888 888 Y8P 888 d88P 888 "888 # Y88b d88P Y88b d88P 888 888 888 888 " 888 d8888888888 Y88b d88P # "Y8888P" "Y8888P" 888 888 8888888888 888 888 d88P 888 "Y8888P" # headers: Cache-Control: schema: type: string Last-Modified: schema: type: string format: RFC1123 ETag: schema: type: string schemas: # # .d8888b. # d88P Y88b # 888 888 # 888 .d88b. 88888b.d88b. 88888b.d88b. .d88b. 88888b. # 888 d88""88b 888 "888 "88b 888 "888 "88b d88""88b 888 "88b # 888 888 888 888 888 888 888 888 888 888 888 888 888 888 # Y88b d88P Y88..88P 888 888 888 888 888 888 Y88..88P 888 888 # "Y8888P" "Y88P" 888 888 888 888 888 888 "Y88P" 888 888 # Identifier: type: string format: xid # NOTE: Does not work currently with oapi-codegen because it generates a # new type declaration instead of a type alias so the unmarshalling fails. # To work around this, there are special conversion APIs in the oapi pkg. x-go-type: string # x-go-type-import: # name: xid # path: github.com/rs/xid example: "cc5lnd2s1s4652adtu50" description: A unique identifier for this resource. NullableIdentifier: type: string format: xid nullable: true example: "cc5lnd2s1s4652adtu50" description: A unique identifier for this resource. Mark: description: | A polymorphic identifier which is either a raw ID, a slug or both values combined and separated by a hyphen. This allows endpoints to respond to varying forms of a resource's ID which may be present in different app contexts. For example, a slug may be used in a URL but raw IDs are often exposed as part of API responses or in certain endpoint parameters. This type allows flexibility in user experience as well as the API surface while ensuring performance during database queries and other operations. For example, given a thread with the ID `cc5lnd2s1s4652adtu50` and the slug `top-10-movies-thread`, Storyden will understand both the forms: `cc5lnd2s1s4652adtu50-top-10-movies-thread` or `cc5lnd2s1s4652adtu50` or `top-10-movies-thread` as the identifier for that thread. Marks are only ever used on the read path as they are a derivative data type and are not stored in the database as-is, while IDs and slugs are. The write path typically exposes slugs as writable and IDs as immutable. x-go-type: string type: string format: xid-prefixed-kebab-case-string example: "cc5lnd2s1s4652adtu50-top-10-movies-thread" Info: description: Basic public information about the Storyden installation. type: object required: - title - description - content - accent_colour - authentication_mode - capabilities - onboarding_status properties: title: type: string description: type: string content: $ref: "#/components/schemas/PostContent" accent_colour: type: string onboarding_status: $ref: "#/components/schemas/OnboardingStatus" authentication_mode: $ref: "#/components/schemas/AuthMode" capabilities: $ref: "#/components/schemas/InstanceCapabilityList" metadata: $ref: "#/components/schemas/Metadata" OnboardingStatus: description: | Derived from data state, indicates what stage in the onboarding process the Storyden installation is in for directing first-time setup steps. type: string enum: - requires_first_account - requires_category - requires_more_accounts - requires_first_post - complete InstanceCapability: type: string enum: - gen_ai - semdex - email_client - sms_client InstanceCapabilityList: type: array items: { $ref: "#/components/schemas/InstanceCapability" } Visibility: type: string enum: - draft - unlisted - review - published VisibilityMutationProps: type: object required: [visibility] properties: visibility: { $ref: "#/components/schemas/Visibility" } Slug: description: A URL-safe slug for uniquely identifying resources. type: string ThreadMark: description: | A thread's ID and optional slug separated by a dash = it's unique mark. This allows endpoints to respond to varying forms of a thread's ID. For example, given a thread with the ID `cc5lnd2s1s4652adtu50` and the slug `top-10-movies-thread`, Storyden will understand both the forms: `cc5lnd2s1s4652adtu50-top-10-movies-thread` and `cc5lnd2s1s4652adtu50` as the identifier for that thread. x-go-type: string type: string format: xid-prefixed-kebab-case-string example: "cc5lnd2s1s4652adtu50-top-10-movies-thread" CommonProperties: type: object required: - id - createdAt - updatedAt properties: id: { $ref: "#/components/schemas/Identifier" } createdAt: type: string format: date-time description: The time the resource was created. updatedAt: type: string format: date-time description: The time the resource was updated. deletedAt: type: string format: date-time description: The time the resource was soft-deleted. misc: type: object description: Arbitrary extra data stored with the resource. APIError: type: object description: | A description of an error including a human readable message and any related metadata from the request and associated services. required: [error] properties: error: description: The internal error, not intended for end-user display. type: string message: description: A human-readable message intended for end-user display. type: string suggested: description: A suggested action for the user. type: string metadata: description: Any additional metadata related to the error. type: object additionalProperties: true Metadata: type: object additionalProperties: true description: Arbitrary metadata for the resource. PaginatedResult: description: To be composed with paginated resource responses. type: object required: [page_size, results, total_pages, current_page] properties: page_size: type: integer results: type: integer total_pages: type: integer current_page: type: integer next_page: type: integer URL: description: A web address type: string format: url AccountName: type: string description: The account owners display name. example: Barnaby Keene AccountHandle: type: string x-go-type: string description: The unique @ handle of an account. example: Southclaws AccountBio: type: string description: The rich-text bio for an account's public profile. example: <body><p>hi, my name is</p><p>southclaws</p></body> EmailAddress: description: A valid email address. type: string example: "hello@storyden.org" ProfileReference: type: object description: A minimal reference to an account. required: [id, joined, handle, name, roles] properties: id: { $ref: "#/components/schemas/Identifier" } joined: { $ref: "#/components/schemas/MemberJoinedDate" } suspended: { $ref: "#/components/schemas/MemberSuspendedDate" } handle: { $ref: "#/components/schemas/AccountHandle" } name: { $ref: "#/components/schemas/AccountName" } ThreadTitle: type: string description: The title of a thread. example: Hello world! PostContent: description: | The body text of a post within a thread. The type is either a string or an object, depending on what was used during creation. Strings can be used for basic plain text or markdown content and objects are used for more complex types such as Slate.js editor documents. type: string RelevanceScore: description: | For recommendations and other uses, only available when a Semdex is configured for content indexing and contextual relativity scoring. type: number BeaconProps: x-go-type: string description: | A beacon is a lightweight reference to an object used for tracking purposes. It contains only the kind and ID of the object. This is mostly used for tracking read states of threads. But may be used for more. I should clarify, not the morally questionable kind of "tracking". type: object required: [k, id] properties: k: { $ref: "#/components/schemas/DatagraphItemKind" } id: type: string description: The identifier for the object related to tracking. # # d8888 888 d8b # d88888 888 Y8P # d88P888 888 # d88P 888 .d88888 88888b.d88b. 888 88888b. # d88P 888 d88" 888 888 "888 "88b 888 888 "88b # d88P 888 888 888 888 888 888 888 888 888 # d8888888888 Y88b 888 888 888 888 888 888 888 # d88P 888 "Y88888 888 888 888 888 888 888 # AdminSettingsProps: description: Storyden installation and administration settings. type: object required: - title - description - content - accent_colour - authentication_mode properties: title: type: string description: type: string content: $ref: "#/components/schemas/PostContent" accent_colour: type: string authentication_mode: $ref: "#/components/schemas/AuthMode" metadata: $ref: "#/components/schemas/Metadata" AdminSettingsMutableProps: type: object properties: title: type: string description: type: string content: $ref: "#/components/schemas/PostContent" accent_colour: type: string authentication_mode: $ref: "#/components/schemas/AuthMode" metadata: description: | The settings metadata may be used by frontends to store arbitrary vendor-specific configuration data specific to the frontend itself. $ref: "#/components/schemas/Metadata" # # 8888888b. 888 # 888 Y88b 888 # 888 888 888 # 888 d88P .d88b. 888 .d88b. # 8888888P" d88""88b 888 d8P Y8b # 888 T88b 888 888 888 88888888 # 888 T88b Y88..88P 888 Y8b. # 888 T88b "Y88P" 888 "Y8888 # Role: type: object allOf: - $ref: "#/components/schemas/CommonProperties" - $ref: "#/components/schemas/RoleProps" RoleListResult: type: object required: [roles] properties: roles: { $ref: "#/components/schemas/RoleList" } RoleList: type: array items: $ref: "#/components/schemas/Role" AccountRole: type: object allOf: - $ref: "#/components/schemas/Role" - $ref: "#/components/schemas/AccountRoleProps" AccountRoleList: type: array items: $ref: "#/components/schemas/AccountRole" AccountRoleProps: type: object required: [badge, default] properties: badge: description: | One role may be designated as a badge for the account. If ture, it should be displayed prominently on the profile or in other contexts. type: boolean default: description: | There are two built-in roles: everyone and admin, this boolean flag is set if this role is one of the default built-in roles. type: boolean RoleProps: type: object required: [name, colour, permissions] properties: name: type: string colour: type: string permissions: $ref: "#/components/schemas/PermissionList" RoleInitialProps: type: object required: [name, colour, permissions] properties: name: type: string colour: type: string permissions: $ref: "#/components/schemas/PermissionList" RoleMutableProps: type: object properties: name: type: string colour: type: string permissions: $ref: "#/components/schemas/PermissionList" Permission: type: string enum: # Posts (Threads, replies and posts) - "CREATE_POST" - "READ_PUBLISHED_THREADS" - "CREATE_REACTION" - "MANAGE_POSTS" - "MANAGE_CATEGORIES" - "CREATE_INVITATION" # Library (Page tree nodes) - "READ_PUBLISHED_LIBRARY" - "MANAGE_LIBRARY" - "SUBMIT_LIBRARY_NODE" # Assets - "UPLOAD_ASSET" # Events - "MANAGE_EVENTS" # Profiles (listing and viewing member profiles) - "LIST_PROFILES" - "READ_PROFILE" # Collections - "CREATE_COLLECTION" - "LIST_COLLECTIONS" - "READ_COLLECTION" - "MANAGE_COLLECTIONS" - "COLLECTION_SUBMIT" # Personal access keys for automation/MCP - "USE_PERSONAL_ACCESS_KEYS" # Administrative (Settings, bans, etc) - "MANAGE_SETTINGS" - "MANAGE_SUSPENSIONS" - "MANAGE_ROLES" - "MANAGE_REPORTS" - "VIEW_ACCOUNTS" # Administrator implicitly has all permissions. - "ADMINISTRATOR" PermissionList: type: array items: $ref: "#/components/schemas/Permission" # # d8888 888 888 # d88888 888 888 # d88P888 888 888 # d88P 888 888 888 888888 88888b. # d88P 888 888 888 888 888 "88b # d88P 888 888 888 888 888 888 # d8888888888 Y88b 888 Y88b. 888 888 # d88P 888 "Y88888 "Y888 888 888 # AuthProviderList: type: array items: $ref: "#/components/schemas/AuthProvider" AuthMode: type: string enum: - handle - email - phone AuthProvider: type: object required: [provider, name] properties: provider: description: The slug name of the provider. type: string name: description: The human-readable name of the provider. type: string link: description: The hyperlink to render for the user. type: string AuthPair: type: object required: [identifier, token] properties: identifier: example: "odin" type: string token: example: "password" type: string AuthEmailPasswordInitialProps: type: object required: [email, password] properties: email: { $ref: "#/components/schemas/EmailAddress" } password: type: string handle: $ref: "#/components/schemas/AccountHandle" AuthEmailPasswordReset: type: object required: [email, token_url] properties: email: { $ref: "#/components/schemas/EmailAddress" } token_url: type: object required: [url, query] properties: url: description: | The URL to include in the password reset email. This URL's host must match the configured Storyden instance's web address value. type: string query: description: | The query parameters to store the reset token in. This is a frontend client specific value. type: string AuthEmailInitialProps: type: object required: [email] properties: email: { $ref: "#/components/schemas/EmailAddress" } handle: $ref: "#/components/schemas/AccountHandle" AuthEmailVerifyProps: type: object required: [email, code] properties: email: description: | The email address to be verified, only necessary for when submitting a verification without a session cookie present. $ref: "#/components/schemas/EmailAddress" code: example: "728562" type: string AuthPasswordInitialProps: type: object required: [password] properties: password: example: "password123" type: string AuthPasswordMutableProps: type: object required: [old, new] properties: old: example: "password123" type: string new: example: "password456" type: string AuthPasswordResetProps: type: object required: [token, new] properties: token: type: string new: example: "password456" type: string AuthSuccess: type: object required: [id] properties: id: type: string OAuthCallback: type: object required: - state - code properties: state: type: string code: type: string WebAuthnPublicKeyCreationOptions: description: | https://www.w3.org/TR/webauthn-2/#sctn-credentialcreationoptions-extension type: object required: [publicKey] properties: publicKey: $ref: "#/components/schemas/PublicKeyCredentialCreationOptions" PublicKeyCredentialCreationOptions: description: | https://www.w3.org/TR/webautehn-2/#dictdef-publickeycredentialcreationoptions type: object required: - rp - user - challenge - excludeCredentials - pubKeyCredParams properties: rp: { $ref: "#/components/schemas/PublicKeyCredentialRpEntity" } user: { $ref: "#/components/schemas/PublicKeyCredentialUserEntity" } challenge: type: string pubKeyCredParams: type: array items: { $ref: "#/components/schemas/PublicKeyCredentialParameters" } timeout: type: integer excludeCredentials: type: array items: { $ref: "#/components/schemas/PublicKeyCredentialDescriptor" } authenticatorSelection: { $ref: "#/components/schemas/AuthenticatorSelectionCriteria" } attestation: { $ref: "#/components/schemas/AttestationConveyancePreference" } extensions: { $ref: "#/components/schemas/AuthenticationExtensionsClientInputs" } PublicKeyCredentialRpEntity: description: | https://www.w3.org/TR/webauthn-2/#dictdef-publickeycredentialrpentity type: object required: [name, id] properties: id: type: string name: type: string PublicKeyCredentialUserEntity: description: | https://www.w3.org/TR/webauthn-2/#dictdef-publickeycredentialuserentity type: object required: [id, name, displayName] properties: id: type: string name: type: string displayName: type: string PublicKeyCredentialParameters: description: | https://www.w3.org/TR/webauthn-2/#dictdef-publickeycredentialparameters type: object required: [type, alg] properties: type: $ref: "#/components/schemas/PublicKeyCredentialType" alg: type: number PublicKeyCredentialType: description: | https://www.w3.org/TR/webauthn-2/#enumdef-publickeycredentialtype type: string enum: [public-key] PublicKeyCredentialDescriptor: description: | https://www.w3.org/TR/webauthn-2/#dictdef-publickeycredentialdescriptor type: object required: [type, id] properties: type: $ref: "#/components/schemas/PublicKeyCredentialType" id: type: string transports: type: array items: type: string enum: ["ble", "internal", "nfc", "usb", "cable", "hybrid"] AuthenticatorSelectionCriteria: description: | https://www.w3.org/TR/webauthn-2/#dictdef-authenticatorselectioncriteria type: object required: - authenticatorAttachment - residentKey properties: authenticatorAttachment: $ref: "#/components/schemas/AuthenticatorAttachment" residentKey: $ref: "#/components/schemas/ResidentKeyRequirement" requireResidentKey: type: boolean userVerification: $ref: "#/components/schemas/UserVerificationRequirement" AuthenticatorAttachment: description: | https://www.w3.org/TR/webauthn-2/#enumdef-authenticatorattachment type: string enum: [platform, cross-platform] ResidentKeyRequirement: description: | https://www.w3.org/TR/webauthn-2/#enumdef-residentkeyrequirement type: string enum: - discouraged - preferred - required UserVerificationRequirement: description: | https://www.w3.org/TR/webauthn-2/#enumdef-userverificationrequirement type: string default: preferred enum: - discouraged - preferred - required AttestationConveyancePreference: description: | https://www.w3.org/TR/webauthn-2/#enum-attestation-convey type: string enum: - direct - enterprise - indirect - none AuthenticationExtensionsClientInputs: description: | https://www.w3.org/TR/webauthn-2/#dictdef-authenticationextensionsclientinputs type: object additionalProperties: true PublicKeyCredential: description: | https://www.w3.org/TR/webauthn-2/#iface-pkcredential type: object required: - id - rawId - response - type properties: id: type: string rawId: type: string response: { $ref: "#/components/schemas/AuthenticatorResponse" } type: type: string clientExtensionResults: type: object authenticatorAttachment: type: string AuthenticatorResponse: description: | https://www.w3.org/TR/webauthn-2/#authenticatorresponse type: object required: [clientDataJSON] properties: clientDataJSON: type: string attestationObject: type: string transports: type: array items: type: string authenticatorData: type: string signature: type: string userHandle: type: string CredentialRequestOptions: description: | https://www.w3.org/TR/webauthn-2/#sctn-credentialrequestoptions-extension type: object required: [publicKey] properties: publicKey: $ref: "#/components/schemas/PublicKeyCredentialRequestOptions" PublicKeyCredentialRequestOptions: description: | https://www.w3.org/TR/webauthn-2/#dictdef-publickeycredentialrequestoptions type: object required: [challenge] properties: challenge: type: string timeout: type: integer rpId: type: string allowCredentials: type: array items: $ref: "#/components/schemas/PublicKeyCredentialDescriptor" userVerification: type: string enum: ["discouraged", "preferred", "required"] PhoneRequestCodeProps: description: The phone number request payload. type: object required: [identifier, phone_number] properties: identifier: description: The desired username to link to the phone number. example: "southclaws" type: string phone_number: description: The phone number to receive the one-time code on. type: string PhoneSubmitCodeProps: description: The Phone submit code payload. type: object required: [code] properties: code: type: string AccessKey: type: object allOf: - $ref: "#/components/schemas/CommonProperties" - $ref: "#/components/schemas/AccessKeyProps" OwnedAccessKey: description: | An owned access key is a key that has been already issued to an account, it is used specifically for administrator listing of all access keys where it's necessary to include the account that created the key. type: object allOf: - $ref: "#/components/schemas/CommonProperties" - $ref: "#/components/schemas/AccessKeyProps" - required: [created_by] properties: created_by: { $ref: "#/components/schemas/ProfileReference" } AccessKeyIssued: description: | An access key issued to an account, this is the full access key object including the secret. This is only exposed upon creation of the key and the secret value is never stored. The caller that receives this object is responsible for securely storing the secret value for later use. type: object allOf: - $ref: "#/components/schemas/AccessKey" - $ref: "#/components/schemas/AccessKeySecret" AccessKeyProps: type: object required: [name, enabled] properties: name: description: The name of the access key. type: string enabled: type: boolean expires_at: type: string format: date-time description: When the access key expires, if null, it never expires. AccessKeyInitialProps: type: object required: [name] properties: name: description: The name of the access key. type: string expires_at: type: string format: date-time description: When the access key expires, if null, it never expires. AccessKeySecret: type: object required: [secret] properties: secret: description: | The secret key used to authenticate with the API. Keys are prefixed with a kind identifier, "sdpak" refers to a Storyden Personal Access Key and "sdbak" refers to a Storyden Bot Access Key. The two kinds are not interchangeable however they do not have behavioural differences and is merely a visual cue. type: string example: "sdpak_a1b2c3d4cfc00d429ba841f9425c62f82341381b" AccessKeyList: type: array items: { $ref: "#/components/schemas/AccessKey" } AccessKeyListResult: type: object required: [keys] properties: keys: { $ref: "#/components/schemas/AccessKeyList" } OwnedAccessKeyList: type: array items: { $ref: "#/components/schemas/OwnedAccessKey" } OwnedAccessKeyListResult: type: object required: [keys] properties: keys: { $ref: "#/components/schemas/OwnedAccessKeyList" } # # d8888 888 # d88888 888 # d88P888 888 # d88P 888 .d8888b .d8888b .d88b. 888 888 88888b. 888888 # d88P 888 d88P" d88P" d88""88b 888 888 888 "88b 888 # d88P 888 888 888 888 888 888 888 888 888 888 # d8888888888 Y88b. Y88b. Y88..88P Y88b 888 888 888 Y88b. # d88P 888 "Y8888P "Y8888P "Y88P" "Y88888 888 888 "Y888 # Account: type: object allOf: - $ref: "#/components/schemas/CommonProperties" - $ref: "#/components/schemas/AccountCommonProps" AccountCommonProps: required: [ joined, handle, name, roles, bio, links, meta, verified_status, email_addresses, admin, ] properties: joined: { $ref: "#/components/schemas/MemberJoinedDate" } suspended: { $ref: "#/components/schemas/MemberSuspendedDate" } handle: $ref: "#/components/schemas/AccountHandle" name: $ref: "#/components/schemas/AccountName" roles: $ref: "#/components/schemas/AccountRoleList" bio: $ref: "#/components/schemas/AccountBio" links: $ref: "#/components/schemas/ProfileExternalLinkList" meta: $ref: "#/components/schemas/Metadata" verified_status: $ref: "#/components/schemas/AccountVerifiedStatus" email_addresses: $ref: "#/components/schemas/AccountEmailAddressList" notifications: $ref: "#/components/schemas/NotificationCount" admin: type: boolean invited_by: $ref: "#/components/schemas/ProfileReference" AccountMutableProps: type: object properties: handle: $ref: "#/components/schemas/AccountHandle" name: $ref: "#/components/schemas/AccountName" bio: $ref: "#/components/schemas/AccountBio" interests: $ref: "#/components/schemas/TagNameList" links: $ref: "#/components/schemas/ProfileExternalLinkList" meta: $ref: "#/components/schemas/Metadata" AccountAuthMethods: type: object required: [active, available] properties: active: { $ref: "#/components/schemas/AccountAuthMethodList" } available: { $ref: "#/components/schemas/AuthProviderList" } AccountAuthMethodList: type: array items: { $ref: "#/components/schemas/AccountAuthMethod" } AccountAuthMethod: description: | An authentication method is an active instance of an authentication provider associated with an account. Use this to display a user's active authentication methods so they can edit or remove it. type: object required: [id, created_at, name, identifier, provider] properties: id: description: The internal unique ID this method has. type: string created_at: type: string format: date-time description: When this auth method was registered to the account. name: description: The personal name given to the method. type: string identifier: description: The external identifier (third party ID or device ID) type: string provider: { $ref: "#/components/schemas/AuthProvider" } AccountVerifiedStatus: type: string enum: [none, verified_email] AccountEmailAddressList: description: | If the instance is configured to not use any email features for auth or transactional/content communications, this will always be empty. type: array items: { $ref: "#/components/schemas/AccountEmailAddress" } AccountEmailAddress: type: object required: [id, email_address, verified] properties: id: { $ref: "#/components/schemas/Identifier" } email_address: { $ref: "#/components/schemas/EmailAddress" } verified: description: Is the email address verified to be owned by the account? type: boolean AccountEmailInitialProps: type: object required: [email_address] properties: email_address: { $ref: "#/components/schemas/EmailAddress" } # # 8888888 d8b 888 888 d8b # 888 Y8P 888 888 Y8P # 888 888 888 # 888 88888b. 888 888 888 888888 8888b. 888888 888 .d88b. 88888b. # 888 888 "88b 888 888 888 888 "88b 888 888 d88""88b 888 "88b # 888 888 888 Y88 88P 888 888 .d888888 888 888 888 888 888 888 # 888 888 888 Y8bd8P 888 Y88b. 888 888 Y88b. 888 Y88..88P 888 888 # 8888888 888 888 Y88P 888 "Y888 "Y888888 "Y888 888 "Y88P" 888 888 # Invitation: type: object allOf: - $ref: "#/components/schemas/CommonProperties" - $ref: "#/components/schemas/InvitationProps" InvitationList: type: array items: { $ref: "#/components/schemas/Invitation" } InvitationListResult: type: object allOf: - { $ref: "#/components/schemas/PaginatedResult" } - type: object required: [invitations] properties: invitations: { $ref: "#/components/schemas/InvitationList" } InvitationProps: type: object required: [creator] properties: creator: { $ref: "#/components/schemas/ProfileReference" } message: type: string InvitationInitialProps: type: object properties: message: type: string # # 888b 888 888 d8b .d888 d8b 888 d8b # 8888b 888 888 Y8P d88P" Y8P 888 Y8P # 88888b 888 888 888 888 # 888Y88b 888 .d88b. 888888 888 888888 888 .d8888b 8888b. 888888 888 .d88b. 88888b. # 888 Y88b888 d88""88b 888 888 888 888 d88P" "88b 888 888 d88""88b 888 "88b # 888 Y88888 888 888 888 888 888 888 888 .d888888 888 888 888 888 888 888 # 888 Y8888 Y88..88P Y88b. 888 888 888 Y88b. 888 888 Y88b. 888 Y88..88P 888 888 # 888 Y888 "Y88P" "Y888 888 888 888 "Y8888P "Y888888 "Y888 888 "Y88P" 888 888 # Notification: type: object required: [id, created_at, event, status] properties: id: { $ref: "#/components/schemas/Identifier" } created_at: type: string format: date-time description: The time the resource was created. event: { $ref: "#/components/schemas/NotificationEvent" } item: { $ref: "#/components/schemas/DatagraphItem" } source: { $ref: "#/components/schemas/ProfileReference" } status: { $ref: "#/components/schemas/NotificationStatus" } NotificationMutableProps: type: object properties: status: { $ref: "#/components/schemas/NotificationStatus" } NotificationList: type: array items: { $ref: "#/components/schemas/Notification" } NotificationListResult: type: object allOf: - { $ref: "#/components/schemas/PaginatedResult" } - type: object required: [notifications] properties: notifications: { $ref: "#/components/schemas/NotificationList" } NotificationEvent: description: | The kind of event that triggered the notification. Identical to the `notification.Event` enumerated type. type: string enum: - thread_reply - post_like - follow - profile_mention - event_host_added - member_attending_event - member_declined_event - attendee_removed - report_submitted - report_updated NotificationStatus: type: string enum: [unread, read] NotificationStatusList: type: array items: { $ref: "#/components/schemas/NotificationStatus" } NotificationCount: type: integer # # 8888888b. 888 # 888 Y88b 888 # 888 888 888 # 888 d88P .d88b. 88888b. .d88b. 888d888 888888 # 8888888P" d8P Y8b 888 "88b d88""88b 888P" 888 # 888 T88b 88888888 888 888 888 888 888 888 # 888 T88b Y8b. 888 d88P Y88..88P 888 Y88b. # 888 T88b "Y8888 88888P" "Y88P" 888 "Y888 # 888 # 888 # 888 # Report: type: object allOf: - $ref: "#/components/schemas/CommonProperties" - $ref: "#/components/schemas/ReportRefProps" - $ref: "#/components/schemas/ReportProps" ReportList: type: array items: { $ref: "#/components/schemas/Report" } ReportListResult: type: object allOf: - { $ref: "#/components/schemas/PaginatedResult" } - type: object required: [reports] properties: reports: { $ref: "#/components/schemas/ReportList" } ReportProps: type: object properties: item: { $ref: "#/components/schemas/DatagraphItem" } ReportRefProps: type: object required: [target_id, target_kind, reported_by, status] properties: target_id: $ref: "#/components/schemas/Identifier" target_kind: $ref: "#/components/schemas/DatagraphItemKind" reported_by: $ref: "#/components/schemas/ProfileReference" handled_by: $ref: "#/components/schemas/ProfileReference" comment: type: string status: $ref: "#/components/schemas/ReportStatus" ReportInitialProps: type: object required: [target_id, target_kind] properties: target_id: $ref: "#/components/schemas/Identifier" target_kind: $ref: "#/components/schemas/DatagraphItemKind" comment: type: string ReportMutableProps: type: object properties: status: $ref: "#/components/schemas/ReportStatus" handled_by: $ref: "#/components/schemas/Identifier" ReportStatus: type: string enum: [submitted, acknowledged, resolved] # # 8888888b. .d888 d8b 888 # 888 Y88b d88P" Y8P 888 # 888 888 888 888 # 888 d88P 888d888 .d88b. 888888 888 888 .d88b. # 8888888P" 888P" d88""88b 888 888 888 d8P Y8b # 888 888 888 888 888 888 888 88888888 # 888 888 Y88..88P 888 888 888 Y8b. # 888 888 "Y88P" 888 888 888 "Y8888 # PublicProfile: type: object allOf: - $ref: "#/components/schemas/CommonProperties" - required: - createdAt - joined - handle - name - roles - bio - followers - following - like_score - interests - links - meta properties: createdAt: deprecated: true type: string joined: { $ref: "#/components/schemas/MemberJoinedDate" } suspended: { $ref: "#/components/schemas/MemberSuspendedDate" } handle: $ref: "#/components/schemas/AccountHandle" name: $ref: "#/components/schemas/AccountName" roles: $ref: "#/components/schemas/AccountRoleList" bio: $ref: "#/components/schemas/AccountBio" image: type: string followers: $ref: "#/components/schemas/ProfileFollowersCount" following: $ref: "#/components/schemas/ProfileFollowingCount" like_score: $ref: "#/components/schemas/LikeScore" interests: $ref: "#/components/schemas/TagReferenceList" links: $ref: "#/components/schemas/ProfileExternalLinkList" invited_by: $ref: "#/components/schemas/ProfileReference" meta: $ref: "#/components/schemas/Metadata" PublicProfileFollowersResult: allOf: - { $ref: "#/components/schemas/PaginatedResult" } - type: object required: [followers] properties: followers: { $ref: "#/components/schemas/ProfileFollowersList" } PublicProfileFollowingResult: allOf: - { $ref: "#/components/schemas/PaginatedResult" } - type: object required: [following] properties: following: { $ref: "#/components/schemas/ProfileFollowingList" } ProfileExternalLinkList: type: array items: $ref: "#/components/schemas/ProfileExternalLink" ProfileExternalLink: type: object required: [text, url] properties: text: type: string url: type: string PublicProfileListResult: allOf: - { $ref: "#/components/schemas/PaginatedResult" } - type: object required: [profiles] properties: profiles: { $ref: "#/components/schemas/PublicProfileList" } PublicProfileList: type: array items: { $ref: "#/components/schemas/PublicProfile" } ProfileFollowersList: type: array items: { $ref: "#/components/schemas/ProfileReference" } ProfileFollowingList: type: array items: { $ref: "#/components/schemas/ProfileReference" } ProfileFollowersCount: type: integer ProfileFollowingCount: type: integer MemberJoinedDate: type: string format: date-time description: The time the resource was created. MemberSuspendedDate: type: string format: date-time description: The time the resource was created. # # .d8888b. 888 # d88P Y88b 888 # 888 888 888 # 888 8888b. 888888 .d88b. .d88b. .d88b. 888d888 888 888 # 888 "88b 888 d8P Y8b d88P"88b d88""88b 888P" 888 888 # 888 888 .d888888 888 88888888 888 888 888 888 888 888 888 # Y88b d88P 888 888 Y88b. Y8b. Y88b 888 Y88..88P 888 Y88b 888 # "Y8888P" "Y888888 "Y888 "Y8888 "Y88888 "Y88P" 888 "Y88888 # 888 888 # Y8b d88P Y8b d88P # "Y88P" "Y88P" # Category: type: object allOf: - $ref: "#/components/schemas/CommonProperties" - $ref: "#/components/schemas/CategoryCommonProps" - $ref: "#/components/schemas/CategoryAdditional" CategoryReference: type: object allOf: - $ref: "#/components/schemas/CommonProperties" - $ref: "#/components/schemas/CategoryCommonProps" CategoryCommonProps: type: object required: [name, slug, description, colour, sort, children] properties: name: $ref: "#/components/schemas/CategoryName" slug: $ref: "#/components/schemas/CategorySlug" description: type: string colour: type: string sort: type: integer parent: $ref: "#/components/schemas/Identifier" description: Parent category identifier. Unset indicates a root-level category. cover_image: $ref: "#/components/schemas/Asset" children: { $ref: "#/components/schemas/CategoryList" } meta: { $ref: "#/components/schemas/Metadata" } CategoryInitialProps: type: object required: [name, description, colour] properties: name: $ref: "#/components/schemas/CategoryName" slug: $ref: "#/components/schemas/CategorySlug" description: type: string colour: type: string parent: $ref: "#/components/schemas/Identifier" description: Parent category identifier. Unset indicates a root-level category. cover_image_asset_id: { $ref: "#/components/schemas/Identifier" } meta: { $ref: "#/components/schemas/Metadata" } CategoryMutableProps: type: object properties: name: $ref: "#/components/schemas/CategoryName" slug: $ref: "#/components/schemas/CategorySlug" description: type: string colour: type: string cover_image_asset_id: allOf: - $ref: "#/components/schemas/NullableIdentifier" nullable: true description: Optional cover image asset identifier for the category. meta: { $ref: "#/components/schemas/Metadata" } CategoryDeleteProps: type: object required: [move_to] properties: move_to: $ref: "#/components/schemas/Identifier" description: Category ID to move all posts to before deleting this category. CategoryName: description: A category's user-facing name. type: string CategorySlug: description: A category's URL-safe slug. type: string CategorySlugList: description: A list of category names. type: array items: $ref: "#/components/schemas/CategorySlug" CategoryAdditional: type: object required: [postCount] properties: postCount: type: integer CategoryList: type: array items: { $ref: "#/components/schemas/Category" } CategoryListResult: type: object required: [categories] properties: categories: $ref: "#/components/schemas/CategoryList" CategoryPositionMutableProps: type: object description: | Parameters for repositioning a category in the hierarchy. Update the parent using `parent`, and/or reposition among siblings using `before` or `after`. Using both `before` and `after` is not allowed. properties: parent: $ref: "#/components/schemas/NullableIdentifier" description: Optional new parent category identifier. Set to null to move to the root level. before: $ref: "#/components/schemas/Identifier" description: Move this category before the sibling with this identifier. after: $ref: "#/components/schemas/Identifier" description: Move this category after the sibling with this identifier. # # 88888888888 # 888 # 888 # 888 8888b. .d88b. # 888 "88b d88P"88b # 888 .d888888 888 888 # 888 888 888 Y88b 888 # 888 "Y888888 "Y88888 # 888 # Y8b d88P # "Y88P" # Tag: type: object description: | A tag is a label that can be applied to posts or pages to organise related content. They can be used to filter and search for content. The Tag schema provides all the data for a tag including its items, so it's quite a heavy object if referencing a lot of items. For a lighter weight version, use a TagReference for use-cases such as tag searches. allOf: - $ref: "#/components/schemas/TagReferenceProps" - $ref: "#/components/schemas/TagProps" TagReference: description: | A minimal representation of a tag for use in most contexts where you don't need the full list of items associated with the tag. type: object allOf: - $ref: "#/components/schemas/TagReferenceProps" TagProps: type: object required: [id, items] properties: id: { $ref: "#/components/schemas/Identifier" } items: { $ref: "#/components/schemas/DatagraphItemList" } TagReferenceProps: type: object required: [name, colour, item_count] properties: name: { $ref: "#/components/schemas/TagName" } colour: { $ref: "#/components/schemas/TagColour" } item_count: { $ref: "#/components/schemas/TagItemCount" } TagName: type: string description: The name of a tag. TagColour: type: string description: The colour of a tag. TagItemCount: type: integer description: The number of items tagged with this tag. TagReferenceList: type: array description: A list of tags. items: { $ref: "#/components/schemas/TagReference" } TagNameList: type: array items: { $ref: "#/components/schemas/TagName" } TagListIDs: type: array description: A list of tags IDs. items: { $ref: "#/components/schemas/Identifier" } TagListResult: type: object required: [tags] properties: tags: { $ref: "#/components/schemas/TagReferenceList" } # # 8888888b. 888 # 888 Y88b 888 # 888 888 888 # 888 d88P .d88b. .d8888b 888888 # 8888888P" d88""88b 88K 888 # 888 888 888 "Y8888b. 888 # 888 Y88..88P X88 Y88b. # 888 "Y88P" 88888P' "Y888 # Post: type: object description: | A post represents a temporal piece of content, it can be a thread, or a reply to a thread or something else such as a blog, announcement, etc. Post is used in generic use-cases where it may not matter whether you want a thread or a reply, such as search results or recommendations. allOf: - { $ref: "#/components/schemas/CommonProperties" } - { $ref: "#/components/schemas/PostReferenceProps" } - { $ref: "#/components/schemas/PostProps" } PostReference: description: | A minimal object used to refer to a post without providing a lot of unnecessary data such as the full content or child items. type: object allOf: - { $ref: "#/components/schemas/CommonProperties" } - { $ref: "#/components/schemas/PostReferenceProps" } PostProps: description: | The general properties required for any post-like resource. Is composed with Threads or Replies to provide the basic common properties. type: object required: [body, body_links] properties: body: { $ref: "#/components/schemas/PostContent" } body_links: { $ref: "#/components/schemas/LinkReferenceList" } PostReferenceProps: type: object required: [title, slug, author, assets, reacts, collections, likes] properties: title: { $ref: "#/components/schemas/ThreadTitle" } description: { $ref: "#/components/schemas/PostDescription" } slug: { $ref: "#/components/schemas/ThreadMark" } author: { $ref: "#/components/schemas/ProfileReference" } assets: { $ref: "#/components/schemas/AssetList" } reacts: { $ref: "#/components/schemas/ReactList" } collections: { $ref: "#/components/schemas/CollectionStatus" } likes: { $ref: "#/components/schemas/LikeData" } meta: { $ref: "#/components/schemas/Metadata" } PostReferenceList: type: array items: { $ref: "#/components/schemas/PostReference" } PostMutableProps: type: object properties: body: { $ref: "#/components/schemas/PostContent" } meta: { $ref: "#/components/schemas/Metadata" } url: { $ref: "#/components/schemas/URL" } PostDescription: type: string description: A short version of the post's body text for use in previews. # # 88888888888 888 888 # 888 888 888 # 888 888 888 # 888 88888b. 888d888 .d88b. 8888b. .d88888 # 888 888 "88b 888P" d8P Y8b "88b d88" 888 # 888 888 888 888 88888888 .d888888 888 888 # 888 888 888 888 Y8b. 888 888 Y88b 888 # 888 888 888 888 "Y8888 "Y888888 "Y88888 # Thread: allOf: - $ref: "#/components/schemas/ThreadReference" - $ref: "#/components/schemas/DatagraphRecommendations" - type: object required: [replies] properties: replies: { $ref: "#/components/schemas/PaginatedReplyList" } ThreadInitialProps: type: object required: [title] properties: title: { $ref: "#/components/schemas/ThreadTitle" } body: { $ref: "#/components/schemas/PostContent" } tags: { $ref: "#/components/schemas/TagNameList" } meta: { $ref: "#/components/schemas/Metadata" } category: { $ref: "#/components/schemas/Identifier" } visibility: { $ref: "#/components/schemas/Visibility" } url: { $ref: "#/components/schemas/URL" } ThreadMutableProps: type: object properties: title: { $ref: "#/components/schemas/ThreadTitle" } body: { $ref: "#/components/schemas/PostContent" } tags: { $ref: "#/components/schemas/TagNameList" } meta: { $ref: "#/components/schemas/Metadata" } category: { $ref: "#/components/schemas/Identifier" } visibility: { $ref: "#/components/schemas/Visibility" } url: { $ref: "#/components/schemas/URL" } ThreadReference: type: object description: | A thread reference includes most of the information about a thread but does not include the posts within the thread. Useful for rendering large lists of threads or other situations when you don't need the full data. allOf: - $ref: "#/components/schemas/CommonProperties" - $ref: "#/components/schemas/PostReferenceProps" - $ref: "#/components/schemas/PostProps" - $ref: "#/components/schemas/ThreadReferenceProps" ThreadReferenceProps: type: object required: - pinned - visibility - tags - reply_status - collections properties: pinned: type: boolean description: Whether the thread is pinned in this category. visibility: { $ref: "#/components/schemas/Visibility" } read_status: { $ref: "#/components/schemas/ReadStatus" } reply_status: { $ref: "#/components/schemas/ReplyStatus" } category: { $ref: "#/components/schemas/CategoryReference" } link: { $ref: "#/components/schemas/LinkReference" } tags: { $ref: "#/components/schemas/TagReferenceList" } last_reply_at: type: string format: date-time description: The time of the last reply to the thread. ReadStatus: description: | Information about the read status of a thread for the requesting authenticated user. If the user is not authenticated or they have not read the thread before, this will not be included in the Thread object. type: object required: [last_read_at, replies_since] properties: last_read_at: type: string format: date-time description: | When requested by an authenticated account, shows the last time they last read the thread at. replies_since: type: integer description: | When requested by an authenticated account, shows the number of new replies since they last read the thread. ReplyStatus: type: object required: [replies, replied] properties: replies: description: The total number of replies to the thread. type: integer replied: description: | If requested by an authenticated account, the number of replies that were made by that account to the thread. type: integer ThreadList: type: array items: $ref: "#/components/schemas/ThreadReference" ThreadListResult: allOf: - { $ref: "#/components/schemas/PaginatedResult" } - type: object required: [threads] properties: threads: { $ref: "#/components/schemas/ThreadList" } # # 8888888b. 888 # 888 Y88b 888 # 888 888 888 # 888 d88P .d88b. 88888b. 888 888 888 # 8888888P" d8P Y8b 888 "88b 888 888 888 # 888 T88b 88888888 888 888 888 888 888 # 888 T88b Y8b. 888 d88P 888 Y88b 888 # 888 T88b "Y8888 88888P" 888 "Y88888 # 888 888 # 888 Y8b d88P # 888 "Y88P" # Reply: type: object description: | A new post within a thread of posts. A post may reply to another post in the thread by specifying the `reply_to` property. The identifier in the `reply_to` value must be post within the same thread. allOf: - { $ref: "#/components/schemas/CommonProperties" } - { $ref: "#/components/schemas/PostReferenceProps" } - { $ref: "#/components/schemas/PostProps" } - { $ref: "#/components/schemas/ReplyProps" } PaginatedReplyList: allOf: - $ref: "#/components/schemas/PaginatedResult" - type: object required: [replies] properties: replies: { $ref: "#/components/schemas/ReplyList" } ReplyList: type: array items: { $ref: "#/components/schemas/Reply" } ReplyProps: type: object required: [root_id, root_slug] properties: root_id: { $ref: "#/components/schemas/Identifier" } root_slug: { $ref: "#/components/schemas/ThreadMark" } reply_to: { $ref: "#/components/schemas/Identifier" } ReplyInitialProps: type: object required: [body] properties: body: { $ref: "#/components/schemas/PostContent" } meta: { $ref: "#/components/schemas/Metadata" } reply_to: { $ref: "#/components/schemas/Identifier" } url: { $ref: "#/components/schemas/URL" } # # 8888888b. 888 # 888 Y88b 888 # 888 888 888 # 888 d88P .d88b. 8888b. .d8888b 888888 # 8888888P" d8P Y8b "88b d88P" 888 # 888 T88b 88888888 .d888888 888 888 # 888 T88b Y8b. 888 888 Y88b. Y88b. # 888 T88b "Y8888 "Y888888 "Y8888P "Y888 # React: type: object required: [id, emoji, author] properties: id: { $ref: "#/components/schemas/Identifier" } emoji: { $ref: "#/components/schemas/ReactEmoji" } author: { $ref: "#/components/schemas/ProfileReference" } ReactInitialProps: description: Reactions are currently just simple emoji characters. type: object required: [emoji] properties: emoji: { $ref: "#/components/schemas/ReactEmoji" } ReactList: description: A list of reactions this post has had from people. type: array items: { $ref: "#/components/schemas/React" } ReactEmoji: description: | A single emoji character representing a reaction. In future, this will be augmented with a more fully fledged custom emoji system. type: string # # 888b d888 888 d8b # 8888b d8888 888 Y8P # 88888b.d88888 888 # 888Y88888P888 .d88b. .d88888 888 8888b. # 888 Y888P 888 d8P Y8b d88" 888 888 "88b # 888 Y8P 888 88888888 888 888 888 .d888888 # 888 " 888 Y8b. Y88b 888 888 888 888 # 888 888 "Y8888 "Y88888 888 "Y888888 # AssetID: $ref: "#/components/schemas/Identifier" AssetIDs: type: array items: { $ref: "#/components/schemas/AssetID" } AssetList: type: array items: { $ref: "#/components/schemas/Asset" } Asset: type: object required: [id, filename, path, mime_type, width, height] properties: id: $ref: "#/components/schemas/AssetID" filename: type: string path: description: | The API path of the asset, conforms to the schema's GET `/assets`. type: string mime_type: type: string width: type: number height: type: number # NOTE: Presence is dictated by the callee, not the API (currently.) parent: { $ref: "#/components/schemas/Asset" } AssetSourceURL: description: An asset source URL holds the address of an off-platform media asset which is not hosted on a Storyden instance. It may represent a source URL for an intended download or an asset which is stored elsewhere. type: string AssetSourceList: type: array items: { $ref: "#/components/schemas/AssetSourceURL" } # # 888 d8b 888 # 888 Y8P 888 # 888 888 # 888 888 888 888 .d88b. # 888 888 888 .88P d8P Y8b # 888 888 888888K 88888888 # 888 888 888 "88b Y8b. # 88888888 888 888 888 "Y8888 # ItemLike: description: A like on an item, contains the owner only. type: object allOf: - $ref: "#/components/schemas/LikeProps" - required: [owner] properties: owner: { $ref: "#/components/schemas/ProfileReference" } ItemLikeList: type: array items: { $ref: "#/components/schemas/ItemLike" } ProfileLike: description: A like on an item, contains the item only. type: object allOf: - $ref: "#/components/schemas/LikeProps" - required: [item] properties: item: { $ref: "#/components/schemas/DatagraphItem" } ProfileLikeList: type: array items: { $ref: "#/components/schemas/ProfileLike" } LikeProps: type: object required: [id, created_at] properties: id: { $ref: "#/components/schemas/Identifier" } created_at: type: string format: date-time ProfileLikeListResult: allOf: - $ref: "#/components/schemas/PaginatedResult" - type: object required: [likes] properties: likes: { $ref: "#/components/schemas/ProfileLikeList" } LikeData: type: object required: [likes, liked] properties: likes: { $ref: "#/components/schemas/LikeCount" } liked: { $ref: "#/components/schemas/LikeStatus" } LikeCount: description: | A simple count of likes for contexts where pulling the full list would be overkill. For use on minimal item reference schemas. type: integer LikeScore: description: The total number of likes received by a member. type: integer LikeStatus: description: | A boolean indicating if the account in context has liked this item. type: boolean # # .d8888b. 888 888 888 d8b # d88P Y88b 888 888 888 Y8P # 888 888 888 888 888 # 888 .d88b. 888 888 .d88b. .d8888b 888888 888 .d88b. 88888b. # 888 d88""88b 888 888 d8P Y8b d88P" 888 888 d88""88b 888 "88b # 888 888 888 888 888 888 88888888 888 888 888 888 888 888 888 # Y88b d88P Y88..88P 888 888 Y8b. Y88b. Y88b. 888 Y88..88P 888 888 # "Y8888P" "Y88P" 888 888 "Y8888 "Y8888P "Y888 888 "Y88P" 888 888 # Collection: description: | A collection is a group of threads owned by a user. It allows users to curate their own lists of content from the site. Collections can only contain root level posts (threads) with titles and slugs to link to. type: object allOf: - $ref: "#/components/schemas/CommonProperties" - $ref: "#/components/schemas/CollectionCommonProps" - $ref: "#/components/schemas/CollectionAdditionalProps" CollectionWithItems: description: | The full properties of a collection, for rendering a single collection somewhere where you can afford to show all the items in the collection. type: object required: [items] allOf: - $ref: "#/components/schemas/CommonProperties" - $ref: "#/components/schemas/CollectionCommonProps" - required: [items] properties: items: { $ref: "#/components/schemas/CollectionItemList" } CollectionCommonProps: description: A reference to the collection type: object required: [name, slug, owner] properties: name: { $ref: "#/components/schemas/CollectionName" } slug: { $ref: "#/components/schemas/CollectionSlug" } description: { $ref: "#/components/schemas/CollectionDescription" } owner: { $ref: "#/components/schemas/ProfileReference" } CollectionAdditionalProps: type: object required: [item_count, has_queried_item] properties: item_count: type: integer has_queried_item: type: boolean CollectionList: type: array items: { $ref: "#/components/schemas/Collection" } CollectionInitialProps: type: object required: [name] properties: name: { $ref: "#/components/schemas/CollectionName" } slug: { $ref: "#/components/schemas/CollectionSlug" } description: { $ref: "#/components/schemas/CollectionDescription" } CollectionMutableProps: type: object properties: name: { $ref: "#/components/schemas/CollectionName" } slug: { $ref: "#/components/schemas/CollectionSlug" } description: { $ref: "#/components/schemas/CollectionDescription" } CollectionItemList: type: array items: { $ref: "#/components/schemas/CollectionItem" } CollectionItem: allOf: - $ref: "#/components/schemas/CommonProperties" - $ref: "#/components/schemas/CollectionItemMetadata" - required: [item] properties: item: { $ref: "#/components/schemas/DatagraphItem" } CollectionItemMetadata: type: object required: [owner, added_at, membership_type] properties: owner: $ref: "#/components/schemas/ProfileReference" added_at: type: string format: date-time description: The time that the item was added to the collection. membership_type: $ref: "#/components/schemas/CollectionItemMembershipType" relevance_score: $ref: "#/components/schemas/RelevanceScore" CollectionItemMembershipType: type: string enum: [normal, submission_review, submission_accepted] CollectionStatus: type: object required: [in_collections, has_collected] properties: in_collections: { $ref: "#/components/schemas/CollectionCount" } has_collected: { $ref: "#/components/schemas/HasCollected" } CollectionCount: description: How many collections has this item been added to? type: integer HasCollected: description: | A boolean indicating if the account in context has collected this item. type: boolean CollectionName: type: string CollectionSlug: $ref: "#/components/schemas/Mark" CollectionDescription: type: string # # 888b 888 888 # 8888b 888 888 # 88888b 888 888 # 888Y88b 888 .d88b. .d88888 .d88b. # 888 Y88b888 d88""88b d88" 888 d8P Y8b # 888 Y88888 888 888 888 888 88888888 # 888 Y8888 Y88..88P Y88b 888 Y8b. # 888 Y888 "Y88P" "Y88888 "Y8888 # Node: description: | A node is a text document with children and assets. It serves as an abstraction for grouping structured data objects. It can represent things such as brands, manufacturers, authors, directors, etc. Nodes can be referenced in content posts and they also have their own content. type: object allOf: - $ref: "#/components/schemas/CommonProperties" - $ref: "#/components/schemas/NodeCommonProps" NodeWithChildren: description: | The full properties of a node including all child nodes. type: object required: [children] allOf: - $ref: "#/components/schemas/Node" - $ref: "#/components/schemas/DatagraphRecommendations" - required: [properties, child_property_schema, children] properties: properties: { $ref: "#/components/schemas/PropertyList" } child_property_schema: $ref: "#/components/schemas/PropertySchemaList" children: type: array items: { $ref: "#/components/schemas/NodeWithChildren" } NodeName: type: string NodeSlug: $ref: "#/components/schemas/Slug" NodeDescription: type: string NodeCommonProps: description: The main properties of a node. type: object required: - name - slug - assets - description - owner - hide_child_tree - tags - visibility - meta properties: name: { $ref: "#/components/schemas/NodeName" } slug: { $ref: "#/components/schemas/NodeSlug" } assets: { $ref: "#/components/schemas/AssetList" } link: { $ref: "#/components/schemas/LinkReference" } description: { $ref: "#/components/schemas/NodeDescription" } primary_image: { $ref: "#/components/schemas/Asset" } content: { $ref: "#/components/schemas/PostContent" } owner: { $ref: "#/components/schemas/ProfileReference" } parent: { $ref: "#/components/schemas/Node" } hide_child_tree: description: | A boolean indicating if the children of this node tree are hidden when querying the full tree. This is useful for nodes that contain a large amount of children and do not need to be rendered in a tree view (such as a sidebar navigation). These children can still be accessed via the node or node children GET operations for rendering. type: boolean tags: { $ref: "#/components/schemas/TagReferenceList" } visibility: { $ref: "#/components/schemas/Visibility" } relevance_score: { $ref: "#/components/schemas/RelevanceScore" } meta: { $ref: "#/components/schemas/Metadata" } NodeTree: type: array items: { $ref: "#/components/schemas/NodeWithChildren" } NodeList: type: array items: { $ref: "#/components/schemas/Node" } NodeListResult: allOf: - { $ref: "#/components/schemas/PaginatedResult" } - type: object required: [nodes] properties: nodes: { $ref: "#/components/schemas/NodeTree" } NodeInitialProps: type: object required: [name] properties: name: { $ref: "#/components/schemas/NodeName" } slug: { $ref: "#/components/schemas/NodeSlug" } asset_ids: { $ref: "#/components/schemas/AssetIDs" } asset_sources: { $ref: "#/components/schemas/AssetSourceList" } url: { $ref: "#/components/schemas/URL" } description: { $ref: "#/components/schemas/NodeDescription" } primary_image_asset_id: { $ref: "#/components/schemas/AssetID" } content: { $ref: "#/components/schemas/PostContent" } parent: { $ref: "#/components/schemas/NodeSlug" } hide_child_tree: type: boolean properties: { $ref: "#/components/schemas/PropertyMutationList" } tags: { $ref: "#/components/schemas/TagNameList" } visibility: { $ref: "#/components/schemas/Visibility" } meta: { $ref: "#/components/schemas/Metadata" } NodeMutableProps: description: | Note: Properties are replace-all and are not merged with existing. type: object properties: name: { $ref: "#/components/schemas/NodeName" } slug: { $ref: "#/components/schemas/NodeSlug" } asset_ids: { $ref: "#/components/schemas/AssetIDs" } asset_sources: { $ref: "#/components/schemas/AssetSourceList" } url: type: string format: url nullable: true description: { $ref: "#/components/schemas/NodeDescription" } primary_image_asset_id: { $ref: "#/components/schemas/NullableIdentifier" } content: { $ref: "#/components/schemas/PostContent" } parent: { $ref: "#/components/schemas/NodeSlug" } hide_child_tree: type: boolean properties: { $ref: "#/components/schemas/PropertyMutationList" } tags: { $ref: "#/components/schemas/TagNameList" } meta: { $ref: "#/components/schemas/Metadata" } NodeGenerateTitleRequest: description: | A request for a generated title for a node. A request for a generated title does not use the existing content on a node but takes the current client's content state (from an "edit mode" text box for example) and sends that in order to generate a potential title using an LLM. type: object required: [content] properties: content: type: string NodeGenerateTitleResult: description: The result of a title generation request from an LLM. type: object required: [title] properties: title: type: string NodeGenerateTagsRequest: description: | A request for generated tags for a node. A request for generated tags does not use the existing content on a node but takes the current client's content state (from an "edit mode" text box for example) and sends that in order to generate potential tags using an LLM. type: object required: [content] properties: content: type: string NodeGenerateTagsResult: description: The result of a tag generation request from an LLM. type: object required: [tags] properties: tags: { $ref: "#/components/schemas/TagNameList" } NodeGenerateContentRequest: description: | A request for generated content for a node. A request for generated content does not use the existing content on a node but takes the current client's content state (from an "edit mode" text box for example) and sends that in order to generate potential content using an LLM. type: object required: [content] properties: content: type: string NodeGenerateContentResult: description: The result of a content generation request from an LLM. type: object required: [content] properties: content: type: string PropertyMutableProps: description: | Note: Properties are replace-all and are not merged with existing. type: object required: [properties] properties: properties: { $ref: "#/components/schemas/PropertyMutationList" } Property: type: object required: [fid, name, type, sort, value] properties: fid: { $ref: "#/components/schemas/Identifier" } name: { $ref: "#/components/schemas/PropertyName" } type: { $ref: "#/components/schemas/PropertyType" } value: { $ref: "#/components/schemas/PropertyValue" } sort: type: string PropertyList: type: array items: { $ref: "#/components/schemas/Property" } PropertyName: type: string PropertyType: type: string enum: - text - number - timestamp - boolean PropertyValue: type: string PropertySortKey: type: string PropertyMutation: description: | A property mutation is a change to a property on a node. It can be used to update existing properties or add new properties to a node. When a property already exists by name/fid, type and sort columns are optional. type: object required: [name, value] properties: fid: { $ref: "#/components/schemas/Identifier" } name: { $ref: "#/components/schemas/PropertyName" } value: { $ref: "#/components/schemas/PropertyValue" } type: { $ref: "#/components/schemas/PropertyType" } sort: { $ref: "#/components/schemas/PropertySortKey" } PropertyMutationList: type: array items: { $ref: "#/components/schemas/PropertyMutation" } PropertySchema: type: object required: [fid, name, type, sort] properties: fid: { $ref: "#/components/schemas/Identifier" } name: { $ref: "#/components/schemas/PropertyName" } type: { $ref: "#/components/schemas/PropertyType" } sort: type: string PropertySchemaList: type: array items: { $ref: "#/components/schemas/PropertySchema" } PropertySchemaMutableProps: description: | Mutating property schemas permits updating existing fields as well as adding new fields. The discinction is determined by the presence of the `id` field. When an `id` field is provided, the operation is treated as an update operation where any of the other fields will be used to write new values. If an `id` field is omitted, the schema is considered a new field and is subject to a uniqueness constraint on the `name` field. type: object required: [name, type, sort] properties: fid: { $ref: "#/components/schemas/Identifier" } name: { $ref: "#/components/schemas/PropertyName" } type: { $ref: "#/components/schemas/PropertyType" } sort: type: string NodePositionMutableProps: type: object description: | Parameters for repositioning a node in the hierarchy. You may change the node's parent using `parent`, and/or reposition it among its siblings using one of: `before`, `after`, or `index`. Using multiple reordering properties is not allowed. properties: parent: type: string nullable: true description: | Optional new parent node slug. Set to null to move node to the root. before: type: string description: Move this node before the sibling with this ID. after: type: string description: Move this node after the sibling with this ID. example: parent: "d031a8do2dtqtahe9nl0" before: "cc5lnd2s1s4652adtu50" # # 888 d8b 888 # 888 Y8P 888 # 888 888 # 888 888 88888b. 888 888 # 888 888 888 "88b 888 .88P # 888 888 888 888 888888K # 888 888 888 888 888 "88b # 88888888 888 888 888 888 888 # Link: description: | A web address with content information such as title, description, etc. type: object required: [url, assets, slug, domain] allOf: - { $ref: "#/components/schemas/CommonProperties" } - { $ref: "#/components/schemas/LinkReferenceProps" } - { $ref: "#/components/schemas/LinkProps" } - { $ref: "#/components/schemas/DatagraphRecommendations" } LinkReference: description: | A minimal object used to refer to a link without sending too much data. type: object allOf: - { $ref: "#/components/schemas/CommonProperties" } - { $ref: "#/components/schemas/LinkReferenceProps" } LinkProps: description: | All the resources that a link has been referenced in. May be large. required: [assets, posts, nodes, collections] properties: assets: { $ref: "#/components/schemas/AssetList" } posts: { $ref: "#/components/schemas/PostReferenceList" } nodes: { $ref: "#/components/schemas/NodeList" } LinkReferenceProps: type: object required: [url, slug, domain] properties: url: { $ref: "#/components/schemas/URL" } slug: { $ref: "#/components/schemas/LinkSlug" } domain: { $ref: "#/components/schemas/LinkDomain" } title: { $ref: "#/components/schemas/LinkTitle" } description: { $ref: "#/components/schemas/LinkDescription" } favicon_image: { $ref: "#/components/schemas/Asset" } primary_image: { $ref: "#/components/schemas/Asset" } LinkTitle: type: string example: "The Open Graph Protocol" LinkDescription: type: string example: "The Open Graph protocol enables any web page to become a rich object in a social graph." LinkSlug: type: string example: github-com-southclaws-storyden LinkDomain: type: string example: github.com LinkReferenceList: type: array items: { $ref: "#/components/schemas/LinkReference" } LinkListResult: allOf: - { $ref: "#/components/schemas/PaginatedResult" } - type: object required: [links] properties: links: { $ref: "#/components/schemas/LinkReferenceList" } LinkInitialProps: type: object required: [url] properties: url: { $ref: "#/components/schemas/URL" } title: { $ref: "#/components/schemas/LinkTitle" } description: { $ref: "#/components/schemas/LinkDescription" } # # 8888888b. 888 888 # 888 "Y88b 888 888 # 888 888 888 888 # 888 888 8888b. 888888 8888b. .d88b. 888d888 8888b. 88888b. 88888b. # 888 888 "88b 888 "88b d88P"88b 888P" "88b 888 "88b 888 "88b # 888 888 .d888888 888 .d888888 888 888 888 .d888888 888 888 888 888 # 888 .d88P 888 888 Y88b. 888 888 Y88b 888 888 888 888 888 d88P 888 888 # 8888888P" "Y888888 "Y888 "Y888888 "Y88888 888 "Y888888 88888P" 888 888 # 888 888 # Y8b d88P 888 # "Y88P" 888 # DatagraphSearchResult: type: object allOf: - { $ref: "#/components/schemas/PaginatedResult" } - type: object required: [items] properties: items: { $ref: "#/components/schemas/DatagraphItemList" } DatagraphItemList: type: array items: { $ref: "#/components/schemas/DatagraphItem" } DatagraphItem: type: object discriminator: propertyName: kind mapping: post: "#/components/schemas/DatagraphItemPost" thread: "#/components/schemas/DatagraphItemThread" reply: "#/components/schemas/DatagraphItemReply" node: "#/components/schemas/DatagraphItemNode" profile: "#/components/schemas/DatagraphItemProfile" oneOf: - $ref: "#/components/schemas/DatagraphItemPost" - $ref: "#/components/schemas/DatagraphItemThread" - $ref: "#/components/schemas/DatagraphItemReply" - $ref: "#/components/schemas/DatagraphItemNode" - $ref: "#/components/schemas/DatagraphItemProfile" DatagraphItemPost: type: object required: [kind, ref] properties: kind: { $ref: "#/components/schemas/DatagraphItemKind" } ref: { $ref: "#/components/schemas/Post" } DatagraphItemThread: type: object required: [kind, ref] properties: kind: { $ref: "#/components/schemas/DatagraphItemKind" } ref: { $ref: "#/components/schemas/Thread" } DatagraphItemReply: type: object required: [kind, ref] properties: kind: { $ref: "#/components/schemas/DatagraphItemKind" } ref: { $ref: "#/components/schemas/Reply" } DatagraphItemNode: type: object required: [kind, ref] properties: kind: { $ref: "#/components/schemas/DatagraphItemKind" } ref: { $ref: "#/components/schemas/Node" } DatagraphItemProfile: type: object required: [kind, ref] properties: kind: { $ref: "#/components/schemas/DatagraphItemKind" } ref: { $ref: "#/components/schemas/PublicProfile" } DatagraphItemKind: type: string enum: [post, thread, reply, node, collection, profile, event] DatagraphRecommendations: required: [recomentations] properties: recomentations: { $ref: "#/components/schemas/DatagraphItemList" } # # 8888888888 888 # 888 888 # 888 888 # 8888888 888 888 .d88b. 88888b. 888888 # 888 888 888 d8P Y8b 888 "88b 888 # 888 Y88 88P 88888888 888 888 888 # 888 Y8bd8P Y8b. 888 888 Y88b. # 8888888888 Y88P "Y8888 888 888 "Y888 # Event: description: | An event represents any kind of event, such as an online or in-person gathering, a conference, a workshop, a webinar, etc. Events will contain a start and end timestamp and may have a location and other metadata. Each event also gets its own thread for discussion and planning. This is automatically created for every new event and is linked to the event. type: object allOf: - { $ref: "#/components/schemas/CommonProperties" } - { $ref: "#/components/schemas/EventReferenceProps" } - { $ref: "#/components/schemas/EventProps" } EventReference: description: | A minimal object used to refer to an event without providing all data. type: object allOf: - { $ref: "#/components/schemas/CommonProperties" } - { $ref: "#/components/schemas/EventReferenceProps" } EventList: type: array items: { $ref: "#/components/schemas/EventReference" } EventListResult: allOf: - { $ref: "#/components/schemas/PaginatedResult" } - type: object required: [events] properties: events: { $ref: "#/components/schemas/EventList" } EventProps: type: object required: [thread] properties: thread: { $ref: "#/components/schemas/Thread" } EventReferenceProps: type: object required: - name - slug - description - time_range - participants - participation_policy - visibility - location properties: name: { $ref: "#/components/schemas/EventName" } slug: { $ref: "#/components/schemas/EventSlug" } description: { $ref: "#/components/schemas/EventDescription" } time_range: { $ref: "#/components/schemas/EventTimeRange" } primary_image: { $ref: "#/components/schemas/Asset" } participants: { $ref: "#/components/schemas/EventParticipantList" } participation_policy: { $ref: "#/components/schemas/EventParticipationPolicy" } visibility: { $ref: "#/components/schemas/Visibility" } location: { $ref: "#/components/schemas/EventLocation" } capacity: { $ref: "#/components/schemas/EventCapacity" } meta: { $ref: "#/components/schemas/Metadata" } EventInitialProps: type: object required: - name - content - time_range - participation_policy - visibility - thread_category_id properties: name: { $ref: "#/components/schemas/EventName" } slug: { $ref: "#/components/schemas/EventSlug" } description: { $ref: "#/components/schemas/EventDescription" } content: { $ref: "#/components/schemas/PostContent" } time_range: { $ref: "#/components/schemas/EventTimeRange" } primary_image_asset_id: { $ref: "#/components/schemas/AssetID" } participation_policy: { $ref: "#/components/schemas/EventParticipationPolicy" } visibility: { $ref: "#/components/schemas/Visibility" } location: { $ref: "#/components/schemas/EventLocation" } capacity: { $ref: "#/components/schemas/EventCapacity" } thread_category_id: { $ref: "#/components/schemas/Identifier" } meta: { $ref: "#/components/schemas/Metadata" } EventMutableProps: type: object properties: name: { $ref: "#/components/schemas/EventName" } slug: { $ref: "#/components/schemas/EventSlug" } description: { $ref: "#/components/schemas/EventDescription" } content: { $ref: "#/components/schemas/PostContent" } time_range: { $ref: "#/components/schemas/EventTimeRange" } primary_image_asset_id: { $ref: "#/components/schemas/AssetID" } participation_policy: { $ref: "#/components/schemas/EventParticipationPolicy" } visibility: { $ref: "#/components/schemas/Visibility" } location: { $ref: "#/components/schemas/EventLocation" } capacity: { $ref: "#/components/schemas/EventCapacity" } meta: { $ref: "#/components/schemas/Metadata" } EventName: type: string example: "Friday beers, coding and design hack night" EventSlug: type: string example: friday-beers-coding-design-hack-night EventDescription: type: string example: "Join us for a night of coding, design and beers!" EventTimeRange: description: | A time range for an event, which may span multiple days or times of day. type: object required: [start, end] properties: start: type: string format: date-time end: type: string format: date-time EventParticipantList: description: A list of attendees, hosts and invites for an event. type: array items: { $ref: "#/components/schemas/EventParticipant" } EventParticipant: type: object required: [profile, role, status] properties: profile: { $ref: "#/components/schemas/ProfileReference" } role: { $ref: "#/components/schemas/EventParticipantRole" } status: { $ref: "#/components/schemas/EventParticipationStatus" } EventParticipantMutableProps: type: object default: { status: "requested", role: "attendee" } properties: role: { $ref: "#/components/schemas/EventParticipantRole" } status: { $ref: "#/components/schemas/EventParticipationStatus" } EventParticipantRole: type: string enum: [attendee, host] EventParticipationStatus: type: string enum: [requested, invited, attending, declined] EventParticipationPolicy: type: string enum: [open, closed, invite_only] EventLocation: description: | An event location can be either physical or virtual. A physical location may have an address or coordinates. A virtual location may have a link. type: object discriminator: propertyName: location_type mapping: physical: "#/components/schemas/EventLocationPhysical" virtual: "#/components/schemas/EventLocationVirtual" oneOf: - $ref: "#/components/schemas/EventLocationPhysical" - $ref: "#/components/schemas/EventLocationVirtual" EventLocationType: type: string enum: [physical, virtual] EventLocationPhysical: description: | A physical location for an event, such as a venue, a park, a street address, etc. This location may have a name, address, and coordinates. A URL may also be added for a Google maps link etc. type: object required: [location_type, name] properties: location_type: $ref: "#/components/schemas/EventLocationType" name: type: string address: type: string latitude: type: number longitude: type: number url: type: string EventLocationVirtual: description: | A virtual location for an event, such as a URL, a video conference link, a Discord server, etc. This location may have a URL. type: object required: [location_type, name] properties: location_type: $ref: "#/components/schemas/EventLocationType" name: type: string url: type: string EventCapacity: description: The maximum number of attendees that can attend the event. type: integer securitySchemes: browser: type: apiKey in: cookie name: storyden-session access_key: type: http scheme: bearer webauthn: type: apiKey in: cookie name: "storyden-webauthn-session" # # ..:. .***= # .+#%%%%%#+ ... :%%%+ # #%%%+==+#. =%%%. :%%%+ # :%%%%: -*%%%=-. :==+==: ---: :== ---- .---- .-===-:%%%+ :==+=-: .---..-==-. # +%%%%%#*=. #%%%%%%-.+%%%%#%%%%+ .%%%##%%% -%%%#. .#%%#=*%%%%%%%%%%+ =%%#+=+#%#- -%%%#%#%%%%* # .-+#%%%%%- +%%%:..#%%%= +%%%*.%%%#-. . :#%%#..#%%#:#%%%= .+%%%+-%%%*===+%%%:-%%%+ .#%%%. # +%%%# =%%%. .%%%# .%%%%.%%%+ .#%%##%%#:.%%%# :%%%+=%%%*+++++++:-%%%: +%%%. # .##*===#%%%= =%%%. +%%%#=-=#%%%-.%%%+ .#%%%%*. +%%%#=-=#%%%+.#%%+:..=++= -%%%: +%%%. # -*%%%%%%%*- =%%%. :*%%%%%%#+: .%%%+ -%%%#. -*%%%%%*%%%+ .+#%%%%%%+. -%%%: +%%%. # .:::. .:::. -%%%*. .:. .:::. # -%%%* # -***+ #

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Southclaws/storyden'

If you have feedback or need assistance with the MCP directory API, please join our Discord server