Duvet DOCS
GitHub

Spaces

Create Space

POST /api/spaces

Create a new space. The authenticated user becomes the owner. Human-only.

JSON Body

FieldTypeDescription
name stringSpace name
description ?string?Space description

Returns: CreateSpaceResult object.

Update Space

PATCH /api/spaces/{spaceId}

Update space metadata. Supports both JSON and multipart/form-data for image uploads. Uses OptionalField for nullable fields (send null to clear, omit to keep). Requires being the owner or an Administrator, checked before any upload; otherwise 403 with "you don't have permission to manage this space".

JSON Body

FieldTypeDescription
name ?stringNew space name
description ?string?New description (null to clear)
banner ?string?null or an empty string removes the banner, and its current ID keeps it. A new one is uploaded (multipart body): any other value is a 400
icon ?string?Same as banner, for the icon
locale ?string?Space locale (null to clear)

Multipart Body

Supports file uploads for banner and icon:

FieldTypeDescription
name ?stringNew space name
description ?stringNew description
locale ?stringSpace locale
banner ?fileBanner image file (max 10MB)
icon ?fileIcon image file (max 10MB)
remove_banner ?stringSet to "true" to remove the banner
remove_icon ?stringSet to "true" to remove the icon

Returns: Space object.

Errors: 400 when a JSON icon or banner sets an image; 413 for an image over 10 MB or over the space bucket's limits; 422 when the space has no storage bucket. A new image is deleted again when the update fails.

Search Messages

GET /api/spaces/{spaceId}/messages/search

Search the messages of the rooms of the space that the user can view, newest first. Human-only. It needs some text or a filter. The values of one filter are alternatives (any of them), and different filters must all match. Pin notices are no results.

Query Parameters

FieldTypeDescription
query ?stringUp to 200 characters. Each of its words (a run of letters and digits) must start a word of the message, except one-letter words, which must be whole words. Case and accents don't matter.
author_id ?uuidMessages by this user. Repeat it, up to 10 times, for any of several.
mentions ?uuidMessages that mention this user. Repeat it, up to 10 times, for any of several.
room_id ?uuidMessages in this room. Repeat it, up to 25 times, for any of several.
has ?stringlink, embed, file, image, video, sound or sticker: messages with one. Repeat it for any of several.
pinned ?booleantrue for the pinned messages only, false for the others
after ?ISO 8601Messages sent after this time
before ?ISO 8601Messages sent before this time
cursor ?uuidThe ID of the previous page's last message, for the page after it
limit ?integerMessages per page, 1 to 50 (default 25)

Returns: MessageSearchResponse object.

Errors: 400 for a search without text or filters, an unknown has value or an ID that isn't a UUID; 403 when the user isn't a member of the space; 404 for a room_id the user can't view or that isn't in the space; 503 when the search takes over 5 seconds, so it needs narrowing.


Rooms

Create Room

POST /api/spaces/{spaceId}/rooms

Create a new room inside a space. Requires ManageChannels permission.

JSON Body

FieldTypeDescription
name stringRoom name
type integerRoom type (1 = text, 2 = voice, 3 = category)
parent_id ?uuid?Parent category: a category of this space, or a 400. Ignored for categories

Returns: Room object.

Update Room

PATCH /api/spaces/{spaceId}/rooms/{roomId}

Update room settings. Categories only support name and position changes.

JSON Body

FieldTypeDescription
name ?string?New room name (null to clear)
description ?string?New description (null to clear, ignored for categories)
parent_id ?uuid?New parent category, a category of this space or a 400 (null to unparent, ignored for categories)
position ?integerNew sort position

Returns: Room object.

Delete Room

DELETE /api/spaces/{spaceId}/rooms/{roomId}

Delete a room from a space. Requires ManageChannels permission.

Returns: 204 No Content

Errors: 404 when the room isn't one of this space's.


Room Overwrites

Upsert Permission Overwrite

PUT /api/spaces/{spaceId}/rooms/{roomId}/overwrites

Create or update a permission overwrite for a room. Requires ManageChannels permission in that room. Every permission you newly allow or deny must be one you have in that room, unless you own the space or are an Administrator. Keeping or clearing existing allows and denies isn't restricted. A room has at most one overwrite per target, so this replaces it if there is one, and its target type can't change. The target must be a role of this space (the @everyone role's ID is the space ID) or a member of it (404 otherwise), and flags outside the permission table are rejected (400).

JSON Body

FieldTypeDescription
target_id uuidTarget role or member ID
target_type integer0 = role, 1 = member; any other value is rejected
allow_flags integerAllowed permission flags bitfield
deny_flags integerDenied permission flags bitfield

Returns: RoomOverwrite object.

Delete Permission Overwrite

DELETE /api/spaces/{spaceId}/rooms/{roomId}/overwrites/{targetId}

Remove a permission overwrite from a room. Requires ManageChannels permission in that room.

Returns: 204 No Content


Room Invites

POST /api/spaces/{spaceId}/rooms/{roomId}/invites

Generate an invite link for a specific room of the space. Requires CreateInvites permission. The body is optional.

JSON Body

FieldTypeDescription
max_age ?integerHow many seconds the invite works for, up to 604800 (7 days). Without it, or 0, it works until it is revoked

Returns: InviteCode object.

Errors: 400 for a max_age below 0 or over 604800, or when the space already has 1000 invites that work (revoke some, or let them expire); 404 when the room isn't one of this space's. Once expired or revoked, the invite is a 404 to look up (GET /api/invites/{code}) and to join.

List Invites

GET /api/spaces/{spaceId}/invites

List the space's invites that still work (at most 1000), newest first. Expired ones are deleted within the hour. Requires ManageInvites permission.

Returns: Array of InviteCode objects.

Errors: 403 without ManageInvites.

Revoke Invite

DELETE /api/spaces/{spaceId}/invites/{inviteId}

Delete one of the space's invites: its link stops working. Requires ManageInvites permission.

Returns: 204 No Content

Errors: 403 without ManageInvites; 404 when the invite isn't one of this space's.


Roles

Create Role

POST /api/spaces/{spaceId}/roles

Create a new role in a space. Requires ManageRoles permission. The new role can only include permissions you have, and flags outside the permission table are rejected (400).

JSON Body

FieldTypeDescription
name stringRole name
permissions ?integerPermission flags bitfield
color_from ?integer?Gradient start color (int32)
color_via ?integer?Gradient middle color (int32)
color_to ?integer?Gradient end color (int32)
hoisted ?booleanWhether the role is displayed separately in the member list

Returns: Role object.

Update Role

PATCH /api/spaces/{spaceId}/roles/{roleId}

Update an existing role. Requires ManageRoles permission. Unless you own the space, the role must be below your highest role, it can't be moved to or above it, and you can only add permissions you have. Flags outside the permission table are rejected (400).

JSON Body

FieldTypeDescription
name ?stringNew role name
permissions ?integerNew permission flags bitfield
color_from ?integer?Gradient start color
color_via ?integer?Gradient middle color
color_to ?integer?Gradient end color
hoisted ?booleanDisplay separately in member list
position ?integerRole sort position
clear_colors ?booleanSet to true to remove all role colors

Returns: Role object.

Delete Role

DELETE /api/spaces/{spaceId}/roles/{roleId}

Delete a role from a space. Requires ManageRoles permission. Unless you own the space, the role must be below your highest role.

Returns: 204 No Content

Assign Role to Member

PUT /api/spaces/{spaceId}/members/{memberId}/roles/{roleId}

Assign a role to a space member. Requires ManageRoles permission. Unless you own the space, the role must be below your highest role.

Returns: 200 OK with an empty body.

Errors: 403 without ManageRoles, checked first so the answer says nothing about who is a member; 404 for a member or role that isn't the space's.

Remove Role from Member

DELETE /api/spaces/{spaceId}/members/{memberId}/roles/{roleId}

Remove a role from a space member. Requires ManageRoles permission. Unless you own the space, the role must be below your highest role.

Returns: 204 No Content

Errors: 403 without ManageRoles, checked first so the answer says nothing about who is a member; 404 for a member or role that isn't the space's.


Emojis

List Emojis

GET /api/spaces/{spaceId}/emojis

List all custom emojis in a space.

Returns: Array of SpaceEmoji objects.

Create Emoji

POST /api/spaces/{spaceId}/emojis

Upload a new custom emoji to a space. Sent as multipart/form-data with an image file.

JSON Body / Multipart

FieldTypeDescription
name stringEmoji name

Returns: SpaceEmoji object.

Errors: 413 for a file over the space bucket's upload limit, or with no room left for it; 422 when the space has no storage bucket.

Update Emoji

PATCH /api/spaces/{spaceId}/emojis/{emojiId}

Rename a custom emoji.

JSON Body

FieldTypeDescription
name stringNew emoji name

Returns: SpaceEmoji object.

Delete Emoji

DELETE /api/spaces/{spaceId}/emojis/{emojiId}

Delete a custom emoji from a space.

Returns: 204 No Content


Stickers

List Stickers

GET /api/spaces/{spaceId}/stickers

List all custom stickers in a space.

Returns: Array of SpaceSticker objects.

Create Sticker

POST /api/spaces/{spaceId}/stickers

Upload a new custom sticker to a space. Sent as multipart/form-data with an image file.

Multipart Body

FieldTypeDescription
name stringSticker name

Returns: SpaceSticker object.

Errors: 413 for a file over the space bucket's upload limit, or with no room left for it; 422 when the space has no storage bucket.

Update Sticker

PATCH /api/spaces/{spaceId}/stickers/{stickerId}

Rename a custom sticker.

JSON Body

FieldTypeDescription
name stringNew sticker name

Returns: SpaceSticker object.

Delete Sticker

DELETE /api/spaces/{spaceId}/stickers/{stickerId}

Delete a custom sticker from a space.

Returns: 204 No Content


Members

List Members

GET /api/spaces/{spaceId}/members

Retrieve paginated members for a space.

Query Parameters

FieldTypeDescription
after_id ?uuidCursor: member ID to paginate after
after_pos ?integerCursor: position to paginate after
count ?integerNumber of members to return

Returns: Array of MemberWithUser objects.

Leave Space

DELETE /api/spaces/{spaceId}/members/@me

Remove the authenticated user from the space. Space owners cannot leave their own space.

Returns: 204 No Content


Bots

Add Bot to Space

POST /api/spaces/{spaceId}/bots/{botUserId}

Add a bot user to a space. Requires ManageBots permission. The bot must be public. Human-only.

Returns: Member object.

Remove Bot from Space

DELETE /api/spaces/{spaceId}/bots/{botUserId}

Remove a bot user from a space. Requires ManageBots permission. Human-only.

Returns: 204 No Content


Attachments

List Space Attachments

GET /api/spaces/{spaceId}/attachments

Retrieve all attachments owned by the space (emojis and stickers, where message_id IS NULL).

Returns: Array of Attachment objects.

Get Space Storage Usage

GET /api/spaces/{spaceId}/attachments/storage

Retrieve total storage bytes used by the space.

Returns: StorageStatus object.

Delete Space Attachment

DELETE /api/spaces/{spaceId}/attachments/{attachmentId}

Delete one of the space's own attachments (the images of its emojis and stickers, the ones its attachment list shows), and the emojis and stickers made from it, which get SPACE_EMOJI_DELETE and SPACE_STICKER_DELETE. Human-only. Requires ManageSpaceAttachments.

Returns: 204 No Content

Errors: 403 without ManageSpaceAttachments; 404 when the attachment isn't one of this space's.

Delete All Space Attachments

DELETE /api/spaces/{spaceId}/attachments

Delete all attachments in a space, and its emojis and stickers with them (SPACE_EMOJI_DELETE, SPACE_STICKER_DELETE). Human-only.

Returns: 204 No Content


Storage Buckets

All storage bucket endpoints are human-only: they handle third-party S3 credentials.

List Space Buckets

GET /api/spaces/{spaceId}/buckets

List all S3-compatible storage buckets configured for a space.

Returns: Array of StorageBucket objects.

Create Space Bucket

POST /api/spaces/{spaceId}/buckets

Add a new S3-compatible storage bucket to a space.

JSON Body

FieldTypeDescription
name stringDisplay name for the bucket
endpoint stringS3-compatible endpoint URL
region ?stringBucket region
bucket_name stringActual bucket name on the provider
access_key_id stringS3 access key ID
secret_access_key stringS3 secret access key
use_path_style ?booleanUse path-style addressing instead of virtual-hosted
max_bytes ?integer?Maximum total storage in bytes
upload_limit_bytes ?integer?Per-upload size limit in bytes

Returns: StorageBucket object.

Errors: 400 with invalid storage configuration: ... when the bucket can't be reached with these settings, or when max_bytes or upload_limit_bytes isn't a positive number.

Update Space Bucket

PATCH /api/spaces/{spaceId}/buckets/{bucketId}

Update an existing storage bucket configuration.

JSON Body

FieldTypeDescription
name stringDisplay name
endpoint stringS3-compatible endpoint URL
region ?stringBucket region
bucket_name stringActual bucket name
access_key_id stringS3 access key ID
secret_access_key ?stringS3 secret access key (omit to keep existing)
use_path_style ?booleanUse path-style addressing
max_bytes ?integer?Maximum total storage in bytes
upload_limit_bytes ?integer?Per-upload size limit in bytes

Returns: StorageBucket object.

Errors: 400 with invalid storage configuration: ... when the bucket can't be reached with these settings, or when max_bytes or upload_limit_bytes isn't a positive number; 404 when the space has no such bucket.

Delete Space Bucket

DELETE /api/spaces/{spaceId}/buckets/{bucketId}

Delete a storage bucket from a space.

Returns: 204 No Content

Activate Space Bucket

POST /api/spaces/{spaceId}/buckets/{bucketId}/activate

Activate a storage bucket so new uploads go to it.

Returns: 204 No Content

Deactivate Space Bucket

POST /api/spaces/{spaceId}/buckets/{bucketId}/deactivate

Deactivate a storage bucket. Existing files remain accessible but new uploads will not use it.

Returns: 204 No Content