openapi.yaml•228 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"
#
# ..:. .***=
# .+#%%%%%#+ ... :%%%+
# #%%%+==+#. =%%%. :%%%+
# :%%%%: -*%%%=-. :==+==: ---: :== ---- .---- .-===-:%%%+ :==+=-: .---..-==-.
# +%%%%%#*=. #%%%%%%-.+%%%%#%%%%+ .%%%##%%% -%%%#. .#%%#=*%%%%%%%%%%+ =%%#+=+#%#- -%%%#%#%%%%*
# .-+#%%%%%- +%%%:..#%%%= +%%%*.%%%#-. . :#%%#..#%%#:#%%%= .+%%%+-%%%*===+%%%:-%%%+ .#%%%.
# +%%%# =%%%. .%%%# .%%%%.%%%+ .#%%##%%#:.%%%# :%%%+=%%%*+++++++:-%%%: +%%%.
# .##*===#%%%= =%%%. +%%%#=-=#%%%-.%%%+ .#%%%%*. +%%%#=-=#%%%+.#%%+:..=++= -%%%: +%%%.
# -*%%%%%%%*- =%%%. :*%%%%%%#+: .%%%+ -%%%#. -*%%%%%*%%%+ .+#%%%%%%+. -%%%: +%%%.
# .:::. .:::. -%%%*. .:. .:::.
# -%%%*
# -***+
#