Beeper Files API
File upload, download, and streaming helpers for message attachments and drafts.
File upload, download, and streaming helpers for message attachments and drafts.
openapi: 3.1.0
info:
title: Beeper Desktop Accounts Files API
version: 5.0.0
description: 'Beeper Desktop''s local HTTP and WebSocket API. One auth flow and one chat shape work across WhatsApp, iMessage, Telegram, Slack, Matrix, Discord, Twitter/X, Signal, and more.
Beeper is built on the Matrix standard. Identifiers and rich text use Matrix conventions: `mxc://` and `localmxc://` URLs reference media on the Matrix homeserver and on this device''s local bridge respectively; message text is Matrix HTML on the wire; `@room` is a group-mention sentinel.
## Quickstart
1. Discover the server with `GET /v1/info`. The Desktop API is local-only unless the user has enabled remote access.
2. Authenticate with an access token from Beeper Desktop, or run OAuth2 Authorization Code with PKCE under the OAuth tag.
3. Call `GET /v1/accounts` to see connected Chat Accounts, then `GET /v1/chats` for the unified inbox.
## WebSocket
Connect to `/v1/ws` with the same Bearer token in the upgrade request. Browser `new WebSocket()` clients are not supported yet because browsers cannot set the Authorization header. After the server sends `ready`, send `{"type":"subscriptions.set","chatIDs":["*"]}` to receive every chat update, or pass specific chat IDs. The server replies with `subscriptions.updated`, then streams `chat.upserted`, `chat.deleted`, `message.upserted`, and `message.deleted`.
Delivery is at-most-once. There is no replay on reconnect, and `seq` is per connection. Refetch via HTTP after a disconnect to reconcile drift. Initial subscription state is empty; `subscriptions.set` replaces previous state; `["*"]` cannot be combined with specific chat IDs.
## Conventions
- IDs and cursors are opaque strings.
- Timestamps are ISO 8601 with timezone, except OAuth fields that use Unix seconds per RFC.
- Pagination is `cursor` plus `direction=before|after`.
- Sends return a `pendingMessageID`; resolve it with `GET /v1/chats/{chatID}/messages/{messageID}` or wait for `message.upserted` over the WebSocket.
- Optional fields may be omitted when unknown. Nullable write fields use `null` as an explicit clear operation.
- Every response carries `X-Beeper-Desktop-Version` so clients can tell which app version produced it.'
termsOfService: https://www.beeper.com/terms
contact:
name: Beeper
email: help@beeper.com
url: https://www.beeper.com
license:
name: Proprietary
url: https://www.beeper.com/terms
servers:
- url: http://localhost:23373
description: Beeper Desktop API server
security:
- bearerAuth: []
tags:
- name: Files
description: File upload, download, and streaming helpers for message attachments and drafts.
paths:
/v1/assets/download:
post:
summary: Download a file
description: Download a Matrix file using its mxc:// or localmxc:// URL to the device running Beeper Desktop and return the local file URL.
tags:
- Files
operationId: downloadAsset
security:
- bearerAuth: []
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/DownloadAssetInput'
responses:
'200':
description: Request executed successfully
headers:
X-Beeper-Desktop-Version:
$ref: '#/components/headers/X-Beeper-Desktop-Version'
content:
application/json:
schema:
$ref: '#/components/schemas/DownloadAssetOutput'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/UnauthorizedError'
'403':
$ref: '#/components/responses/ForbiddenError'
'404':
$ref: '#/components/responses/NotFound'
'422':
$ref: '#/components/responses/UnprocessableEntity'
'429':
$ref: '#/components/responses/TooManyRequests'
'500':
$ref: '#/components/responses/InternalServerError'
/v1/assets/serve:
get:
summary: Serve a file
description: Stream a file given an mxc://, localmxc://, or file:// URL. Downloads first if not cached. Supports Range requests for seeking in large files.
tags:
- Files
operationId: serveAsset
security:
- bearerAuth: []
parameters:
- schema:
type: string
minLength: 1
description: File URL to serve. Accepts mxc://, localmxc://, or file:// URLs.
required: true
description: File URL to serve. Accepts mxc://, localmxc://, or file:// URLs.
name: url
in: query
responses:
'200':
description: File stream
headers:
X-Beeper-Desktop-Version:
$ref: '#/components/headers/X-Beeper-Desktop-Version'
content:
application/octet-stream:
schema:
type: string
format: binary
'206':
description: Partial file stream
headers:
X-Beeper-Desktop-Version:
$ref: '#/components/headers/X-Beeper-Desktop-Version'
content:
application/octet-stream:
schema:
type: string
format: binary
'304':
description: File not modified
headers:
X-Beeper-Desktop-Version:
$ref: '#/components/headers/X-Beeper-Desktop-Version'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/UnauthorizedError'
'403':
$ref: '#/components/responses/ForbiddenError'
'404':
$ref: '#/components/responses/NotFound'
'416':
description: Requested range not satisfiable
headers:
X-Beeper-Desktop-Version:
$ref: '#/components/headers/X-Beeper-Desktop-Version'
'422':
$ref: '#/components/responses/UnprocessableEntity'
'429':
$ref: '#/components/responses/TooManyRequests'
'500':
$ref: '#/components/responses/InternalServerError'
/v1/assets/upload:
post:
summary: Upload a file
description: Upload a file to a temporary location using multipart/form-data. Returns an uploadID that can be referenced when sending a message or materializing a draft attachment.
tags:
- Files
operationId: uploadAsset
security:
- bearerAuth: []
requestBody:
content:
multipart/form-data:
schema:
$ref: '#/components/schemas/UploadAssetMultipart'
responses:
'200':
description: Request executed successfully
headers:
X-Beeper-Desktop-Version:
$ref: '#/components/headers/X-Beeper-Desktop-Version'
content:
application/json:
schema:
$ref: '#/components/schemas/UploadAssetOutput'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/UnauthorizedError'
'403':
$ref: '#/components/responses/ForbiddenError'
'404':
$ref: '#/components/responses/NotFound'
'422':
$ref: '#/components/responses/UnprocessableEntity'
'429':
$ref: '#/components/responses/TooManyRequests'
'500':
$ref: '#/components/responses/InternalServerError'
/v1/assets/upload/base64:
post:
summary: Upload a file (base64)
description: Upload a file using a JSON body with base64-encoded content. Returns an uploadID that can be referenced when sending a message or materializing a draft attachment. Alternative to the multipart upload endpoint.
tags:
- Files
operationId: uploadAssetBase64
security:
- bearerAuth: []
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/UploadAssetInput'
responses:
'200':
description: Request executed successfully
headers:
X-Beeper-Desktop-Version:
$ref: '#/components/headers/X-Beeper-Desktop-Version'
content:
application/json:
schema:
$ref: '#/components/schemas/UploadAssetOutput'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/UnauthorizedError'
'403':
$ref: '#/components/responses/ForbiddenError'
'404':
$ref: '#/components/responses/NotFound'
'422':
$ref: '#/components/responses/UnprocessableEntity'
'429':
$ref: '#/components/responses/TooManyRequests'
'500':
$ref: '#/components/responses/InternalServerError'
components:
responses:
UnauthorizedError:
description: Access token is missing or invalid
headers:
X-Beeper-Desktop-Version:
$ref: '#/components/headers/X-Beeper-Desktop-Version'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
NotFound:
description: Resource not found
headers:
X-Beeper-Desktop-Version:
$ref: '#/components/headers/X-Beeper-Desktop-Version'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
TooManyRequests:
description: Too many requests - rate limit exceeded
headers:
X-Beeper-Desktop-Version:
$ref: '#/components/headers/X-Beeper-Desktop-Version'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
UnprocessableEntity:
description: Unprocessable entity - validation error
headers:
X-Beeper-Desktop-Version:
$ref: '#/components/headers/X-Beeper-Desktop-Version'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
InternalServerError:
description: Internal server error
headers:
X-Beeper-Desktop-Version:
$ref: '#/components/headers/X-Beeper-Desktop-Version'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
BadRequest:
description: Invalid request parameters
headers:
X-Beeper-Desktop-Version:
$ref: '#/components/headers/X-Beeper-Desktop-Version'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
ForbiddenError:
description: Access token does not have the required scope
headers:
X-Beeper-Desktop-Version:
$ref: '#/components/headers/X-Beeper-Desktop-Version'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
schemas:
DownloadAssetInput:
type: object
properties:
url:
type: string
minLength: 1
description: Matrix content URL (mxc:// or localmxc://) for the file to download.
required:
- url
example:
url: mxc://example.org/Q4x9CqGz1pB3Oa6XgJ
DownloadAssetOutput:
type: object
properties:
srcURL:
type: string
description: Local file URL to the downloaded file.
error:
type: string
description: Error message if the download failed.
UploadAssetInput:
type: object
properties:
content:
type: string
minLength: 1
maxLength: 750000000
description: Base64-encoded file content (max ~500MB decoded)
fileName:
type: string
description: Original filename. Generated if omitted
mimeType:
type: string
description: MIME type. Auto-detected from magic bytes if omitted
required:
- content
description: Upload a temporary file. Upload IDs can be referenced by send-message and draft attachment requests while the temporary upload remains available.
UploadAssetOutput:
type: object
properties:
uploadID:
type: string
description: Unique upload ID for this temporary file
srcURL:
type: string
description: Local file URL (file://) for the uploaded file
fileName:
type: string
description: Resolved filename
mimeType:
type: string
description: Detected or provided MIME type
fileSize:
type: number
description: File size in bytes
width:
type: number
description: Width in pixels (images/videos)
height:
type: number
description: Height in pixels (images/videos)
duration:
type: number
description: Duration in seconds (audio/videos)
error:
type: string
description: Error message if upload failed
UploadAssetMultipart:
type: object
properties:
file:
type: string
description: The file to upload (max 500 MB).
format: binary
fileName:
type: string
description: Original filename. Defaults to the uploaded file name if omitted
mimeType:
type: string
description: MIME type. Auto-detected from magic bytes if omitted
required:
- file
description: Upload a temporary file. Upload IDs can be referenced by send-message and draft attachment requests while the temporary upload remains available.
Error:
type: object
properties:
message:
type: string
description: Error message
code:
type: string
description: Machine-readable error code
details:
anyOf:
- type: object
properties:
issues:
type: array
items:
type: object
properties:
code:
type: string
description: Validation issue code
example: invalid_type
message:
type: string
description: Human-readable description of the validation issue
path:
type: array
items:
anyOf:
- type: string
x-stainless-variantName: field
- type: number
x-stainless-variantName: index
description: Path pointing to the invalid field within the payload
example:
- body
- chatID
required:
- code
- message
- path
description: List of validation issues
required:
- issues
description: Validation error details
x-stainless-variantName: validation_details
- type: object
additionalProperties:
nullable: true
x-stainless-any: true
description: Additional error context
x-stainless-variantName: context
- nullable: true
description: Arbitrary details payload supplied by the server
x-stainless-any: true
x-stainless-variantName: arbitrary
- nullable: true
description: Additional error details for debugging
required:
- message
- code
headers:
X-Beeper-Desktop-Version:
description: Beeper Desktop application version providing this response.
schema:
type: string
example: 4.0.0
securitySchemes:
bearerAuth:
type: http
scheme: bearer
description: Bearer token authentication. Access token obtained via OAuth2 PKCE flow or created in-app. Required for all API operations.
oauth2:
type: oauth2
description: OAuth2 Authorization Code flow with PKCE for obtaining bearer access tokens. Used by MCP servers to authenticate clients.
flows:
authorizationCode:
authorizationUrl: http://localhost:23373/oauth/authorize
tokenUrl: http://localhost:23373/oauth/token
scopes:
read: Read access to messages, chats, and accounts
write: Write access to send messages, edit messages, react to messages, archive chats, and set reminders
externalDocs:
description: Beeper Desktop API Documentation
url: https://developers.beeper.com/desktop-api