session-open-group-server/src/api.yaml

1304 lines
53 KiB
YAML

openapi: 3.0.1
info:
title: Session Open Group Server
description: >
API documentation for Session open groups. This is the API that
[Session](https://getsession.org) and related tools use to interface with open groups.
contact:
name: The Oxen Project
email: team@oxen.io
url: https://getsession.org
license:
name: GPL v3.0
url: https://www.gnu.org/licenses/gpl-3.0.en.html
version: "3.0"
externalDocs:
description: Find out more about the Oxen project
url: http://oxen.io
tags:
- name: Rooms
description: Access to a server's rooms (AKA open groups) and room management
- name: Messages
description: Message-related endpoints for accessing, submitting, deleting, etc.
- name: Batch
description: Endpoint for submitting a batch of requests at once.
- name: Users
description: Management of users and user-related info.
security:
- pubkey: []
nonce: []
timestamp: []
signature: []
paths:
/rooms:
get:
tags: [Rooms]
summary: "Returns a list of available rooms on the server."
description: >
Rooms to which the user does not have access (e.g. because they are banned) are not
included.
responses:
200:
description: successful operation
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/Room"
/room/{roomToken}:
get:
tags: [Rooms]
summary: Returns information about the given room.
parameters:
- $ref: "#/components/parameters/pathRoomToken"
responses:
200:
description: successful operation
content:
application/json:
schema:
$ref: "#/components/schemas/Room"
403:
description: >
Forbidden. Returned if the user is banned from the room or otherwise does not have read
access to the room.
content: {}
/room/{roomToken}/pollInfo:
get:
tags: [Rooms]
summary: Polls a room for metadata updates.
parameters:
- $ref: "#/components/parameters/pathRoomToken"
- name: info_updated
description: >
The client's current `info_updates` value for the room. The full room metadata is
returned in the response if the room's last update count does not equal the given value.
in: query
required: true
schema:
type: integer
format: int64
example: 4567
description: >
Retrives room metadata for this room, including the instantaneous room details (such as the
user's permission and current number of active users)
responses:
200:
description: >
Results of polling the room for updated information. This endpoint always returns
ephemeral data, such as the number of active users and the current user's permissions,
and will include the full room details if changed since the client's last update.
Note that the `details` field is only present and populated if it differs from the
provided `info_updated` value; otherwise the values are unchanged and so it is omitted.
content:
application/json:
schema:
type: object
properties:
token:
$ref: "#/components/schemas/RoomToken"
active_users:
$ref: "#/components/schemas/Room/properties/active_users"
read:
$ref: "#/components/schemas/Room/properties/read"
write:
$ref: "#/components/schemas/Room/properties/write"
upload:
$ref: "#/components/schemas/Room/properties/upload"
info_updates:
$ref: "#/components/schemas/Room/properties/info_updates"
details:
allOf:
- $ref: "#/components/schemas/Room"
/room/{roomToken}/message:
post:
tags: [Messages]
summary: Posts a new message to a room.
parameters:
- $ref: "#/components/parameters/pathRoomToken"
requestBody:
description: >
JSON body containing the message details to be submitted to the room. Note that the
`session_id` field is not contained in the response (since it is simply the client's own
ID).
required: true
content:
application/json:
schema:
type: object
required: [data, signature]
properties:
data:
type: string
format: byte
description: "Base64-encoded message data."
example: bWFpbiBzY3JlZW4gdHVybiBvbg==
signature:
type: string
format: byte
description: >
Base64-encoded message data XEd25519 signature, signed by the poster's X25519
key contained in the session ID.
example: NjgwYzFjOGI0YTljNTliNDk1MDRmMzY5YzFmMzRkYjM4ZTU3Mzk2YzA2ODYwODk3MzI1ZmFhMjNkYTZmNzE3YTk3MmY4MTJjZDU1MGFkMTQ2Yzk1MTdlOGM1NzMyZjgxZDE3NWViODg5OGQxZjQyMjg5ZWNkNjNjODJiMDZjNzM=
files:
type: array
description: >
Optional list of file IDs attached to this message. The referenced file IDs
must have been recently uploaded and not already referenced by another message.
Referenced files will have their expiries updated to 15 days, and will be
deleted if the message is deleted.
If any of the files are already associated with another message then the
association is ignored.
When submitting a message *edit* this field must contain the IDs of any newly
uploaded files that are part of the edit, existing attachment IDs may be omitted
(but including them is not an error).
items:
type: integer
format: int64
example: [4571, 4572]
responses:
201:
description: Message created
content:
application/json:
schema:
$ref: "#/components/schemas/Message"
403:
description: >
Forbidden. Returned if the user does not have permission to post messages to this room.
content:
application/json:
schema:
type: object
properties:
banned:
type: boolean
description: >
True if permission was denied because the user is banned, omitted otherwise.
noWrite:
type: boolean
description: >
True if permission was denied because the user is lacking write permission,
for example because of default room settings or a restriction applied to the
user.
reason:
type: string
description: >
A short, English-language string describing the reason the failure occured.
This is for use as a fallback ONLY: clients should prefer to identify failure
through examining the other fields in the response and only use `reason` as a
user-facing failure description if no known failure is included (which might
happen if the server speaks a new version of the protocol than the client
understands).
example: "Future horrible failure reason"
/room/{roomToken}/message/{messageId}:
get:
tags: [Messages]
summary: Returns a single posted message by ID.
parameters:
- $ref: "#/components/parameters/pathRoomToken"
- name: messageId
in: path
description: ID of the message to retrieve.
required: true
schema:
type: integer
format: int64
responses:
200:
description: successful operation
content:
application/json:
schema:
$ref: "#/components/schemas/Message"
403:
description: Forbidden
put:
tags: [Messages]
summary: Submits replacement message content (i.e. for edits).
description: >
Re-posts a message, replacing its existing content with new content and a new signature.
This edit may only be initiated by the creator of the post.
parameters:
- $ref: "#/components/parameters/pathRoomToken"
- name: messageId
in: path
description: ID of the message to replace.
required: true
schema:
type: integer
format: int64
requestBody:
$ref: "#/paths/~1room~1%7BroomToken%7D~1message/post/requestBody"
responses:
200:
description: Message updated successfully
content:
application/json:
schema:
$ref: "#/components/schemas/Message"
403:
description: >
Forbidden. Returned if the user does not have permission to post messages to this room,
or isn't the owner of the message being edited.
Note: the `reason` string is provided only as a fallback for forwards compatibility:
clients should attempt to identify the reason using the given boolean flags first, and
only use `reason` as a fallback if it can find no known reasons in the boolean fields.
This situation may arise if a future version of the specification (that the client
doesn't yet support) adds new failure reasons.
content:
application/json:
schema:
type: object
properties:
banned:
type: boolean
description: >
True if the user is banned from the room and thus no longer has edit
permissions. Omitted when false.
noWrite:
type: boolean
description: >
True if the user does not have write permissions to the room, e.g. because the
user has been restricted or room permissions have changed since the message
was posted. Omitted when false.
notYours:
type: boolean
description: >
True if the message was posted by another user, and thus cannot be edited by
the current user. Omitted when false.
reason:
$ref: "#/paths/~1room~1%7BroomToken%7D~1message/post/responses/403/content/application~1json/schema/properties/reason"
/room/{roomToken}/messages/recent:
get:
tags: [Messages]
summary: "Retrieves recent messages posted to this room."
description: >
Returns the most recent `limit` messages (100 if no limit is given). This only returns
extant messages, and always returns the latest versions: that is, deleted message indicators
and pre-editing versions of messages are not returned. Messages are returned in order from
most recent to least recent.
parameters:
- $ref: "#/components/parameters/pathRoomToken"
- $ref: "#/components/parameters/queryMessagesLimit"
responses:
200:
description: successful operation
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Message'
/room/{roomToken}/messages/before/{messageId}:
get:
tags: [Messages]
summary: "Retrieves messages from the room preceding a given id."
description: >
Retrieves messages from the room immediately preceding the given message ID. This endpoint
is intended to be used with `.../recent` to allow a client to retrieve the most recent
messages and then walk backwards through batches of ever-older messages. As with
`.../recent`, messages are returned in order from most recent to least recent.
As with `.../recent`, this endpoint does not include deleted messages and always returns the
current version (i.e. fully edited) of edited messages.
parameters:
- $ref: "#/components/parameters/pathRoomToken"
- $ref: "#/components/parameters/queryMessagesLimit"
- name: messageId
in: path
description: "The id of the message whose preceding messages are sought."
required: true
schema:
type: integer
format: int64
responses:
200:
description: successful operation
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Message'
/room/{roomToken}/messages/since/{updateId}:
get:
tags: [Messages]
summary: "Retrieves message updates from a room."
description: >
This endpoint retrieves new, edited, and deleted messages posted to this room since the
given update id. Returns `limit` messages at a time (100 if no limit is given). Returned
messages include any new messages, updates to existing messages (i.e. edits), and message
deletions made to the room since the given update id. Messages are returned in "update"
order, that is, in the order in which the change was applied to the room, from oldest the
newest.
parameters:
- $ref: "#/components/parameters/pathRoomToken"
- $ref: "#/components/parameters/queryMessagesLimit"
- name: updateId
in: path
required: true
description: >
The update id from which to retrieve message updates. To retrieve from the beginning of
the room's message history use a value of 0 (the first room update will always be >= 1).
schema:
type: integer
format: int64
responses:
200:
description: successful operation
content:
application/json:
schema:
type: object
properties:
more:
type: integer
format: int32
description: >
Indicates the number of additional message updates after the last one
returned. A positive value indicates that more messages are available (that
is: that the limit was binding).
messages:
type: array
items:
$ref: '#/components/schemas/Message'
/room/{roomToken}/file:
post:
tags: [Files]
summary: "Uploads a file to a room."
description: >
Takes the request as binary in the body and takes other properties via submitted headers.
This saves space, particularly for large uploads. The user must have upload and posting
permissions for the room. The file will have a default lifetime of 1 hour, but that is
extended to 15 days when the containing message referencing the uploaded file is posted.
See also the `.../fileJson` endpoint for submitting via a json body.
parameters:
- $ref: "#/components/parameters/pathRoomToken"
- name: X-Filename
in: header
description: >
Suggested filename of the upload. Typically the basename of the file uploaded from the
user.
schema:
type: string
requestBody:
description: The file content, in bytes.
required: true
content:
'*/*':
{}
responses:
200:
description: successful operation
content:
application/json:
schema:
type: object
properties:
id:
type: integer
format: int64
description: "The id of the file on the server."
403:
description: >
Upload forbidden. This response code indicates that the user does not have posting
and/or upload permissions in the room either because of room settings, user restriction,
or because the user is banned.
content:
application/json:
schema:
type: object
properties:
banned:
type: boolean
description: >
True if the upload was denied because the user is banned, omitted otherwise.
noWrite:
type: boolean
description: >
True if the upload was denied because the user does not have write access to
the room (but is not banned). Omitted otherwise.
noUpload:
type: boolean
description: >
True if the upload was denied because the user does not have upload access to
the room (but is not banned and has write permissions). Omitted otherwise.
/room/{roomToken}/fileJSON:
post:
tags: [Files]
summary: "Uploads a file to a room using a JSON encoded body."
description: >
This is less efficient when a binary upload is possible because the body must be passed as
base64-encoded data (which is 33% larger). The user must have upload and posting
permissions for the room. The file will have a default lifetime of 1 hour, but that is
extended to 15 days when the containing message referencing the upload is submitted.
parameters:
- $ref: "#/components/parameters/pathRoomToken"
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [filename, content]
properties:
filename:
type: string
description: "Suggested filename of the upload. Typically the basename of the file uploaded from the user."
content:
type: string
format: byte
description: The file content, in base64 encoding.
responses:
200:
$ref: "#/paths/~1room~1%7BroomToken%7D~1file/post/responses/200"
403:
$ref: "#/paths/~1room~1%7BroomToken%7D~1file/post/responses/403"
/room/{roomToken}/file/{fileId}:
get:
tags: [Files]
summary: "Retrieves a file from the room via JSON."
description: >
Retrieves a file via a fileId from the room via a JSON object response. This is noticeably
less efficient (particularly for large files) than the binary version when making direct
requests because the file data must be encoded using base64 encoding.
parameters:
- $ref: "#/components/parameters/pathRoomToken"
- $ref: "#/components/parameters/pathFileId"
responses:
200:
description: successful operation; returns the file in JSON.
content:
application/json:
schema:
type: object
properties:
filename:
type: string
description: >
The suggested filename of the file. Omitted if the file was uploaded without a
filename (e.g. from older clients, or clients that specify an empty filename.)
size:
type: integer
format: int64
description: >
The file size, in bytes. (*Not* the length of the base64-encoded data.)
uploaded:
type: number
format: double
description: The unix timestamp when the file was uploaded.
expires:
type: number
format: double
nullable: true
description: >
The unix timestamp when the file is scheduled to be removed. Will be null if
the attachment is permanent, such as for room images or attachments in pinned
messages.
403:
$ref: "#/paths/~1room~1%7BroomToken%7D/get/responses/403"
404:
description: >
The referenced file does not exist. (It may have expired, or may be invalid.)
/room/{roomToken}/file/{fileId}/{filename}:
get:
tags: [Files]
summary: "Retrieves a file from the room as binary."
description: >
Retrieves a file via a fileId from the room, returning the file content directly as the
binary response body. The filename parameter is ignored and may be empty: it is primarily
included to aid in clients that want the request to include a filename, and differentiates
this as a request retrieving the file itself rather than the file as a JSON response. See
the version without `/filename` for a JSON-returning version.
parameters:
- $ref: "#/components/parameters/pathRoomToken"
- $ref: "#/components/parameters/pathFileId"
- name: filename
in: path
required: true
description: >
Filename if known by the requesting client, and empty otherwise. The value of this
parameter is ignored by the server itself: it is included to differentiate this request
from the JSON version, and so that clients may include a filename in the request URL for
contexts where that is useful.
schema:
type: integer
format: int64
responses:
200:
description: successful operation; returns the file, in raw bytes.
headers:
Content-Length:
description: The size of the file.
schema:
type: integer
format: int64
example: 12345
Date:
description: The HTTP timestamp at which the file was uploaded.
schema:
type: string
example: "Thu, 7 Oct 2021 00:42:00 GMT"
Expires:
description: >
The HTTP timestamp at which the file is scheduled to expire. This header is omitted
if the attachment is non-expiring (e.g. for attachments in a pinned message).
schema:
type: string
example: "Fri, 22 Oct 2021 00:42:42 GMT"
content:
application/octet-stream:
schema:
type: string
format: binary
403:
$ref: "#/paths/~1room~1%7BroomToken%7D~1file~1%7BfileId%7D/get/responses/403"
404:
$ref: "#/paths/~1room~1%7BroomToken%7D~1file~1%7BfileId%7D/get/responses/403"
/user/{sessionId}/ban:
post:
tags: [Users]
summary: Bans or unbans a user.
description: >
Applies or removes a ban of a user from specific rooms, or from the server globally.
Note that the given session ID does not have to exist: it is possible to preemptively ban
users who have never visited the server or room(s).
The user's messages are not deleted by this request. In order to ban and delete all
messages use the `/sequence` endpoint to bundle a `/user/.../ban` with a
`/user/.../deleteMessages` request.
parameters:
- $ref: "#/components/parameters/pathSessionId"
requestBody:
description: Details of the ban to apply. To unban a user, specify a negative timeout.
required: true
content:
application/json:
schema:
type: object
properties:
rooms:
type: array
items:
$ref: "#/components/schemas/RoomToken"
minItems: 1
description: >
List of room tokens to which the ban should be applied. The invoking user must
be a moderator (or admin) of all of the given rooms.
Exclusive of `global`.
global:
type: boolean
description: >
If true then apply the the ban at the global level, i.e. server-wide. The
invoking user must be a server-level moderator or admin.
Exclusive of `rooms`.
timeout:
type: number
format: double
nullable: true
example: 86400
description: >
How long the ban should apply, in seconds. If there is an existing ban on the
user in the given rooms or globally this updates the existing expiry to the
given value. If omitted or `null` the ban does not expire.
If this value is set to a negative value (`-1` is suggested) then any existing
bans for this user are *removed* from the given rooms/server. Note, however,
that server bans and room bans are independent: removing a server-level ban does
not remove room-specific bans, and removing a room-level ban will not grant room
access to a user who also has a server-level ban.
examples:
tworooms:
summary: "1-day ban from two rooms"
value:
rooms: ["session", "lokinet"]
timeout: 86400
permaban:
summary: "Permanent server ban"
value:
global: true
timeout: null
delete_all: true
unban:
summary: "Unban a user from a room"
value:
rooms: ["lokinet"]
global: false,
timeout: -1
responses:
200:
description: Ban applied successfully.
content: {}
403:
description: >
Permission denied. The user attempting to set the ban does not have moderator
permissions for one or more of the given rooms (or server moderator permission for a
global ban).
content: {}
/user/{sessionId}/permission:
post:
tags: [Users]
summary: Applies permissions or restrictions to a user.
description: >
Applies or removes a user's permissions to one or more rooms.
The request specifies grants (`true`) or revocations (`false`) of permissions to apply.
Granting or revoking a permission adds a specific override for the given user that overrides
the default room permissions.
You can explicitly clear one or more permission setting by specifying a timeout of `-1` (in
this case the actual true/false value of the permissions are ignored).
Note that the given session ID does not have to exist: it is possible to grant permissions
preemptively for a session ID that has never visited the server or room(s).
parameters:
- $ref: "#/components/parameters/pathSessionId"
requestBody:
description: "Details of the permission update to apply."
required: true
content:
application/json:
schema:
type: object
required: [rooms]
properties:
rooms:
type: array
items:
$ref: "#/components/schemas/RoomToken"
minItems: 1
description: >
List of room tokens to which the permissions should be applied. The invoking
user must be a moderator (or admin) of all of the given rooms.
timeout:
type: number
format: double
nullable: true
example: 86400
description: >
How long the new permission (or restriction) should apply, in seconds. If the
user already has future permission changes scheduled then they will be cancelled
and replaced the changes scheduled here.
When the timeout expires, the specific override will be removed and the user's
permission will revert to the room's defaults.
Using a timeout of -1 clears any given permission/restrictions immediately.
Note that, in this case, the actual true/false value is ignored. For instance,
`timeout: -1, read: false` and `timeout: -1, read: true` both clear any existing
user-specific permission for `read`.
read:
type: boolean
nullable: true
example: false
description: >
If true this grants permission to read the room's messages even if the room
defaults do not allow reading. If false this restricts permission to read the
room's messages even if the room's default allows reading. Specifying this as
null will explicitly delete any user-specific read override (effectively
returning the user's read permission to the room's default).
write:
type: boolean
nullable: true
example: true
description: >
If true this grants permission to post messages to the room, even if the room's
default permissions do not allow posting. If false this restricts the user from
posting. Specifying this as null will explicitly delete any user-specific write
override, returning the user's effective permission to the room's default.
upload:
type: boolean
nullable: true
example: true
description: >
If true this grants permission to upload files to the room for this user, even
if the room's default permission does not allow uploads. If false the user is
restricted from uploading files. Specifying as null will explicitly delete any
user-specific override, returning the user's effective permission to the room's
default.
examples:
tworooms:
summary: "1-day mute in two rooms"
value:
rooms: ["session", "lokinet"]
timeout: 86400
write: false
allow-uploads:
summary: "Allow file attachments for 1 week"
value:
rooms: ["session-help"]
upload: true
timeout: 604800
secretroom:
summary: "Grant access to a restricted room"
value:
rooms: ["top-secret"]
read: true
write: true
upload: true
responses:
200:
description: Permission update applied successfully.
content: {}
403:
description: >
Permission denied. The user attempting to set the permissions does not have moderator
permissions for one or more of the given rooms.
content: {}
/user/{sessionId}/moderator:
post:
tags: [Users]
summary: Adds or removes moderator powers.
description: >
Adds or removes moderator or admin permissions to a user for specific rooms, or globally on
the server.
Note that the given session ID does not have to exist: it is possible to grant moderator
permissions preemptively for a session ID that has never visited the server or room(s).
parameters:
- $ref: "#/components/parameters/pathSessionId"
requestBody:
description: "Details of the permission update to apply."
required: true
content:
application/json:
schema:
type: object
properties:
rooms:
type: array
items:
$ref: "#/components/schemas/RoomToken"
minItems: 1
description: >
List of room tokens to which the moderator status should be applied. The
invoking user must be an admin of all of the given rooms.
Exclusive of `global`.
global:
type: boolean
description: >
If true then appoint this user as a moderator or admin of the global server.
The user will receive moderator/admin ability in all rooms on the server.
moderator:
type: boolean
description: >
If `true` then this user will be granted moderator permission to either the
listed room or the server globally.
If `false` then this user will have their moderator and admin permissions
removed from the given rooms (or server).
admin:
type: boolean
description: >
If `true` then this user will be granted moderator and admin permissions to the
given rooms or server. Admin permissions are required to appoint new moderators
or administrators.
If false then this user will have their admin permission removed, but will
remain a moderator (if they were previously a moderator or admin). To remove
both moderator and admin status you can specify simply `moderator: false` rather
than needing to specify both values as false.
visible:
type: boolean
description: >
Whether this user should be a "visible" moderator in the server rooms. Visible
moderators are identified to all room users (e.g. via a special status badge in
Session clients).
Invisible moderators/admins have the same permission as as visible ones, but
their moderator/admin status is only visible to other moderators but not to
ordinary room participants.
The default if this field is omitted is true for room-specific moderators/admins
and false for server-level global moderators/admins.
examples:
tworooms:
summary: "1-day mute in two rooms"
value:
rooms: ["session", "lokinet"]
timeout: 86400
write: false
allow-uploads:
summary: "Allow file attachments for 1 week"
value:
rooms: ["session-help"]
upload: true
timeout: 604800
secretroom:
summary: "Grant access to a restricted room"
value:
rooms: ["top-secret"]
read: true
write: true
upload: true
responses:
200:
description: Permission update applied successfully.
content: {}
403:
description: >
Permission denied. The user attempting to set the permissions does not have moderator
permissions for one or more of the given rooms.
content: {}
/user/{sessionId}/deleteMessages:
post:
tags: [Users]
summary: Deletes all of a user's messages.
description: >
Deletes all messages posted by the given user from one or more rooms, or from all rooms on
the server.
The caller must have moderator permission in all given rooms, or be a server moderator for
global server deletion.
parameters:
- $ref: "#/components/parameters/pathSessionId"
requestBody:
description: "Details of the deletion."
required: true
content:
application/json:
schema:
type: object
properties:
rooms:
type: array
items:
$ref: "#/components/schemas/RoomToken"
minItems: 1
description: >
List of room tokens from which messages should be deleted. The invoking user
must be a moderator (or admin) or all of the given rooms.
Exclusive of `global`.
global:
type: boolean
description: >
If true then delete all messages made by this user from all rooms on the server.
The invoking user must be a server-level moderator or admin. In particular,
this does *not* allow a non-server moderator to delete the user's messages from
all rooms they moderate.
Exclusive of `rooms`.
examples:
tworooms:
summary: "Delete all messages from two rooms"
value:
rooms: ["session", "lokinet"]
permaban:
summary: "Delete all messages from all rooms"
value:
global: true
responses:
200:
description: Messages deleted successfully.
content:
application/json:
schema:
type: object
properties:
id:
$ref: "#/components/schemas/SessionID"
messages_deleted:
type: integer
format: int64
description: The number of messages deleted.
403:
description: >
Permission denied. The user attempting to set the ban does not have moderator
permissions for one or more of the given rooms (or server moderator permission for a
global ban).
content: {}
/batch:
post:
tags: [Batch]
summary: "Utility endpoint to allow submitting multiple independent requests at once."
description: "This is used, for example, to poll multiple rooms on the same server for updates in a single query rather than needing to make multiple requests for each room.\n\nNo guarantee is made as to the order in which sub-requests are processed; use the `/sequence` instead if you need that."
requestBody:
description: "List of sub-requests to issue for this batch request."
required: true
content:
application/json:
schema:
type: array
items:
type: object
required: [method, path]
properties:
method:
type: string
description: "The request method, usually GET for batched requests, though other methods are also permitted."
path:
type: string
description: "The request path, e.g. `/room/123/messages/since/45678`"
json:
description: "Optional nested json structure containing a json body for the POST/PUT requests. Exclusive of `bytes`, and may not be provided for methods that do not accept a body (such as GET)."
oneOf:
- type: object
- type: array
bytes:
description: "Optional body, encoded in base64, for the POST/PUT request. Exclusive of `json` and may not be provided for methods that do not accept a body (such as GET)."
type: string
format: byte
responses:
200:
description: "Batch jobs completed. Note that 200 only means the batch was processed; for individual sub-requests see the relevant sub-response code. The returned array returns responses in exactly the same order as the request's list of sub-requests (regardless of the actual order jobs were processed)."
content:
application/json:
schema:
type: array
items:
type: object
required: [code, content-type, body]
properties:
code:
type: integer
format: int32
description: "HTTP response code for the subrequest (e.g. 200, 404, etc.)"
content-type:
type: string
description: "HTTP content-type of the subrequest response (e.g. `application/json`)"
body:
oneOf:
- type: object
- type: array
- type: string
format: byte
description: "The response body. For responses with `content-type` set to `application/json` this will be the direct object or array response; for any other content otherwise this will be a string containing the base64-encoded response data."
/sequence:
post:
tags: [Batch]
summary: "Utility endpoint to submit a batch of sequenced, dependent requests."
description: "The requests are guaranteed to be performed sequentially in the order given in the request and will abort if any request does not return a status-`2xx` response.\n\nFor example, this can be used to ban and delete all of a user's messages by sequencing the ban followed by the delete_all: if the ban fails (e.g. because permission is denied) then the delete_all will not occur. The batch body and response are identical to the `/batch` endpoint; requests that are not carried out because of an earlier failure will have a response code of `412` (Precondition Failed)."
requestBody:
$ref: "#/paths/~1batch/post/requestBody"
responses:
200:
$ref: "#/paths/~1batch/post/responses/200"
components:
schemas:
RoomToken:
type: string
title: A room token used in URLs to identify the room.
pattern: "^[\\w-]{1,64}$"
example: "session-general"
SessionID:
type: string
title: A session ID, in hex.
description: >
The Session ID is the fixed byte `05` followed by the 32-byte X25519 pubkey used to sign and
encrypt messages.
pattern: "^05[0-9a-fA-F]{64}$"
Room:
title: Information about a room
type: object
properties:
token:
$ref: "#/components/schemas/RoomToken"
name:
type: string
description: Room name to display to users.
example: "Session General Discussion"
description:
type: string
description: Room description to display to users. Omitted if not set.
example: "General chat related to the Session messenger."
info_updates:
type: integer
format: int64
description: >
Monotonic room information counter that increases each time the room's metadata changes.
example: 12345
updates:
type: integer
format: int64
description: >
Monotonic room post counter that increases each time a message is posted, edited, or
deleted in this room. (Note that changes to this field do *not* update the room's
`info_updates` value.)
example: 567890
created:
type: number
format: double
description: Unix timestamp when the room was created
example: 1633629915.34607
active_users:
type: object
description: >
Number of recently active users in the room over recent time periods.
Users are considered "active" if they have access the room (checking for new messages,
etc.) at least once in the given time periods.
Note that changes to this field do *not* update the room's `info_updates` value.
properties:
hour:
type: integer
format: int64
description: "Number of active users in the past hour."
day:
type: integer
format: int64
description: "Number of active users in the past 24 hours."
week:
type: integer
format: int64
description: "Number of active users in the past week."
month:
type: integer
format: int64
description: "Number of active users in the past 30 days."
example: { hour: 842, day: 1917, week: 3481, month: 5609 }
image_id:
type: integer
format: int64
description: >
File ID of an uploaded file containing the room's image. Omitted if there is no image.
example: 42
pinned_messages:
type: array
items:
type: integer
format: int64
description: >
IDs of this room's pinned messages, in order of when they were pinned.
example: [512, 4998, 11]
moderators:
type: array
items:
type: string
description: >
Session IDs of the room's public moderators.
example:
- "050123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
- "05fedcba9876543210fedcba9876543210fedcba9876543210fedcba9876543210"
admins:
type: array
items:
type: string
description: >
Session IDs of the room's public administrators. (Administrators are moderators who
also have permission to add or remove other moderators.)
example:
- "050123456776543210012345677654321001234567765432100123456776543210"
hidden_mods:
type: array
items:
type: string
description: >
Session IDs of moderators who are not publicly displayed as moderators of the room.
This field is only present if the requestor is a moderator/admin of the room or server.
example:
- "0589abcdeffedcba9889abcdeffedcba9889abcdeffedcba9889abcdeffedcba98"
hidden_admins:
type: array
items:
type: string
description: >
Session IDs of admins who are not publicly displayed as administrators of the room.
This field is only present if the requestor is a moderator/admin of the room or server.
example:
- "050011223344556677001122334455667700112233445566770011223344556677"
moderator:
type: boolean
description: >
Will be set to true if the requestor is recognized with moderator permissions in the
room. Omitted otherwise.
example: true
admin:
type: boolean
description: >
Will be set to true if the requestor is recognized with admin permissions in the room.
Omitted otherwise.
example: true
read:
type: boolean
description: >
Whether the user has permission to read messages in the room. (Note that changes to
this property do not cause an `info_update` increment.)
example: true
write:
type: boolean
description: >
Whether the user has permission to post messages to the room. (Note that changes to
this property do not cause an `info_update` increment.)
example: true
upload:
type: boolean
description: >
Whether the user has permissions to upload attachments to messages posted to the room.
(Note that changes to this property do not cause an `info_update` increment.)
example: true
Message:
title: The content of a posted message
type: object
properties:
id:
type: integer
format: int64
description: The numeric message id.
session_id:
allOf:
- $ref: "#/components/schemas/SessionID"
- type: object
description: >
The session ID of the user who posted this message. Omitted in contexts where the
information isn't available or isn't useful or available, such as in the
confirmation of submitting a post.
timestamp:
type: number
format: double
description: >
Unix timestamp of when the message was posted to the server.
edited:
type: number
format: double
description: >
Unix timestamp of the last edit to this message. This field is omitted if the message
has never been edited.
updated:
type: integer
format: int64
description: >
Set to the room's current monotonic update counter when this message is first posted and
whenever the message is edited or deleted. Thus an update to this value for the same
message indicates an update or deletion.
data:
type: string
format: byte
description: >
The posted message data, encoded in base64. For a deleted message this field is
omitted. For an edited message, this field contains the latest message value.
signature:
type: string
format: byte
description: >
An XEd25519 signature of the data contained in `data`, signed using the X25519 pubkey
contained in the user's Session ID. This field is omitted when `data` is omitted (i.e.
for deleted messages.)
parameters:
pathRoomToken:
name: roomToken
in: path
description: "Token of the room to which the request is being made."
required: true
schema:
$ref: "#/components/schemas/RoomToken"
queryMessagesLimit:
name: limit
in: query
required: false
description: "Number of messages to return. If omitted 100 messages are returned."
schema:
type: integer
format: int32
minimum: 1
maximum: 255
pathFileId:
name: fileId
in: path
required: true
description: "ID of a file uploaded to the room."
schema:
type: integer
format: int64
pathSessionId:
name: sessionId
in: path
required: true
description: "Session ID of a user."
schema:
$ref: "#/components/schemas/SessionID"
securitySchemes:
pubkey:
type: apiKey
name: X-SOGS-Pubkey
in: header
description: "The Session ID of the requestor"
nonce:
type: apiKey
name: X-SOGS-Nonce
in: header
description: >
A unique nonce string, in base64, of exactly 16 base64 characters (96 bits). This must be
unique for every request from this pubkey within the last 24 hours; nonce reuse will result
in failed requests. It is typically sufficient to generate 96 bits (12 bytes) or random
data for each request, but clients are free to use other nonce generation mechanisms if
desired.
timestamp:
type: apiKey
name: X-SOGS-Timestamp
in: header
description: >
Unix timestamp integer (expressed as a string) of the time when the request was initiated
(to help avoid replay attacks). This timestamp must be within ±24 hours of the server's
time when the request is received.
signature:
type: apiKey
name: X-SOGS-Signature
in: header
description: >
XEd25519 signature of
`METHOD || PATH || NONCE || TIMESTAMP || SERVER_PUBKEY || BODY`
signed using the client's Session ID pubkey, using base64 encoding (with or without
padding).
# vim:sw=2:et:tw=100