# Docs - Introduction: Getting started with Storyden. - **Introduction** - [Welcome to Storyden!](/docs/introduction): It's really cool! - [What is Storyden?](/docs/introduction/what-is-storyden): It's basically run-your-own-reddit, privately and securely. - **Setup** - VPS - [VPS](/docs/introduction/vps): Deploy Storyden onto a Linux machine in minutes! - [Docker Compose](/docs/introduction/vps/docker-compose): Setting up a Storyden container with Docker Compose - [Docker](/docs/introduction/vps/docker): Setting up a Storyden container with Docker - [Fly.io](/docs/introduction/fly): Setting up a Storyden instance on Fly.io in under 5 minutes! - [Local development](/docs/introduction/local-dev) - **Concepts** - Discussion - [Discussion](/docs/introduction/discussion) - [Threads](/docs/introduction/discussion/threads): Where the discussion begins. - [Categories](/docs/introduction/discussion/categories): Where discussions are organised. - [Tags](/docs/introduction/discussion/tags): How topics are discovered. - [Replies](/docs/introduction/discussion/replies): How the conversation flows. - [Reacts](/docs/introduction/discussion/reacts): For when you want to show some emotion! - Library - [Library](/docs/introduction/library): The place for collecting, organising and curating communal knowledge. Powered by AI! - [Pages](/docs/introduction/library/pages) - Semdex - [Semdex](/docs/introduction/semdex): The Storyden semantic search index. - [With local vector DB](/docs/introduction/semdex/local): A local embedded vector database for testing. - [With Pinecone](/docs/introduction/semdex/pinecone) - Autofill - [Autofill](/docs/introduction/autofill): Autofill resource properties using language models. - Collections - [Collections](/docs/introduction/collections): Curate and collect content across the community. - [Links](/docs/introduction/links): Shared bookmarks, indexed for easy search. - Members - [Members](/docs/introduction/members): The only two industries that call their patrons "users" are drugs and tech. - [Permissions](/docs/introduction/members/permissions): Storyden provides a set of permissions for granular access control via Roles. - [Roles](/docs/introduction/members/roles): Roles are a way to group members together and assign them specific permissions. - [Marks](/docs/introduction/marks): Marks are flexible shapeshifting identifiers for use in slugs and API calls. - Content - [Content](/docs/introduction/content): Enhanced HTML structured content for handling @mentions, cross references and more. - [References](/docs/introduction/content/references): The backbone of the datagraph. - [Security](/docs/introduction/content/security): Never trust the client! - Datagraph - [Datagraph](/docs/introduction/datagraph): The fabric that binds content together. - **Extending** - MCP (Model Context Protocol) - [MCP (Model Context Protocol)](/docs/introduction/mcp): Storyden comes with an MCP server built in! The only limit is your imagination! (and your AI usage credits...) - API - [API](/docs/introduction/api) - OAuth 2.0 & OIDC: Use Storyden as an OAuth 2.0 authorization server and OpenID Connect provider. - [OAuth 2.0 & OpenID Connect](/docs/introduction/oauth): Storyden can act as an OAuth 2.0 authorisation server and OpenID Connect provider, letting external applications authenticate as your members. - [Device Authorization Flow](/docs/introduction/oauth/device-flow): Let CLI tools, headless apps, and other input-limited devices authenticate as Storyden members. - [Authorization Code Flow](/docs/introduction/oauth/authorization-code): Standard OAuth 2.0 authorization code flow with PKCE for web and native apps. - [Scopes & Permissions](/docs/introduction/oauth/scopes): How OAuth scopes map to Storyden permissions, and how tokens are granted based on what members are actually allowed to do. - [OAuth Clients](/docs/introduction/oauth/clients): Register and manage OAuth 2.0 clients, the applications that can request tokens from your Storyden instance. - [Client Registration](/docs/introduction/oauth/client-registration): How OAuth clients identify themselves to Storyden: pre-registered clients, Dynamic Client Registration (DCR), and Client ID Metadata Documents (CIMD) for MCP connectors. - Plugins - [Plugins](/docs/introduction/plugins): Extend, embrace, ex... no wait, not that! - Frontend - [Frontend](/docs/introduction/frontend): Build your own frontend against the Storyden API. Its kinda like a CMS without a head. - [Routing and Resources](/docs/introduction/frontend/resolve): How the API and frontend work together to point users at the right pages. - Extending: Learn how to extend Storyden with custom plugins. - [Extending Storyden](/docs/extending): Add custom behaviour to your Storyden site with plugins. - **Quick Start** - [Plugin Model](/docs/extending/model): The architecture and lifecycle model for Storyden plugins. - Tutorials: Hands-on plugin walkthroughs. - [Tutorials](/docs/extending/tutorials): Learn how to build your own plugins for your Storyden instance or others. - [Build a Go Plugin](/docs/extending/tutorials/go-plugin): Build, package, and use a tiny Storyden plugin in Go. - **Reference** - Supervised Runtimes - [Local](/docs/extending/supervised-runtimes/local) - [Sprites](/docs/extending/supervised-runtimes/sprites) - [Manifest](/docs/extending/manifest): Generated schema reference for plugin manifests. - [Capabilities and Limits](/docs/extending/capabilities): What plugins can do today, and where the boundaries are. - [Security](/docs/extending/security): Token, transport, identity, and permission boundaries for plugins. - API - [API](/docs/extending/api): How plugin HTTP endpoints and RPC methods work together. - [Events](/docs/extending/api/events): Generated reference for Storyden plugin event payloads. - Host to Plugin - [Host to Plugin](/docs/extending/api/host-to-plugin): Generated method reference pages for Host to Plugin RPC. - [configure](/docs/extending/api/host-to-plugin/configure): Host to Plugin RPC method. - [event](/docs/extending/api/host-to-plugin/event): Host to Plugin RPC method. - [ping](/docs/extending/api/host-to-plugin/ping): Host to Plugin RPC method. - [robot_model_provider_generate](/docs/extending/api/host-to-plugin/robot_model_provider_generate): Host to Plugin RPC method. - [robot_model_provider_list_models](/docs/extending/api/host-to-plugin/robot_model_provider_list_models): Host to Plugin RPC method. - [robot_tool_call](/docs/extending/api/host-to-plugin/robot_tool_call): Host to Plugin RPC method. - Plugin to Host - [Plugin to Host](/docs/extending/api/plugin-to-host): Generated method reference pages for Plugin to Host RPC. - [access_get](/docs/extending/api/plugin-to-host/access_get): Plugin to Host RPC method. - [get_config](/docs/extending/api/plugin-to-host/get_config): Plugin to Host RPC method. - [robot_run](/docs/extending/api/plugin-to-host/robot_run): Plugin to Host RPC method. - Cookbook: More than a static forum? Mix features together to make... more features? - [Cookbook](/docs/cookbook): More than a static forum? Mix features together to make... more features? - [Discord Connector](/docs/cookbook/discord-integration-plugin): A Discord-first community workflow for building a Storyden knowledgebase with plugins. - Reference: Reference manuals for specific Storyden features. - **Introduction** - [Reference](/docs/reference): The instruction manual for Storyden. Print it out and staple it together! - **Configuring Storyden** - [Configuration via Environment Variables](/docs/reference/configuration): Reference for configuring Storyden with environment variables. - [SSR Client IP Forwarding](/docs/reference/ssr-client-ip): How Storyden preserves browser IP context for SSR API requests and how to configure client IP mode. - Email - [Email](/docs/reference/email): Email in Storyden is optional and intentionally minimal. - [SMTP](/docs/reference/email/smtp): Configure Storyden to send emails through an SMTP server. - [SendGrid](/docs/reference/email/sendgrid): Configure Storyden to send emails through SendGrid. - [Settings Page](/docs/reference/settings): The various settings available in the admin dashboard and how to use them to run the best site you can! - **Data management** - Database - [Database](/docs/reference/database): Configure database storage for your Storyden deployment. - [SQLite](/docs/reference/database/sqlite): Fast embedded database with zero configuration - [PostgreSQL](/docs/reference/database/postgresql): A proven relational database for serious deployments - [libSQL/Turso](/docs/reference/database/turso): Distributed SQLite with global edge replication - Search: Storyden search providers. - [Search](/docs/reference/search): Configure search capabilities for your Storyden deployment. - [Database](/docs/reference/search/database): Simple, built-in, default keyword-based search - [Bleve](/docs/reference/search/bleve): Fast local-disk search capabilities via Bleve - [Redis](/docs/reference/search/redis): Fast search indexing via Redis full-text capabilities. - [Re-indexing](/docs/reference/search/reindexing): Re-build Storyden's search index manually. - **Authentication** - OAuth2 Providers - [OAuth2 Providers](/docs/reference/oauth): Configure third-party authentication for your Storyden community - [Google OAuth](/docs/reference/oauth/google): Configure Google Sign-In for your Storyden community - [GitHub OAuth](/docs/reference/oauth/github): Enable GitHub authentication for developer communities - [Discord OAuth](/docs/reference/oauth/discord): Enable Discord authentication for gaming and community platforms - [Keycloak OAuth](/docs/reference/oauth/keycloak): Use Keycloak or any OIDC-compatible provider for authentication - [Access Keys](/docs/reference/access-keys): API authentication using access keys - API Reference: The Storyden RESTful API. - [Overview](/docs/api): Build powerful clients, automations and more with the API. - Misc - [Banner Get](/docs/api/misc/BannerGet): Get the banner image. - [Banner Upload](/docs/api/misc/BannerUpload): Upload and process the installation's banner image. - [API documentation](/docs/api/misc/GetDocs): 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. - [Get Info](/docs/api/misc/GetInfo): 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. - [Get Session](/docs/api/misc/GetSession): Provides the instance settings and, if authenticated, the member's settings as well. This is effectively the same as calling `GetInfo` and `AccountGet` at the same time. This is a convenience endpoint to reduce round-trips for root level data needed to render a client's initial UI. - [OpenAPI specification](/docs/api/misc/GetSpec): 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. - [Get the software version string.](/docs/api/misc/GetVersion): The version number includes the date and time of the release build as well as a short representation of the Git commit hash. - [Icon Get](/docs/api/misc/IconGet): Get the logo icon image. - [Icon Upload](/docs/api/misc/IconUpload): Upload and process the installation's logo image. - [Send Beacon](/docs/api/misc/SendBeacon): 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. - Admin - [Admin Access Key Delete](/docs/api/admin/AdminAccessKeyDelete): Revoke an access key. This will immediately invalidate the key and it will no longer be usable for authentication. - [Admin Access Key List](/docs/api/admin/AdminAccessKeyList): 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. - [Admin Account Ban Create](/docs/api/admin/AdminAccountBanCreate): 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. - [Admin Account Ban Remove](/docs/api/admin/AdminAccountBanRemove): Given the account is suspended, remove the suspended state. - [Admin O Auth Client Create](/docs/api/admin/AdminOAuthClientCreate): Create an OAuth client. Confidential clients receive a generated secret once at creation time and must authenticate to `/oauth/token` when using confidential grants. Public clients do not receive or use a client secret. - [Admin O Auth Client Delete](/docs/api/admin/AdminOAuthClientDelete): Delete an OAuth client. Deleting a client also removes its pending OAuth records and refresh tokens, preventing existing grants from being renewed. Existing JWT access tokens are self-contained and remain valid until expiry. - [Admin O Auth Client Get](/docs/api/admin/AdminOAuthClientGet): Read an OAuth client. OAuth clients represent application/software identity. They are not the same thing as a user authorisation; user-owned authorisations are represented by device authorisations, authorisation requests, and refresh tokens. - [Admin O Auth Client List](/docs/api/admin/AdminOAuthClientList): List OAuth clients registered for this instance. This admin view includes both member-created third-party clients and built-in first-party clients. Built-in clients will not be owned by an account; their grants and refresh tokens are owned by the approving account instead. - [Admin O Auth Client Update](/docs/api/admin/AdminOAuthClientUpdate): Update an OAuth client. Changing allowed grants or scopes only affects future authorisation and refresh operations. Already-issued JWT access tokens remain valid until their expiry unless their signing key is rotated. For account-owned clients, allowed permission scopes must be grantable by the owning account. An account with `ADMINISTRATOR` may configure any Storyden permission scope because `ADMINISTRATOR` implicitly grants all permissions. - [Admin O Auth Device Authorisation List](/docs/api/admin/AdminOAuthDeviceAuthorisationList): List OAuth device authorisation records. Device authorisation records are short-lived records created by the OAuth 2.0 Device Authorization Grant. They are not owned by an account until a signed-in user claims and approves or denies the user code. - [Admin O Auth Device Authorization List](/docs/api/admin/AdminOAuthDeviceAuthorizationList): List OAuth device authorisation records. Device authorisation records are short-lived records created by the OAuth 2.0 Device Authorisation Grant. They are not owned by an account until a signed-in user claims and approves or denies the user code. - [Admin O Auth Refresh Token Delete](/docs/api/admin/AdminOAuthRefreshTokenDelete): Revoke an OAuth refresh token. This prevents future refresh-token use. Because Storyden OAuth access tokens are JWTs, any access token already issued from this grant remains valid until its normal expiry. - [Admin O Auth Refresh Token List](/docs/api/admin/AdminOAuthRefreshTokenList): List OAuth refresh tokens. Refresh tokens are account-owned grants for an OAuth client. Revoking a refresh token prevents future token renewal, but does not immediately invalidate already-issued JWT access tokens. Rotation writes a new row per refresh, so this table grows with usage and the response is paginated. - [Admin Settings Get](/docs/api/admin/AdminSettingsGet): Retrieve all configuration settings for installation. This includes the publicly accessible information for the instance as well as admin-only access to sensitive configuration (environment variables) and settings. - [Admin Settings Update](/docs/api/admin/AdminSettingsUpdate): Update non-env configuration settings for installation. - [Audit Event Get](/docs/api/admin/AuditEventGet): Retrieve a specific audit event by ID. - [Audit Event List](/docs/api/admin/AuditEventList): List audit events for the installation. Audit events track important actions taken by accounts with elevated permissions such as admin accounts and moderators. It also provides error logs for system internal components that could not be responded to the client directly such as background job failures and configuration issues. - [Email Queue List](/docs/api/admin/EmailQueueList): List durable email queue records for this installation. Shows pending, failed and sent deliveries with attempt history for diagnostics. - [Email Queue Retry](/docs/api/admin/EmailQueueRetry): Manually retry a delivery for an email queue record. This is used for failed deliveries. This will create a new delivery attempt and update the email queue record accordingly. - [Moderation Action Create](/docs/api/admin/ModerationActionCreate): Create a new moderation action such as a ban or content purge. - [O Auth Remote Connection Authorize](/docs/api/admin/OAuthRemoteConnectionAuthorize): Start OAuth authorization code with PKCE for a remote OAuth connection and return the authorization URL to open in a browser. - [O Auth Remote Connection Create](/docs/api/admin/OAuthRemoteConnectionCreate): Create a remote OAuth connection using CIMD, DCR, or manual configuration. CIMD is preferred when discovery supports it. - [O Auth Remote Connection List](/docs/api/admin/OAuthRemoteConnectionList): List remote OAuth connections configured for this Storyden instance. - [O Auth Remote Discover](/docs/api/admin/OAuthRemoteDiscover): Discover OAuth configuration for a remote protected resource URL. Storyden fetches protected resource metadata, follows the advertised authorization server, and chooses CIMD, DCR, or manual setup according to the discovered authorization server metadata. - Plugins - [Plugin Add](/docs/api/plugins/PluginAdd): Add a plugin to the instance. This will not install or activate the plugin immediately. It will validate and prepare the plugin for install. Plugins can be uploaded directly as files or via a URL to a repository. - [Plugin Cycle Token](/docs/api/plugins/PluginCycleToken): Cycles the static bearer token for an external plugin and returns the newly generated token. This operation is only valid for external plugins. Supervised plugins cycle their connection token automatically. - [Plugin Delete](/docs/api/plugins/PluginDelete): Completely delete a plugin from the instance. This will uninstall the plugin first then remove its binary file from the storage backend. Some plugins may write additional data to the instance, this will not be removed by this operation unless the plugin cleans up after itself. - [Plugin Download Package](/docs/api/plugins/PluginDownloadPackage): Download the original package archive for a supervised plugin installation. The response body is the same zip archive bytes that were uploaded when the plugin was installed or last updated. - [Plugin Get](/docs/api/plugins/PluginGet): Get information about a specific plugin. - [Plugin Get Configuration](/docs/api/plugins/PluginGetConfiguration): Get the current configuration values for a plugin. The shape of the object is defined by the plugin's manifest and should be used to render the current configuration state in the client, using the layout driven by the result of `PluginGetConfigurationSchema` to build a form-like UI. - [Plugin Get Configuration Schema](/docs/api/plugins/PluginGetConfigurationSchema): Returns the configuration schema for a plugin as defined in its manifest file. The schema should be used to render a configuration form for the plugin in the client so that administrators can configure the plugin. - [Plugin Get Logs](/docs/api/plugins/PluginGetLogs): Stream logs for a supervised plugin. If the plugin is running, this endpoint streams live logs after existing log history is sent. External plugins do not have host-managed logs and this endpoint returns a bad request error for external mode. - [Plugin List](/docs/api/plugins/PluginList): List all plugins that are installed on the instance. - [Plugin Set Active State](/docs/api/plugins/PluginSetActiveState): Change the active state of a plugin. This operation only applies to supervised plugins. - `active`: starts the supervised plugin process. - `inactive`: stops the supervised plugin process. External plugins cannot be managed with this endpoint and will return a bad request error. - [Plugin Update Configuration](/docs/api/plugins/PluginUpdateConfiguration): Update the configuration for a plugin. Each plugin defines its own set of configuration parameters in its manifest and this endpoint accepts any object validated against that schema. When a valid configuration is received, it is sent to the plugin via RPC and the plugin is expected to apply the new configuration to itself internally. - [Plugin Update Manifest](/docs/api/plugins/PluginUpdateManifest): Update the manifest for a plugin. This is used for development of plugins where the manifest may change frequently and it's useful to be able to update it without re-uploading the entire plugin bundle. This only works for External plugins that were created by uploading a manifest directly. It does not work for Supervised plugins. - [Plugin Update Package](/docs/api/plugins/PluginUpdatePackage): Replace the package archive for a supervised plugin installation. The uploaded package manifest must have the same plugin ID as the currently installed plugin. If the plugin is active, it is restarted using the new package. If inactive, the package is replaced without changing active state. - Roles - [Role Create](/docs/api/roles/RoleCreate): Creates a role with the specified permissions granted. - [Role Delete](/docs/api/roles/RoleDelete): Deletes a role. - [Role Get](/docs/api/roles/RoleGet): Retreives a role and all its permissions. - [Role List](/docs/api/roles/RoleList): List all roles and their permissions. - [Role Update](/docs/api/roles/RoleUpdate): Updates a role's attributes. - [Role Update Order](/docs/api/roles/RoleUpdateOrder): Update the global ordering of custom roles. The request body must include every non-default role identifier exactly once in the desired order of precedence. - Auth - [Access Key Create](/docs/api/auth/AccessKeyCreate): 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. - [Access Key Delete](/docs/api/auth/AccessKeyDelete): Revoke an access key. This will immediately invalidate the key and it will no longer be usable for authentication. - [Access Key List](/docs/api/auth/AccessKeyList): 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. - [Auth Email Password Signin](/docs/api/auth/AuthEmailPasswordSignin): Sign in to an existing account with a email and password. - [Auth Email Password Signup](/docs/api/auth/AuthEmailPasswordSignup): Register a new account with a email and password. - [Auth Email Signin](/docs/api/auth/AuthEmailSignin): 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. - [Auth Email Signup](/docs/api/auth/AuthEmailSignup): 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. - [Auth Email Verify](/docs/api/auth/AuthEmailVerify): 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. The code is only six digits, so this endpoint MUST be rate limited to keep the search space out of reach of an unauthenticated caller. - [Auth Password Create](/docs/api/auth/AuthPasswordCreate): Given the requesting account does not have a password authentication, add a password authentication method to it with the given password. - [Auth Password Reset](/docs/api/auth/AuthPasswordReset): Complete a password-reset flow using a token that was provided to the member via a reset request operation such as `AuthEmailPasswordReset`. - [Auth Password Reset Request Email](/docs/api/auth/AuthPasswordResetRequestEmail): Request password reset email to be sent to the specified email address. - [Auth Password Signin](/docs/api/auth/AuthPasswordSignin): Sign in to an existing account with a username and password. - [Auth Password Signup](/docs/api/auth/AuthPasswordSignup): Register a new account with a username and password. - [Auth Password Update](/docs/api/auth/AuthPasswordUpdate): Given the requesting account has a password authentication, update the password on file. - [Auth Provider List](/docs/api/auth/AuthProviderList): 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. - [Auth Provider Logout](/docs/api/auth/AuthProviderLogout): 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. - [O Auth Authorise](/docs/api/auth/OAuthAuthorise): Start the browser-based OAuth 2.0 Authorization Code flow with PKCE. This endpoint requires a browser session. If the account is not signed in, Storyden redirects to the frontend login route instead of returning a protocol redirect to the client application. Unlike many OAuth servers, Storyden does not render a consent page from this API endpoint. A valid request creates a short-lived pending authorisation request and redirects the browser to the configured frontend authorisation-code consent URL. Custom frontends can change this URL with `OAUTH_AUTHORISATION_CODE_CONSENT_URL`. The `scope` parameter follows OAuth 2.0 and is optional. Empty or omitted scope means no requested scopes. Storyden permission scopes are granted only when allowed by the client and by the signed-in account's current permissions. - [O Auth Authorise Consent](/docs/api/auth/OAuthAuthoriseConsent): Read a pending OAuth authorisation code request for a signed-in user before they approve or deny consent in the frontend. This is a Storyden frontend/API integration endpoint, not an OAuth protocol endpoint. It returns the client, redirect URI, requested scopes, and currently grantable scopes so the frontend can render a consent screen. - [O Auth Authorise Consent Submit](/docs/api/auth/OAuthAuthoriseConsentSubmit): Approve or deny a pending OAuth authorisation code request for the currently signed-in account. On approval this creates a short-lived authorisation code and returns the client redirect URI containing `code` and optional `state`. On denial the returned redirect URI contains `error=access_denied`. Storyden recomputes the granted scope at approval time from current account permissions and client policy. - [O Auth Client Create](/docs/api/auth/OAuthClientCreate): Create an OAuth client owned by the authenticated account. Member-created clients are third-party explicit-scope clients. The requested allowed scopes must be a subset of the authenticated account's current permissions. - [O Auth Client Delete](/docs/api/auth/OAuthClientDelete): Delete an OAuth client created by the authenticated account. This prevents new OAuth flows for the client and removes associated pending OAuth records and refresh tokens, preventing existing grants from being renewed. Existing JWT access tokens remain valid until expiry. - [O Auth Client Get](/docs/api/auth/OAuthClientGet): Read an OAuth client created by the authenticated account. Member-created clients are third-party application identities. They may be public or confidential but are never first-party inherited-permission clients. - [O Auth Client List](/docs/api/auth/OAuthClientList): List OAuth clients created by the authenticated account. This is the member-facing "apps I created" view. OAuth clients are application definitions: client ID, client type, redirect URIs, allowed scopes, and allowed grants. This does not list built-in first-party clients or third-party apps the member has merely authorised. Use `/auth/oauth/tokens` for the "apps I have authorised" view. - [O Auth Client Register](/docs/api/auth/OAuthClientRegister): RFC 7591 OAuth 2.0 Dynamic Client Registration. Allows clients such as MCP connectors to register themselves without prior administrator configuration. Dynamically registered clients are tenant-owned (they have no account owner), use the explicit scope policy, and are restricted to a conservative grant and scope allowlist. Authorization Code clients must use PKCE; Storyden enforces PKCE (S256) at the authorize and token endpoints for all clients. Public clients register with `token_endpoint_auth_method: none` and receive no client secret. Confidential clients register with `client_secret_basic` or `client_secret_post` and receive a one-time `client_secret` in the response. The registration endpoint is advertised as `registration_endpoint` by the authorization server metadata documents. This is an unauthenticated endpoint that creates server state, so it is heavily rate limited to prevent abuse. - [O Auth Client Update](/docs/api/auth/OAuthClientUpdate): Update an OAuth client created by the authenticated account. Allowed scopes must remain within the authenticated account's current permissions. If the account has `ADMINISTRATOR`, it may configure any Storyden permission scope because `ADMINISTRATOR` implicitly grants all permissions. Changing allowed scopes affects future grants and refreshes but does not immediately invalidate already-issued JWT access tokens. - [O Auth Device Authorisation](/docs/api/auth/OAuthDeviceAuthorisation): Start the OAuth 2.0 Device Authorization Grant for clients that cannot receive a browser redirect directly, such as CLIs, terminals, and desktop tools. The `scope` parameter follows OAuth 2.0 and is optional. Storyden applies additional client policy after parsing the request: - Built-in first-party device clients, such as the default Storyden CLI client, must request exactly `openid profile offline_access`. On approval Storyden expands the issued scope to the approving account's current permissions. - Third-party explicit-scope clients may omit `scope`; omitted scope means no requested scopes. `verification_uri` and `verification_uri_complete` point at the configured frontend consent page, not at an API-rendered HTML page. Custom frontends can change this URL with `OAUTH_DEVICE_AUTHORISATION_CONSENT_URL`. - [O Auth Device Consent](/docs/api/auth/OAuthDeviceConsent): Read a pending OAuth device authorisation request for a signed-in user before they approve or deny consent in the frontend. This is a Storyden frontend/API integration endpoint, not an OAuth protocol endpoint. The API never renders the consent UI directly. A frontend reads this JSON, displays the client and scopes, then submits the user's decision. Reading consent claims the user code for the signed-in account. This prevents another account from approving the same code after it has been displayed. - [O Auth Device Consent Submit](/docs/api/auth/OAuthDeviceConsentSubmit): Approve or deny a pending OAuth device authorisation request for the currently signed-in account. On approval Storyden recomputes the granted scope from the current account permissions and client policy. For first-party inherited clients this means the final token scope may include Storyden permission scopes that were not present in the original device authorisation request. - [O Auth J W K S](/docs/api/auth/OAuthJWKS): List public JSON Web Keys that clients can use to validate Storyden OAuth access tokens and OpenID Connect ID tokens. This is advertised by `/.well-known/openid-configuration` as `jwks_uri`. Storyden serves this under the API mount because the key set is an API resource; the well-known discovery document itself is mounted at the instance root and is intentionally not part of this OpenAPI document. - [O Auth Provider Callback](/docs/api/auth/OAuthProviderCallback): OAuth2 callback. - [O Auth Refresh Token Delete](/docs/api/auth/OAuthRefreshTokenDelete): Revoke one OAuth refresh token issued to the authenticated account. This prevents future refresh-token use for the selected grant. Existing JWT access tokens remain valid until their expiry. - [O Auth Refresh Token List](/docs/api/auth/OAuthRefreshTokenList): List OAuth refresh tokens issued to the authenticated account. This is the member-facing "authorised applications" view: it lists apps the signed-in account has authorised and can revoke. In OAuth terms, these rows are grants/tokens, not application definitions. This may include grants for built-in first-party clients such as the default Storyden CLI. Those clients are not created by the member and therefore do not appear in the member OAuth client list. - [O Auth Remote Callback](/docs/api/auth/OAuthRemoteCallback): Complete a remote OAuth authorization code callback. This validates the saved state, exchanges the code with PKCE, and stores returned tokens on the remote connection. - [O Auth Token](/docs/api/auth/OAuthToken): Exchange an OAuth authorisation code, device code, refresh token, or client credentials grant for tokens. Supported grants are advertised by `/.well-known/openid-configuration`. Public clients authenticate with `client_id` only and must use grants suitable for public clients, such as device code or authorisation code with PKCE. Confidential clients must provide `client_secret` for authorisation-code, refresh-token, and client-credentials exchanges. Storyden access tokens are short-lived JWTs containing the issued `scope`. Revoking a refresh token or changing account permissions does not revoke an already-issued access token; permission changes are applied on the next token issuance or refresh. Device-code polling returns OAuth-compatible errors such as `authorization_pending`, `slow_down`, `expired_token`, `access_denied`, and `invalid_grant`. - [O Auth User Info](/docs/api/auth/OAuthUserInfo): Return OpenID Connect UserInfo claims for the account represented by a valid bearer access token. Claims are scope-gated: - `openid` identifies the subject. - `profile` enables profile claims such as display name. - `email` enables email claims when the account has an email address. Storyden accounts do not always have email addresses, so email claims may be absent even when the `email` scope is present. - [Phone Request Code](/docs/api/auth/PhoneRequestCode): 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. - [Phone Submit Code](/docs/api/auth/PhoneSubmitCode): Complete the phone number authentication flow by submitting the one-time code that was sent to the user's phone. - [Web Authn Get Assertion](/docs/api/auth/WebAuthnGetAssertion): Start the WebAuthn assertion for an existing account. - [Web Authn Make Assertion](/docs/api/auth/WebAuthnMakeAssertion): Complete the credential assertion and sign in to an account. - [Web Authn Make Credential](/docs/api/auth/WebAuthnMakeCredential): Complete WebAuthn registration by creating a new credential. - [Web Authn Request Credential](/docs/api/auth/WebAuthnRequestCredential): Start the WebAuthn registration process by requesting a credential. - Accounts - [Account Add Role](/docs/api/accounts/AccountAddRole): Adds a role to an account. Members without the MANAGE_ROLES permission cannot use this operation. - [Account Auth Method Delete](/docs/api/accounts/AccountAuthMethodDelete): 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. - [Account Auth Provider List](/docs/api/accounts/AccountAuthProviderList): Retrieve a list of authentication providers with a flag indicating which ones are active for the currently authenticated account. - [Account Create](/docs/api/accounts/AccountCreate): Create a human account without creating an authentication method. This is intended for admin and integration driven account provisioning. - [Account Email Add](/docs/api/accounts/AccountEmailAdd): Add an email address to the authenticated account. - [Account Email Password Reset](/docs/api/accounts/AccountEmailPasswordReset): Send a password reset email for the specified account. This is intended for admin. This will trigger a password reset email to the specified email address. The email address must be associated with the account. - [Account Email Remove](/docs/api/accounts/AccountEmailRemove): Remove an email address from the authenticated account. - [Account Get](/docs/api/accounts/AccountGet): Get the information for the currently authenticated account. - [Account Get Avatar](/docs/api/accounts/AccountGetAvatar): Get an avatar for the specified account. - [Account List](/docs/api/accounts/AccountList): List accounts for administrative moderation purposes. This endpoint is intended for staff-facing member search and returns denser account data than the public profile listing such as email addresses, held auth services and administrative flags. Requires VIEW_ACCOUNTS. This is a read-only permission; account mutation endpoints require narrower management permissions like MANAGE_ACCOUNTS, MANAGE_SUSPENSIONS or ADMINISTRATOR. - [Account Manage Create](/docs/api/accounts/AccountManageCreate): Create a human account without creating an authentication method. This is intended for admin and integration driven account provisioning. - [Account Manage Update](/docs/api/accounts/AccountManageUpdate): Update staff-managed account lifecycle fields. - [Account Manage Update Email Verified Status](/docs/api/accounts/AccountManageUpdateEmailVerifiedStatus): Override the verified status of an email address. This is intended for admin and integration driven account management and is not intended to be used for normal verification flows. Changing the verified status of an email address here will not trigger any verification emails or other side effects, it will simply set the field to the provided value. - [Account Moderation Note Create](/docs/api/accounts/AccountModerationNoteCreate): Create an internal moderation note for an account. Notes are immutable and always include the author and timestamp for auditing. - [Account Moderation Note Delete](/docs/api/accounts/AccountModerationNoteDelete): Delete an internal moderation note for an account. - [Account Moderation Note List](/docs/api/accounts/AccountModerationNoteList): List internal moderation notes for an account. Notes are never public and are only visible to staff with VIEW_MODERATION_NOTES permission. - [Account Password Reset Token Get](/docs/api/accounts/AccountPasswordResetTokenGet): Provides the caller with a token that can be used with the endpoint `/auth/password/reset` to reset the account's password. This is intended for admin usage for when the instance is not using email authentication mode or if the target account has no email addresses to send resets. - [Account Remove Role](/docs/api/accounts/AccountRemoveRole): Removes a role from an account. Members without the MANAGE_ROLES cannot use this operation. Admins cannot remove the admin role from themselves. - [Account Role Remove Badge](/docs/api/accounts/AccountRoleRemoveBadge): Removes the badge from the profile. This does not remove the role from the account, only the visual badge-status representation of the role. - [Account Role Set Badge](/docs/api/accounts/AccountRoleSetBadge): 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. - [Account Set Avatar](/docs/api/accounts/AccountSetAvatar): Upload an avatar for the authenticated account. - [Account Update](/docs/api/accounts/AccountUpdate): Update the information for the currently authenticated account. - [Account View](/docs/api/accounts/AccountView): 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. - [Account Warning Create](/docs/api/accounts/AccountWarningCreate): Create an internal moderation warning for an account. Requires the `MANAGE_WARNINGS` permission. - [Account Warning Delete](/docs/api/accounts/AccountWarningDelete): Permanently delete a warning record. Requires the `MANAGE_WARNINGS` permission. - [Account Warning List](/docs/api/accounts/AccountWarningList): List internal moderation warnings for an account. Warnings are never public. Members may view their own warning history, and staff with the `MANAGE_WARNINGS` permission may review warnings for any account. - [Account Warning Update](/docs/api/accounts/AccountWarningUpdate): Update the reason text for an existing warning. Requires the `MANAGE_WARNINGS` permission. - Invitations - [Invitation Create](/docs/api/invitations/InvitationCreate): 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. - [Invitation Delete](/docs/api/invitations/InvitationDelete): Delete an invitation. After deletion, it cannot be used. - [Invitation Get](/docs/api/invitations/InvitationGet): 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. - [Invitation List](/docs/api/invitations/InvitationList): 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. - Notifications - [Notification List](/docs/api/notifications/NotificationList): Retreive all notifications. - [Notification Update](/docs/api/notifications/NotificationUpdate): Change the read status for a notification. - [Notification Update Many](/docs/api/notifications/NotificationUpdateMany): Update the status of multiple notifications in a single request. This endpoint accepts a list of notification IDs with their new status values. Used for "Mark all as read". - Reports - [Report Create](/docs/api/reports/ReportCreate): 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. - [Report List](/docs/api/reports/ReportList): 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. - [Report Update](/docs/api/reports/ReportUpdate): 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. - Profiles - [Profile Followers Add](/docs/api/profiles/ProfileFollowersAdd): Follow the specified profile as the authenticated account. - [Profile Followers Get](/docs/api/profiles/ProfileFollowersGet): Get the followers and following details for a profile. - [Profile Followers Remove](/docs/api/profiles/ProfileFollowersRemove): Unfollow the specified profile as the authenticated account. - [Profile Following Get](/docs/api/profiles/ProfileFollowingGet): Get the profiles that this account is following. - [Profile Get](/docs/api/profiles/ProfileGet): Get a public profile by ID. - [Profile List](/docs/api/profiles/ProfileList): Query and search profiles. - Categories - [Category Create](/docs/api/categories/CategoryCreate): Create a category for organising posts. - [Category Delete](/docs/api/categories/CategoryDelete): Delete a category. All posts in this category will be moved to the specified target category. - [Category Get](/docs/api/categories/CategoryGet): Get information about a category. - [Category List](/docs/api/categories/CategoryList): Get a list of all categories on the site. - [Category Update](/docs/api/categories/CategoryUpdate): Update a category's information. - [Category Update Position](/docs/api/categories/CategoryUpdatePosition): 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 - [Tag Get](/docs/api/tags/TagGet): Get information about a tag. - [Tag List](/docs/api/tags/TagList): Get a list of tags on the site, most used first. The tag table grows with content, so results are paginated. Callers that only need suggestions can read the first page and stop. - Posts - [Post Delete](/docs/api/posts/PostDelete): Archive a post using soft-delete. - [Post Location Get](/docs/api/posts/PostLocationGet): Locate a post just from its ID. This will tell you what kind of post it is and where to find it. Where "a post is" is simple for threads, just the slug. For replies, it will give you the thread slug and the position within the thread: the index, the page and the position on the page. - [Post React Add](/docs/api/posts/PostReactAdd): Add a reaction to a post. - [Post React Remove](/docs/api/posts/PostReactRemove): Remove a reaction from a post. - [Post Update](/docs/api/posts/PostUpdate): Publish changes to a single post. - Threads - [Thread Create](/docs/api/threads/ThreadCreate): Create a new thread within the specified category. - [Thread Delete](/docs/api/threads/ThreadDelete): Archive a thread using soft-delete. - [Get information about a thread and the posts within the thread.](/docs/api/threads/ThreadGet): 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. - [Thread List](/docs/api/threads/ThreadList): Get a list of all threads. - [Thread Update](/docs/api/threads/ThreadUpdate): Publish changes to a thread. - Replies - [Reply Create](/docs/api/replies/ReplyCreate): Create a new post within a thread. - Assets - [Asset Get](/docs/api/assets/AssetGet): Download an asset by its ID. - [Asset Upload](/docs/api/assets/AssetUpload): Upload and process a media file. - Likes - [Like Post Add](/docs/api/likes/LikePostAdd): 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. - [Like Post Get](/docs/api/likes/LikePostGet): Retreives all likes for the given post. Not paginated (yet.) - [Like Post Remove](/docs/api/likes/LikePostRemove): 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. - [Like Profile Get](/docs/api/likes/LikeProfileGet): Retreives all the likes that the given profile has given. - Collections - [Collection Add Node](/docs/api/collections/CollectionAddNode): 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. - [Collection Add Post](/docs/api/collections/CollectionAddPost): 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. - [Collection Create](/docs/api/collections/CollectionCreate): Create a collection for curating posts under the authenticated account. - [Collection Delete](/docs/api/collections/CollectionDelete): Delete a collection owned by the authenticated account. - [Collection Get](/docs/api/collections/CollectionGet): 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. - [Collection List](/docs/api/collections/CollectionList): List collections using the filtering options, newest first. Collections accumulate with members, so results are paginated. - [Collection Remove Node](/docs/api/collections/CollectionRemoveNode): Remove a node from a collection. The collection must be owned by the account making the request. - [Collection Remove Post](/docs/api/collections/CollectionRemovePost): Remove a post from a collection. The collection must be owned by the account making the request. - [Collection Update](/docs/api/collections/CollectionUpdate): Update a collection owned by the authenticated account. - Nodes - [Node Add Asset](/docs/api/nodes/NodeAddAsset): Add an asset to a node. - [Node Add Node](/docs/api/nodes/NodeAddNode): Set a node's parent to the specified node - [Node Create](/docs/api/nodes/NodeCreate): Create a node for curating structured knowledge together. - [Node Delete](/docs/api/nodes/NodeDelete): Delete a node and move all children to its parent or root. - [Node Draft List](/docs/api/nodes/NodeDraftList): List all draft versions across all nodes visible to the caller. This endpoint is designed for moderation and queue screens where you need to see all pending draft proposals in one request. Each draft includes a reference to its target node for context. Drafts are visible based on the caller's permissions: - Draft authors can see their own drafts - Members with `MANAGE_LIBRARY` can see all drafts - Unauthenticated requests receive 401 Unauthorized Results are ordered by `updated_at` descending so recently updated drafts appear first. - [Node Generate Content](/docs/api/nodes/NodeGenerateContent): 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. - [Node Generate Tags](/docs/api/nodes/NodeGenerateTags): 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. - [Node Generate Title](/docs/api/nodes/NodeGenerateTitle): 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. - [Node Get](/docs/api/nodes/NodeGet): Get a node by its URL slug. - [Node List](/docs/api/nodes/NodeList): List nodes using the given filters. Can be used to get a full tree. - [Node List Children](/docs/api/nodes/NodeListChildren): 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. - [Node Remove Asset](/docs/api/nodes/NodeRemoveAsset): Remove an asset from a node. - [Node Remove Node](/docs/api/nodes/NodeRemoveNode): Remove a node from its parent node and back to the top level. - [Node Update](/docs/api/nodes/NodeUpdate): Update a node directly. Direct updates are intended for fast edits by members who can manage the target node. If a node has a working draft version, direct updates to versioned page fields are rejected until the draft is applied or deleted. When a direct update changes versioned page fields and no draft exists, the node's `current_version_id` pointer is cleared because the live node no longer exactly represents an applied checkpoint. - [Node Update Children Property Schema](/docs/api/nodes/NodeUpdateChildrenPropertySchema): 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 - [Node Update Position](/docs/api/nodes/NodeUpdatePosition): 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. - [Node Update Properties](/docs/api/nodes/NodeUpdateProperties): 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. - [Node Update Property Schema](/docs/api/nodes/NodeUpdatePropertySchema): 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. - [Node Update Visibility](/docs/api/nodes/NodeUpdateVisibility): 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. - [Node Version Create](/docs/api/nodes/NodeVersionCreate): Create the single mutable draft checkpoint for a node. This operation requires either `SUBMIT_LIBRARY_NODE_CHANGES` or `MANAGE_LIBRARY` permission. The draft starts as a full snapshot of the node's current versioned page fields. Fields supplied in the request overlay that snapshot, omitted fields keep the snapshotted value, and explicit null values clear nullable fields. A node can have only one draft. If a draft already exists for the node, this operation returns a conflict. Drafts do not mutate the target node until the draft is applied through the version status endpoint by a member with `MANAGE_LIBRARY`. - [Node Version Delete](/docs/api/nodes/NodeVersionDelete): Delete the working draft checkpoint. A draft author can discard their own draft. Members with `MANAGE_LIBRARY` permission can discard any draft for the node. The draft row is removed from history. Applied versions are immutable history entries and cannot be deleted through this endpoint. - [Node Version Draft Get](/docs/api/nodes/NodeVersionDraftGet): Get the node's single working draft checkpoint. This is a stable alias for the draft version of a node. It allows clients to read "the draft" without listing versions and inspecting status values. If the node has no draft, or the draft is not visible to the caller, this operation returns not found. The draft is visible only to its author and members with `MANAGE_LIBRARY`. - [Node Version Draft Update](/docs/api/nodes/NodeVersionDraftUpdate): Update the node's single working draft checkpoint. This is a stable alias for patching the draft version of a node without first listing versions or knowing the draft version identifier. The node must already have a draft visible to the caller. This operation does not create a draft and does not apply the draft to the target node. The caller must be the draft author or have `MANAGE_LIBRARY`. Fields omitted from the request are left unchanged on the draft snapshot. Explicit null values clear nullable fields. Properties are a complete desired-state list for the target node properties. - [Node Version Get](/docs/api/nodes/NodeVersionGet): Get an edit version for a node. The version must belong to the node identified by `node_slug`. Applied versions are immutable historical snapshots and are visible to callers who can read the target node. The draft version is visible only to its author and members with `MANAGE_LIBRARY`. - [Node Version List](/docs/api/nodes/NodeVersionList): List edit versions for a node. Versions have two states: draft and applied. A version is a draft when it is pre-published. There can only be a single draft of a node. Applied versions are immutable historical snapshots of the page fields that were copied into the node. The single draft version, when present, is the working snapshot ahead of the live node and is visible only to its author and members with `MANAGE_LIBRARY`. Results are ordered by `updated_at` descending so draft autosaves and recently applied checkpoints appear before older history. - [Node Version Update](/docs/api/nodes/NodeVersionUpdate): Update the node's single draft checkpoint. This operation is for draft autosave and editing only. It does not change version status and cannot apply a version to the target node. The version must still have draft status and the caller must be the draft author or have `MANAGE_LIBRARY`. Fields omitted from the request are left unchanged on the draft snapshot. Explicit null values clear nullable fields. Properties are a complete desired-state list for the target node properties: when the version is applied, the list replaces the node's existing property set rather than merging with it. - [Node Version Update Status](/docs/api/nodes/NodeVersionUpdateStatus): Update the lifecycle status of a checkpoint. This endpoint is separate from the content patch endpoint because status changes have side effects. For the initial checkpoint workflow, the only supported transition is draft to applied. Applying a version is restricted to members with `MANAGE_LIBRARY`. Applying a draft copies the full draft snapshot into the target node, applies properties as a complete desired-state list, marks the version immutable, and updates the node's `current_version_id` pointer to the applied version. This is a linear operation; applying a draft does not merge against other draft or historical versions. Clients must use this endpoint for lifecycle transitions and must not combine status changes with regular draft content updates. - Links - [Link Create](/docs/api/links/LinkCreate): 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. - [Link Get](/docs/api/links/LinkGet): 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. - [Link List](/docs/api/links/LinkList): List all links using the filtering options. - Datagraph - [Datagraph Matches](/docs/api/datagraph/DatagraphMatches): Query the datagraph optimised for typeahead scenarios. This endpoint is only active when a `SEARCH_PROVIDER` that supports fast access is used. This includes providers such as Bleve and Redis. This endpoint will return a minified set of results directly from the configured search index, without hitting the database. This makes it suitable for performance sensitive use-cases such as type-ahead search, @ mentioning threads/pages, CTRL+K style menus, and more. Results will include a `kind` field and short content, but will not contain graph edges (such as authorship, links, etc.) due to constraints of the underlying search index and to keep payload sizes smaller. - [Datagraph Search](/docs/api/datagraph/DatagraphSearch): Query and search content. - Events - [Event Create](/docs/api/events/EventCreate): 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. - [Event Delete](/docs/api/events/EventDelete): Delete an event. - [Event Get](/docs/api/events/EventGet): Get an event by its ID. - [Event List](/docs/api/events/EventList): List all events using the filtering options. - [Event Participant Remove](/docs/api/events/EventParticipantRemove): Remove a participant from an event. Same rules as EventParticipantUpdate where non-managing members may only remove themselves. Not soft-delete. - [Event Participant Update](/docs/api/events/EventParticipantUpdate): 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. - [Event Update](/docs/api/events/EventUpdate): 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. - Robots - [Robot Chat S S E](/docs/api/robots/RobotChatSSE): Send a message to a Robot and receive its response. This endpoint manages sessions automatically, creating new sessions as needed or continuing existing sessions based on the provided session ID. Each message sent to the Robot is processed according to its playbook and available tools, allowing it to perform actions or retrieve data as part of the conversation. The response from the Robot includes its reply message along with any actions taken during the interaction. This endpoint is a Server Sent Events (SSE) stream, meaning that the response is streamed back to the client in real-time as the Robot generates its reply. - [Create a robot](/docs/api/robots/RobotCreate): Create a new Robot with the specified configuration. A Robot in Storyden consists of a name and description (for humans) as well as a playbook, and a set of available tools to interact with Storyden or plugins. The playbook is a detailed set of instructions that guides behaviour of the Robot to help it assist members in achieving a specific automation goal. Tools are available from either Storyden or plugins that allow it to perform actions or query data. Robots never need all tools and it's best to build goal-specific Robots with minimal sets of tools. - [Delete a robot](/docs/api/robots/RobotDelete): Delete a Robot. - [Get a robot](/docs/api/robots/RobotGet): Retrieve a specific Robot by its ID. Does not include any messages or sessions associated with the Robot, just provides metadata about it. - [Create Robot MCP server](/docs/api/robots/RobotMCPServerCreate): Configure an external streamable HTTP MCP server for Robot tool discovery. - [Delete Robot MCP server](/docs/api/robots/RobotMCPServerDelete): Delete an external MCP server configuration and remove its tools from the runtime Robot tool registry. - [Get Robot MCP server](/docs/api/robots/RobotMCPServerGet): Retrieve an external MCP server configuration and its cached tools. - [Probe Robot MCP server](/docs/api/robots/RobotMCPServerProbe): Resolve an MCP endpoint from a URL, optionally using an MCP Server Card, and attempt a streamable HTTP MCP handshake. - [Refresh Robot MCP server tools](/docs/api/robots/RobotMCPServerRefresh): Connect to the external MCP server, refresh its tool cache, and update the runtime Robot tool registry. - [List Robot MCP servers](/docs/api/robots/RobotMCPServersList): List external MCP servers configured for Robot tool discovery. - [Update Robot MCP server](/docs/api/robots/RobotMCPServerUpdate): Update an external MCP server configuration. Bearer tokens are write-only and are redacted from responses. - [List robot models](/docs/api/robots/RobotModelsList): Retrieve a list of all enabled models from all providers. Model names are in the format `provider/model` some provider models may include further slashes, such as with OpenRouter: `openrouter/openai/gpt-4`. - [Refresh robot provider models](/docs/api/robots/RobotProviderModelsRefresh): Force refresh the cached model list for a Robot model provider. - [List robot providers](/docs/api/robots/RobotProvidersList): Retrieve supported Robot model providers, redacted settings, cache status and cached models. - [Update a robot provider](/docs/api/robots/RobotProviderUpdate): Update a Robot model provider configuration. API keys are write-only and are redacted from responses. - [Get a robot session](/docs/api/robots/RobotSessionGet): Retrieve a specific robot session with all of its messages. Sessions can involve interactions with multiple Robots so the Robot is specified on each message. Messages may not be representative of exactly what is sent into a language model, as certain optimisations may be performed before this such as compaction, summarisation or removal of irrelevant context. Any member with "USE_ROBOTS" can see any other members' sessions and messages with a Robot. Robots are not considered private assistants, but rather shared tools for the team to use for managing their community. - [List robot sessions](/docs/api/robots/RobotSessionsList): Get a paginated list of Robot sessions. These are chat sessions with the Robot system. One session may span multiple Robots as members can switch which Robot they are talking to mid conversation, or the Robot itself may choose to switch to another Robot to achieve a goal. A session is a representation of an entire conversation thread with the Robot system. You may include an account ID to filter sessions by account. Only those with "USE_ROBOTS" permission can use Robots, however sessions, messages and usage is not considered hidden to other accounts with the usage permission. Robots are intended as administrative or moderation tools to be shared among the team rather than private assistants. - [List robots](/docs/api/robots/RobotsList): Get a paginated list of all available robots. - [List robot tools](/docs/api/robots/RobotToolsList): List all tools that may be assigned to Robots, including native Storyden tools and discovered MCP tools. - [Update a robot](/docs/api/robots/RobotUpdate): Update a Robot's name, description, playbook or available tools. - [Create a robot workspace](/docs/api/robots/RobotWorkspaceCreate): Create a reusable Robot workspace template. - [Delete a robot workspace](/docs/api/robots/RobotWorkspaceDelete): Delete a reusable Robot workspace template. - [Get a robot workspace](/docs/api/robots/RobotWorkspaceGet): Retrieve a reusable Robot workspace template. - [Delete a robot workspace instance](/docs/api/robots/RobotWorkspaceInstanceDelete): Delete a live reusable Robot workspace instance. - [Get a robot workspace instance](/docs/api/robots/RobotWorkspaceInstanceGet): Retrieve a live reusable Robot workspace instance. - [List robot workspace instances](/docs/api/robots/RobotWorkspaceInstancesList): Get a paginated list of live reusable Robot workspace instances. - [List robot workspace providers](/docs/api/robots/RobotWorkspaceProvidersList): Retrieve the registered Robot workspace providers. - [List robot workspaces](/docs/api/robots/RobotWorkspacesList): Get a paginated list of reusable Robot workspace templates. - [Update a robot workspace](/docs/api/robots/RobotWorkspaceUpdate): Update a reusable Robot workspace template.