diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 92d8991..3ce698f 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -21,10 +21,10 @@ jobs:
runs-on: ${{ github.repository == 'stainless-sdks/beeper-desktop-api-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata')
steps:
- - uses: actions/checkout@v6
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up Node
- uses: actions/setup-node@v4
+ uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: '22'
@@ -43,10 +43,10 @@ jobs:
contents: read
id-token: write
steps:
- - uses: actions/checkout@v6
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up Node
- uses: actions/setup-node@v4
+ uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: '22'
@@ -61,7 +61,7 @@ jobs:
github.repository == 'stainless-sdks/beeper-desktop-api-typescript' &&
!startsWith(github.ref, 'refs/heads/stl/')
id: github-oidc
- uses: actions/github-script@v8
+ uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0
with:
script: core.setOutput('github_token', await core.getIDToken());
@@ -91,10 +91,10 @@ jobs:
runs-on: ${{ github.repository == 'stainless-sdks/beeper-desktop-api-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
steps:
- - uses: actions/checkout@v6
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up Node
- uses: actions/setup-node@v4
+ uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
with:
node-version: '22'
diff --git a/.github/workflows/publish-npm.yml b/.github/workflows/publish-npm.yml
index 3b8e2b0..76edfd1 100644
--- a/.github/workflows/publish-npm.yml
+++ b/.github/workflows/publish-npm.yml
@@ -20,10 +20,10 @@ jobs:
contents: write
steps:
- - uses: actions/checkout@v6
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up Node
- uses: actions/setup-node@v3
+ uses: actions/setup-node@3235b876344d2a9aa001b8d1453c930bba69e610 # v3.9.1
with:
node-version: '20'
diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml
index 0e12ec5..2d74c68 100644
--- a/.github/workflows/release-doctor.yml
+++ b/.github/workflows/release-doctor.yml
@@ -12,7 +12,7 @@ jobs:
if: github.repository == 'beeper/desktop-api-js' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-please') || github.head_ref == 'next')
steps:
- - uses: actions/checkout@v6
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Check release environment
run: |
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 32dbe0e..affd1ab 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "5.0.0"
+ ".": "5.1.0"
}
diff --git a/.stats.yml b/.stats.yml
index 2dd3fee..3e06ccc 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 30
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/beeper/beeper-desktop-api-c08c14bb754b4cb0e02b21fabb680469368286be339dec0aaa8c69d04a1f021a.yml
-openapi_spec_hash: a10246aaf7cdc33b682fc245bd5f893b
-config_hash: 72f9d43b9b51a5da912e9f3730e53ae2
+configured_endpoints: 56
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/beeper/beeper-desktop-api-baac187842e51587134950c59c4d746bfcb59239f01919ed83b92c24c47d98f4.yml
+openapi_spec_hash: 9de80d05f7562b7ecd07c466f0fdf58b
+config_hash: a8a4a8b869ccd5976fd4107e67d2ecae
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4932b1a..e47c195 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,28 @@
# Changelog
+## 5.1.0 (2026-05-19)
+
+Full Changelog: [v5.0.0...v5.1.0](https://github.com/beeper/desktop-api-js/compare/v5.0.0...v5.1.0)
+
+### Features
+
+* **api:** add login flow, verifications, recovery key methods to app ([b9c1714](https://github.com/beeper/desktop-api-js/commit/b9c1714410139c2139b597338cd002d785653e85))
+* **api:** api update ([0a91186](https://github.com/beeper/desktop-api-js/commit/0a91186fa1a0811dc9eeb9d43c8093aaeb115e95))
+* **api:** remove cli ([40669cb](https://github.com/beeper/desktop-api-js/commit/40669cb5d53274627d81fc4554d4c5d29647e373))
+
+
+### Bug Fixes
+
+* **mcp:** require auth for standalone HTTP server ([eb86fa5](https://github.com/beeper/desktop-api-js/commit/eb86fa551df33109e963e2faf304b0380ac504f2))
+* **typescript:** upgrade tsc-multi so that it works with Node 26 ([550009b](https://github.com/beeper/desktop-api-js/commit/550009b71f922f605d4ca0e0059bbed6627e5fbe))
+
+
+### Chores
+
+* **internal:** regenerate SDK with no functional changes ([8b59f3a](https://github.com/beeper/desktop-api-js/commit/8b59f3a10dc81df3e61d1d467f221edf4fc2d032))
+* redact api-key headers in debug logs ([f34de70](https://github.com/beeper/desktop-api-js/commit/f34de708e01ce81a9cb6a9dcd180c44e76b4f2fd))
+* **tests:** remove redundant File import ([91bb886](https://github.com/beeper/desktop-api-js/commit/91bb8861dbbe6cbf63c3c8f6a3a03c76d579c084))
+
## 5.0.0 (2026-05-07)
Full Changelog: [v4.8.0...v5.0.0](https://github.com/beeper/desktop-api-js/compare/v4.8.0...v5.0.0)
diff --git a/README.md b/README.md
index 86d6f1f..7c59c7f 100644
--- a/README.md
+++ b/README.md
@@ -220,7 +220,7 @@ const client = createClient({
});
// ... then make API calls as usual.
-const accounts = await client.accounts.list();
+const account = await client.accounts.retrieve('accountID');
const chat = await client.chats.create({
accountID: 'accountID',
participantIDs: ['string'],
@@ -246,7 +246,7 @@ const client: PartialBeeperDesktop<{ accounts: BaseAccounts }> = createClient({
// Function parameter type
async function main(client: PartialBeeperDesktop<{ accounts: BaseAccounts }>) {
- const accounts = await client.accounts.list();
+ const account = await client.accounts.retrieve('accountID');
}
// Works with any client that has the accounts resource
diff --git a/api.md b/api.md
index bde6c07..5c996b9 100644
--- a/api.md
+++ b/api.md
@@ -14,6 +14,8 @@ Methods:
Types:
+- APIError
+- AppStateSnapshot
- Attachment
- Error
- Message
@@ -25,10 +27,13 @@ Types:
Types:
- Account
+- AccountBridge
+- AccountRetrieveResponse
- AccountListResponse
Methods:
+- client.accounts.retrieve(accountID) -> AccountRetrieveResponse
- client.accounts.list() -> AccountListResponse
## Contacts
@@ -42,6 +47,59 @@ Methods:
- client.accounts.contacts.list(accountID, { ...params }) -> UsersCursorSearch
- client.accounts.contacts.search(accountID, { ...params }) -> ContactSearchResponse
+# Bridges
+
+Types:
+
+- Bridge
+- CookieField
+- DisappearingTimerCapability
+- GroupFieldCapability
+- GroupTypeCapabilities
+- LoginFlow
+- LoginInputField
+- LoginSession
+- ProvisioningCapabilities
+- ResolveIdentifierCapabilities
+- BridgeRetrieveResponse
+- BridgeListResponse
+
+Methods:
+
+- client.bridges.retrieve(bridgeID) -> BridgeRetrieveResponse
+- client.bridges.list() -> BridgeListResponse
+- client.bridges.retrieveCapabilities(bridgeID) -> ProvisioningCapabilities
+
+## LoginFlows
+
+Types:
+
+- LoginFlowListResponse
+
+Methods:
+
+- client.bridges.loginFlows.list(bridgeID) -> LoginFlowListResponse
+
+## Connections
+
+## LoginSessions
+
+Types:
+
+- LoginSessionCancelResponse
+
+Methods:
+
+- client.bridges.loginSessions.create(bridgeID, { ...params }) -> LoginSession
+- client.bridges.loginSessions.retrieve(loginSessionID, { ...params }) -> LoginSession
+- client.bridges.loginSessions.cancel(loginSessionID, { ...params }) -> LoginSessionCancelResponse
+
+### Steps
+
+Methods:
+
+- client.bridges.loginSessions.steps.submit(stepID, { ...params }) -> LoginSession
+
# Chats
Types:
@@ -125,3 +183,95 @@ Types:
Methods:
- client.info.retrieve() -> InfoRetrieveResponse
+
+# App
+
+Types:
+
+- Verification
+- AppSessionResponse
+
+Methods:
+
+- client.app.session() -> AppSessionResponse
+
+## Login
+
+Types:
+
+- LoginRegisterResponse
+- LoginResponseResponse
+- LoginStartResponse
+
+Methods:
+
+- client.app.login.email({ ...params }) -> void
+- client.app.login.register({ ...params }) -> LoginRegisterResponse
+- client.app.login.response({ ...params }) -> LoginResponseResponse
+- client.app.login.start() -> LoginStartResponse
+
+### Verification
+
+#### RecoveryKey
+
+Types:
+
+- RecoveryKeyVerifyResponse
+
+Methods:
+
+- client.app.login.verification.recoveryKey.verify({ ...params }) -> RecoveryKeyVerifyResponse
+
+##### Reset
+
+Types:
+
+- ResetCreateResponse
+- ResetConfirmResponse
+
+Methods:
+
+- client.app.login.verification.recoveryKey.reset.create({ ...params }) -> ResetCreateResponse
+- client.app.login.verification.recoveryKey.reset.confirm({ ...params }) -> ResetConfirmResponse
+
+## Verifications
+
+Types:
+
+- VerificationCreateResponse
+- VerificationRetrieveResponse
+- VerificationListResponse
+- VerificationAcceptResponse
+- VerificationCancelResponse
+
+Methods:
+
+- client.app.verifications.create({ ...params }) -> VerificationCreateResponse
+- client.app.verifications.retrieve(verificationID) -> VerificationRetrieveResponse
+- client.app.verifications.list() -> VerificationListResponse
+- client.app.verifications.accept(verificationID) -> VerificationAcceptResponse
+- client.app.verifications.cancel(verificationID, { ...params }) -> VerificationCancelResponse
+
+### Qr
+
+Types:
+
+- QrConfirmScannedResponse
+- QrScanResponse
+
+Methods:
+
+- client.app.verifications.qr.confirmScanned(verificationID) -> QrConfirmScannedResponse
+- client.app.verifications.qr.scan({ ...params }) -> QrScanResponse
+
+### SAS
+
+Types:
+
+- SASConfirmResponse
+- SASStartResponse
+
+Methods:
+
+- client.app.verifications.sas.confirm(verificationID) -> SASConfirmResponse
+- client.app.verifications.sas.start(verificationID) -> SASStartResponse
diff --git a/package.json b/package.json
index 0943a76..e510903 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@beeper/desktop-api",
- "version": "5.0.0",
+ "version": "5.1.0",
"description": "The official TypeScript library for the Beeper Desktop API",
"author": "Beeper Desktop ",
"types": "dist/index.d.ts",
@@ -43,7 +43,7 @@
"publint": "^0.2.12",
"ts-jest": "^29.1.0",
"ts-node": "^10.5.0",
- "tsc-multi": "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.9/tsc-multi.tgz",
+ "tsc-multi": "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.11/tsc-multi.tgz",
"tsconfig-paths": "^4.0.0",
"tslib": "^2.8.1",
"typescript": "5.8.3",
diff --git a/packages/mcp-server/manifest.json b/packages/mcp-server/manifest.json
index d59e134..4c124d1 100644
--- a/packages/mcp-server/manifest.json
+++ b/packages/mcp-server/manifest.json
@@ -1,7 +1,7 @@
{
"dxt_version": "0.2",
"name": "@beeper/desktop-mcp",
- "version": "5.0.0",
+ "version": "5.1.0",
"description": "The official MCP Server for the Beeper Desktop API",
"author": {
"name": "Beeper Desktop",
@@ -29,7 +29,7 @@
"user_config": {
"BEEPER_ACCESS_TOKEN": {
"title": "access_token",
- "description": "Bearer access token obtained via OAuth2 PKCE flow or created in-app. Required for all API operations.",
+ "description": "Bearer access token obtained via OAuth2 PKCE flow or created in-app. Required for authenticated API operations.",
"required": true,
"type": "string"
}
diff --git a/packages/mcp-server/package.json b/packages/mcp-server/package.json
index 67c9e04..014babb 100644
--- a/packages/mcp-server/package.json
+++ b/packages/mcp-server/package.json
@@ -1,6 +1,6 @@
{
"name": "@beeper/desktop-mcp",
- "version": "5.0.0",
+ "version": "5.1.0",
"description": "The official MCP Server for the Beeper Desktop API",
"author": "Beeper Desktop ",
"types": "dist/index.d.ts",
@@ -74,7 +74,7 @@
"ts-jest": "^29.1.0",
"ts-morph": "^19.0.0",
"ts-node": "^10.5.0",
- "tsc-multi": "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.9/tsc-multi.tgz",
+ "tsc-multi": "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.11/tsc-multi.tgz",
"tsconfig-paths": "^4.0.0"
},
"imports": {
diff --git a/packages/mcp-server/src/auth.ts b/packages/mcp-server/src/auth.ts
index 150450b..56671e9 100644
--- a/packages/mcp-server/src/auth.ts
+++ b/packages/mcp-server/src/auth.ts
@@ -7,7 +7,6 @@ import { McpOptions } from './options';
export const parseClientAuthHeaders = (req: IncomingMessage, required?: boolean): Partial => {
if (req.headers.authorization) {
const scheme = req.headers.authorization.split(' ')[0]!;
- const value = req.headers.authorization.slice(scheme.length + 1);
switch (scheme) {
case 'Bearer':
return { accessToken: req.headers.authorization.slice('Bearer '.length) };
@@ -16,14 +15,15 @@ export const parseClientAuthHeaders = (req: IncomingMessage, required?: boolean)
'Unsupported authorization scheme. Expected the "Authorization" header to be a supported scheme (Bearer).',
);
}
- } else if (required) {
- throw new Error('Missing required Authorization header; see WWW-Authenticate header for details.');
}
const accessToken =
Array.isArray(req.headers['x-beeper-access-token']) ?
req.headers['x-beeper-access-token'][0]
: req.headers['x-beeper-access-token'];
+ if (!accessToken && required) {
+ throw new Error('Missing required Authorization header; see WWW-Authenticate header for details.');
+ }
return { accessToken };
};
diff --git a/packages/mcp-server/src/code-tool-worker.ts b/packages/mcp-server/src/code-tool-worker.ts
index b7ad928..931835f 100644
--- a/packages/mcp-server/src/code-tool-worker.ts
+++ b/packages/mcp-server/src/code-tool-worker.ts
@@ -111,8 +111,17 @@ const fuse = new Fuse(
'client.focus',
'client.search',
'client.accounts.list',
+ 'client.accounts.retrieve',
'client.accounts.contacts.list',
'client.accounts.contacts.search',
+ 'client.bridges.list',
+ 'client.bridges.retrieve',
+ 'client.bridges.retrieveCapabilities',
+ 'client.bridges.loginFlows.list',
+ 'client.bridges.loginSessions.cancel',
+ 'client.bridges.loginSessions.create',
+ 'client.bridges.loginSessions.retrieve',
+ 'client.bridges.loginSessions.steps.submit',
'client.chats.archive',
'client.chats.create',
'client.chats.list',
@@ -138,6 +147,23 @@ const fuse = new Fuse(
'client.assets.upload',
'client.assets.uploadBase64',
'client.info.retrieve',
+ 'client.app.session',
+ 'client.app.login.email',
+ 'client.app.login.register',
+ 'client.app.login.response',
+ 'client.app.login.start',
+ 'client.app.login.verification.recoveryKey.verify',
+ 'client.app.login.verification.recoveryKey.reset.confirm',
+ 'client.app.login.verification.recoveryKey.reset.create',
+ 'client.app.verifications.accept',
+ 'client.app.verifications.cancel',
+ 'client.app.verifications.create',
+ 'client.app.verifications.list',
+ 'client.app.verifications.retrieve',
+ 'client.app.verifications.qr.confirmScanned',
+ 'client.app.verifications.qr.scan',
+ 'client.app.verifications.sas.confirm',
+ 'client.app.verifications.sas.start',
],
{ threshold: 1, shouldSort: true },
);
diff --git a/packages/mcp-server/src/http.ts b/packages/mcp-server/src/http.ts
index 6a55c8d..3c85a28 100644
--- a/packages/mcp-server/src/http.ts
+++ b/packages/mcp-server/src/http.ts
@@ -3,7 +3,6 @@
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp';
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
import { ClientOptions } from '@beeper/desktop-api';
-import cors from 'cors';
import express from 'express';
import pino from 'pino';
import pinoHttp from 'pino-http';
@@ -12,11 +11,6 @@ import { getLogger } from './logger';
import { McpOptions } from './options';
import { initMcpServer, newMcpServer } from './server';
-const oauthResourceIdentifier = (req: express.Request): string => {
- const protocol = req.headers['x-forwarded-proto'] ?? req.protocol;
- return `${protocol}://${req.get('host')}/`;
-};
-
const newServer = async ({
clientOptions,
mcpOptions,
@@ -32,28 +26,7 @@ const newServer = async ({
const customInstructionsPath = mcpOptions.customInstructionsPath;
const server = await newMcpServer({ stainlessApiKey, customInstructionsPath });
- // parseClientAuthHeaders throws if the Authorization header uses an unsupported
- // scheme, or (when the second arg is true) if the header is missing entirely.
- // On error, we return 401 with WWW-Authenticate pointing to the OAuth metadata
- // endpoint so clients know how to authenticate (RFC 9728).
- let authOptions: Partial;
- try {
- authOptions = parseClientAuthHeaders(req, false);
- } catch (error) {
- const resourceIdentifier = oauthResourceIdentifier(req);
- res.set(
- 'WWW-Authenticate',
- `Bearer resource_metadata="${resourceIdentifier}.well-known/oauth-protected-resource"`,
- );
- res.status(401).json({
- jsonrpc: '2.0',
- error: {
- code: -32000,
- message: `Unauthorized: ${error instanceof Error ? error.message : error}`,
- },
- });
- return null;
- }
+ const authOptions = parseClientAuthHeaders(req, true);
let upstreamClientEnvs: Record | undefined;
const clientEnvsHeader = req.headers['x-stainless-mcp-client-envs'];
@@ -152,16 +125,6 @@ const del = async (req: express.Request, res: express.Response) => {
});
};
-const oauthMetadata = (req: express.Request, res: express.Response) => {
- const resourceIdentifier = oauthResourceIdentifier(req);
- res.json({
- resource: resourceIdentifier,
- authorization_servers: ['http://localhost:23373'],
- bearer_methods_supported: ['header'],
- scopes_supported: 'read write',
- });
-};
-
const redactHeaders = (headers: Record) => {
const hiddenHeaders = /auth|cookie|key|token|x-stainless-mcp-client-envs/i;
const filtered = { ...headers };
@@ -231,8 +194,6 @@ export const streamableHTTPApp = ({
}),
);
- app.get('/.well-known/oauth-protected-resource', cors(), oauthMetadata);
-
app.get('/health', async (req: express.Request, res: express.Response) => {
res.status(200).send('OK');
});
diff --git a/packages/mcp-server/src/local-docs-search.ts b/packages/mcp-server/src/local-docs-search.ts
index e2d6160..ed60808 100644
--- a/packages/mcp-server/src/local-docs-search.ts
+++ b/packages/mcp-server/src/local-docs-search.ts
@@ -56,7 +56,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
httpMethod: 'post',
summary: 'Focus Beeper Desktop app',
description:
- 'Focus Beeper Desktop and optionally navigate to a specific chat, message, or pre-fill plain text and an image path.',
+ 'Focus Beeper Desktop and optionally open a specific chat, jump to a message, or pre-fill text and an image.',
stainlessPath: '(resource) $client > (method) focus',
qualified: 'client.focus',
params: [
@@ -67,7 +67,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
],
response: '{ success: boolean; }',
markdown:
- "## focus\n\n`client.focus(chatID?: string, draftAttachmentPath?: string, draftText?: string, messageID?: string): { success: boolean; }`\n\n**post** `/v1/focus`\n\nFocus Beeper Desktop and optionally navigate to a specific chat, message, or pre-fill plain text and an image path.\n\n### Parameters\n\n- `chatID?: string`\n Optional Beeper chat ID (or local chat ID) to focus after opening the app. If omitted, only opens/focuses the app.\n\n- `draftAttachmentPath?: string`\n Optional image path to populate in the message input field.\n\n- `draftText?: string`\n Optional plain text to populate in the message input field.\n\n- `messageID?: string`\n Optional message ID. Jumps to that message in the chat when opening.\n\n### Returns\n\n- `{ success: boolean; }`\n Response indicating successful app focus action.\n\n - `success: boolean`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.focus();\n\nconsole.log(response);\n```",
+ "## focus\n\n`client.focus(chatID?: string, draftAttachmentPath?: string, draftText?: string, messageID?: string): { success: boolean; }`\n\n**post** `/v1/focus`\n\nFocus Beeper Desktop and optionally open a specific chat, jump to a message, or pre-fill text and an image.\n\n### Parameters\n\n- `chatID?: string`\n Optional Beeper chat ID (or local chat ID) to focus after opening the app. If omitted, only opens/focuses the app.\n\n- `draftAttachmentPath?: string`\n Optional local image path to populate in the message input field.\n\n- `draftText?: string`\n Optional plain text to populate in the message input field.\n\n- `messageID?: string`\n Optional message ID. Jumps to that message in the chat when opening.\n\n### Returns\n\n- `{ success: boolean; }`\n Response indicating successful app focus action.\n\n - `success: boolean`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.focus();\n\nconsole.log(response);\n```",
perLanguage: {
typescript: {
method: 'client.focus',
@@ -86,7 +86,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
},
cli: {
method: '$client focus',
- example: "beeper-desktop-cli focus \\\n --access-token 'My Access Token'",
+ example: "beeper-desktop focus \\\n --access-token 'My Access Token'",
},
php: {
method: 'focus',
@@ -105,14 +105,14 @@ const EMBEDDED_METHODS: MethodEntry[] = [
httpMethod: 'get',
summary: 'Search',
description:
- 'Returns matching chats, participant name matches in groups, and the first page of messages in one call. Paginate messages via search-messages. Paginate chats via search-chats.',
+ 'Return matching chats, participant matches in group chats, and the first page of message results in one call. Use the dedicated chat and message search endpoints for pagination.',
stainlessPath: '(resource) $client > (method) search',
qualified: 'client.search',
params: ['query: string;'],
response:
'{ results: { chats: object[]; in_groups: object[]; messages: { chats: object; hasMore: boolean; items: message[]; newestCursor: string; oldestCursor: string; }; }; }',
markdown:
- "## search\n\n`client.search(query: string): { results: object; }`\n\n**get** `/v1/search`\n\nReturns matching chats, participant name matches in groups, and the first page of messages in one call. Paginate messages via search-messages. Paginate chats via search-chats.\n\n### Parameters\n\n- `query: string`\n User-typed search text. Literal word matching (non-semantic).\n\n### Returns\n\n- `{ results: { chats: object[]; in_groups: object[]; messages: { chats: object; hasMore: boolean; items: message[]; newestCursor: string; oldestCursor: string; }; }; }`\n\n - `results: { chats: { id: string; accountID: string; network: string; participants: { hasMore: boolean; items: user[]; total: number; }; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: { allowedReactions?: string[]; archive?: boolean; attachments?: object; customEmojiReactions?: boolean; delete?: -2 | -1 | 0 | 1 | 2; deleteChat?: boolean; deleteChatForEveryone?: boolean; deleteForMe?: boolean; deleteMaxAge?: number; disappearingTimer?: object; edit?: -2 | -1 | 0 | 1 | 2; editMaxAge?: number; editMaxCount?: number; formatting?: object; locationMessage?: -2 | -1 | 0 | 1 | 2; markAsUnread?: boolean; maxTextLength?: number; messageRequest?: object; participantActions?: object; poll?: -2 | -1 | 0 | 1 | 2; reaction?: -2 | -1 | 0 | 1 | 2; reactionCount?: number; readReceipts?: boolean; reply?: -2 | -1 | 0 | 1 | 2; state?: object; thread?: -2 | -1 | 0 | 1 | 2; typingNotifications?: boolean; }; description?: string; draft?: { text: string; attachments?: object; }; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: { dismissOnIncomingMessage?: boolean; remindAt?: string; }; snooze?: { snoozeUntil?: string; userSnoozedAt?: string; }; unreadMentionsCount?: number; }[]; in_groups: { id: string; accountID: string; network: string; participants: { hasMore: boolean; items: user[]; total: number; }; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: { allowedReactions?: string[]; archive?: boolean; attachments?: object; customEmojiReactions?: boolean; delete?: -2 | -1 | 0 | 1 | 2; deleteChat?: boolean; deleteChatForEveryone?: boolean; deleteForMe?: boolean; deleteMaxAge?: number; disappearingTimer?: object; edit?: -2 | -1 | 0 | 1 | 2; editMaxAge?: number; editMaxCount?: number; formatting?: object; locationMessage?: -2 | -1 | 0 | 1 | 2; markAsUnread?: boolean; maxTextLength?: number; messageRequest?: object; participantActions?: object; poll?: -2 | -1 | 0 | 1 | 2; reaction?: -2 | -1 | 0 | 1 | 2; reactionCount?: number; readReceipts?: boolean; reply?: -2 | -1 | 0 | 1 | 2; state?: object; thread?: -2 | -1 | 0 | 1 | 2; typingNotifications?: boolean; }; description?: string; draft?: { text: string; attachments?: object; }; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: { dismissOnIncomingMessage?: boolean; remindAt?: string; }; snooze?: { snoozeUntil?: string; userSnoozedAt?: string; }; unreadMentionsCount?: number; }[]; messages: { chats: object; hasMore: boolean; items: { id: string; accountID: string; chatID: string; senderID: string; sortKey: string; timestamp: string; attachments?: attachment[]; editedTimestamp?: string; isDeleted?: boolean; isHidden?: boolean; isSender?: boolean; isUnread?: boolean; linkedMessageID?: string; links?: object[]; mentions?: string[]; reactions?: reaction[]; seen?: boolean | string | object; senderName?: string; sendStatus?: object; text?: string; type?: string; }[]; newestCursor: string; oldestCursor: string; }; }`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.search({ query: 'x' });\n\nconsole.log(response);\n```",
+ "## search\n\n`client.search(query: string): { results: object; }`\n\n**get** `/v1/search`\n\nReturn matching chats, participant matches in group chats, and the first page of message results in one call. Use the dedicated chat and message search endpoints for pagination.\n\n### Parameters\n\n- `query: string`\n User-typed search text. Uses literal word matching.\n\n### Returns\n\n- `{ results: { chats: object[]; in_groups: object[]; messages: { chats: object; hasMore: boolean; items: message[]; newestCursor: string; oldestCursor: string; }; }; }`\n\n - `results: { chats: { id: string; accountID: string; network: string; participants: { hasMore: boolean; items: user[]; total: number; }; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: { allowedReactions?: string[]; archive?: boolean; attachments?: object; customEmojiReactions?: boolean; delete?: -2 | -1 | 0 | 1 | 2; deleteChat?: boolean; deleteChatForEveryone?: boolean; deleteForMe?: boolean; deleteMaxAge?: number; disappearingTimer?: object; edit?: -2 | -1 | 0 | 1 | 2; editMaxAge?: number; editMaxCount?: number; formatting?: object; locationMessage?: -2 | -1 | 0 | 1 | 2; markAsUnread?: boolean; maxTextLength?: number; messageRequest?: object; participantActions?: object; poll?: -2 | -1 | 0 | 1 | 2; reaction?: -2 | -1 | 0 | 1 | 2; reactionCount?: number; readReceipts?: boolean; reply?: -2 | -1 | 0 | 1 | 2; state?: object; thread?: -2 | -1 | 0 | 1 | 2; typingNotifications?: boolean; }; description?: string; draft?: { text: string; attachments?: object; }; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: { dismissOnIncomingMessage?: boolean; remindAt?: string; }; snooze?: { snoozeUntil?: string; userSnoozedAt?: string; }; unreadMentionsCount?: number; }[]; in_groups: { id: string; accountID: string; network: string; participants: { hasMore: boolean; items: user[]; total: number; }; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: { allowedReactions?: string[]; archive?: boolean; attachments?: object; customEmojiReactions?: boolean; delete?: -2 | -1 | 0 | 1 | 2; deleteChat?: boolean; deleteChatForEveryone?: boolean; deleteForMe?: boolean; deleteMaxAge?: number; disappearingTimer?: object; edit?: -2 | -1 | 0 | 1 | 2; editMaxAge?: number; editMaxCount?: number; formatting?: object; locationMessage?: -2 | -1 | 0 | 1 | 2; markAsUnread?: boolean; maxTextLength?: number; messageRequest?: object; participantActions?: object; poll?: -2 | -1 | 0 | 1 | 2; reaction?: -2 | -1 | 0 | 1 | 2; reactionCount?: number; readReceipts?: boolean; reply?: -2 | -1 | 0 | 1 | 2; state?: object; thread?: -2 | -1 | 0 | 1 | 2; typingNotifications?: boolean; }; description?: string; draft?: { text: string; attachments?: object; }; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: { dismissOnIncomingMessage?: boolean; remindAt?: string; }; snooze?: { snoozeUntil?: string; userSnoozedAt?: string; }; unreadMentionsCount?: number; }[]; messages: { chats: object; hasMore: boolean; items: { id: string; accountID: string; chatID: string; senderID: string; sortKey: string; timestamp: string; attachments?: attachment[]; editedTimestamp?: string; isDeleted?: boolean; isHidden?: boolean; isSender?: boolean; isUnread?: boolean; linkedMessageID?: string; links?: object[]; mentions?: string[]; reactions?: reaction[]; seen?: boolean | string | object; senderName?: string; sendStatus?: object; text?: string; type?: string; }[]; newestCursor: string; oldestCursor: string; }; }`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.search({ query: 'x' });\n\nconsole.log(response);\n```",
perLanguage: {
typescript: {
method: 'client.search',
@@ -131,7 +131,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
},
cli: {
method: '$client search',
- example: "beeper-desktop-cli search \\\n --access-token 'My Access Token' \\\n --query x",
+ example: "beeper-desktop search \\\n --access-token 'My Access Token' \\\n --query x",
},
php: {
method: 'search',
@@ -148,15 +148,15 @@ const EMBEDDED_METHODS: MethodEntry[] = [
name: 'list',
endpoint: '/v1/accounts',
httpMethod: 'get',
- summary: 'List Chat Accounts',
+ summary: 'List chat accounts',
description:
- 'List Chat Accounts connected to this Beeper Desktop instance, including bridge metadata and network identity.',
+ 'List chat accounts connected to this Beeper Client API server, including bridge, network, user identity, and connection status.',
stainlessPath: '(resource) accounts > (method) list',
qualified: 'client.accounts.list',
response:
- "{ accountID: string; bridge: { id: string; provider: 'cloud' | 'self-hosted' | 'local' | 'platform-sdk'; type: string; }; user: object; network?: string; }[]",
+ '{ accountID: string; bridge: object; status: string; user: object; capabilities?: object; loginID?: string; network?: string; statusText?: string; }[]',
markdown:
- "## list\n\n`client.accounts.list(): object[]`\n\n**get** `/v1/accounts`\n\nList Chat Accounts connected to this Beeper Desktop instance, including bridge metadata and network identity.\n\n### Returns\n\n- `{ accountID: string; bridge: { id: string; provider: 'cloud' | 'self-hosted' | 'local' | 'platform-sdk'; type: string; }; user: object; network?: string; }[]`\n Accounts configured on this device. Includes accountID, bridge metadata, optional network name, and user identity.\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst accounts = await client.accounts.list();\n\nconsole.log(accounts);\n```",
+ "## list\n\n`client.accounts.list(): object[]`\n\n**get** `/v1/accounts`\n\nList chat accounts connected to this Beeper Client API server, including bridge, network, user identity, and connection status.\n\n### Returns\n\n- `{ accountID: string; bridge: object; status: string; user: object; capabilities?: object; loginID?: string; network?: string; statusText?: string; }[]`\n Chat accounts configured on this device. Includes accountID, bridge metadata, optional network name, and user identity.\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst accounts = await client.accounts.list();\n\nconsole.log(accounts);\n```",
perLanguage: {
typescript: {
method: 'client.accounts.list',
@@ -175,7 +175,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
},
cli: {
method: 'accounts list',
- example: "beeper-desktop-cli accounts list \\\n --access-token 'My Access Token'",
+ example: "beeper-desktop accounts list \\\n --access-token 'My Access Token'",
},
php: {
method: 'accounts->list',
@@ -188,6 +188,51 @@ const EMBEDDED_METHODS: MethodEntry[] = [
},
},
},
+ {
+ name: 'retrieve',
+ endpoint: '/v1/accounts/{accountID}',
+ httpMethod: 'get',
+ summary: 'Get chat account',
+ description: 'Get one chat account connected to this Beeper Client API server.',
+ stainlessPath: '(resource) accounts > (method) retrieve',
+ qualified: 'client.accounts.retrieve',
+ params: ['accountID: string;'],
+ response:
+ "{ accountID: string; bridge: { id: string; provider: 'cloud' | 'self-hosted' | 'local' | 'platform-sdk'; type: string; }; status: string; user: { id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }; capabilities?: object; loginID?: string; network?: string; statusText?: string; }",
+ markdown:
+ "## retrieve\n\n`client.accounts.retrieve(accountID: string): { accountID: string; bridge: account_bridge; status: string; user: user; capabilities?: object; loginID?: string; network?: string; statusText?: string; }`\n\n**get** `/v1/accounts/{accountID}`\n\nGet one chat account connected to this Beeper Client API server.\n\n### Parameters\n\n- `accountID: string`\n Account ID this resource belongs to.\n\n### Returns\n\n- `{ accountID: string; bridge: { id: string; provider: 'cloud' | 'self-hosted' | 'local' | 'platform-sdk'; type: string; }; status: string; user: { id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }; capabilities?: object; loginID?: string; network?: string; statusText?: string; }`\n A chat account added to Beeper.\n\n - `accountID: string`\n - `bridge: { id: string; provider: 'cloud' | 'self-hosted' | 'local' | 'platform-sdk'; type: string; }`\n - `status: string`\n - `user: { id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }`\n - `capabilities?: object`\n - `loginID?: string`\n - `network?: string`\n - `statusText?: string`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst account = await client.accounts.retrieve('accountID');\n\nconsole.log(account);\n```",
+ perLanguage: {
+ typescript: {
+ method: 'client.accounts.retrieve',
+ example:
+ "import BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop({\n accessToken: process.env['BEEPER_ACCESS_TOKEN'], // This is the default and can be omitted\n});\n\nconst account = await client.accounts.retrieve('accountID');\n\nconsole.log(account.bridge);",
+ },
+ python: {
+ method: 'accounts.retrieve',
+ example:
+ 'import os\nfrom beeper_desktop_api import BeeperDesktop\n\nclient = BeeperDesktop(\n access_token=os.environ.get("BEEPER_ACCESS_TOKEN"), # This is the default and can be omitted\n)\naccount = client.accounts.retrieve(\n "accountID",\n)\nprint(account.bridge)',
+ },
+ go: {
+ method: 'client.Accounts.Get',
+ example:
+ 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/beeper/desktop-api-go"\n\t"github.com/beeper/desktop-api-go/option"\n)\n\nfunc main() {\n\tclient := beeperdesktopapi.NewClient(\n\t\toption.WithAccessToken("My Access Token"),\n\t)\n\taccount, err := client.Accounts.Get(context.TODO(), "accountID")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", account.Bridge)\n}\n',
+ },
+ cli: {
+ method: 'accounts retrieve',
+ example:
+ "beeper-desktop accounts retrieve \\\n --access-token 'My Access Token' \\\n --account-id accountID",
+ },
+ php: {
+ method: 'accounts->retrieve',
+ example:
+ "accounts->retrieve('accountID');\n\nvar_dump($account);",
+ },
+ http: {
+ example:
+ 'curl http://localhost:23373/v1/accounts/$ACCOUNT_ID \\\n -H "Authorization: Bearer $BEEPER_ACCESS_TOKEN"',
+ },
+ },
+ },
{
name: 'search',
endpoint: '/v1/accounts/{accountID}/contacts',
@@ -201,7 +246,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
response:
'{ items: { id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }[]; }',
markdown:
- "## search\n\n`client.accounts.contacts.search(accountID: string, query: string): { items: user[]; }`\n\n**get** `/v1/accounts/{accountID}/contacts`\n\nSearch contacts on a specific account using merged account contacts, network search, and exact identifier lookup.\n\n### Parameters\n\n- `accountID: string`\n Account ID this resource belongs to.\n\n- `query: string`\n Text to search users by. Network-specific behavior.\n\n### Returns\n\n- `{ items: { id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }[]; }`\n\n - `items: { id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }[]`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.accounts.contacts.search('accountID', { query: 'x' });\n\nconsole.log(response);\n```",
+ "## search\n\n`client.accounts.contacts.search(accountID: string, query: string): { items: user[]; }`\n\n**get** `/v1/accounts/{accountID}/contacts`\n\nSearch contacts on a specific account using merged account contacts, network search, and exact identifier lookup.\n\n### Parameters\n\n- `accountID: string`\n Account ID this resource belongs to.\n\n- `query: string`\n Text to search contacts by. Matching behavior depends on the network.\n\n### Returns\n\n- `{ items: { id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }[]; }`\n\n - `items: { id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }[]`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.accounts.contacts.search('accountID', { query: 'x' });\n\nconsole.log(response);\n```",
perLanguage: {
typescript: {
method: 'client.accounts.contacts.search',
@@ -221,7 +266,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
cli: {
method: 'contacts search',
example:
- "beeper-desktop-cli accounts:contacts search \\\n --access-token 'My Access Token' \\\n --account-id accountID \\\n --query x",
+ "beeper-desktop accounts:contacts search \\\n --access-token 'My Access Token' \\\n --account-id accountID \\\n --query x",
},
php: {
method: 'accounts->contacts->search',
@@ -252,7 +297,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
response:
'{ id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }',
markdown:
- "## list\n\n`client.accounts.contacts.list(accountID: string, cursor?: string, direction?: 'after' | 'before', limit?: number, query?: string): { id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }`\n\n**get** `/v1/accounts/{accountID}/contacts/list`\n\nList merged contacts for a specific account with cursor-based pagination.\n\n### Parameters\n\n- `accountID: string`\n Account ID this resource belongs to.\n\n- `cursor?: string`\n Opaque pagination cursor; do not inspect. Use together with 'direction'.\n\n- `direction?: 'after' | 'before'`\n Pagination direction used with 'cursor': 'before' fetches older results, 'after' fetches newer results. Defaults to 'before' when only 'cursor' is provided.\n\n- `limit?: number`\n Maximum contacts to return per page.\n\n- `query?: string`\n Optional search query for blended contact lookup.\n\n### Returns\n\n- `{ id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }`\n User the account belongs to.\n\n - `id: string`\n - `cannotMessage?: boolean`\n - `email?: string`\n - `fullName?: string`\n - `imgURL?: string`\n - `isSelf?: boolean`\n - `phoneNumber?: string`\n - `username?: string`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\n// Automatically fetches more pages as needed.\nfor await (const user of client.accounts.contacts.list('accountID')) {\n console.log(user);\n}\n```",
+ "## list\n\n`client.accounts.contacts.list(accountID: string, cursor?: string, direction?: 'after' | 'before', limit?: number, query?: string): { id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }`\n\n**get** `/v1/accounts/{accountID}/contacts/list`\n\nList merged contacts for a specific account with cursor-based pagination.\n\n### Parameters\n\n- `accountID: string`\n Account ID this resource belongs to.\n\n- `cursor?: string`\n Opaque pagination cursor; do not inspect. Use together with 'direction'.\n\n- `direction?: 'after' | 'before'`\n Pagination direction used with 'cursor': 'before' fetches older results, 'after' fetches newer results. Defaults to 'before' when only 'cursor' is provided.\n\n- `limit?: number`\n Maximum contacts to return per page.\n\n- `query?: string`\n Optional search query for contact lookup.\n\n### Returns\n\n- `{ id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }`\n User the account belongs to.\n\n - `id: string`\n - `cannotMessage?: boolean`\n - `email?: string`\n - `fullName?: string`\n - `imgURL?: string`\n - `isSelf?: boolean`\n - `phoneNumber?: string`\n - `username?: string`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\n// Automatically fetches more pages as needed.\nfor await (const user of client.accounts.contacts.list('accountID')) {\n console.log(user);\n}\n```",
perLanguage: {
typescript: {
method: 'client.accounts.contacts.list',
@@ -272,7 +317,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
cli: {
method: 'contacts list',
example:
- "beeper-desktop-cli accounts:contacts list \\\n --access-token 'My Access Token' \\\n --account-id accountID",
+ "beeper-desktop accounts:contacts list \\\n --access-token 'My Access Token' \\\n --account-id accountID",
},
php: {
method: 'accounts->contacts->list',
@@ -285,19 +330,387 @@ const EMBEDDED_METHODS: MethodEntry[] = [
},
},
},
+ {
+ name: 'list',
+ endpoint: '/v1/bridges',
+ httpMethod: 'get',
+ summary: 'List available bridges',
+ description:
+ 'List available bridges. A bridge is a chat-network connector that can connect or reconnect chat accounts. Connected accounts use the same Account schema as GET /v1/accounts.',
+ stainlessPath: '(resource) bridges > (method) list',
+ qualified: 'client.bridges.list',
+ response:
+ "{ items: { id: string; accounts: account[]; activeAccountCount: number; displayName: string; provider: 'cloud' | 'self-hosted' | 'local' | 'platform-sdk'; status: 'available' | 'connected' | 'limit_reached' | 'temporarily_unavailable' | 'disabled'; supportsMultipleAccounts: boolean; type: string; network?: string; statusText?: string; }[]; }",
+ markdown:
+ "## list\n\n`client.bridges.list(): { items: bridge[]; }`\n\n**get** `/v1/bridges`\n\nList available bridges. A bridge is a chat-network connector that can connect or reconnect chat accounts. Connected accounts use the same Account schema as GET /v1/accounts.\n\n### Returns\n\n- `{ items: { id: string; accounts: account[]; activeAccountCount: number; displayName: string; provider: 'cloud' | 'self-hosted' | 'local' | 'platform-sdk'; status: 'available' | 'connected' | 'limit_reached' | 'temporarily_unavailable' | 'disabled'; supportsMultipleAccounts: boolean; type: string; network?: string; statusText?: string; }[]; }`\n Available bridges and their connected accounts.\n\n - `items: { id: string; accounts: { accountID: string; bridge: account_bridge; status: string; user: user; capabilities?: object; loginID?: string; network?: string; statusText?: string; }[]; activeAccountCount: number; displayName: string; provider: 'cloud' | 'self-hosted' | 'local' | 'platform-sdk'; status: 'available' | 'connected' | 'limit_reached' | 'temporarily_unavailable' | 'disabled'; supportsMultipleAccounts: boolean; type: string; network?: string; statusText?: string; }[]`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst bridges = await client.bridges.list();\n\nconsole.log(bridges);\n```",
+ perLanguage: {
+ typescript: {
+ method: 'client.bridges.list',
+ example:
+ "import BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop({\n accessToken: process.env['BEEPER_ACCESS_TOKEN'], // This is the default and can be omitted\n});\n\nconst bridges = await client.bridges.list();\n\nconsole.log(bridges.items);",
+ },
+ python: {
+ method: 'bridges.list',
+ example:
+ 'import os\nfrom beeper_desktop_api import BeeperDesktop\n\nclient = BeeperDesktop(\n access_token=os.environ.get("BEEPER_ACCESS_TOKEN"), # This is the default and can be omitted\n)\nbridges = client.bridges.list()\nprint(bridges.items)',
+ },
+ go: {
+ method: 'client.Bridges.List',
+ example:
+ 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/beeper/desktop-api-go"\n\t"github.com/beeper/desktop-api-go/option"\n)\n\nfunc main() {\n\tclient := beeperdesktopapi.NewClient(\n\t\toption.WithAccessToken("My Access Token"),\n\t)\n\tbridges, err := client.Bridges.List(context.TODO())\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", bridges.Items)\n}\n',
+ },
+ cli: {
+ method: 'bridges list',
+ example: "beeper-desktop bridges list \\\n --access-token 'My Access Token'",
+ },
+ php: {
+ method: 'bridges->list',
+ example:
+ "bridges->list();\n\nvar_dump($bridges);",
+ },
+ http: {
+ example:
+ 'curl http://localhost:23373/v1/bridges \\\n -H "Authorization: Bearer $BEEPER_ACCESS_TOKEN"',
+ },
+ },
+ },
+ {
+ name: 'retrieve',
+ endpoint: '/v1/bridges/{bridgeID}',
+ httpMethod: 'get',
+ summary: 'Get bridge',
+ description: 'Get one bridge, including the chat accounts connected through it.',
+ stainlessPath: '(resource) bridges > (method) retrieve',
+ qualified: 'client.bridges.retrieve',
+ params: ['bridgeID: string;'],
+ response:
+ "{ id: string; accounts: { accountID: string; bridge: account_bridge; status: string; user: user; capabilities?: object; loginID?: string; network?: string; statusText?: string; }[]; activeAccountCount: number; displayName: string; provider: 'cloud' | 'self-hosted' | 'local' | 'platform-sdk'; status: 'available' | 'connected' | 'limit_reached' | 'temporarily_unavailable' | 'disabled'; supportsMultipleAccounts: boolean; type: string; network?: string; statusText?: string; }",
+ markdown:
+ "## retrieve\n\n`client.bridges.retrieve(bridgeID: string): { id: string; accounts: account[]; activeAccountCount: number; displayName: string; provider: 'cloud' | 'self-hosted' | 'local' | 'platform-sdk'; status: 'available' | 'connected' | 'limit_reached' | 'temporarily_unavailable' | 'disabled'; supportsMultipleAccounts: boolean; type: string; network?: string; statusText?: string; }`\n\n**get** `/v1/bridges/{bridgeID}`\n\nGet one bridge, including the chat accounts connected through it.\n\n### Parameters\n\n- `bridgeID: string`\n Bridge ID.\n\n### Returns\n\n- `{ id: string; accounts: { accountID: string; bridge: account_bridge; status: string; user: user; capabilities?: object; loginID?: string; network?: string; statusText?: string; }[]; activeAccountCount: number; displayName: string; provider: 'cloud' | 'self-hosted' | 'local' | 'platform-sdk'; status: 'available' | 'connected' | 'limit_reached' | 'temporarily_unavailable' | 'disabled'; supportsMultipleAccounts: boolean; type: string; network?: string; statusText?: string; }`\n Available bridge that can connect or reconnect chat accounts.\n\n - `id: string`\n - `accounts: { accountID: string; bridge: { id: string; provider: 'cloud' | 'self-hosted' | 'local' | 'platform-sdk'; type: string; }; status: string; user: { id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }; capabilities?: object; loginID?: string; network?: string; statusText?: string; }[]`\n - `activeAccountCount: number`\n - `displayName: string`\n - `provider: 'cloud' | 'self-hosted' | 'local' | 'platform-sdk'`\n - `status: 'available' | 'connected' | 'limit_reached' | 'temporarily_unavailable' | 'disabled'`\n - `supportsMultipleAccounts: boolean`\n - `type: string`\n - `network?: string`\n - `statusText?: string`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst bridge = await client.bridges.retrieve('local-whatsapp');\n\nconsole.log(bridge);\n```",
+ perLanguage: {
+ typescript: {
+ method: 'client.bridges.retrieve',
+ example:
+ "import BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop({\n accessToken: process.env['BEEPER_ACCESS_TOKEN'], // This is the default and can be omitted\n});\n\nconst bridge = await client.bridges.retrieve('local-whatsapp');\n\nconsole.log(bridge.id);",
+ },
+ python: {
+ method: 'bridges.retrieve',
+ example:
+ 'import os\nfrom beeper_desktop_api import BeeperDesktop\n\nclient = BeeperDesktop(\n access_token=os.environ.get("BEEPER_ACCESS_TOKEN"), # This is the default and can be omitted\n)\nbridge = client.bridges.retrieve(\n "local-whatsapp",\n)\nprint(bridge.id)',
+ },
+ go: {
+ method: 'client.Bridges.Get',
+ example:
+ 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/beeper/desktop-api-go"\n\t"github.com/beeper/desktop-api-go/option"\n)\n\nfunc main() {\n\tclient := beeperdesktopapi.NewClient(\n\t\toption.WithAccessToken("My Access Token"),\n\t)\n\tbridge, err := client.Bridges.Get(context.TODO(), "local-whatsapp")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", bridge.ID)\n}\n',
+ },
+ cli: {
+ method: 'bridges retrieve',
+ example:
+ "beeper-desktop bridges retrieve \\\n --access-token 'My Access Token' \\\n --bridge-id local-whatsapp",
+ },
+ php: {
+ method: 'bridges->retrieve',
+ example:
+ "bridges->retrieve('local-whatsapp');\n\nvar_dump($bridge);",
+ },
+ http: {
+ example:
+ 'curl http://localhost:23373/v1/bridges/$BRIDGE_ID \\\n -H "Authorization: Bearer $BEEPER_ACCESS_TOKEN"',
+ },
+ },
+ },
+ {
+ name: 'retrieve_capabilities',
+ endpoint: '/v1/bridges/{bridgeID}/capabilities',
+ httpMethod: 'get',
+ summary: 'Get bridge capabilities',
+ description:
+ 'Get advanced network capabilities for a bridge. This endpoint is intended for clients that build custom connect or chat-creation flows.',
+ stainlessPath: '(resource) bridges > (method) retrieve_capabilities',
+ qualified: 'client.bridges.retrieveCapabilities',
+ params: ['bridgeID: string;'],
+ response:
+ '{ group_creation: object; resolve_identifier: { any_phone: boolean; contact_list: boolean; create_dm: boolean; lookup_email: boolean; lookup_phone: boolean; lookup_username: boolean; search: boolean; }; image_pack_import?: boolean; }',
+ markdown:
+ "## retrieve_capabilities\n\n`client.bridges.retrieveCapabilities(bridgeID: string): { group_creation: object; resolve_identifier: resolve_identifier_capabilities; image_pack_import?: boolean; }`\n\n**get** `/v1/bridges/{bridgeID}/capabilities`\n\nGet advanced network capabilities for a bridge. This endpoint is intended for clients that build custom connect or chat-creation flows.\n\n### Parameters\n\n- `bridgeID: string`\n Bridge ID.\n\n### Returns\n\n- `{ group_creation: object; resolve_identifier: { any_phone: boolean; contact_list: boolean; create_dm: boolean; lookup_email: boolean; lookup_phone: boolean; lookup_username: boolean; search: boolean; }; image_pack_import?: boolean; }`\n Advanced network capabilities for account lookup and group creation.\n\n - `group_creation: object`\n - `resolve_identifier: { any_phone: boolean; contact_list: boolean; create_dm: boolean; lookup_email: boolean; lookup_phone: boolean; lookup_username: boolean; search: boolean; }`\n - `image_pack_import?: boolean`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst provisioningCapabilities = await client.bridges.retrieveCapabilities('local-whatsapp');\n\nconsole.log(provisioningCapabilities);\n```",
+ perLanguage: {
+ typescript: {
+ method: 'client.bridges.retrieveCapabilities',
+ example:
+ "import BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop({\n accessToken: process.env['BEEPER_ACCESS_TOKEN'], // This is the default and can be omitted\n});\n\nconst provisioningCapabilities = await client.bridges.retrieveCapabilities('local-whatsapp');\n\nconsole.log(provisioningCapabilities.resolve_identifier);",
+ },
+ python: {
+ method: 'bridges.retrieve_capabilities',
+ example:
+ 'import os\nfrom beeper_desktop_api import BeeperDesktop\n\nclient = BeeperDesktop(\n access_token=os.environ.get("BEEPER_ACCESS_TOKEN"), # This is the default and can be omitted\n)\nprovisioning_capabilities = client.bridges.retrieve_capabilities(\n "local-whatsapp",\n)\nprint(provisioning_capabilities.resolve_identifier)',
+ },
+ go: {
+ method: 'client.Bridges.GetCapabilities',
+ example:
+ 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/beeper/desktop-api-go"\n\t"github.com/beeper/desktop-api-go/option"\n)\n\nfunc main() {\n\tclient := beeperdesktopapi.NewClient(\n\t\toption.WithAccessToken("My Access Token"),\n\t)\n\tprovisioningCapabilities, err := client.Bridges.GetCapabilities(context.TODO(), "local-whatsapp")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", provisioningCapabilities.ResolveIdentifier)\n}\n',
+ },
+ cli: {
+ method: 'bridges retrieve_capabilities',
+ example:
+ "beeper-desktop bridges retrieve-capabilities \\\n --access-token 'My Access Token' \\\n --bridge-id local-whatsapp",
+ },
+ php: {
+ method: 'bridges->retrieveCapabilities',
+ example:
+ "bridges->retrieveCapabilities(\n 'local-whatsapp'\n);\n\nvar_dump($provisioningCapabilities);",
+ },
+ http: {
+ example:
+ 'curl http://localhost:23373/v1/bridges/$BRIDGE_ID/capabilities \\\n -H "Authorization: Bearer $BEEPER_ACCESS_TOKEN"',
+ },
+ },
+ },
+ {
+ name: 'list',
+ endpoint: '/v1/bridges/{bridgeID}/login-flows',
+ httpMethod: 'get',
+ summary: 'List login flows',
+ description:
+ 'List connect and reconnect flow options for a bridge. Use a flowID when creating a bridge login session.',
+ stainlessPath: '(resource) bridges.login_flows > (method) list',
+ qualified: 'client.bridges.loginFlows.list',
+ params: ['bridgeID: string;'],
+ response: '{ items: { id: string; description?: string; name?: string; }[]; }',
+ markdown:
+ "## list\n\n`client.bridges.loginFlows.list(bridgeID: string): { items: login_flow[]; }`\n\n**get** `/v1/bridges/{bridgeID}/login-flows`\n\nList connect and reconnect flow options for a bridge. Use a flowID when creating a bridge login session.\n\n### Parameters\n\n- `bridgeID: string`\n Bridge ID.\n\n### Returns\n\n- `{ items: { id: string; description?: string; name?: string; }[]; }`\n\n - `items: { id: string; description?: string; name?: string; }[]`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst loginFlows = await client.bridges.loginFlows.list('local-whatsapp');\n\nconsole.log(loginFlows);\n```",
+ perLanguage: {
+ typescript: {
+ method: 'client.bridges.loginFlows.list',
+ example:
+ "import BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop({\n accessToken: process.env['BEEPER_ACCESS_TOKEN'], // This is the default and can be omitted\n});\n\nconst loginFlows = await client.bridges.loginFlows.list('local-whatsapp');\n\nconsole.log(loginFlows.items);",
+ },
+ python: {
+ method: 'bridges.login_flows.list',
+ example:
+ 'import os\nfrom beeper_desktop_api import BeeperDesktop\n\nclient = BeeperDesktop(\n access_token=os.environ.get("BEEPER_ACCESS_TOKEN"), # This is the default and can be omitted\n)\nlogin_flows = client.bridges.login_flows.list(\n "local-whatsapp",\n)\nprint(login_flows.items)',
+ },
+ go: {
+ method: 'client.Bridges.LoginFlows.List',
+ example:
+ 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/beeper/desktop-api-go"\n\t"github.com/beeper/desktop-api-go/option"\n)\n\nfunc main() {\n\tclient := beeperdesktopapi.NewClient(\n\t\toption.WithAccessToken("My Access Token"),\n\t)\n\tloginFlows, err := client.Bridges.LoginFlows.List(context.TODO(), "local-whatsapp")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", loginFlows.Items)\n}\n',
+ },
+ cli: {
+ method: 'login_flows list',
+ example:
+ "beeper-desktop bridges:login-flows list \\\n --access-token 'My Access Token' \\\n --bridge-id local-whatsapp",
+ },
+ php: {
+ method: 'bridges->loginFlows->list',
+ example:
+ "bridges->loginFlows->list('local-whatsapp');\n\nvar_dump($loginFlows);",
+ },
+ http: {
+ example:
+ 'curl http://localhost:23373/v1/bridges/$BRIDGE_ID/login-flows \\\n -H "Authorization: Bearer $BEEPER_ACCESS_TOKEN"',
+ },
+ },
+ },
+ {
+ name: 'create',
+ endpoint: '/v1/bridges/{bridgeID}/login-sessions',
+ httpMethod: 'post',
+ summary: 'Create bridge login session',
+ description:
+ 'Start a temporary bridge login session to connect a new chat account or reconnect an existing bridge login. Omit loginID and accountID to connect a new account.',
+ stainlessPath: '(resource) bridges.login_sessions > (method) create',
+ qualified: 'client.bridges.loginSessions.create',
+ params: ['bridgeID: string;', 'accountID?: string;', 'flowID?: string;', 'loginID?: string;'],
+ response:
+ "{ bridgeID: string; loginSessionID: string; status: string; account?: object; accountID?: string; currentStep?: { fields: login_input_field[]; stepID: string; type: 'user_input'; attachments?: object[]; instructions?: string; } | { fields: cookie_field[]; stepID: string; type: 'cookies'; url: string; expectedFinalURLRegex?: string; extractJS?: string; instructions?: string; userAgent?: string; } | { display: object | object | object; stepID: string; type: 'display_and_wait'; instructions?: string; } | { type: 'complete'; account?: account; instructions?: string; login?: object; stepID?: string; }; error?: object; login?: { bridgeID: string; loginID: string; removeScopes: 'current-device' | 'all-devices'[]; status: 'connected' | 'connecting' | 'needs_login' | 'logged_out' | 'unknown'; accountIDs?: string[]; statusText?: string; user?: user; }; loginID?: string; }",
+ markdown:
+ "## create\n\n`client.bridges.loginSessions.create(bridgeID: string, accountID?: string, flowID?: string, loginID?: string): { bridgeID: string; loginSessionID: string; status: string; account?: account; accountID?: string; currentStep?: object | object | object | object; error?: api_error; login?: object; loginID?: string; }`\n\n**post** `/v1/bridges/{bridgeID}/login-sessions`\n\nStart a temporary bridge login session to connect a new chat account or reconnect an existing bridge login. Omit loginID and accountID to connect a new account.\n\n### Parameters\n\n- `bridgeID: string`\n Bridge ID.\n\n- `accountID?: string`\n Existing chat account ID to reconnect. Omit to connect a new account.\n\n- `flowID?: string`\n Optional flow ID returned by the list login flows endpoint. If omitted, Beeper chooses the default flow.\n\n- `loginID?: string`\n Existing bridge login ID to reconnect. Omit to connect a new account.\n\n### Returns\n\n- `{ bridgeID: string; loginSessionID: string; status: string; account?: { accountID: string; bridge: account_bridge; status: string; user: user; capabilities?: object; loginID?: string; network?: string; statusText?: string; }; accountID?: string; currentStep?: { fields: object[]; stepID: string; type: 'user_input'; attachments?: object[]; instructions?: string; } | { fields: object[]; stepID: string; type: 'cookies'; url: string; expectedFinalURLRegex?: string; extractJS?: string; instructions?: string; userAgent?: string; } | { display: { data: string; type: 'qr'; } | { imageURL: string; type: 'emoji'; } | { type: 'nothing'; }; stepID: string; type: 'display_and_wait'; instructions?: string; } | { type: 'complete'; account?: object; instructions?: string; login?: { bridgeID: string; loginID: string; removeScopes: 'current-device' | 'all-devices'[]; status: 'connected' | 'connecting' | 'needs_login' | 'logged_out' | 'unknown'; accountIDs?: string[]; statusText?: string; user?: user; }; stepID?: string; }; error?: { code: string; message: string; details?: object; }; login?: { bridgeID: string; loginID: string; removeScopes: 'current-device' | 'all-devices'[]; status: 'connected' | 'connecting' | 'needs_login' | 'logged_out' | 'unknown'; accountIDs?: string[]; statusText?: string; user?: object; }; loginID?: string; }`\n\n - `bridgeID: string`\n - `loginSessionID: string`\n - `status: string`\n - `account?: { accountID: string; bridge: { id: string; provider: 'cloud' | 'self-hosted' | 'local' | 'platform-sdk'; type: string; }; status: string; user: { id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }; capabilities?: object; loginID?: string; network?: string; statusText?: string; }`\n - `accountID?: string`\n - `currentStep?: { fields: { id: string; initialValue?: string; label?: string; optional?: boolean; placeholder?: string; type?: string; }[]; stepID: string; type: 'user_input'; attachments?: object[]; instructions?: string; } | { fields: { id: string; name?: string; type?: 'cookie' | 'header' | 'local_storage'; }[]; stepID: string; type: 'cookies'; url: string; expectedFinalURLRegex?: string; extractJS?: string; instructions?: string; userAgent?: string; } | { display: { data: string; type: 'qr'; } | { imageURL: string; type: 'emoji'; } | { type: 'nothing'; }; stepID: string; type: 'display_and_wait'; instructions?: string; } | { type: 'complete'; account?: { accountID: string; bridge: object; status: string; user: object; capabilities?: object; loginID?: string; network?: string; statusText?: string; }; instructions?: string; login?: { bridgeID: string; loginID: string; removeScopes: 'current-device' | 'all-devices'[]; status: 'connected' | 'connecting' | 'needs_login' | 'logged_out' | 'unknown'; accountIDs?: string[]; statusText?: string; user?: { id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }; }; stepID?: string; }`\n - `error?: { code: string; message: string; details?: object; }`\n - `login?: { bridgeID: string; loginID: string; removeScopes: 'current-device' | 'all-devices'[]; status: 'connected' | 'connecting' | 'needs_login' | 'logged_out' | 'unknown'; accountIDs?: string[]; statusText?: string; user?: { id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }; }`\n - `loginID?: string`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst loginSession = await client.bridges.loginSessions.create('local-whatsapp');\n\nconsole.log(loginSession);\n```",
+ perLanguage: {
+ typescript: {
+ method: 'client.bridges.loginSessions.create',
+ example:
+ "import BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop({\n accessToken: process.env['BEEPER_ACCESS_TOKEN'], // This is the default and can be omitted\n});\n\nconst loginSession = await client.bridges.loginSessions.create('local-whatsapp');\n\nconsole.log(loginSession.bridgeID);",
+ },
+ python: {
+ method: 'bridges.login_sessions.create',
+ example:
+ 'import os\nfrom beeper_desktop_api import BeeperDesktop\n\nclient = BeeperDesktop(\n access_token=os.environ.get("BEEPER_ACCESS_TOKEN"), # This is the default and can be omitted\n)\nlogin_session = client.bridges.login_sessions.create(\n bridge_id="local-whatsapp",\n)\nprint(login_session.bridge_id)',
+ },
+ go: {
+ method: 'client.Bridges.LoginSessions.New',
+ example:
+ 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/beeper/desktop-api-go"\n\t"github.com/beeper/desktop-api-go/option"\n)\n\nfunc main() {\n\tclient := beeperdesktopapi.NewClient(\n\t\toption.WithAccessToken("My Access Token"),\n\t)\n\tloginSession, err := client.Bridges.LoginSessions.New(\n\t\tcontext.TODO(),\n\t\t"local-whatsapp",\n\t\tbeeperdesktopapi.BridgeLoginSessionNewParams{},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", loginSession.BridgeID)\n}\n',
+ },
+ cli: {
+ method: 'login_sessions create',
+ example:
+ "beeper-desktop bridges:login-sessions create \\\n --access-token 'My Access Token' \\\n --bridge-id local-whatsapp",
+ },
+ php: {
+ method: 'bridges->loginSessions->create',
+ example:
+ "bridges->loginSessions->create(\n 'local-whatsapp', accountID: 'x', flowID: 'x', loginID: 'x'\n);\n\nvar_dump($loginSession);",
+ },
+ http: {
+ example:
+ 'curl http://localhost:23373/v1/bridges/$BRIDGE_ID/login-sessions \\\n -X POST \\\n -H "Authorization: Bearer $BEEPER_ACCESS_TOKEN"',
+ },
+ },
+ },
+ {
+ name: 'retrieve',
+ endpoint: '/v1/bridges/{bridgeID}/login-sessions/{loginSessionID}',
+ httpMethod: 'get',
+ summary: 'Get bridge login session',
+ description: 'Get the current state of a temporary bridge login session.',
+ stainlessPath: '(resource) bridges.login_sessions > (method) retrieve',
+ qualified: 'client.bridges.loginSessions.retrieve',
+ params: ['bridgeID: string;', 'loginSessionID: string;'],
+ response:
+ "{ bridgeID: string; loginSessionID: string; status: string; account?: object; accountID?: string; currentStep?: { fields: login_input_field[]; stepID: string; type: 'user_input'; attachments?: object[]; instructions?: string; } | { fields: cookie_field[]; stepID: string; type: 'cookies'; url: string; expectedFinalURLRegex?: string; extractJS?: string; instructions?: string; userAgent?: string; } | { display: object | object | object; stepID: string; type: 'display_and_wait'; instructions?: string; } | { type: 'complete'; account?: account; instructions?: string; login?: object; stepID?: string; }; error?: object; login?: { bridgeID: string; loginID: string; removeScopes: 'current-device' | 'all-devices'[]; status: 'connected' | 'connecting' | 'needs_login' | 'logged_out' | 'unknown'; accountIDs?: string[]; statusText?: string; user?: user; }; loginID?: string; }",
+ markdown:
+ "## retrieve\n\n`client.bridges.loginSessions.retrieve(bridgeID: string, loginSessionID: string): { bridgeID: string; loginSessionID: string; status: string; account?: account; accountID?: string; currentStep?: object | object | object | object; error?: api_error; login?: object; loginID?: string; }`\n\n**get** `/v1/bridges/{bridgeID}/login-sessions/{loginSessionID}`\n\nGet the current state of a temporary bridge login session.\n\n### Parameters\n\n- `bridgeID: string`\n Bridge ID.\n\n- `loginSessionID: string`\n Temporary bridge login session ID.\n\n### Returns\n\n- `{ bridgeID: string; loginSessionID: string; status: string; account?: { accountID: string; bridge: account_bridge; status: string; user: user; capabilities?: object; loginID?: string; network?: string; statusText?: string; }; accountID?: string; currentStep?: { fields: object[]; stepID: string; type: 'user_input'; attachments?: object[]; instructions?: string; } | { fields: object[]; stepID: string; type: 'cookies'; url: string; expectedFinalURLRegex?: string; extractJS?: string; instructions?: string; userAgent?: string; } | { display: { data: string; type: 'qr'; } | { imageURL: string; type: 'emoji'; } | { type: 'nothing'; }; stepID: string; type: 'display_and_wait'; instructions?: string; } | { type: 'complete'; account?: object; instructions?: string; login?: { bridgeID: string; loginID: string; removeScopes: 'current-device' | 'all-devices'[]; status: 'connected' | 'connecting' | 'needs_login' | 'logged_out' | 'unknown'; accountIDs?: string[]; statusText?: string; user?: user; }; stepID?: string; }; error?: { code: string; message: string; details?: object; }; login?: { bridgeID: string; loginID: string; removeScopes: 'current-device' | 'all-devices'[]; status: 'connected' | 'connecting' | 'needs_login' | 'logged_out' | 'unknown'; accountIDs?: string[]; statusText?: string; user?: object; }; loginID?: string; }`\n\n - `bridgeID: string`\n - `loginSessionID: string`\n - `status: string`\n - `account?: { accountID: string; bridge: { id: string; provider: 'cloud' | 'self-hosted' | 'local' | 'platform-sdk'; type: string; }; status: string; user: { id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }; capabilities?: object; loginID?: string; network?: string; statusText?: string; }`\n - `accountID?: string`\n - `currentStep?: { fields: { id: string; initialValue?: string; label?: string; optional?: boolean; placeholder?: string; type?: string; }[]; stepID: string; type: 'user_input'; attachments?: object[]; instructions?: string; } | { fields: { id: string; name?: string; type?: 'cookie' | 'header' | 'local_storage'; }[]; stepID: string; type: 'cookies'; url: string; expectedFinalURLRegex?: string; extractJS?: string; instructions?: string; userAgent?: string; } | { display: { data: string; type: 'qr'; } | { imageURL: string; type: 'emoji'; } | { type: 'nothing'; }; stepID: string; type: 'display_and_wait'; instructions?: string; } | { type: 'complete'; account?: { accountID: string; bridge: object; status: string; user: object; capabilities?: object; loginID?: string; network?: string; statusText?: string; }; instructions?: string; login?: { bridgeID: string; loginID: string; removeScopes: 'current-device' | 'all-devices'[]; status: 'connected' | 'connecting' | 'needs_login' | 'logged_out' | 'unknown'; accountIDs?: string[]; statusText?: string; user?: { id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }; }; stepID?: string; }`\n - `error?: { code: string; message: string; details?: object; }`\n - `login?: { bridgeID: string; loginID: string; removeScopes: 'current-device' | 'all-devices'[]; status: 'connected' | 'connecting' | 'needs_login' | 'logged_out' | 'unknown'; accountIDs?: string[]; statusText?: string; user?: { id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }; }`\n - `loginID?: string`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst loginSession = await client.bridges.loginSessions.retrieve('123', { bridgeID: 'local-whatsapp' });\n\nconsole.log(loginSession);\n```",
+ perLanguage: {
+ typescript: {
+ method: 'client.bridges.loginSessions.retrieve',
+ example:
+ "import BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop({\n accessToken: process.env['BEEPER_ACCESS_TOKEN'], // This is the default and can be omitted\n});\n\nconst loginSession = await client.bridges.loginSessions.retrieve('123', {\n bridgeID: 'local-whatsapp',\n});\n\nconsole.log(loginSession.bridgeID);",
+ },
+ python: {
+ method: 'bridges.login_sessions.retrieve',
+ example:
+ 'import os\nfrom beeper_desktop_api import BeeperDesktop\n\nclient = BeeperDesktop(\n access_token=os.environ.get("BEEPER_ACCESS_TOKEN"), # This is the default and can be omitted\n)\nlogin_session = client.bridges.login_sessions.retrieve(\n login_session_id="123",\n bridge_id="local-whatsapp",\n)\nprint(login_session.bridge_id)',
+ },
+ go: {
+ method: 'client.Bridges.LoginSessions.Get',
+ example:
+ 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/beeper/desktop-api-go"\n\t"github.com/beeper/desktop-api-go/option"\n)\n\nfunc main() {\n\tclient := beeperdesktopapi.NewClient(\n\t\toption.WithAccessToken("My Access Token"),\n\t)\n\tloginSession, err := client.Bridges.LoginSessions.Get(\n\t\tcontext.TODO(),\n\t\t"123",\n\t\tbeeperdesktopapi.BridgeLoginSessionGetParams{\n\t\t\tBridgeID: "local-whatsapp",\n\t\t},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", loginSession.BridgeID)\n}\n',
+ },
+ cli: {
+ method: 'login_sessions retrieve',
+ example:
+ "beeper-desktop bridges:login-sessions retrieve \\\n --access-token 'My Access Token' \\\n --bridge-id local-whatsapp \\\n --login-session-id 123",
+ },
+ php: {
+ method: 'bridges->loginSessions->retrieve',
+ example:
+ "bridges->loginSessions->retrieve(\n '123', bridgeID: 'local-whatsapp'\n);\n\nvar_dump($loginSession);",
+ },
+ http: {
+ example:
+ 'curl http://localhost:23373/v1/bridges/$BRIDGE_ID/login-sessions/$LOGIN_SESSION_ID \\\n -H "Authorization: Bearer $BEEPER_ACCESS_TOKEN"',
+ },
+ },
+ },
+ {
+ name: 'cancel',
+ endpoint: '/v1/bridges/{bridgeID}/login-sessions/{loginSessionID}',
+ httpMethod: 'delete',
+ summary: 'Cancel bridge login session',
+ description: 'Cancel a temporary bridge login session.',
+ stainlessPath: '(resource) bridges.login_sessions > (method) cancel',
+ qualified: 'client.bridges.loginSessions.cancel',
+ params: ['bridgeID: string;', 'loginSessionID: string;'],
+ response: "{ bridgeID: string; loginSessionID: string; status: 'cancelled'; }",
+ markdown:
+ "## cancel\n\n`client.bridges.loginSessions.cancel(bridgeID: string, loginSessionID: string): { bridgeID: string; loginSessionID: string; status: 'cancelled'; }`\n\n**delete** `/v1/bridges/{bridgeID}/login-sessions/{loginSessionID}`\n\nCancel a temporary bridge login session.\n\n### Parameters\n\n- `bridgeID: string`\n Bridge ID.\n\n- `loginSessionID: string`\n Temporary bridge login session ID.\n\n### Returns\n\n- `{ bridgeID: string; loginSessionID: string; status: 'cancelled'; }`\n\n - `bridgeID: string`\n - `loginSessionID: string`\n - `status: 'cancelled'`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.bridges.loginSessions.cancel('123', { bridgeID: 'local-whatsapp' });\n\nconsole.log(response);\n```",
+ perLanguage: {
+ typescript: {
+ method: 'client.bridges.loginSessions.cancel',
+ example:
+ "import BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop({\n accessToken: process.env['BEEPER_ACCESS_TOKEN'], // This is the default and can be omitted\n});\n\nconst response = await client.bridges.loginSessions.cancel('123', { bridgeID: 'local-whatsapp' });\n\nconsole.log(response.bridgeID);",
+ },
+ python: {
+ method: 'bridges.login_sessions.cancel',
+ example:
+ 'import os\nfrom beeper_desktop_api import BeeperDesktop\n\nclient = BeeperDesktop(\n access_token=os.environ.get("BEEPER_ACCESS_TOKEN"), # This is the default and can be omitted\n)\nresponse = client.bridges.login_sessions.cancel(\n login_session_id="123",\n bridge_id="local-whatsapp",\n)\nprint(response.bridge_id)',
+ },
+ go: {
+ method: 'client.Bridges.LoginSessions.Cancel',
+ example:
+ 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/beeper/desktop-api-go"\n\t"github.com/beeper/desktop-api-go/option"\n)\n\nfunc main() {\n\tclient := beeperdesktopapi.NewClient(\n\t\toption.WithAccessToken("My Access Token"),\n\t)\n\tresponse, err := client.Bridges.LoginSessions.Cancel(\n\t\tcontext.TODO(),\n\t\t"123",\n\t\tbeeperdesktopapi.BridgeLoginSessionCancelParams{\n\t\t\tBridgeID: "local-whatsapp",\n\t\t},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.BridgeID)\n}\n',
+ },
+ cli: {
+ method: 'login_sessions cancel',
+ example:
+ "beeper-desktop bridges:login-sessions cancel \\\n --access-token 'My Access Token' \\\n --bridge-id local-whatsapp \\\n --login-session-id 123",
+ },
+ php: {
+ method: 'bridges->loginSessions->cancel',
+ example:
+ "bridges->loginSessions->cancel(\n '123', bridgeID: 'local-whatsapp'\n);\n\nvar_dump($response);",
+ },
+ http: {
+ example:
+ 'curl http://localhost:23373/v1/bridges/$BRIDGE_ID/login-sessions/$LOGIN_SESSION_ID \\\n -X DELETE \\\n -H "Authorization: Bearer $BEEPER_ACCESS_TOKEN"',
+ },
+ },
+ },
+ {
+ name: 'submit',
+ endpoint: '/v1/bridges/{bridgeID}/login-sessions/{loginSessionID}/steps/{stepID}',
+ httpMethod: 'post',
+ summary: 'Submit login step',
+ description: 'Submit input for the current step of a bridge login session.',
+ stainlessPath: '(resource) bridges.login_sessions.steps > (method) submit',
+ qualified: 'client.bridges.loginSessions.steps.submit',
+ params: [
+ 'bridgeID: string;',
+ 'loginSessionID: string;',
+ 'stepID: string;',
+ "type: 'user_input' | 'cookies' | 'display_and_wait';",
+ 'fields?: object;',
+ 'lastURL?: string;',
+ "source?: 'api' | 'webview' | 'browser_extension';",
+ ],
+ response:
+ "{ bridgeID: string; loginSessionID: string; status: string; account?: object; accountID?: string; currentStep?: { fields: login_input_field[]; stepID: string; type: 'user_input'; attachments?: object[]; instructions?: string; } | { fields: cookie_field[]; stepID: string; type: 'cookies'; url: string; expectedFinalURLRegex?: string; extractJS?: string; instructions?: string; userAgent?: string; } | { display: object | object | object; stepID: string; type: 'display_and_wait'; instructions?: string; } | { type: 'complete'; account?: account; instructions?: string; login?: object; stepID?: string; }; error?: object; login?: { bridgeID: string; loginID: string; removeScopes: 'current-device' | 'all-devices'[]; status: 'connected' | 'connecting' | 'needs_login' | 'logged_out' | 'unknown'; accountIDs?: string[]; statusText?: string; user?: user; }; loginID?: string; }",
+ markdown:
+ "## submit\n\n`client.bridges.loginSessions.steps.submit(bridgeID: string, loginSessionID: string, stepID: string, type: 'user_input' | 'cookies' | 'display_and_wait', fields?: object, lastURL?: string, source?: 'api' | 'webview' | 'browser_extension'): { bridgeID: string; loginSessionID: string; status: string; account?: account; accountID?: string; currentStep?: object | object | object | object; error?: api_error; login?: object; loginID?: string; }`\n\n**post** `/v1/bridges/{bridgeID}/login-sessions/{loginSessionID}/steps/{stepID}`\n\nSubmit input for the current step of a bridge login session.\n\n### Parameters\n\n- `bridgeID: string`\n Bridge ID.\n\n- `loginSessionID: string`\n Temporary bridge login session ID.\n\n- `stepID: string`\n Current bridge login session step ID.\n\n- `type: 'user_input' | 'cookies' | 'display_and_wait'`\n\n- `fields?: object`\n Field values keyed by the field IDs from the current step.\n\n- `lastURL?: string`\n Last browser URL reached during a cookies step, if available.\n\n- `source?: 'api' | 'webview' | 'browser_extension'`\n How the step was completed. Omit unless the client needs to distinguish an embedded webview or browser extension.\n\n### Returns\n\n- `{ bridgeID: string; loginSessionID: string; status: string; account?: { accountID: string; bridge: account_bridge; status: string; user: user; capabilities?: object; loginID?: string; network?: string; statusText?: string; }; accountID?: string; currentStep?: { fields: object[]; stepID: string; type: 'user_input'; attachments?: object[]; instructions?: string; } | { fields: object[]; stepID: string; type: 'cookies'; url: string; expectedFinalURLRegex?: string; extractJS?: string; instructions?: string; userAgent?: string; } | { display: { data: string; type: 'qr'; } | { imageURL: string; type: 'emoji'; } | { type: 'nothing'; }; stepID: string; type: 'display_and_wait'; instructions?: string; } | { type: 'complete'; account?: object; instructions?: string; login?: { bridgeID: string; loginID: string; removeScopes: 'current-device' | 'all-devices'[]; status: 'connected' | 'connecting' | 'needs_login' | 'logged_out' | 'unknown'; accountIDs?: string[]; statusText?: string; user?: user; }; stepID?: string; }; error?: { code: string; message: string; details?: object; }; login?: { bridgeID: string; loginID: string; removeScopes: 'current-device' | 'all-devices'[]; status: 'connected' | 'connecting' | 'needs_login' | 'logged_out' | 'unknown'; accountIDs?: string[]; statusText?: string; user?: object; }; loginID?: string; }`\n\n - `bridgeID: string`\n - `loginSessionID: string`\n - `status: string`\n - `account?: { accountID: string; bridge: { id: string; provider: 'cloud' | 'self-hosted' | 'local' | 'platform-sdk'; type: string; }; status: string; user: { id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }; capabilities?: object; loginID?: string; network?: string; statusText?: string; }`\n - `accountID?: string`\n - `currentStep?: { fields: { id: string; initialValue?: string; label?: string; optional?: boolean; placeholder?: string; type?: string; }[]; stepID: string; type: 'user_input'; attachments?: object[]; instructions?: string; } | { fields: { id: string; name?: string; type?: 'cookie' | 'header' | 'local_storage'; }[]; stepID: string; type: 'cookies'; url: string; expectedFinalURLRegex?: string; extractJS?: string; instructions?: string; userAgent?: string; } | { display: { data: string; type: 'qr'; } | { imageURL: string; type: 'emoji'; } | { type: 'nothing'; }; stepID: string; type: 'display_and_wait'; instructions?: string; } | { type: 'complete'; account?: { accountID: string; bridge: object; status: string; user: object; capabilities?: object; loginID?: string; network?: string; statusText?: string; }; instructions?: string; login?: { bridgeID: string; loginID: string; removeScopes: 'current-device' | 'all-devices'[]; status: 'connected' | 'connecting' | 'needs_login' | 'logged_out' | 'unknown'; accountIDs?: string[]; statusText?: string; user?: { id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }; }; stepID?: string; }`\n - `error?: { code: string; message: string; details?: object; }`\n - `login?: { bridgeID: string; loginID: string; removeScopes: 'current-device' | 'all-devices'[]; status: 'connected' | 'connecting' | 'needs_login' | 'logged_out' | 'unknown'; accountIDs?: string[]; statusText?: string; user?: { id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }; }`\n - `loginID?: string`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst loginSession = await client.bridges.loginSessions.steps.submit('x', {\n bridgeID: 'local-whatsapp',\n loginSessionID: '123',\n type: 'user_input',\n});\n\nconsole.log(loginSession);\n```",
+ perLanguage: {
+ typescript: {
+ method: 'client.bridges.loginSessions.steps.submit',
+ example:
+ "import BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop({\n accessToken: process.env['BEEPER_ACCESS_TOKEN'], // This is the default and can be omitted\n});\n\nconst loginSession = await client.bridges.loginSessions.steps.submit('x', {\n bridgeID: 'local-whatsapp',\n loginSessionID: '123',\n type: 'user_input',\n});\n\nconsole.log(loginSession.bridgeID);",
+ },
+ python: {
+ method: 'bridges.login_sessions.steps.submit',
+ example:
+ 'import os\nfrom beeper_desktop_api import BeeperDesktop\n\nclient = BeeperDesktop(\n access_token=os.environ.get("BEEPER_ACCESS_TOKEN"), # This is the default and can be omitted\n)\nlogin_session = client.bridges.login_sessions.steps.submit(\n step_id="x",\n bridge_id="local-whatsapp",\n login_session_id="123",\n type="user_input",\n)\nprint(login_session.bridge_id)',
+ },
+ go: {
+ method: 'client.Bridges.LoginSessions.Steps.Submit',
+ example:
+ 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/beeper/desktop-api-go"\n\t"github.com/beeper/desktop-api-go/option"\n)\n\nfunc main() {\n\tclient := beeperdesktopapi.NewClient(\n\t\toption.WithAccessToken("My Access Token"),\n\t)\n\tloginSession, err := client.Bridges.LoginSessions.Steps.Submit(\n\t\tcontext.TODO(),\n\t\t"x",\n\t\tbeeperdesktopapi.BridgeLoginSessionStepSubmitParams{\n\t\t\tBridgeID: "local-whatsapp",\n\t\t\tLoginSessionID: "123",\n\t\t\tType: beeperdesktopapi.BridgeLoginSessionStepSubmitParamsTypeUserInput,\n\t\t},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", loginSession.BridgeID)\n}\n',
+ },
+ cli: {
+ method: 'steps submit',
+ example:
+ "beeper-desktop bridges:login-sessions:steps submit \\\n --access-token 'My Access Token' \\\n --bridge-id local-whatsapp \\\n --login-session-id 123 \\\n --step-id x \\\n --type user_input",
+ },
+ php: {
+ method: 'bridges->loginSessions->steps->submit',
+ example:
+ "bridges->loginSessions->steps->submit(\n 'x',\n bridgeID: 'local-whatsapp',\n loginSessionID: '123',\n type: 'user_input',\n fields: ['foo' => 'string'],\n lastURL: 'lastURL',\n source: 'api',\n);\n\nvar_dump($loginSession);",
+ },
+ http: {
+ example:
+ 'curl http://localhost:23373/v1/bridges/$BRIDGE_ID/login-sessions/$LOGIN_SESSION_ID/steps/$STEP_ID \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $BEEPER_ACCESS_TOKEN" \\\n -d \'{\n "type": "user_input"\n }\'',
+ },
+ },
+ },
{
name: 'retrieve',
endpoint: '/v1/chats/{chatID}',
httpMethod: 'get',
summary: 'Retrieve chat details',
- description: 'Retrieve chat details including metadata, participants, and latest message',
+ description: 'Retrieve chat details, including metadata, participants, and the latest message.',
stainlessPath: '(resource) chats > (method) retrieve',
qualified: 'client.chats.retrieve',
params: ['chatID: string;', 'maxParticipantCount?: number;'],
response:
"{ id: string; accountID: string; network: string; participants: object; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: object; description?: string; draft?: object; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: object; snooze?: object; unreadMentionsCount?: number; }",
markdown:
- "## retrieve\n\n`client.chats.retrieve(chatID: string, maxParticipantCount?: number): { id: string; accountID: string; network: string; participants: object; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: object; description?: string; draft?: object; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: object; snooze?: object; unreadMentionsCount?: number; }`\n\n**get** `/v1/chats/{chatID}`\n\nRetrieve chat details including metadata, participants, and latest message\n\n### Parameters\n\n- `chatID: string`\n Chat ID. Input routes also accept the local chat ID from this Beeper Desktop installation when available.\n\n- `maxParticipantCount?: number`\n Maximum number of participants to return. Use -1 for all; otherwise 0-500. Defaults to 100. List and search endpoints return up to 20 participants per chat.\n\n### Returns\n\n- `{ id: string; accountID: string; network: string; participants: { hasMore: boolean; items: object[]; total: number; }; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: { allowedReactions?: string[]; archive?: boolean; attachments?: object; customEmojiReactions?: boolean; delete?: -2 | -1 | 0 | 1 | 2; deleteChat?: boolean; deleteChatForEveryone?: boolean; deleteForMe?: boolean; deleteMaxAge?: number; disappearingTimer?: { omitEmptyTimer?: boolean; timers?: number[]; types?: 'afterRead' | 'afterSend'[]; }; edit?: -2 | -1 | 0 | 1 | 2; editMaxAge?: number; editMaxCount?: number; formatting?: object; locationMessage?: -2 | -1 | 0 | 1 | 2; markAsUnread?: boolean; maxTextLength?: number; messageRequest?: { acceptWithButton?: -2 | -1 | 0 | 1 | 2; acceptWithMessage?: -2 | -1 | 0 | 1 | 2; }; participantActions?: { ban?: -2 | -1 | 0 | 1 | 2; invite?: -2 | -1 | 0 | 1 | 2; kick?: -2 | -1 | 0 | 1 | 2; leave?: -2 | -1 | 0 | 1 | 2; revokeInvite?: -2 | -1 | 0 | 1 | 2; }; poll?: -2 | -1 | 0 | 1 | 2; reaction?: -2 | -1 | 0 | 1 | 2; reactionCount?: number; readReceipts?: boolean; reply?: -2 | -1 | 0 | 1 | 2; state?: { avatar?: object; description?: object; disappearingTimer?: object; title?: object; }; thread?: -2 | -1 | 0 | 1 | 2; typingNotifications?: boolean; }; description?: string; draft?: { text: string; attachments?: object; }; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: { dismissOnIncomingMessage?: boolean; remindAt?: string; }; snooze?: { snoozeUntil?: string; userSnoozedAt?: string; }; unreadMentionsCount?: number; }`\n\n - `id: string`\n - `accountID: string`\n - `network: string`\n - `participants: { hasMore: boolean; items: { id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }[]; total: number; }`\n - `title: string`\n - `type: 'single' | 'group'`\n - `unreadCount: number`\n - `capabilities?: { allowedReactions?: string[]; archive?: boolean; attachments?: object; customEmojiReactions?: boolean; delete?: -2 | -1 | 0 | 1 | 2; deleteChat?: boolean; deleteChatForEveryone?: boolean; deleteForMe?: boolean; deleteMaxAge?: number; disappearingTimer?: { omitEmptyTimer?: boolean; timers?: number[]; types?: 'afterRead' | 'afterSend'[]; }; edit?: -2 | -1 | 0 | 1 | 2; editMaxAge?: number; editMaxCount?: number; formatting?: object; locationMessage?: -2 | -1 | 0 | 1 | 2; markAsUnread?: boolean; maxTextLength?: number; messageRequest?: { acceptWithButton?: -2 | -1 | 0 | 1 | 2; acceptWithMessage?: -2 | -1 | 0 | 1 | 2; }; participantActions?: { ban?: -2 | -1 | 0 | 1 | 2; invite?: -2 | -1 | 0 | 1 | 2; kick?: -2 | -1 | 0 | 1 | 2; leave?: -2 | -1 | 0 | 1 | 2; revokeInvite?: -2 | -1 | 0 | 1 | 2; }; poll?: -2 | -1 | 0 | 1 | 2; reaction?: -2 | -1 | 0 | 1 | 2; reactionCount?: number; readReceipts?: boolean; reply?: -2 | -1 | 0 | 1 | 2; state?: { avatar?: { level: -2 | -1 | 0 | 1 | 2; }; description?: { level: -2 | -1 | 0 | 1 | 2; }; disappearingTimer?: { level: -2 | -1 | 0 | 1 | 2; }; title?: { level: -2 | -1 | 0 | 1 | 2; }; }; thread?: -2 | -1 | 0 | 1 | 2; typingNotifications?: boolean; }`\n - `description?: string`\n - `draft?: { text: string; attachments?: object; }`\n - `imgURL?: string`\n - `isArchived?: boolean`\n - `isLowPriority?: boolean`\n - `isMarkedUnread?: boolean`\n - `isMuted?: boolean`\n - `isPinned?: boolean`\n - `isReadOnly?: boolean`\n - `lastActivity?: string`\n - `lastReadMessageSortKey?: string`\n - `localChatID?: string`\n - `messageExpirySeconds?: number`\n - `reminder?: { dismissOnIncomingMessage?: boolean; remindAt?: string; }`\n - `snooze?: { snoozeUntil?: string; userSnoozedAt?: string; }`\n - `unreadMentionsCount?: number`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst chat = await client.chats.retrieve('!NCdzlIaMjZUmvmvyHU:beeper.com');\n\nconsole.log(chat);\n```",
+ "## retrieve\n\n`client.chats.retrieve(chatID: string, maxParticipantCount?: number): { id: string; accountID: string; network: string; participants: object; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: object; description?: string; draft?: object; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: object; snooze?: object; unreadMentionsCount?: number; }`\n\n**get** `/v1/chats/{chatID}`\n\nRetrieve chat details, including metadata, participants, and the latest message.\n\n### Parameters\n\n- `chatID: string`\n Chat ID. Input routes also accept the local chat ID from this installation when available.\n\n- `maxParticipantCount?: number`\n Maximum number of participants to return. Use -1 for all; otherwise 0-500. Defaults to 100. List and search endpoints return up to 20 participants per chat.\n\n### Returns\n\n- `{ id: string; accountID: string; network: string; participants: { hasMore: boolean; items: object[]; total: number; }; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: { allowedReactions?: string[]; archive?: boolean; attachments?: object; customEmojiReactions?: boolean; delete?: -2 | -1 | 0 | 1 | 2; deleteChat?: boolean; deleteChatForEveryone?: boolean; deleteForMe?: boolean; deleteMaxAge?: number; disappearingTimer?: { omitEmptyTimer?: boolean; timers?: number[]; types?: 'afterRead' | 'afterSend'[]; }; edit?: -2 | -1 | 0 | 1 | 2; editMaxAge?: number; editMaxCount?: number; formatting?: object; locationMessage?: -2 | -1 | 0 | 1 | 2; markAsUnread?: boolean; maxTextLength?: number; messageRequest?: { acceptWithButton?: -2 | -1 | 0 | 1 | 2; acceptWithMessage?: -2 | -1 | 0 | 1 | 2; }; participantActions?: { ban?: -2 | -1 | 0 | 1 | 2; invite?: -2 | -1 | 0 | 1 | 2; kick?: -2 | -1 | 0 | 1 | 2; leave?: -2 | -1 | 0 | 1 | 2; revokeInvite?: -2 | -1 | 0 | 1 | 2; }; poll?: -2 | -1 | 0 | 1 | 2; reaction?: -2 | -1 | 0 | 1 | 2; reactionCount?: number; readReceipts?: boolean; reply?: -2 | -1 | 0 | 1 | 2; state?: { avatar?: object; description?: object; disappearingTimer?: object; title?: object; }; thread?: -2 | -1 | 0 | 1 | 2; typingNotifications?: boolean; }; description?: string; draft?: { text: string; attachments?: object; }; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: { dismissOnIncomingMessage?: boolean; remindAt?: string; }; snooze?: { snoozeUntil?: string; userSnoozedAt?: string; }; unreadMentionsCount?: number; }`\n\n - `id: string`\n - `accountID: string`\n - `network: string`\n - `participants: { hasMore: boolean; items: { id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }[]; total: number; }`\n - `title: string`\n - `type: 'single' | 'group'`\n - `unreadCount: number`\n - `capabilities?: { allowedReactions?: string[]; archive?: boolean; attachments?: object; customEmojiReactions?: boolean; delete?: -2 | -1 | 0 | 1 | 2; deleteChat?: boolean; deleteChatForEveryone?: boolean; deleteForMe?: boolean; deleteMaxAge?: number; disappearingTimer?: { omitEmptyTimer?: boolean; timers?: number[]; types?: 'afterRead' | 'afterSend'[]; }; edit?: -2 | -1 | 0 | 1 | 2; editMaxAge?: number; editMaxCount?: number; formatting?: object; locationMessage?: -2 | -1 | 0 | 1 | 2; markAsUnread?: boolean; maxTextLength?: number; messageRequest?: { acceptWithButton?: -2 | -1 | 0 | 1 | 2; acceptWithMessage?: -2 | -1 | 0 | 1 | 2; }; participantActions?: { ban?: -2 | -1 | 0 | 1 | 2; invite?: -2 | -1 | 0 | 1 | 2; kick?: -2 | -1 | 0 | 1 | 2; leave?: -2 | -1 | 0 | 1 | 2; revokeInvite?: -2 | -1 | 0 | 1 | 2; }; poll?: -2 | -1 | 0 | 1 | 2; reaction?: -2 | -1 | 0 | 1 | 2; reactionCount?: number; readReceipts?: boolean; reply?: -2 | -1 | 0 | 1 | 2; state?: { avatar?: { level: -2 | -1 | 0 | 1 | 2; }; description?: { level: -2 | -1 | 0 | 1 | 2; }; disappearingTimer?: { level: -2 | -1 | 0 | 1 | 2; }; title?: { level: -2 | -1 | 0 | 1 | 2; }; }; thread?: -2 | -1 | 0 | 1 | 2; typingNotifications?: boolean; }`\n - `description?: string`\n - `draft?: { text: string; attachments?: object; }`\n - `imgURL?: string`\n - `isArchived?: boolean`\n - `isLowPriority?: boolean`\n - `isMarkedUnread?: boolean`\n - `isMuted?: boolean`\n - `isPinned?: boolean`\n - `isReadOnly?: boolean`\n - `lastActivity?: string`\n - `lastReadMessageSortKey?: string`\n - `localChatID?: string`\n - `messageExpirySeconds?: number`\n - `reminder?: { dismissOnIncomingMessage?: boolean; remindAt?: string; }`\n - `snooze?: { snoozeUntil?: string; userSnoozedAt?: string; }`\n - `unreadMentionsCount?: number`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst chat = await client.chats.retrieve('!NCdzlIaMjZUmvmvyHU:beeper.com');\n\nconsole.log(chat);\n```",
perLanguage: {
typescript: {
method: 'client.chats.retrieve',
@@ -317,7 +730,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
cli: {
method: 'chats retrieve',
example:
- "beeper-desktop-cli chats retrieve \\\n --access-token 'My Access Token' \\\n --chat-id '!NCdzlIaMjZUmvmvyHU:beeper.com'",
+ "beeper-desktop chats retrieve \\\n --access-token 'My Access Token' \\\n --chat-id '!NCdzlIaMjZUmvmvyHU:beeper.com'",
},
php: {
method: 'chats->retrieve',
@@ -368,7 +781,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
cli: {
method: 'chats create',
example:
- "beeper-desktop-cli chats create \\\n --access-token 'My Access Token' \\\n --account-id accountID \\\n --participant-id string \\\n --type single",
+ "beeper-desktop chats create \\\n --access-token 'My Access Token' \\\n --account-id accountID \\\n --participant-id string \\\n --type single",
},
php: {
method: 'chats->create',
@@ -387,7 +800,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
httpMethod: 'post',
summary: 'Start a direct chat',
description:
- 'Resolve a user/contact and open a direct chat. Reuses and returns an existing direct chat when one is found. Available in Beeper Desktop v4.2.808+.',
+ 'Resolve a user/contact and open a direct chat. Reuses and returns an existing direct chat when one is found. Available in Beeper v4.2.808+.',
stainlessPath: '(resource) chats > (method) start',
qualified: 'client.chats.start',
params: [
@@ -399,7 +812,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
response:
"{ id: string; accountID: string; network: string; participants: object; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: object; description?: string; draft?: object; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: object; snooze?: object; unreadMentionsCount?: number; }",
markdown:
- "## start\n\n`client.chats.start(accountID: string, user: { id?: string; email?: string; fullName?: string; phoneNumber?: string; username?: string; }, allowInvite?: boolean, messageText?: string): object`\n\n**post** `/v1/chats/start`\n\nResolve a user/contact and open a direct chat. Reuses and returns an existing direct chat when one is found. Available in Beeper Desktop v4.2.808+.\n\n### Parameters\n\n- `accountID: string`\n Account to create or start the chat on.\n\n- `user: { id?: string; email?: string; fullName?: string; phoneNumber?: string; username?: string; }`\n Merged user-like contact payload used to resolve the best identifier.\n - `id?: string`\n Known user ID when available.\n - `email?: string`\n Email candidate.\n - `fullName?: string`\n Display name hint used for ranking only.\n - `phoneNumber?: string`\n Phone number candidate (E.164 preferred).\n - `username?: string`\n Username/handle candidate.\n\n- `allowInvite?: boolean`\n Whether invite-based DM creation is allowed when required by the platform.\n\n- `messageText?: string`\n Optional first message content if the platform requires it to create the chat.\n\n### Returns\n\n- `{ id: string; accountID: string; network: string; participants: { hasMore: boolean; items: user[]; total: number; }; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: { allowedReactions?: string[]; archive?: boolean; attachments?: object; customEmojiReactions?: boolean; delete?: -2 | -1 | 0 | 1 | 2; deleteChat?: boolean; deleteChatForEveryone?: boolean; deleteForMe?: boolean; deleteMaxAge?: number; disappearingTimer?: object; edit?: -2 | -1 | 0 | 1 | 2; editMaxAge?: number; editMaxCount?: number; formatting?: object; locationMessage?: -2 | -1 | 0 | 1 | 2; markAsUnread?: boolean; maxTextLength?: number; messageRequest?: object; participantActions?: object; poll?: -2 | -1 | 0 | 1 | 2; reaction?: -2 | -1 | 0 | 1 | 2; reactionCount?: number; readReceipts?: boolean; reply?: -2 | -1 | 0 | 1 | 2; state?: object; thread?: -2 | -1 | 0 | 1 | 2; typingNotifications?: boolean; }; description?: string; draft?: { text: string; attachments?: object; }; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: { dismissOnIncomingMessage?: boolean; remindAt?: string; }; snooze?: { snoozeUntil?: string; userSnoozedAt?: string; }; unreadMentionsCount?: number; }`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.chats.start({\n accountID: 'accountID',\n user: {},\n});\n\nconsole.log(response);\n```",
+ "## start\n\n`client.chats.start(accountID: string, user: { id?: string; email?: string; fullName?: string; phoneNumber?: string; username?: string; }, allowInvite?: boolean, messageText?: string): object`\n\n**post** `/v1/chats/start`\n\nResolve a user/contact and open a direct chat. Reuses and returns an existing direct chat when one is found. Available in Beeper v4.2.808+.\n\n### Parameters\n\n- `accountID: string`\n Account to create or start the chat on.\n\n- `user: { id?: string; email?: string; fullName?: string; phoneNumber?: string; username?: string; }`\n Contact-like user payload used to resolve the best identifier.\n - `id?: string`\n Known user ID when available.\n - `email?: string`\n Email candidate.\n - `fullName?: string`\n Display name hint used for ranking only.\n - `phoneNumber?: string`\n Phone number candidate (E.164 preferred).\n - `username?: string`\n Username/handle candidate.\n\n- `allowInvite?: boolean`\n Whether invite-based DM creation is allowed when required by the platform.\n\n- `messageText?: string`\n Optional first message content if the platform requires it to create the chat.\n\n### Returns\n\n- `{ id: string; accountID: string; network: string; participants: { hasMore: boolean; items: user[]; total: number; }; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: { allowedReactions?: string[]; archive?: boolean; attachments?: object; customEmojiReactions?: boolean; delete?: -2 | -1 | 0 | 1 | 2; deleteChat?: boolean; deleteChatForEveryone?: boolean; deleteForMe?: boolean; deleteMaxAge?: number; disappearingTimer?: object; edit?: -2 | -1 | 0 | 1 | 2; editMaxAge?: number; editMaxCount?: number; formatting?: object; locationMessage?: -2 | -1 | 0 | 1 | 2; markAsUnread?: boolean; maxTextLength?: number; messageRequest?: object; participantActions?: object; poll?: -2 | -1 | 0 | 1 | 2; reaction?: -2 | -1 | 0 | 1 | 2; reactionCount?: number; readReceipts?: boolean; reply?: -2 | -1 | 0 | 1 | 2; state?: object; thread?: -2 | -1 | 0 | 1 | 2; typingNotifications?: boolean; }; description?: string; draft?: { text: string; attachments?: object; }; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: { dismissOnIncomingMessage?: boolean; remindAt?: string; }; snooze?: { snoozeUntil?: string; userSnoozedAt?: string; }; unreadMentionsCount?: number; }`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.chats.start({\n accountID: 'accountID',\n user: {},\n});\n\nconsole.log(response);\n```",
perLanguage: {
typescript: {
method: 'client.chats.start',
@@ -419,7 +832,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
cli: {
method: 'chats start',
example:
- "beeper-desktop-cli chats start \\\n --access-token 'My Access Token' \\\n --account-id accountID \\\n --user '{}'",
+ "beeper-desktop chats start \\\n --access-token 'My Access Token' \\\n --account-id accountID \\\n --user '{}'",
},
php: {
method: 'chats->start',
@@ -464,7 +877,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
},
cli: {
method: 'chats list',
- example: "beeper-desktop-cli chats list \\\n --access-token 'My Access Token'",
+ example: "beeper-desktop chats list \\\n --access-token 'My Access Token'",
},
php: {
method: 'chats->list',
@@ -502,7 +915,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
response:
"{ id: string; accountID: string; network: string; participants: object; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: object; description?: string; draft?: object; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: object; snooze?: object; unreadMentionsCount?: number; }",
markdown:
- "## search\n\n`client.chats.search(accountIDs?: string[], cursor?: string, direction?: 'after' | 'before', inbox?: 'primary' | 'low-priority' | 'archive', includeMuted?: boolean, lastActivityAfter?: string, lastActivityBefore?: string, limit?: number, query?: string, scope?: 'titles' | 'participants', type?: 'single' | 'group' | 'any', unreadOnly?: boolean): { id: string; accountID: string; network: string; participants: object; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: object; description?: string; draft?: object; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: object; snooze?: object; unreadMentionsCount?: number; }`\n\n**get** `/v1/chats/search`\n\nSearch chats by title, network, or participant names.\n\n### Parameters\n\n- `accountIDs?: string[]`\n Provide an array of account IDs to filter chats from specific messaging accounts only\n\n- `cursor?: string`\n Opaque pagination cursor; do not inspect. Use together with 'direction'.\n\n- `direction?: 'after' | 'before'`\n Pagination direction used with 'cursor': 'before' fetches older results, 'after' fetches newer results. Defaults to 'before' when only 'cursor' is provided.\n\n- `inbox?: 'primary' | 'low-priority' | 'archive'`\n Filter by inbox type: \"primary\" (non-archived, non-low-priority), \"low-priority\", or \"archive\". If not specified, shows all chats.\n\n- `includeMuted?: boolean`\n Include chats marked as Muted by the user, which are usually less important. Default: true. Set to false if the user wants a more refined search.\n\n- `lastActivityAfter?: string`\n Provide an ISO datetime string to only retrieve chats with last activity after this time\n\n- `lastActivityBefore?: string`\n Provide an ISO datetime string to only retrieve chats with last activity before this time\n\n- `limit?: number`\n Set the maximum number of chats to retrieve. Valid range: 1-200, default is 50\n\n- `query?: string`\n Literal token search (non-semantic). Use single words users type (e.g., \"dinner\"). When multiple words provided, ALL must match. Case-insensitive.\n\n- `scope?: 'titles' | 'participants'`\n Search scope: 'titles' matches title + network; 'participants' matches participant names.\n\n- `type?: 'single' | 'group' | 'any'`\n Specify the type of chats to retrieve: use \"single\" for direct messages, \"group\" for group chats, or \"any\" to get all types\n\n- `unreadOnly?: boolean`\n Set to true to only retrieve chats that have unread messages\n\n### Returns\n\n- `{ id: string; accountID: string; network: string; participants: { hasMore: boolean; items: object[]; total: number; }; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: { allowedReactions?: string[]; archive?: boolean; attachments?: object; customEmojiReactions?: boolean; delete?: -2 | -1 | 0 | 1 | 2; deleteChat?: boolean; deleteChatForEveryone?: boolean; deleteForMe?: boolean; deleteMaxAge?: number; disappearingTimer?: { omitEmptyTimer?: boolean; timers?: number[]; types?: 'afterRead' | 'afterSend'[]; }; edit?: -2 | -1 | 0 | 1 | 2; editMaxAge?: number; editMaxCount?: number; formatting?: object; locationMessage?: -2 | -1 | 0 | 1 | 2; markAsUnread?: boolean; maxTextLength?: number; messageRequest?: { acceptWithButton?: -2 | -1 | 0 | 1 | 2; acceptWithMessage?: -2 | -1 | 0 | 1 | 2; }; participantActions?: { ban?: -2 | -1 | 0 | 1 | 2; invite?: -2 | -1 | 0 | 1 | 2; kick?: -2 | -1 | 0 | 1 | 2; leave?: -2 | -1 | 0 | 1 | 2; revokeInvite?: -2 | -1 | 0 | 1 | 2; }; poll?: -2 | -1 | 0 | 1 | 2; reaction?: -2 | -1 | 0 | 1 | 2; reactionCount?: number; readReceipts?: boolean; reply?: -2 | -1 | 0 | 1 | 2; state?: { avatar?: object; description?: object; disappearingTimer?: object; title?: object; }; thread?: -2 | -1 | 0 | 1 | 2; typingNotifications?: boolean; }; description?: string; draft?: { text: string; attachments?: object; }; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: { dismissOnIncomingMessage?: boolean; remindAt?: string; }; snooze?: { snoozeUntil?: string; userSnoozedAt?: string; }; unreadMentionsCount?: number; }`\n\n - `id: string`\n - `accountID: string`\n - `network: string`\n - `participants: { hasMore: boolean; items: { id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }[]; total: number; }`\n - `title: string`\n - `type: 'single' | 'group'`\n - `unreadCount: number`\n - `capabilities?: { allowedReactions?: string[]; archive?: boolean; attachments?: object; customEmojiReactions?: boolean; delete?: -2 | -1 | 0 | 1 | 2; deleteChat?: boolean; deleteChatForEveryone?: boolean; deleteForMe?: boolean; deleteMaxAge?: number; disappearingTimer?: { omitEmptyTimer?: boolean; timers?: number[]; types?: 'afterRead' | 'afterSend'[]; }; edit?: -2 | -1 | 0 | 1 | 2; editMaxAge?: number; editMaxCount?: number; formatting?: object; locationMessage?: -2 | -1 | 0 | 1 | 2; markAsUnread?: boolean; maxTextLength?: number; messageRequest?: { acceptWithButton?: -2 | -1 | 0 | 1 | 2; acceptWithMessage?: -2 | -1 | 0 | 1 | 2; }; participantActions?: { ban?: -2 | -1 | 0 | 1 | 2; invite?: -2 | -1 | 0 | 1 | 2; kick?: -2 | -1 | 0 | 1 | 2; leave?: -2 | -1 | 0 | 1 | 2; revokeInvite?: -2 | -1 | 0 | 1 | 2; }; poll?: -2 | -1 | 0 | 1 | 2; reaction?: -2 | -1 | 0 | 1 | 2; reactionCount?: number; readReceipts?: boolean; reply?: -2 | -1 | 0 | 1 | 2; state?: { avatar?: { level: -2 | -1 | 0 | 1 | 2; }; description?: { level: -2 | -1 | 0 | 1 | 2; }; disappearingTimer?: { level: -2 | -1 | 0 | 1 | 2; }; title?: { level: -2 | -1 | 0 | 1 | 2; }; }; thread?: -2 | -1 | 0 | 1 | 2; typingNotifications?: boolean; }`\n - `description?: string`\n - `draft?: { text: string; attachments?: object; }`\n - `imgURL?: string`\n - `isArchived?: boolean`\n - `isLowPriority?: boolean`\n - `isMarkedUnread?: boolean`\n - `isMuted?: boolean`\n - `isPinned?: boolean`\n - `isReadOnly?: boolean`\n - `lastActivity?: string`\n - `lastReadMessageSortKey?: string`\n - `localChatID?: string`\n - `messageExpirySeconds?: number`\n - `reminder?: { dismissOnIncomingMessage?: boolean; remindAt?: string; }`\n - `snooze?: { snoozeUntil?: string; userSnoozedAt?: string; }`\n - `unreadMentionsCount?: number`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\n// Automatically fetches more pages as needed.\nfor await (const chat of client.chats.search()) {\n console.log(chat);\n}\n```",
+ "## search\n\n`client.chats.search(accountIDs?: string[], cursor?: string, direction?: 'after' | 'before', inbox?: 'primary' | 'low-priority' | 'archive', includeMuted?: boolean, lastActivityAfter?: string, lastActivityBefore?: string, limit?: number, query?: string, scope?: 'titles' | 'participants', type?: 'single' | 'group' | 'any', unreadOnly?: boolean): { id: string; accountID: string; network: string; participants: object; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: object; description?: string; draft?: object; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: object; snooze?: object; unreadMentionsCount?: number; }`\n\n**get** `/v1/chats/search`\n\nSearch chats by title, network, or participant names.\n\n### Parameters\n\n- `accountIDs?: string[]`\n Limit results to specific chat accounts.\n\n- `cursor?: string`\n Opaque pagination cursor; do not inspect. Use together with 'direction'.\n\n- `direction?: 'after' | 'before'`\n Pagination direction used with 'cursor': 'before' fetches older results, 'after' fetches newer results. Defaults to 'before' when only 'cursor' is provided.\n\n- `inbox?: 'primary' | 'low-priority' | 'archive'`\n Filter by inbox type: \"primary\" (non-archived, non-low-priority), \"low-priority\", or \"archive\". If not specified, shows all chats.\n\n- `includeMuted?: boolean`\n Include chats marked as Muted by the user, which are usually less important. Default: true. Set to false if the user wants a more refined search.\n\n- `lastActivityAfter?: string`\n Only include chats with last activity after this ISO 8601 datetime.\n\n- `lastActivityBefore?: string`\n Only include chats with last activity before this ISO 8601 datetime.\n\n- `limit?: number`\n Set the maximum number of chats to retrieve. Valid range: 1-200, default is 50\n\n- `query?: string`\n Literal chat search. Use words the user typed, such as \"dinner\". When multiple words are provided, all must match. Case-insensitive.\n\n- `scope?: 'titles' | 'participants'`\n Search scope: 'titles' matches title + network; 'participants' matches participant names.\n\n- `type?: 'single' | 'group' | 'any'`\n Specify the type of chats to retrieve: use \"single\" for direct messages, \"group\" for group chats, or \"any\" to get all types\n\n- `unreadOnly?: boolean`\n Set to true to only retrieve chats that have unread messages\n\n### Returns\n\n- `{ id: string; accountID: string; network: string; participants: { hasMore: boolean; items: object[]; total: number; }; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: { allowedReactions?: string[]; archive?: boolean; attachments?: object; customEmojiReactions?: boolean; delete?: -2 | -1 | 0 | 1 | 2; deleteChat?: boolean; deleteChatForEveryone?: boolean; deleteForMe?: boolean; deleteMaxAge?: number; disappearingTimer?: { omitEmptyTimer?: boolean; timers?: number[]; types?: 'afterRead' | 'afterSend'[]; }; edit?: -2 | -1 | 0 | 1 | 2; editMaxAge?: number; editMaxCount?: number; formatting?: object; locationMessage?: -2 | -1 | 0 | 1 | 2; markAsUnread?: boolean; maxTextLength?: number; messageRequest?: { acceptWithButton?: -2 | -1 | 0 | 1 | 2; acceptWithMessage?: -2 | -1 | 0 | 1 | 2; }; participantActions?: { ban?: -2 | -1 | 0 | 1 | 2; invite?: -2 | -1 | 0 | 1 | 2; kick?: -2 | -1 | 0 | 1 | 2; leave?: -2 | -1 | 0 | 1 | 2; revokeInvite?: -2 | -1 | 0 | 1 | 2; }; poll?: -2 | -1 | 0 | 1 | 2; reaction?: -2 | -1 | 0 | 1 | 2; reactionCount?: number; readReceipts?: boolean; reply?: -2 | -1 | 0 | 1 | 2; state?: { avatar?: object; description?: object; disappearingTimer?: object; title?: object; }; thread?: -2 | -1 | 0 | 1 | 2; typingNotifications?: boolean; }; description?: string; draft?: { text: string; attachments?: object; }; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: { dismissOnIncomingMessage?: boolean; remindAt?: string; }; snooze?: { snoozeUntil?: string; userSnoozedAt?: string; }; unreadMentionsCount?: number; }`\n\n - `id: string`\n - `accountID: string`\n - `network: string`\n - `participants: { hasMore: boolean; items: { id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }[]; total: number; }`\n - `title: string`\n - `type: 'single' | 'group'`\n - `unreadCount: number`\n - `capabilities?: { allowedReactions?: string[]; archive?: boolean; attachments?: object; customEmojiReactions?: boolean; delete?: -2 | -1 | 0 | 1 | 2; deleteChat?: boolean; deleteChatForEveryone?: boolean; deleteForMe?: boolean; deleteMaxAge?: number; disappearingTimer?: { omitEmptyTimer?: boolean; timers?: number[]; types?: 'afterRead' | 'afterSend'[]; }; edit?: -2 | -1 | 0 | 1 | 2; editMaxAge?: number; editMaxCount?: number; formatting?: object; locationMessage?: -2 | -1 | 0 | 1 | 2; markAsUnread?: boolean; maxTextLength?: number; messageRequest?: { acceptWithButton?: -2 | -1 | 0 | 1 | 2; acceptWithMessage?: -2 | -1 | 0 | 1 | 2; }; participantActions?: { ban?: -2 | -1 | 0 | 1 | 2; invite?: -2 | -1 | 0 | 1 | 2; kick?: -2 | -1 | 0 | 1 | 2; leave?: -2 | -1 | 0 | 1 | 2; revokeInvite?: -2 | -1 | 0 | 1 | 2; }; poll?: -2 | -1 | 0 | 1 | 2; reaction?: -2 | -1 | 0 | 1 | 2; reactionCount?: number; readReceipts?: boolean; reply?: -2 | -1 | 0 | 1 | 2; state?: { avatar?: { level: -2 | -1 | 0 | 1 | 2; }; description?: { level: -2 | -1 | 0 | 1 | 2; }; disappearingTimer?: { level: -2 | -1 | 0 | 1 | 2; }; title?: { level: -2 | -1 | 0 | 1 | 2; }; }; thread?: -2 | -1 | 0 | 1 | 2; typingNotifications?: boolean; }`\n - `description?: string`\n - `draft?: { text: string; attachments?: object; }`\n - `imgURL?: string`\n - `isArchived?: boolean`\n - `isLowPriority?: boolean`\n - `isMarkedUnread?: boolean`\n - `isMuted?: boolean`\n - `isPinned?: boolean`\n - `isReadOnly?: boolean`\n - `lastActivity?: string`\n - `lastReadMessageSortKey?: string`\n - `localChatID?: string`\n - `messageExpirySeconds?: number`\n - `reminder?: { dismissOnIncomingMessage?: boolean; remindAt?: string; }`\n - `snooze?: { snoozeUntil?: string; userSnoozedAt?: string; }`\n - `unreadMentionsCount?: number`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\n// Automatically fetches more pages as needed.\nfor await (const chat of client.chats.search()) {\n console.log(chat);\n}\n```",
perLanguage: {
typescript: {
method: 'client.chats.search',
@@ -521,7 +934,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
},
cli: {
method: 'chats search',
- example: "beeper-desktop-cli chats search \\\n --access-token 'My Access Token'",
+ example: "beeper-desktop chats search \\\n --access-token 'My Access Token'",
},
php: {
method: 'chats->search',
@@ -540,12 +953,12 @@ const EMBEDDED_METHODS: MethodEntry[] = [
httpMethod: 'post',
summary: 'Archive or unarchive a chat',
description:
- 'Archive or unarchive a chat. Set archived=true to move to archive, archived=false to move back to inbox',
+ 'Archive or unarchive a chat. Set archived=true to move it to Archive, or archived=false to move it back to the inbox.',
stainlessPath: '(resource) chats > (method) archive',
qualified: 'client.chats.archive',
params: ['chatID: string;', 'archived?: boolean;'],
markdown:
- "## archive\n\n`client.chats.archive(chatID: string, archived?: boolean): void`\n\n**post** `/v1/chats/{chatID}/archive`\n\nArchive or unarchive a chat. Set archived=true to move to archive, archived=false to move back to inbox\n\n### Parameters\n\n- `chatID: string`\n Chat ID. Input routes also accept the local chat ID from this Beeper Desktop installation when available.\n\n- `archived?: boolean`\n True to archive, false to unarchive\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nawait client.chats.archive('!NCdzlIaMjZUmvmvyHU:beeper.com')\n```",
+ "## archive\n\n`client.chats.archive(chatID: string, archived?: boolean): void`\n\n**post** `/v1/chats/{chatID}/archive`\n\nArchive or unarchive a chat. Set archived=true to move it to Archive, or archived=false to move it back to the inbox.\n\n### Parameters\n\n- `chatID: string`\n Chat ID. Input routes also accept the local chat ID from this installation when available.\n\n- `archived?: boolean`\n True to archive, false to unarchive\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nawait client.chats.archive('!NCdzlIaMjZUmvmvyHU:beeper.com')\n```",
perLanguage: {
typescript: {
method: 'client.chats.archive',
@@ -565,7 +978,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
cli: {
method: 'chats archive',
example:
- "beeper-desktop-cli chats archive \\\n --access-token 'My Access Token' \\\n --chat-id '!NCdzlIaMjZUmvmvyHU:beeper.com'",
+ "beeper-desktop chats archive \\\n --access-token 'My Access Token' \\\n --chat-id '!NCdzlIaMjZUmvmvyHU:beeper.com'",
},
php: {
method: 'chats->archive',
@@ -584,7 +997,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
httpMethod: 'patch',
summary: 'Update chat',
description:
- 'Update supported chat fields. Non-empty draft objects are accepted only when the current draft is empty. Send draft=null to clear the draft before setting new draft text or attachments.',
+ 'Update supported chat fields. Non-empty drafts are accepted only when the current draft is empty. Send draft=null to clear the draft before setting new draft text or attachments.',
stainlessPath: '(resource) chats > (method) update',
qualified: 'client.chats.update',
params: [
@@ -602,7 +1015,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
response:
"{ id: string; accountID: string; network: string; participants: object; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: object; description?: string; draft?: object; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: object; snooze?: object; unreadMentionsCount?: number; }",
markdown:
- "## update\n\n`client.chats.update(chatID: string, description?: string, draft?: { text: string; attachments?: object; }, imgURL?: string, isArchived?: boolean, isLowPriority?: boolean, isMuted?: boolean, isPinned?: boolean, messageExpirySeconds?: number, title?: string): { id: string; accountID: string; network: string; participants: object; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: object; description?: string; draft?: object; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: object; snooze?: object; unreadMentionsCount?: number; }`\n\n**patch** `/v1/chats/{chatID}`\n\nUpdate supported chat fields. Non-empty draft objects are accepted only when the current draft is empty. Send draft=null to clear the draft before setting new draft text or attachments.\n\n### Parameters\n\n- `chatID: string`\n Chat ID. Input routes also accept the local chat ID from this Beeper Desktop installation when available.\n\n- `description?: string`\n Group chat description/topic. Support depends on the chat account and chat permissions.\n\n- `draft?: { text: string; attachments?: object; }`\n Draft object to set or clear. Non-empty drafts are only accepted when the current draft is empty. Send draft=null to clear text and attachments together before setting a new draft.\n - `text: string`\n Draft text. Plain text and Markdown are converted to Matrix HTML with the same rules used by send and edit.\n - `attachments?: object`\n Draft attachments keyed by attachment ID. Each attachment must reference an uploadID returned by the upload file endpoint.\n\n- `imgURL?: string`\n Local filesystem path to a group chat avatar image. Support depends on the chat account and chat permissions.\n\n- `isArchived?: boolean`\n Archive or unarchive the chat.\n\n- `isLowPriority?: boolean`\n Mark or unmark the chat as low priority when supported by the account.\n\n- `isMuted?: boolean`\n Mute or unmute the chat.\n\n- `isPinned?: boolean`\n Pin or unpin the chat when supported by the account.\n\n- `messageExpirySeconds?: number`\n Disappearing-message timer in seconds, or null to clear when supported.\n\n- `title?: string`\n Custom chat title. Support depends on the chat account and chat permissions.\n\n### Returns\n\n- `{ id: string; accountID: string; network: string; participants: { hasMore: boolean; items: object[]; total: number; }; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: { allowedReactions?: string[]; archive?: boolean; attachments?: object; customEmojiReactions?: boolean; delete?: -2 | -1 | 0 | 1 | 2; deleteChat?: boolean; deleteChatForEveryone?: boolean; deleteForMe?: boolean; deleteMaxAge?: number; disappearingTimer?: { omitEmptyTimer?: boolean; timers?: number[]; types?: 'afterRead' | 'afterSend'[]; }; edit?: -2 | -1 | 0 | 1 | 2; editMaxAge?: number; editMaxCount?: number; formatting?: object; locationMessage?: -2 | -1 | 0 | 1 | 2; markAsUnread?: boolean; maxTextLength?: number; messageRequest?: { acceptWithButton?: -2 | -1 | 0 | 1 | 2; acceptWithMessage?: -2 | -1 | 0 | 1 | 2; }; participantActions?: { ban?: -2 | -1 | 0 | 1 | 2; invite?: -2 | -1 | 0 | 1 | 2; kick?: -2 | -1 | 0 | 1 | 2; leave?: -2 | -1 | 0 | 1 | 2; revokeInvite?: -2 | -1 | 0 | 1 | 2; }; poll?: -2 | -1 | 0 | 1 | 2; reaction?: -2 | -1 | 0 | 1 | 2; reactionCount?: number; readReceipts?: boolean; reply?: -2 | -1 | 0 | 1 | 2; state?: { avatar?: object; description?: object; disappearingTimer?: object; title?: object; }; thread?: -2 | -1 | 0 | 1 | 2; typingNotifications?: boolean; }; description?: string; draft?: { text: string; attachments?: object; }; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: { dismissOnIncomingMessage?: boolean; remindAt?: string; }; snooze?: { snoozeUntil?: string; userSnoozedAt?: string; }; unreadMentionsCount?: number; }`\n\n - `id: string`\n - `accountID: string`\n - `network: string`\n - `participants: { hasMore: boolean; items: { id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }[]; total: number; }`\n - `title: string`\n - `type: 'single' | 'group'`\n - `unreadCount: number`\n - `capabilities?: { allowedReactions?: string[]; archive?: boolean; attachments?: object; customEmojiReactions?: boolean; delete?: -2 | -1 | 0 | 1 | 2; deleteChat?: boolean; deleteChatForEveryone?: boolean; deleteForMe?: boolean; deleteMaxAge?: number; disappearingTimer?: { omitEmptyTimer?: boolean; timers?: number[]; types?: 'afterRead' | 'afterSend'[]; }; edit?: -2 | -1 | 0 | 1 | 2; editMaxAge?: number; editMaxCount?: number; formatting?: object; locationMessage?: -2 | -1 | 0 | 1 | 2; markAsUnread?: boolean; maxTextLength?: number; messageRequest?: { acceptWithButton?: -2 | -1 | 0 | 1 | 2; acceptWithMessage?: -2 | -1 | 0 | 1 | 2; }; participantActions?: { ban?: -2 | -1 | 0 | 1 | 2; invite?: -2 | -1 | 0 | 1 | 2; kick?: -2 | -1 | 0 | 1 | 2; leave?: -2 | -1 | 0 | 1 | 2; revokeInvite?: -2 | -1 | 0 | 1 | 2; }; poll?: -2 | -1 | 0 | 1 | 2; reaction?: -2 | -1 | 0 | 1 | 2; reactionCount?: number; readReceipts?: boolean; reply?: -2 | -1 | 0 | 1 | 2; state?: { avatar?: { level: -2 | -1 | 0 | 1 | 2; }; description?: { level: -2 | -1 | 0 | 1 | 2; }; disappearingTimer?: { level: -2 | -1 | 0 | 1 | 2; }; title?: { level: -2 | -1 | 0 | 1 | 2; }; }; thread?: -2 | -1 | 0 | 1 | 2; typingNotifications?: boolean; }`\n - `description?: string`\n - `draft?: { text: string; attachments?: object; }`\n - `imgURL?: string`\n - `isArchived?: boolean`\n - `isLowPriority?: boolean`\n - `isMarkedUnread?: boolean`\n - `isMuted?: boolean`\n - `isPinned?: boolean`\n - `isReadOnly?: boolean`\n - `lastActivity?: string`\n - `lastReadMessageSortKey?: string`\n - `localChatID?: string`\n - `messageExpirySeconds?: number`\n - `reminder?: { dismissOnIncomingMessage?: boolean; remindAt?: string; }`\n - `snooze?: { snoozeUntil?: string; userSnoozedAt?: string; }`\n - `unreadMentionsCount?: number`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst chat = await client.chats.update('!NCdzlIaMjZUmvmvyHU:beeper.com');\n\nconsole.log(chat);\n```",
+ "## update\n\n`client.chats.update(chatID: string, description?: string, draft?: { text: string; attachments?: object; }, imgURL?: string, isArchived?: boolean, isLowPriority?: boolean, isMuted?: boolean, isPinned?: boolean, messageExpirySeconds?: number, title?: string): { id: string; accountID: string; network: string; participants: object; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: object; description?: string; draft?: object; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: object; snooze?: object; unreadMentionsCount?: number; }`\n\n**patch** `/v1/chats/{chatID}`\n\nUpdate supported chat fields. Non-empty drafts are accepted only when the current draft is empty. Send draft=null to clear the draft before setting new draft text or attachments.\n\n### Parameters\n\n- `chatID: string`\n Chat ID. Input routes also accept the local chat ID from this installation when available.\n\n- `description?: string`\n Group chat description/topic. Support depends on the chat account and chat permissions.\n\n- `draft?: { text: string; attachments?: object; }`\n Draft object to set or clear. Non-empty drafts are only accepted when the current draft is empty. Send draft=null to clear text and attachments together before setting a new draft.\n - `text: string`\n Draft text. Plain text and Markdown are converted to Beeper rich text with the same rules used by send and edit.\n - `attachments?: object`\n Draft attachments keyed by attachment ID. Each attachment must reference an uploadID returned by the upload file endpoint.\n\n- `imgURL?: string`\n Local filesystem path to a group chat avatar image. Support depends on the chat account and chat permissions.\n\n- `isArchived?: boolean`\n Archive or unarchive the chat.\n\n- `isLowPriority?: boolean`\n Mark or unmark the chat as low priority when supported by the account.\n\n- `isMuted?: boolean`\n Mute or unmute the chat.\n\n- `isPinned?: boolean`\n Pin or unpin the chat when supported by the account.\n\n- `messageExpirySeconds?: number`\n Disappearing-message timer in seconds, or null to clear when supported.\n\n- `title?: string`\n Custom chat title. Support depends on the chat account and chat permissions.\n\n### Returns\n\n- `{ id: string; accountID: string; network: string; participants: { hasMore: boolean; items: object[]; total: number; }; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: { allowedReactions?: string[]; archive?: boolean; attachments?: object; customEmojiReactions?: boolean; delete?: -2 | -1 | 0 | 1 | 2; deleteChat?: boolean; deleteChatForEveryone?: boolean; deleteForMe?: boolean; deleteMaxAge?: number; disappearingTimer?: { omitEmptyTimer?: boolean; timers?: number[]; types?: 'afterRead' | 'afterSend'[]; }; edit?: -2 | -1 | 0 | 1 | 2; editMaxAge?: number; editMaxCount?: number; formatting?: object; locationMessage?: -2 | -1 | 0 | 1 | 2; markAsUnread?: boolean; maxTextLength?: number; messageRequest?: { acceptWithButton?: -2 | -1 | 0 | 1 | 2; acceptWithMessage?: -2 | -1 | 0 | 1 | 2; }; participantActions?: { ban?: -2 | -1 | 0 | 1 | 2; invite?: -2 | -1 | 0 | 1 | 2; kick?: -2 | -1 | 0 | 1 | 2; leave?: -2 | -1 | 0 | 1 | 2; revokeInvite?: -2 | -1 | 0 | 1 | 2; }; poll?: -2 | -1 | 0 | 1 | 2; reaction?: -2 | -1 | 0 | 1 | 2; reactionCount?: number; readReceipts?: boolean; reply?: -2 | -1 | 0 | 1 | 2; state?: { avatar?: object; description?: object; disappearingTimer?: object; title?: object; }; thread?: -2 | -1 | 0 | 1 | 2; typingNotifications?: boolean; }; description?: string; draft?: { text: string; attachments?: object; }; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: { dismissOnIncomingMessage?: boolean; remindAt?: string; }; snooze?: { snoozeUntil?: string; userSnoozedAt?: string; }; unreadMentionsCount?: number; }`\n\n - `id: string`\n - `accountID: string`\n - `network: string`\n - `participants: { hasMore: boolean; items: { id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }[]; total: number; }`\n - `title: string`\n - `type: 'single' | 'group'`\n - `unreadCount: number`\n - `capabilities?: { allowedReactions?: string[]; archive?: boolean; attachments?: object; customEmojiReactions?: boolean; delete?: -2 | -1 | 0 | 1 | 2; deleteChat?: boolean; deleteChatForEveryone?: boolean; deleteForMe?: boolean; deleteMaxAge?: number; disappearingTimer?: { omitEmptyTimer?: boolean; timers?: number[]; types?: 'afterRead' | 'afterSend'[]; }; edit?: -2 | -1 | 0 | 1 | 2; editMaxAge?: number; editMaxCount?: number; formatting?: object; locationMessage?: -2 | -1 | 0 | 1 | 2; markAsUnread?: boolean; maxTextLength?: number; messageRequest?: { acceptWithButton?: -2 | -1 | 0 | 1 | 2; acceptWithMessage?: -2 | -1 | 0 | 1 | 2; }; participantActions?: { ban?: -2 | -1 | 0 | 1 | 2; invite?: -2 | -1 | 0 | 1 | 2; kick?: -2 | -1 | 0 | 1 | 2; leave?: -2 | -1 | 0 | 1 | 2; revokeInvite?: -2 | -1 | 0 | 1 | 2; }; poll?: -2 | -1 | 0 | 1 | 2; reaction?: -2 | -1 | 0 | 1 | 2; reactionCount?: number; readReceipts?: boolean; reply?: -2 | -1 | 0 | 1 | 2; state?: { avatar?: { level: -2 | -1 | 0 | 1 | 2; }; description?: { level: -2 | -1 | 0 | 1 | 2; }; disappearingTimer?: { level: -2 | -1 | 0 | 1 | 2; }; title?: { level: -2 | -1 | 0 | 1 | 2; }; }; thread?: -2 | -1 | 0 | 1 | 2; typingNotifications?: boolean; }`\n - `description?: string`\n - `draft?: { text: string; attachments?: object; }`\n - `imgURL?: string`\n - `isArchived?: boolean`\n - `isLowPriority?: boolean`\n - `isMarkedUnread?: boolean`\n - `isMuted?: boolean`\n - `isPinned?: boolean`\n - `isReadOnly?: boolean`\n - `lastActivity?: string`\n - `lastReadMessageSortKey?: string`\n - `localChatID?: string`\n - `messageExpirySeconds?: number`\n - `reminder?: { dismissOnIncomingMessage?: boolean; remindAt?: string; }`\n - `snooze?: { snoozeUntil?: string; userSnoozedAt?: string; }`\n - `unreadMentionsCount?: number`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst chat = await client.chats.update('!NCdzlIaMjZUmvmvyHU:beeper.com');\n\nconsole.log(chat);\n```",
perLanguage: {
typescript: {
method: 'client.chats.update',
@@ -622,7 +1035,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
cli: {
method: 'chats update',
example:
- "beeper-desktop-cli chats update \\\n --access-token 'My Access Token' \\\n --chat-id '!NCdzlIaMjZUmvmvyHU:beeper.com'",
+ "beeper-desktop chats update \\\n --access-token 'My Access Token' \\\n --chat-id '!NCdzlIaMjZUmvmvyHU:beeper.com'",
},
php: {
method: 'chats->update',
@@ -647,7 +1060,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
response:
"{ id: string; accountID: string; network: string; participants: object; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: object; description?: string; draft?: object; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: object; snooze?: object; unreadMentionsCount?: number; }",
markdown:
- "## mark_read\n\n`client.chats.markRead(chatID: string, messageID?: string): { id: string; accountID: string; network: string; participants: object; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: object; description?: string; draft?: object; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: object; snooze?: object; unreadMentionsCount?: number; }`\n\n**post** `/v1/chats/{chatID}/read`\n\nMark a chat as read, optionally through a specific message ID.\n\n### Parameters\n\n- `chatID: string`\n Chat ID. Input routes also accept the local chat ID from this Beeper Desktop installation when available.\n\n- `messageID?: string`\n Optional message ID to mark read through.\n\n### Returns\n\n- `{ id: string; accountID: string; network: string; participants: { hasMore: boolean; items: object[]; total: number; }; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: { allowedReactions?: string[]; archive?: boolean; attachments?: object; customEmojiReactions?: boolean; delete?: -2 | -1 | 0 | 1 | 2; deleteChat?: boolean; deleteChatForEveryone?: boolean; deleteForMe?: boolean; deleteMaxAge?: number; disappearingTimer?: { omitEmptyTimer?: boolean; timers?: number[]; types?: 'afterRead' | 'afterSend'[]; }; edit?: -2 | -1 | 0 | 1 | 2; editMaxAge?: number; editMaxCount?: number; formatting?: object; locationMessage?: -2 | -1 | 0 | 1 | 2; markAsUnread?: boolean; maxTextLength?: number; messageRequest?: { acceptWithButton?: -2 | -1 | 0 | 1 | 2; acceptWithMessage?: -2 | -1 | 0 | 1 | 2; }; participantActions?: { ban?: -2 | -1 | 0 | 1 | 2; invite?: -2 | -1 | 0 | 1 | 2; kick?: -2 | -1 | 0 | 1 | 2; leave?: -2 | -1 | 0 | 1 | 2; revokeInvite?: -2 | -1 | 0 | 1 | 2; }; poll?: -2 | -1 | 0 | 1 | 2; reaction?: -2 | -1 | 0 | 1 | 2; reactionCount?: number; readReceipts?: boolean; reply?: -2 | -1 | 0 | 1 | 2; state?: { avatar?: object; description?: object; disappearingTimer?: object; title?: object; }; thread?: -2 | -1 | 0 | 1 | 2; typingNotifications?: boolean; }; description?: string; draft?: { text: string; attachments?: object; }; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: { dismissOnIncomingMessage?: boolean; remindAt?: string; }; snooze?: { snoozeUntil?: string; userSnoozedAt?: string; }; unreadMentionsCount?: number; }`\n\n - `id: string`\n - `accountID: string`\n - `network: string`\n - `participants: { hasMore: boolean; items: { id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }[]; total: number; }`\n - `title: string`\n - `type: 'single' | 'group'`\n - `unreadCount: number`\n - `capabilities?: { allowedReactions?: string[]; archive?: boolean; attachments?: object; customEmojiReactions?: boolean; delete?: -2 | -1 | 0 | 1 | 2; deleteChat?: boolean; deleteChatForEveryone?: boolean; deleteForMe?: boolean; deleteMaxAge?: number; disappearingTimer?: { omitEmptyTimer?: boolean; timers?: number[]; types?: 'afterRead' | 'afterSend'[]; }; edit?: -2 | -1 | 0 | 1 | 2; editMaxAge?: number; editMaxCount?: number; formatting?: object; locationMessage?: -2 | -1 | 0 | 1 | 2; markAsUnread?: boolean; maxTextLength?: number; messageRequest?: { acceptWithButton?: -2 | -1 | 0 | 1 | 2; acceptWithMessage?: -2 | -1 | 0 | 1 | 2; }; participantActions?: { ban?: -2 | -1 | 0 | 1 | 2; invite?: -2 | -1 | 0 | 1 | 2; kick?: -2 | -1 | 0 | 1 | 2; leave?: -2 | -1 | 0 | 1 | 2; revokeInvite?: -2 | -1 | 0 | 1 | 2; }; poll?: -2 | -1 | 0 | 1 | 2; reaction?: -2 | -1 | 0 | 1 | 2; reactionCount?: number; readReceipts?: boolean; reply?: -2 | -1 | 0 | 1 | 2; state?: { avatar?: { level: -2 | -1 | 0 | 1 | 2; }; description?: { level: -2 | -1 | 0 | 1 | 2; }; disappearingTimer?: { level: -2 | -1 | 0 | 1 | 2; }; title?: { level: -2 | -1 | 0 | 1 | 2; }; }; thread?: -2 | -1 | 0 | 1 | 2; typingNotifications?: boolean; }`\n - `description?: string`\n - `draft?: { text: string; attachments?: object; }`\n - `imgURL?: string`\n - `isArchived?: boolean`\n - `isLowPriority?: boolean`\n - `isMarkedUnread?: boolean`\n - `isMuted?: boolean`\n - `isPinned?: boolean`\n - `isReadOnly?: boolean`\n - `lastActivity?: string`\n - `lastReadMessageSortKey?: string`\n - `localChatID?: string`\n - `messageExpirySeconds?: number`\n - `reminder?: { dismissOnIncomingMessage?: boolean; remindAt?: string; }`\n - `snooze?: { snoozeUntil?: string; userSnoozedAt?: string; }`\n - `unreadMentionsCount?: number`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst chat = await client.chats.markRead('!NCdzlIaMjZUmvmvyHU:beeper.com');\n\nconsole.log(chat);\n```",
+ "## mark_read\n\n`client.chats.markRead(chatID: string, messageID?: string): { id: string; accountID: string; network: string; participants: object; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: object; description?: string; draft?: object; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: object; snooze?: object; unreadMentionsCount?: number; }`\n\n**post** `/v1/chats/{chatID}/read`\n\nMark a chat as read, optionally through a specific message ID.\n\n### Parameters\n\n- `chatID: string`\n Chat ID. Input routes also accept the local chat ID from this installation when available.\n\n- `messageID?: string`\n Optional message ID to mark read through.\n\n### Returns\n\n- `{ id: string; accountID: string; network: string; participants: { hasMore: boolean; items: object[]; total: number; }; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: { allowedReactions?: string[]; archive?: boolean; attachments?: object; customEmojiReactions?: boolean; delete?: -2 | -1 | 0 | 1 | 2; deleteChat?: boolean; deleteChatForEveryone?: boolean; deleteForMe?: boolean; deleteMaxAge?: number; disappearingTimer?: { omitEmptyTimer?: boolean; timers?: number[]; types?: 'afterRead' | 'afterSend'[]; }; edit?: -2 | -1 | 0 | 1 | 2; editMaxAge?: number; editMaxCount?: number; formatting?: object; locationMessage?: -2 | -1 | 0 | 1 | 2; markAsUnread?: boolean; maxTextLength?: number; messageRequest?: { acceptWithButton?: -2 | -1 | 0 | 1 | 2; acceptWithMessage?: -2 | -1 | 0 | 1 | 2; }; participantActions?: { ban?: -2 | -1 | 0 | 1 | 2; invite?: -2 | -1 | 0 | 1 | 2; kick?: -2 | -1 | 0 | 1 | 2; leave?: -2 | -1 | 0 | 1 | 2; revokeInvite?: -2 | -1 | 0 | 1 | 2; }; poll?: -2 | -1 | 0 | 1 | 2; reaction?: -2 | -1 | 0 | 1 | 2; reactionCount?: number; readReceipts?: boolean; reply?: -2 | -1 | 0 | 1 | 2; state?: { avatar?: object; description?: object; disappearingTimer?: object; title?: object; }; thread?: -2 | -1 | 0 | 1 | 2; typingNotifications?: boolean; }; description?: string; draft?: { text: string; attachments?: object; }; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: { dismissOnIncomingMessage?: boolean; remindAt?: string; }; snooze?: { snoozeUntil?: string; userSnoozedAt?: string; }; unreadMentionsCount?: number; }`\n\n - `id: string`\n - `accountID: string`\n - `network: string`\n - `participants: { hasMore: boolean; items: { id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }[]; total: number; }`\n - `title: string`\n - `type: 'single' | 'group'`\n - `unreadCount: number`\n - `capabilities?: { allowedReactions?: string[]; archive?: boolean; attachments?: object; customEmojiReactions?: boolean; delete?: -2 | -1 | 0 | 1 | 2; deleteChat?: boolean; deleteChatForEveryone?: boolean; deleteForMe?: boolean; deleteMaxAge?: number; disappearingTimer?: { omitEmptyTimer?: boolean; timers?: number[]; types?: 'afterRead' | 'afterSend'[]; }; edit?: -2 | -1 | 0 | 1 | 2; editMaxAge?: number; editMaxCount?: number; formatting?: object; locationMessage?: -2 | -1 | 0 | 1 | 2; markAsUnread?: boolean; maxTextLength?: number; messageRequest?: { acceptWithButton?: -2 | -1 | 0 | 1 | 2; acceptWithMessage?: -2 | -1 | 0 | 1 | 2; }; participantActions?: { ban?: -2 | -1 | 0 | 1 | 2; invite?: -2 | -1 | 0 | 1 | 2; kick?: -2 | -1 | 0 | 1 | 2; leave?: -2 | -1 | 0 | 1 | 2; revokeInvite?: -2 | -1 | 0 | 1 | 2; }; poll?: -2 | -1 | 0 | 1 | 2; reaction?: -2 | -1 | 0 | 1 | 2; reactionCount?: number; readReceipts?: boolean; reply?: -2 | -1 | 0 | 1 | 2; state?: { avatar?: { level: -2 | -1 | 0 | 1 | 2; }; description?: { level: -2 | -1 | 0 | 1 | 2; }; disappearingTimer?: { level: -2 | -1 | 0 | 1 | 2; }; title?: { level: -2 | -1 | 0 | 1 | 2; }; }; thread?: -2 | -1 | 0 | 1 | 2; typingNotifications?: boolean; }`\n - `description?: string`\n - `draft?: { text: string; attachments?: object; }`\n - `imgURL?: string`\n - `isArchived?: boolean`\n - `isLowPriority?: boolean`\n - `isMarkedUnread?: boolean`\n - `isMuted?: boolean`\n - `isPinned?: boolean`\n - `isReadOnly?: boolean`\n - `lastActivity?: string`\n - `lastReadMessageSortKey?: string`\n - `localChatID?: string`\n - `messageExpirySeconds?: number`\n - `reminder?: { dismissOnIncomingMessage?: boolean; remindAt?: string; }`\n - `snooze?: { snoozeUntil?: string; userSnoozedAt?: string; }`\n - `unreadMentionsCount?: number`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst chat = await client.chats.markRead('!NCdzlIaMjZUmvmvyHU:beeper.com');\n\nconsole.log(chat);\n```",
perLanguage: {
typescript: {
method: 'client.chats.markRead',
@@ -667,7 +1080,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
cli: {
method: 'chats mark_read',
example:
- "beeper-desktop-cli chats mark-read \\\n --access-token 'My Access Token' \\\n --chat-id '!NCdzlIaMjZUmvmvyHU:beeper.com'",
+ "beeper-desktop chats mark-read \\\n --access-token 'My Access Token' \\\n --chat-id '!NCdzlIaMjZUmvmvyHU:beeper.com'",
},
php: {
method: 'chats->markRead',
@@ -692,7 +1105,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
response:
"{ id: string; accountID: string; network: string; participants: object; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: object; description?: string; draft?: object; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: object; snooze?: object; unreadMentionsCount?: number; }",
markdown:
- "## mark_unread\n\n`client.chats.markUnread(chatID: string, messageID?: string): { id: string; accountID: string; network: string; participants: object; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: object; description?: string; draft?: object; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: object; snooze?: object; unreadMentionsCount?: number; }`\n\n**post** `/v1/chats/{chatID}/unread`\n\nMark a chat as unread, optionally from a specific message ID.\n\n### Parameters\n\n- `chatID: string`\n Chat ID. Input routes also accept the local chat ID from this Beeper Desktop installation when available.\n\n- `messageID?: string`\n Optional message ID to mark unread from.\n\n### Returns\n\n- `{ id: string; accountID: string; network: string; participants: { hasMore: boolean; items: object[]; total: number; }; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: { allowedReactions?: string[]; archive?: boolean; attachments?: object; customEmojiReactions?: boolean; delete?: -2 | -1 | 0 | 1 | 2; deleteChat?: boolean; deleteChatForEveryone?: boolean; deleteForMe?: boolean; deleteMaxAge?: number; disappearingTimer?: { omitEmptyTimer?: boolean; timers?: number[]; types?: 'afterRead' | 'afterSend'[]; }; edit?: -2 | -1 | 0 | 1 | 2; editMaxAge?: number; editMaxCount?: number; formatting?: object; locationMessage?: -2 | -1 | 0 | 1 | 2; markAsUnread?: boolean; maxTextLength?: number; messageRequest?: { acceptWithButton?: -2 | -1 | 0 | 1 | 2; acceptWithMessage?: -2 | -1 | 0 | 1 | 2; }; participantActions?: { ban?: -2 | -1 | 0 | 1 | 2; invite?: -2 | -1 | 0 | 1 | 2; kick?: -2 | -1 | 0 | 1 | 2; leave?: -2 | -1 | 0 | 1 | 2; revokeInvite?: -2 | -1 | 0 | 1 | 2; }; poll?: -2 | -1 | 0 | 1 | 2; reaction?: -2 | -1 | 0 | 1 | 2; reactionCount?: number; readReceipts?: boolean; reply?: -2 | -1 | 0 | 1 | 2; state?: { avatar?: object; description?: object; disappearingTimer?: object; title?: object; }; thread?: -2 | -1 | 0 | 1 | 2; typingNotifications?: boolean; }; description?: string; draft?: { text: string; attachments?: object; }; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: { dismissOnIncomingMessage?: boolean; remindAt?: string; }; snooze?: { snoozeUntil?: string; userSnoozedAt?: string; }; unreadMentionsCount?: number; }`\n\n - `id: string`\n - `accountID: string`\n - `network: string`\n - `participants: { hasMore: boolean; items: { id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }[]; total: number; }`\n - `title: string`\n - `type: 'single' | 'group'`\n - `unreadCount: number`\n - `capabilities?: { allowedReactions?: string[]; archive?: boolean; attachments?: object; customEmojiReactions?: boolean; delete?: -2 | -1 | 0 | 1 | 2; deleteChat?: boolean; deleteChatForEveryone?: boolean; deleteForMe?: boolean; deleteMaxAge?: number; disappearingTimer?: { omitEmptyTimer?: boolean; timers?: number[]; types?: 'afterRead' | 'afterSend'[]; }; edit?: -2 | -1 | 0 | 1 | 2; editMaxAge?: number; editMaxCount?: number; formatting?: object; locationMessage?: -2 | -1 | 0 | 1 | 2; markAsUnread?: boolean; maxTextLength?: number; messageRequest?: { acceptWithButton?: -2 | -1 | 0 | 1 | 2; acceptWithMessage?: -2 | -1 | 0 | 1 | 2; }; participantActions?: { ban?: -2 | -1 | 0 | 1 | 2; invite?: -2 | -1 | 0 | 1 | 2; kick?: -2 | -1 | 0 | 1 | 2; leave?: -2 | -1 | 0 | 1 | 2; revokeInvite?: -2 | -1 | 0 | 1 | 2; }; poll?: -2 | -1 | 0 | 1 | 2; reaction?: -2 | -1 | 0 | 1 | 2; reactionCount?: number; readReceipts?: boolean; reply?: -2 | -1 | 0 | 1 | 2; state?: { avatar?: { level: -2 | -1 | 0 | 1 | 2; }; description?: { level: -2 | -1 | 0 | 1 | 2; }; disappearingTimer?: { level: -2 | -1 | 0 | 1 | 2; }; title?: { level: -2 | -1 | 0 | 1 | 2; }; }; thread?: -2 | -1 | 0 | 1 | 2; typingNotifications?: boolean; }`\n - `description?: string`\n - `draft?: { text: string; attachments?: object; }`\n - `imgURL?: string`\n - `isArchived?: boolean`\n - `isLowPriority?: boolean`\n - `isMarkedUnread?: boolean`\n - `isMuted?: boolean`\n - `isPinned?: boolean`\n - `isReadOnly?: boolean`\n - `lastActivity?: string`\n - `lastReadMessageSortKey?: string`\n - `localChatID?: string`\n - `messageExpirySeconds?: number`\n - `reminder?: { dismissOnIncomingMessage?: boolean; remindAt?: string; }`\n - `snooze?: { snoozeUntil?: string; userSnoozedAt?: string; }`\n - `unreadMentionsCount?: number`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst chat = await client.chats.markUnread('!NCdzlIaMjZUmvmvyHU:beeper.com');\n\nconsole.log(chat);\n```",
+ "## mark_unread\n\n`client.chats.markUnread(chatID: string, messageID?: string): { id: string; accountID: string; network: string; participants: object; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: object; description?: string; draft?: object; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: object; snooze?: object; unreadMentionsCount?: number; }`\n\n**post** `/v1/chats/{chatID}/unread`\n\nMark a chat as unread, optionally from a specific message ID.\n\n### Parameters\n\n- `chatID: string`\n Chat ID. Input routes also accept the local chat ID from this installation when available.\n\n- `messageID?: string`\n Optional message ID to mark unread from.\n\n### Returns\n\n- `{ id: string; accountID: string; network: string; participants: { hasMore: boolean; items: object[]; total: number; }; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: { allowedReactions?: string[]; archive?: boolean; attachments?: object; customEmojiReactions?: boolean; delete?: -2 | -1 | 0 | 1 | 2; deleteChat?: boolean; deleteChatForEveryone?: boolean; deleteForMe?: boolean; deleteMaxAge?: number; disappearingTimer?: { omitEmptyTimer?: boolean; timers?: number[]; types?: 'afterRead' | 'afterSend'[]; }; edit?: -2 | -1 | 0 | 1 | 2; editMaxAge?: number; editMaxCount?: number; formatting?: object; locationMessage?: -2 | -1 | 0 | 1 | 2; markAsUnread?: boolean; maxTextLength?: number; messageRequest?: { acceptWithButton?: -2 | -1 | 0 | 1 | 2; acceptWithMessage?: -2 | -1 | 0 | 1 | 2; }; participantActions?: { ban?: -2 | -1 | 0 | 1 | 2; invite?: -2 | -1 | 0 | 1 | 2; kick?: -2 | -1 | 0 | 1 | 2; leave?: -2 | -1 | 0 | 1 | 2; revokeInvite?: -2 | -1 | 0 | 1 | 2; }; poll?: -2 | -1 | 0 | 1 | 2; reaction?: -2 | -1 | 0 | 1 | 2; reactionCount?: number; readReceipts?: boolean; reply?: -2 | -1 | 0 | 1 | 2; state?: { avatar?: object; description?: object; disappearingTimer?: object; title?: object; }; thread?: -2 | -1 | 0 | 1 | 2; typingNotifications?: boolean; }; description?: string; draft?: { text: string; attachments?: object; }; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: { dismissOnIncomingMessage?: boolean; remindAt?: string; }; snooze?: { snoozeUntil?: string; userSnoozedAt?: string; }; unreadMentionsCount?: number; }`\n\n - `id: string`\n - `accountID: string`\n - `network: string`\n - `participants: { hasMore: boolean; items: { id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }[]; total: number; }`\n - `title: string`\n - `type: 'single' | 'group'`\n - `unreadCount: number`\n - `capabilities?: { allowedReactions?: string[]; archive?: boolean; attachments?: object; customEmojiReactions?: boolean; delete?: -2 | -1 | 0 | 1 | 2; deleteChat?: boolean; deleteChatForEveryone?: boolean; deleteForMe?: boolean; deleteMaxAge?: number; disappearingTimer?: { omitEmptyTimer?: boolean; timers?: number[]; types?: 'afterRead' | 'afterSend'[]; }; edit?: -2 | -1 | 0 | 1 | 2; editMaxAge?: number; editMaxCount?: number; formatting?: object; locationMessage?: -2 | -1 | 0 | 1 | 2; markAsUnread?: boolean; maxTextLength?: number; messageRequest?: { acceptWithButton?: -2 | -1 | 0 | 1 | 2; acceptWithMessage?: -2 | -1 | 0 | 1 | 2; }; participantActions?: { ban?: -2 | -1 | 0 | 1 | 2; invite?: -2 | -1 | 0 | 1 | 2; kick?: -2 | -1 | 0 | 1 | 2; leave?: -2 | -1 | 0 | 1 | 2; revokeInvite?: -2 | -1 | 0 | 1 | 2; }; poll?: -2 | -1 | 0 | 1 | 2; reaction?: -2 | -1 | 0 | 1 | 2; reactionCount?: number; readReceipts?: boolean; reply?: -2 | -1 | 0 | 1 | 2; state?: { avatar?: { level: -2 | -1 | 0 | 1 | 2; }; description?: { level: -2 | -1 | 0 | 1 | 2; }; disappearingTimer?: { level: -2 | -1 | 0 | 1 | 2; }; title?: { level: -2 | -1 | 0 | 1 | 2; }; }; thread?: -2 | -1 | 0 | 1 | 2; typingNotifications?: boolean; }`\n - `description?: string`\n - `draft?: { text: string; attachments?: object; }`\n - `imgURL?: string`\n - `isArchived?: boolean`\n - `isLowPriority?: boolean`\n - `isMarkedUnread?: boolean`\n - `isMuted?: boolean`\n - `isPinned?: boolean`\n - `isReadOnly?: boolean`\n - `lastActivity?: string`\n - `lastReadMessageSortKey?: string`\n - `localChatID?: string`\n - `messageExpirySeconds?: number`\n - `reminder?: { dismissOnIncomingMessage?: boolean; remindAt?: string; }`\n - `snooze?: { snoozeUntil?: string; userSnoozedAt?: string; }`\n - `unreadMentionsCount?: number`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst chat = await client.chats.markUnread('!NCdzlIaMjZUmvmvyHU:beeper.com');\n\nconsole.log(chat);\n```",
perLanguage: {
typescript: {
method: 'client.chats.markUnread',
@@ -712,7 +1125,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
cli: {
method: 'chats mark_unread',
example:
- "beeper-desktop-cli chats mark-unread \\\n --access-token 'My Access Token' \\\n --chat-id '!NCdzlIaMjZUmvmvyHU:beeper.com'",
+ "beeper-desktop chats mark-unread \\\n --access-token 'My Access Token' \\\n --chat-id '!NCdzlIaMjZUmvmvyHU:beeper.com'",
},
php: {
method: 'chats->markUnread',
@@ -731,14 +1144,14 @@ const EMBEDDED_METHODS: MethodEntry[] = [
httpMethod: 'post',
summary: 'Notify anyway',
description:
- 'Force a delivery notification when supported by the underlying network. Currently intended for iMessage on macOS; unsupported networks return an error.',
+ 'Send a notification despite the recipient focus state when the network supports it. Currently intended for iMessage on macOS; unsupported networks return an error.',
stainlessPath: '(resource) chats > (method) notify_anyway',
qualified: 'client.chats.notifyAnyway',
params: ['chatID: string;'],
response:
"{ id: string; accountID: string; network: string; participants: object; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: object; description?: string; draft?: object; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: object; snooze?: object; unreadMentionsCount?: number; }",
markdown:
- "## notify_anyway\n\n`client.chats.notifyAnyway(chatID: string): { id: string; accountID: string; network: string; participants: object; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: object; description?: string; draft?: object; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: object; snooze?: object; unreadMentionsCount?: number; }`\n\n**post** `/v1/chats/{chatID}/notify-anyway`\n\nForce a delivery notification when supported by the underlying network. Currently intended for iMessage on macOS; unsupported networks return an error.\n\n### Parameters\n\n- `chatID: string`\n Chat ID. Input routes also accept the local chat ID from this Beeper Desktop installation when available.\n\n### Returns\n\n- `{ id: string; accountID: string; network: string; participants: { hasMore: boolean; items: object[]; total: number; }; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: { allowedReactions?: string[]; archive?: boolean; attachments?: object; customEmojiReactions?: boolean; delete?: -2 | -1 | 0 | 1 | 2; deleteChat?: boolean; deleteChatForEveryone?: boolean; deleteForMe?: boolean; deleteMaxAge?: number; disappearingTimer?: { omitEmptyTimer?: boolean; timers?: number[]; types?: 'afterRead' | 'afterSend'[]; }; edit?: -2 | -1 | 0 | 1 | 2; editMaxAge?: number; editMaxCount?: number; formatting?: object; locationMessage?: -2 | -1 | 0 | 1 | 2; markAsUnread?: boolean; maxTextLength?: number; messageRequest?: { acceptWithButton?: -2 | -1 | 0 | 1 | 2; acceptWithMessage?: -2 | -1 | 0 | 1 | 2; }; participantActions?: { ban?: -2 | -1 | 0 | 1 | 2; invite?: -2 | -1 | 0 | 1 | 2; kick?: -2 | -1 | 0 | 1 | 2; leave?: -2 | -1 | 0 | 1 | 2; revokeInvite?: -2 | -1 | 0 | 1 | 2; }; poll?: -2 | -1 | 0 | 1 | 2; reaction?: -2 | -1 | 0 | 1 | 2; reactionCount?: number; readReceipts?: boolean; reply?: -2 | -1 | 0 | 1 | 2; state?: { avatar?: object; description?: object; disappearingTimer?: object; title?: object; }; thread?: -2 | -1 | 0 | 1 | 2; typingNotifications?: boolean; }; description?: string; draft?: { text: string; attachments?: object; }; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: { dismissOnIncomingMessage?: boolean; remindAt?: string; }; snooze?: { snoozeUntil?: string; userSnoozedAt?: string; }; unreadMentionsCount?: number; }`\n\n - `id: string`\n - `accountID: string`\n - `network: string`\n - `participants: { hasMore: boolean; items: { id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }[]; total: number; }`\n - `title: string`\n - `type: 'single' | 'group'`\n - `unreadCount: number`\n - `capabilities?: { allowedReactions?: string[]; archive?: boolean; attachments?: object; customEmojiReactions?: boolean; delete?: -2 | -1 | 0 | 1 | 2; deleteChat?: boolean; deleteChatForEveryone?: boolean; deleteForMe?: boolean; deleteMaxAge?: number; disappearingTimer?: { omitEmptyTimer?: boolean; timers?: number[]; types?: 'afterRead' | 'afterSend'[]; }; edit?: -2 | -1 | 0 | 1 | 2; editMaxAge?: number; editMaxCount?: number; formatting?: object; locationMessage?: -2 | -1 | 0 | 1 | 2; markAsUnread?: boolean; maxTextLength?: number; messageRequest?: { acceptWithButton?: -2 | -1 | 0 | 1 | 2; acceptWithMessage?: -2 | -1 | 0 | 1 | 2; }; participantActions?: { ban?: -2 | -1 | 0 | 1 | 2; invite?: -2 | -1 | 0 | 1 | 2; kick?: -2 | -1 | 0 | 1 | 2; leave?: -2 | -1 | 0 | 1 | 2; revokeInvite?: -2 | -1 | 0 | 1 | 2; }; poll?: -2 | -1 | 0 | 1 | 2; reaction?: -2 | -1 | 0 | 1 | 2; reactionCount?: number; readReceipts?: boolean; reply?: -2 | -1 | 0 | 1 | 2; state?: { avatar?: { level: -2 | -1 | 0 | 1 | 2; }; description?: { level: -2 | -1 | 0 | 1 | 2; }; disappearingTimer?: { level: -2 | -1 | 0 | 1 | 2; }; title?: { level: -2 | -1 | 0 | 1 | 2; }; }; thread?: -2 | -1 | 0 | 1 | 2; typingNotifications?: boolean; }`\n - `description?: string`\n - `draft?: { text: string; attachments?: object; }`\n - `imgURL?: string`\n - `isArchived?: boolean`\n - `isLowPriority?: boolean`\n - `isMarkedUnread?: boolean`\n - `isMuted?: boolean`\n - `isPinned?: boolean`\n - `isReadOnly?: boolean`\n - `lastActivity?: string`\n - `lastReadMessageSortKey?: string`\n - `localChatID?: string`\n - `messageExpirySeconds?: number`\n - `reminder?: { dismissOnIncomingMessage?: boolean; remindAt?: string; }`\n - `snooze?: { snoozeUntil?: string; userSnoozedAt?: string; }`\n - `unreadMentionsCount?: number`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst chat = await client.chats.notifyAnyway('!NCdzlIaMjZUmvmvyHU:beeper.com');\n\nconsole.log(chat);\n```",
+ "## notify_anyway\n\n`client.chats.notifyAnyway(chatID: string): { id: string; accountID: string; network: string; participants: object; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: object; description?: string; draft?: object; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: object; snooze?: object; unreadMentionsCount?: number; }`\n\n**post** `/v1/chats/{chatID}/notify-anyway`\n\nSend a notification despite the recipient focus state when the network supports it. Currently intended for iMessage on macOS; unsupported networks return an error.\n\n### Parameters\n\n- `chatID: string`\n Chat ID. Input routes also accept the local chat ID from this installation when available.\n\n### Returns\n\n- `{ id: string; accountID: string; network: string; participants: { hasMore: boolean; items: object[]; total: number; }; title: string; type: 'single' | 'group'; unreadCount: number; capabilities?: { allowedReactions?: string[]; archive?: boolean; attachments?: object; customEmojiReactions?: boolean; delete?: -2 | -1 | 0 | 1 | 2; deleteChat?: boolean; deleteChatForEveryone?: boolean; deleteForMe?: boolean; deleteMaxAge?: number; disappearingTimer?: { omitEmptyTimer?: boolean; timers?: number[]; types?: 'afterRead' | 'afterSend'[]; }; edit?: -2 | -1 | 0 | 1 | 2; editMaxAge?: number; editMaxCount?: number; formatting?: object; locationMessage?: -2 | -1 | 0 | 1 | 2; markAsUnread?: boolean; maxTextLength?: number; messageRequest?: { acceptWithButton?: -2 | -1 | 0 | 1 | 2; acceptWithMessage?: -2 | -1 | 0 | 1 | 2; }; participantActions?: { ban?: -2 | -1 | 0 | 1 | 2; invite?: -2 | -1 | 0 | 1 | 2; kick?: -2 | -1 | 0 | 1 | 2; leave?: -2 | -1 | 0 | 1 | 2; revokeInvite?: -2 | -1 | 0 | 1 | 2; }; poll?: -2 | -1 | 0 | 1 | 2; reaction?: -2 | -1 | 0 | 1 | 2; reactionCount?: number; readReceipts?: boolean; reply?: -2 | -1 | 0 | 1 | 2; state?: { avatar?: object; description?: object; disappearingTimer?: object; title?: object; }; thread?: -2 | -1 | 0 | 1 | 2; typingNotifications?: boolean; }; description?: string; draft?: { text: string; attachments?: object; }; imgURL?: string; isArchived?: boolean; isLowPriority?: boolean; isMarkedUnread?: boolean; isMuted?: boolean; isPinned?: boolean; isReadOnly?: boolean; lastActivity?: string; lastReadMessageSortKey?: string; localChatID?: string; messageExpirySeconds?: number; reminder?: { dismissOnIncomingMessage?: boolean; remindAt?: string; }; snooze?: { snoozeUntil?: string; userSnoozedAt?: string; }; unreadMentionsCount?: number; }`\n\n - `id: string`\n - `accountID: string`\n - `network: string`\n - `participants: { hasMore: boolean; items: { id: string; cannotMessage?: boolean; email?: string; fullName?: string; imgURL?: string; isSelf?: boolean; phoneNumber?: string; username?: string; }[]; total: number; }`\n - `title: string`\n - `type: 'single' | 'group'`\n - `unreadCount: number`\n - `capabilities?: { allowedReactions?: string[]; archive?: boolean; attachments?: object; customEmojiReactions?: boolean; delete?: -2 | -1 | 0 | 1 | 2; deleteChat?: boolean; deleteChatForEveryone?: boolean; deleteForMe?: boolean; deleteMaxAge?: number; disappearingTimer?: { omitEmptyTimer?: boolean; timers?: number[]; types?: 'afterRead' | 'afterSend'[]; }; edit?: -2 | -1 | 0 | 1 | 2; editMaxAge?: number; editMaxCount?: number; formatting?: object; locationMessage?: -2 | -1 | 0 | 1 | 2; markAsUnread?: boolean; maxTextLength?: number; messageRequest?: { acceptWithButton?: -2 | -1 | 0 | 1 | 2; acceptWithMessage?: -2 | -1 | 0 | 1 | 2; }; participantActions?: { ban?: -2 | -1 | 0 | 1 | 2; invite?: -2 | -1 | 0 | 1 | 2; kick?: -2 | -1 | 0 | 1 | 2; leave?: -2 | -1 | 0 | 1 | 2; revokeInvite?: -2 | -1 | 0 | 1 | 2; }; poll?: -2 | -1 | 0 | 1 | 2; reaction?: -2 | -1 | 0 | 1 | 2; reactionCount?: number; readReceipts?: boolean; reply?: -2 | -1 | 0 | 1 | 2; state?: { avatar?: { level: -2 | -1 | 0 | 1 | 2; }; description?: { level: -2 | -1 | 0 | 1 | 2; }; disappearingTimer?: { level: -2 | -1 | 0 | 1 | 2; }; title?: { level: -2 | -1 | 0 | 1 | 2; }; }; thread?: -2 | -1 | 0 | 1 | 2; typingNotifications?: boolean; }`\n - `description?: string`\n - `draft?: { text: string; attachments?: object; }`\n - `imgURL?: string`\n - `isArchived?: boolean`\n - `isLowPriority?: boolean`\n - `isMarkedUnread?: boolean`\n - `isMuted?: boolean`\n - `isPinned?: boolean`\n - `isReadOnly?: boolean`\n - `lastActivity?: string`\n - `lastReadMessageSortKey?: string`\n - `localChatID?: string`\n - `messageExpirySeconds?: number`\n - `reminder?: { dismissOnIncomingMessage?: boolean; remindAt?: string; }`\n - `snooze?: { snoozeUntil?: string; userSnoozedAt?: string; }`\n - `unreadMentionsCount?: number`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst chat = await client.chats.notifyAnyway('!NCdzlIaMjZUmvmvyHU:beeper.com');\n\nconsole.log(chat);\n```",
perLanguage: {
typescript: {
method: 'client.chats.notifyAnyway',
@@ -758,7 +1171,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
cli: {
method: 'chats notify_anyway',
example:
- "beeper-desktop-cli chats notify-anyway \\\n --access-token 'My Access Token' \\\n --chat-id '!NCdzlIaMjZUmvmvyHU:beeper.com'",
+ "beeper-desktop chats notify-anyway \\\n --access-token 'My Access Token' \\\n --chat-id '!NCdzlIaMjZUmvmvyHU:beeper.com'",
},
php: {
method: 'chats->notifyAnyway',
@@ -776,12 +1189,12 @@ const EMBEDDED_METHODS: MethodEntry[] = [
endpoint: '/v1/chats/{chatID}/reminders',
httpMethod: 'post',
summary: 'Create a chat reminder',
- description: 'Set a reminder for a chat at a specific time',
+ description: 'Set a reminder for a chat at a specific time.',
stainlessPath: '(resource) chats.reminders > (method) create',
qualified: 'client.chats.reminders.create',
params: ['chatID: string;', 'reminder: { remindAt: string; dismissOnIncomingMessage?: boolean; };'],
markdown:
- "## create\n\n`client.chats.reminders.create(chatID: string, reminder: { remindAt: string; dismissOnIncomingMessage?: boolean; }): void`\n\n**post** `/v1/chats/{chatID}/reminders`\n\nSet a reminder for a chat at a specific time\n\n### Parameters\n\n- `chatID: string`\n Chat ID. Input routes also accept the local chat ID from this Beeper Desktop installation when available.\n\n- `reminder: { remindAt: string; dismissOnIncomingMessage?: boolean; }`\n Reminder configuration\n - `remindAt: string`\n Timestamp when the reminder should trigger.\n - `dismissOnIncomingMessage?: boolean`\n Cancel reminder if someone messages in the chat\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nawait client.chats.reminders.create('!NCdzlIaMjZUmvmvyHU:beeper.com', { reminder: { remindAt: '2025-08-31T23:30:12.520Z' } })\n```",
+ "## create\n\n`client.chats.reminders.create(chatID: string, reminder: { remindAt: string; dismissOnIncomingMessage?: boolean; }): void`\n\n**post** `/v1/chats/{chatID}/reminders`\n\nSet a reminder for a chat at a specific time.\n\n### Parameters\n\n- `chatID: string`\n Chat ID. Input routes also accept the local chat ID from this installation when available.\n\n- `reminder: { remindAt: string; dismissOnIncomingMessage?: boolean; }`\n Reminder configuration\n - `remindAt: string`\n Timestamp when the reminder should trigger.\n - `dismissOnIncomingMessage?: boolean`\n Cancel reminder if someone messages in the chat\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nawait client.chats.reminders.create('!NCdzlIaMjZUmvmvyHU:beeper.com', { reminder: { remindAt: '2025-08-31T23:30:12.520Z' } })\n```",
perLanguage: {
typescript: {
method: 'client.chats.reminders.create',
@@ -801,7 +1214,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
cli: {
method: 'reminders create',
example:
- "beeper-desktop-cli chats:reminders create \\\n --access-token 'My Access Token' \\\n --chat-id '!NCdzlIaMjZUmvmvyHU:beeper.com' \\\n --reminder \"{remindAt: '2025-08-31T23:30:12.520Z'}\"",
+ "beeper-desktop chats:reminders create \\\n --access-token 'My Access Token' \\\n --chat-id '!NCdzlIaMjZUmvmvyHU:beeper.com' \\\n --reminder \"{remindAt: '2025-08-31T23:30:12.520Z'}\"",
},
php: {
method: 'chats->reminders->create',
@@ -819,12 +1232,12 @@ const EMBEDDED_METHODS: MethodEntry[] = [
endpoint: '/v1/chats/{chatID}/reminders',
httpMethod: 'delete',
summary: 'Delete a chat reminder',
- description: 'Clear an existing reminder from a chat',
+ description: 'Clear an existing reminder from a chat.',
stainlessPath: '(resource) chats.reminders > (method) delete',
qualified: 'client.chats.reminders.delete',
params: ['chatID: string;'],
markdown:
- "## delete\n\n`client.chats.reminders.delete(chatID: string): void`\n\n**delete** `/v1/chats/{chatID}/reminders`\n\nClear an existing reminder from a chat\n\n### Parameters\n\n- `chatID: string`\n Chat ID. Input routes also accept the local chat ID from this Beeper Desktop installation when available.\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nawait client.chats.reminders.delete('!NCdzlIaMjZUmvmvyHU:beeper.com')\n```",
+ "## delete\n\n`client.chats.reminders.delete(chatID: string): void`\n\n**delete** `/v1/chats/{chatID}/reminders`\n\nClear an existing reminder from a chat.\n\n### Parameters\n\n- `chatID: string`\n Chat ID. Input routes also accept the local chat ID from this installation when available.\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nawait client.chats.reminders.delete('!NCdzlIaMjZUmvmvyHU:beeper.com')\n```",
perLanguage: {
typescript: {
method: 'client.chats.reminders.delete',
@@ -844,7 +1257,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
cli: {
method: 'reminders delete',
example:
- "beeper-desktop-cli chats:reminders delete \\\n --access-token 'My Access Token' \\\n --chat-id '!NCdzlIaMjZUmvmvyHU:beeper.com'",
+ "beeper-desktop chats:reminders delete \\\n --access-token 'My Access Token' \\\n --chat-id '!NCdzlIaMjZUmvmvyHU:beeper.com'",
},
php: {
method: 'chats->reminders->delete',
@@ -869,7 +1282,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
response:
'{ chatID: string; messageID: string; reactionKey: string; success: true; transactionID: string; }',
markdown:
- "## add\n\n`client.chats.messages.reactions.add(chatID: string, messageID: string, reactionKey: string, transactionID?: string): { chatID: string; messageID: string; reactionKey: string; success: true; transactionID: string; }`\n\n**post** `/v1/chats/{chatID}/messages/{messageID}/reactions`\n\nAdd a reaction to an existing message.\n\n### Parameters\n\n- `chatID: string`\n Chat ID. Input routes also accept the local chat ID from this Beeper Desktop installation when available.\n\n- `messageID: string`\n Message ID.\n\n- `reactionKey: string`\n Reaction key to add (emoji, shortcode, or custom emoji key)\n\n- `transactionID?: string`\n Optional transaction ID for deduplication and send tracking\n\n### Returns\n\n- `{ chatID: string; messageID: string; reactionKey: string; success: true; transactionID: string; }`\n\n - `chatID: string`\n - `messageID: string`\n - `reactionKey: string`\n - `success: true`\n - `transactionID: string`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.chats.messages.reactions.add('1343993', { chatID: '!NCdzlIaMjZUmvmvyHU:beeper.com', reactionKey: 'x' });\n\nconsole.log(response);\n```",
+ "## add\n\n`client.chats.messages.reactions.add(chatID: string, messageID: string, reactionKey: string, transactionID?: string): { chatID: string; messageID: string; reactionKey: string; success: true; transactionID: string; }`\n\n**post** `/v1/chats/{chatID}/messages/{messageID}/reactions`\n\nAdd a reaction to an existing message.\n\n### Parameters\n\n- `chatID: string`\n Chat ID. Input routes also accept the local chat ID from this installation when available.\n\n- `messageID: string`\n Message ID.\n\n- `reactionKey: string`\n Reaction key to add (emoji, shortcode, or custom emoji key)\n\n- `transactionID?: string`\n Optional transaction ID for deduplication and send tracking\n\n### Returns\n\n- `{ chatID: string; messageID: string; reactionKey: string; success: true; transactionID: string; }`\n\n - `chatID: string`\n - `messageID: string`\n - `reactionKey: string`\n - `success: true`\n - `transactionID: string`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.chats.messages.reactions.add('1343993', { chatID: '!NCdzlIaMjZUmvmvyHU:beeper.com', reactionKey: 'x' });\n\nconsole.log(response);\n```",
perLanguage: {
typescript: {
method: 'client.chats.messages.reactions.add',
@@ -889,7 +1302,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
cli: {
method: 'reactions add',
example:
- "beeper-desktop-cli chats:messages:reactions add \\\n --access-token 'My Access Token' \\\n --chat-id '!NCdzlIaMjZUmvmvyHU:beeper.com' \\\n --message-id 1343993 \\\n --reaction-key x",
+ "beeper-desktop chats:messages:reactions add \\\n --access-token 'My Access Token' \\\n --chat-id '!NCdzlIaMjZUmvmvyHU:beeper.com' \\\n --message-id 1343993 \\\n --reaction-key x",
},
php: {
method: 'chats->messages->reactions->add',
@@ -913,7 +1326,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
params: ['chatID: string;', 'messageID: string;', 'reactionKey: string;'],
response: '{ chatID: string; messageID: string; reactionKey: string; success: true; }',
markdown:
- "## delete\n\n`client.chats.messages.reactions.delete(chatID: string, messageID: string, reactionKey: string): { chatID: string; messageID: string; reactionKey: string; success: true; }`\n\n**delete** `/v1/chats/{chatID}/messages/{messageID}/reactions/{reactionKey}`\n\nRemove the reaction added by the authenticated user from an existing message.\n\n### Parameters\n\n- `chatID: string`\n Chat ID. Input routes also accept the local chat ID from this Beeper Desktop installation when available.\n\n- `messageID: string`\n Message ID.\n\n- `reactionKey: string`\n Reaction key to remove (emoji, shortcode, or custom emoji key)\n\n### Returns\n\n- `{ chatID: string; messageID: string; reactionKey: string; success: true; }`\n\n - `chatID: string`\n - `messageID: string`\n - `reactionKey: string`\n - `success: true`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst reaction = await client.chats.messages.reactions.delete('x', { chatID: '!NCdzlIaMjZUmvmvyHU:beeper.com', messageID: '1343993' });\n\nconsole.log(reaction);\n```",
+ "## delete\n\n`client.chats.messages.reactions.delete(chatID: string, messageID: string, reactionKey: string): { chatID: string; messageID: string; reactionKey: string; success: true; }`\n\n**delete** `/v1/chats/{chatID}/messages/{messageID}/reactions/{reactionKey}`\n\nRemove the reaction added by the authenticated user from an existing message.\n\n### Parameters\n\n- `chatID: string`\n Chat ID. Input routes also accept the local chat ID from this installation when available.\n\n- `messageID: string`\n Message ID.\n\n- `reactionKey: string`\n Reaction key to remove (emoji, shortcode, or custom emoji key)\n\n### Returns\n\n- `{ chatID: string; messageID: string; reactionKey: string; success: true; }`\n\n - `chatID: string`\n - `messageID: string`\n - `reactionKey: string`\n - `success: true`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst reaction = await client.chats.messages.reactions.delete('x', { chatID: '!NCdzlIaMjZUmvmvyHU:beeper.com', messageID: '1343993' });\n\nconsole.log(reaction);\n```",
perLanguage: {
typescript: {
method: 'client.chats.messages.reactions.delete',
@@ -933,7 +1346,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
cli: {
method: 'reactions delete',
example:
- "beeper-desktop-cli chats:messages:reactions delete \\\n --access-token 'My Access Token' \\\n --chat-id '!NCdzlIaMjZUmvmvyHU:beeper.com' \\\n --message-id 1343993 \\\n --reaction-key x",
+ "beeper-desktop chats:messages:reactions delete \\\n --access-token 'My Access Token' \\\n --chat-id '!NCdzlIaMjZUmvmvyHU:beeper.com' \\\n --message-id 1343993 \\\n --reaction-key x",
},
php: {
method: 'chats->messages->reactions->delete',
@@ -972,7 +1385,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
response:
"{ id: string; accountID: string; chatID: string; senderID: string; sortKey: string; timestamp: string; attachments?: { type: 'unknown' | 'img' | 'video' | 'audio'; id?: string; duration?: number; fileName?: string; fileSize?: number; isGif?: boolean; isSticker?: boolean; isVoiceNote?: boolean; mimeType?: string; posterImg?: string; size?: object; srcURL?: string; transcription?: object; }[]; editedTimestamp?: string; isDeleted?: boolean; isHidden?: boolean; isSender?: boolean; isUnread?: boolean; linkedMessageID?: string; links?: { title: string; url: string; favicon?: string; img?: string; imgSize?: { height?: number; width?: number; }; originalURL?: string; summary?: string; }[]; mentions?: string[]; reactions?: { id: string; participantID: string; reactionKey: string; emoji?: boolean; imgURL?: string; }[]; seen?: boolean | string | object; senderName?: string; sendStatus?: { status: 'SUCCESS' | 'PENDING' | 'FAIL_RETRIABLE' | 'FAIL_PERMANENT'; timestamp: string; deliveredToUsers?: string[]; internalError?: string; message?: string; reason?: string; }; text?: string; type?: string; }",
markdown:
- "## search\n\n`client.messages.search(accountIDs?: string[], chatIDs?: string[], chatType?: 'group' | 'single', cursor?: string, dateAfter?: string, dateBefore?: string, direction?: 'after' | 'before', excludeLowPriority?: boolean, includeMuted?: boolean, limit?: number, mediaTypes?: 'any' | 'video' | 'image' | 'link' | 'file'[], query?: string, sender?: string): { id: string; accountID: string; chatID: string; senderID: string; sortKey: string; timestamp: string; attachments?: attachment[]; editedTimestamp?: string; isDeleted?: boolean; isHidden?: boolean; isSender?: boolean; isUnread?: boolean; linkedMessageID?: string; links?: object[]; mentions?: string[]; reactions?: reaction[]; seen?: boolean | string | object; senderName?: string; sendStatus?: object; text?: string; type?: string; }`\n\n**get** `/v1/messages/search`\n\nSearch messages across chats.\n\n### Parameters\n\n- `accountIDs?: string[]`\n Limit search to specific account IDs.\n\n- `chatIDs?: string[]`\n Limit search to specific chat IDs.\n\n- `chatType?: 'group' | 'single'`\n Filter by chat type: 'group' for group chats, 'single' for 1:1 chats.\n\n- `cursor?: string`\n Opaque pagination cursor; do not inspect. Use together with 'direction'.\n\n- `dateAfter?: string`\n Only include messages with timestamp strictly after this ISO 8601 datetime (e.g., '2024-07-01T00:00:00Z' or '2024-07-01T00:00:00+02:00').\n\n- `dateBefore?: string`\n Only include messages with timestamp strictly before this ISO 8601 datetime (e.g., '2024-07-31T23:59:59Z' or '2024-07-31T23:59:59+02:00').\n\n- `direction?: 'after' | 'before'`\n Pagination direction used with 'cursor': 'before' fetches older results, 'after' fetches newer results. Defaults to 'before' when only 'cursor' is provided.\n\n- `excludeLowPriority?: boolean`\n Exclude messages marked Low Priority by the user. Default: true. Set to false to include all.\n\n- `includeMuted?: boolean`\n Include messages in chats marked as Muted by the user, which are usually less important. Default: true. Set to false if the user wants a more refined search.\n\n- `limit?: number`\n Maximum number of messages to return.\n\n- `mediaTypes?: 'any' | 'video' | 'image' | 'link' | 'file'[]`\n Filter messages by media types. Use ['any'] for any media type, or specify exact types like ['video', 'image']. Omit for no media filtering.\n\n- `query?: string`\n Literal word search (non-semantic). Finds messages containing these EXACT words in any order. Use single words users actually type, not concepts or phrases. Example: use \"dinner\" not \"dinner plans\", use \"sick\" not \"health issues\". If omitted, returns results filtered only by other parameters.\n\n- `sender?: string`\n Filter by sender: 'me' (messages sent by the authenticated user), 'others' (messages sent by others), or a specific user ID string (user.id).\n\n### Returns\n\n- `{ id: string; accountID: string; chatID: string; senderID: string; sortKey: string; timestamp: string; attachments?: { type: 'unknown' | 'img' | 'video' | 'audio'; id?: string; duration?: number; fileName?: string; fileSize?: number; isGif?: boolean; isSticker?: boolean; isVoiceNote?: boolean; mimeType?: string; posterImg?: string; size?: object; srcURL?: string; transcription?: object; }[]; editedTimestamp?: string; isDeleted?: boolean; isHidden?: boolean; isSender?: boolean; isUnread?: boolean; linkedMessageID?: string; links?: { title: string; url: string; favicon?: string; img?: string; imgSize?: { height?: number; width?: number; }; originalURL?: string; summary?: string; }[]; mentions?: string[]; reactions?: { id: string; participantID: string; reactionKey: string; emoji?: boolean; imgURL?: string; }[]; seen?: boolean | string | object; senderName?: string; sendStatus?: { status: 'SUCCESS' | 'PENDING' | 'FAIL_RETRIABLE' | 'FAIL_PERMANENT'; timestamp: string; deliveredToUsers?: string[]; internalError?: string; message?: string; reason?: string; }; text?: string; type?: string; }`\n\n - `id: string`\n - `accountID: string`\n - `chatID: string`\n - `senderID: string`\n - `sortKey: string`\n - `timestamp: string`\n - `attachments?: { type: 'unknown' | 'img' | 'video' | 'audio'; id?: string; duration?: number; fileName?: string; fileSize?: number; isGif?: boolean; isSticker?: boolean; isVoiceNote?: boolean; mimeType?: string; posterImg?: string; size?: { height?: number; width?: number; }; srcURL?: string; transcription?: { engine: string; transcription: string; language?: string; }; }[]`\n - `editedTimestamp?: string`\n - `isDeleted?: boolean`\n - `isHidden?: boolean`\n - `isSender?: boolean`\n - `isUnread?: boolean`\n - `linkedMessageID?: string`\n - `links?: { title: string; url: string; favicon?: string; img?: string; imgSize?: { height?: number; width?: number; }; originalURL?: string; summary?: string; }[]`\n - `mentions?: string[]`\n - `reactions?: { id: string; participantID: string; reactionKey: string; emoji?: boolean; imgURL?: string; }[]`\n - `seen?: boolean | string | object`\n - `senderName?: string`\n - `sendStatus?: { status: 'SUCCESS' | 'PENDING' | 'FAIL_RETRIABLE' | 'FAIL_PERMANENT'; timestamp: string; deliveredToUsers?: string[]; internalError?: string; message?: string; reason?: string; }`\n - `text?: string`\n - `type?: string`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\n// Automatically fetches more pages as needed.\nfor await (const message of client.messages.search()) {\n console.log(message);\n}\n```",
+ "## search\n\n`client.messages.search(accountIDs?: string[], chatIDs?: string[], chatType?: 'group' | 'single', cursor?: string, dateAfter?: string, dateBefore?: string, direction?: 'after' | 'before', excludeLowPriority?: boolean, includeMuted?: boolean, limit?: number, mediaTypes?: 'any' | 'video' | 'image' | 'link' | 'file'[], query?: string, sender?: string): { id: string; accountID: string; chatID: string; senderID: string; sortKey: string; timestamp: string; attachments?: attachment[]; editedTimestamp?: string; isDeleted?: boolean; isHidden?: boolean; isSender?: boolean; isUnread?: boolean; linkedMessageID?: string; links?: object[]; mentions?: string[]; reactions?: reaction[]; seen?: boolean | string | object; senderName?: string; sendStatus?: object; text?: string; type?: string; }`\n\n**get** `/v1/messages/search`\n\nSearch messages across chats.\n\n### Parameters\n\n- `accountIDs?: string[]`\n Limit search to specific account IDs.\n\n- `chatIDs?: string[]`\n Limit search to specific chat IDs.\n\n- `chatType?: 'group' | 'single'`\n Filter by chat type: 'group' for group chats, 'single' for 1:1 chats.\n\n- `cursor?: string`\n Opaque pagination cursor; do not inspect. Use together with 'direction'.\n\n- `dateAfter?: string`\n Only include messages with timestamp strictly after this ISO 8601 datetime (e.g., '2024-07-01T00:00:00Z' or '2024-07-01T00:00:00+02:00').\n\n- `dateBefore?: string`\n Only include messages with timestamp strictly before this ISO 8601 datetime (e.g., '2024-07-31T23:59:59Z' or '2024-07-31T23:59:59+02:00').\n\n- `direction?: 'after' | 'before'`\n Pagination direction used with 'cursor': 'before' fetches older results, 'after' fetches newer results. Defaults to 'before' when only 'cursor' is provided.\n\n- `excludeLowPriority?: boolean`\n Exclude messages marked Low Priority by the user. Default: true. Set to false to include all.\n\n- `includeMuted?: boolean`\n Include messages in chats marked as Muted by the user, which are usually less important. Default: true. Set to false if the user wants a more refined search.\n\n- `limit?: number`\n Maximum number of messages to return.\n\n- `mediaTypes?: 'any' | 'video' | 'image' | 'link' | 'file'[]`\n Filter messages by media types. Use ['any'] for any media type, or specify exact types like ['video', 'image']. Omit for no media filtering.\n\n- `query?: string`\n Literal word search. Finds messages containing these words in any order. Use words the user actually typed, not inferred concepts. Example: use \"dinner\" rather than \"dinner plans\". If omitted, returns results filtered only by the other parameters.\n\n- `sender?: string`\n Filter by sender: 'me' (messages sent by the authenticated user), 'others' (messages sent by others), or a specific user ID string (user.id).\n\n### Returns\n\n- `{ id: string; accountID: string; chatID: string; senderID: string; sortKey: string; timestamp: string; attachments?: { type: 'unknown' | 'img' | 'video' | 'audio'; id?: string; duration?: number; fileName?: string; fileSize?: number; isGif?: boolean; isSticker?: boolean; isVoiceNote?: boolean; mimeType?: string; posterImg?: string; size?: object; srcURL?: string; transcription?: object; }[]; editedTimestamp?: string; isDeleted?: boolean; isHidden?: boolean; isSender?: boolean; isUnread?: boolean; linkedMessageID?: string; links?: { title: string; url: string; favicon?: string; img?: string; imgSize?: { height?: number; width?: number; }; originalURL?: string; summary?: string; }[]; mentions?: string[]; reactions?: { id: string; participantID: string; reactionKey: string; emoji?: boolean; imgURL?: string; }[]; seen?: boolean | string | object; senderName?: string; sendStatus?: { status: 'SUCCESS' | 'PENDING' | 'FAIL_RETRIABLE' | 'FAIL_PERMANENT'; timestamp: string; deliveredToUsers?: string[]; internalError?: string; message?: string; reason?: string; }; text?: string; type?: string; }`\n\n - `id: string`\n - `accountID: string`\n - `chatID: string`\n - `senderID: string`\n - `sortKey: string`\n - `timestamp: string`\n - `attachments?: { type: 'unknown' | 'img' | 'video' | 'audio'; id?: string; duration?: number; fileName?: string; fileSize?: number; isGif?: boolean; isSticker?: boolean; isVoiceNote?: boolean; mimeType?: string; posterImg?: string; size?: { height?: number; width?: number; }; srcURL?: string; transcription?: { engine: string; transcription: string; language?: string; }; }[]`\n - `editedTimestamp?: string`\n - `isDeleted?: boolean`\n - `isHidden?: boolean`\n - `isSender?: boolean`\n - `isUnread?: boolean`\n - `linkedMessageID?: string`\n - `links?: { title: string; url: string; favicon?: string; img?: string; imgSize?: { height?: number; width?: number; }; originalURL?: string; summary?: string; }[]`\n - `mentions?: string[]`\n - `reactions?: { id: string; participantID: string; reactionKey: string; emoji?: boolean; imgURL?: string; }[]`\n - `seen?: boolean | string | object`\n - `senderName?: string`\n - `sendStatus?: { status: 'SUCCESS' | 'PENDING' | 'FAIL_RETRIABLE' | 'FAIL_PERMANENT'; timestamp: string; deliveredToUsers?: string[]; internalError?: string; message?: string; reason?: string; }`\n - `text?: string`\n - `type?: string`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\n// Automatically fetches more pages as needed.\nfor await (const message of client.messages.search()) {\n console.log(message);\n}\n```",
perLanguage: {
typescript: {
method: 'client.messages.search',
@@ -991,7 +1404,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
},
cli: {
method: 'messages search',
- example: "beeper-desktop-cli messages search \\\n --access-token 'My Access Token'",
+ example: "beeper-desktop messages search \\\n --access-token 'My Access Token'",
},
php: {
method: 'messages->search',
@@ -1016,7 +1429,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
response:
"{ id: string; accountID: string; chatID: string; senderID: string; sortKey: string; timestamp: string; attachments?: { type: 'unknown' | 'img' | 'video' | 'audio'; id?: string; duration?: number; fileName?: string; fileSize?: number; isGif?: boolean; isSticker?: boolean; isVoiceNote?: boolean; mimeType?: string; posterImg?: string; size?: object; srcURL?: string; transcription?: object; }[]; editedTimestamp?: string; isDeleted?: boolean; isHidden?: boolean; isSender?: boolean; isUnread?: boolean; linkedMessageID?: string; links?: { title: string; url: string; favicon?: string; img?: string; imgSize?: { height?: number; width?: number; }; originalURL?: string; summary?: string; }[]; mentions?: string[]; reactions?: { id: string; participantID: string; reactionKey: string; emoji?: boolean; imgURL?: string; }[]; seen?: boolean | string | object; senderName?: string; sendStatus?: { status: 'SUCCESS' | 'PENDING' | 'FAIL_RETRIABLE' | 'FAIL_PERMANENT'; timestamp: string; deliveredToUsers?: string[]; internalError?: string; message?: string; reason?: string; }; text?: string; type?: string; }",
markdown:
- "## list\n\n`client.messages.list(chatID: string, cursor?: string, direction?: 'after' | 'before'): { id: string; accountID: string; chatID: string; senderID: string; sortKey: string; timestamp: string; attachments?: attachment[]; editedTimestamp?: string; isDeleted?: boolean; isHidden?: boolean; isSender?: boolean; isUnread?: boolean; linkedMessageID?: string; links?: object[]; mentions?: string[]; reactions?: reaction[]; seen?: boolean | string | object; senderName?: string; sendStatus?: object; text?: string; type?: string; }`\n\n**get** `/v1/chats/{chatID}/messages`\n\nList all messages in a chat with cursor-based pagination. Sorted by timestamp.\n\n### Parameters\n\n- `chatID: string`\n Chat ID. Input routes also accept the local chat ID from this Beeper Desktop installation when available.\n\n- `cursor?: string`\n Opaque pagination cursor; do not inspect. Use together with 'direction'.\n\n- `direction?: 'after' | 'before'`\n Pagination direction used with 'cursor': 'before' fetches older results, 'after' fetches newer results. Defaults to 'before' when only 'cursor' is provided.\n\n### Returns\n\n- `{ id: string; accountID: string; chatID: string; senderID: string; sortKey: string; timestamp: string; attachments?: { type: 'unknown' | 'img' | 'video' | 'audio'; id?: string; duration?: number; fileName?: string; fileSize?: number; isGif?: boolean; isSticker?: boolean; isVoiceNote?: boolean; mimeType?: string; posterImg?: string; size?: object; srcURL?: string; transcription?: object; }[]; editedTimestamp?: string; isDeleted?: boolean; isHidden?: boolean; isSender?: boolean; isUnread?: boolean; linkedMessageID?: string; links?: { title: string; url: string; favicon?: string; img?: string; imgSize?: { height?: number; width?: number; }; originalURL?: string; summary?: string; }[]; mentions?: string[]; reactions?: { id: string; participantID: string; reactionKey: string; emoji?: boolean; imgURL?: string; }[]; seen?: boolean | string | object; senderName?: string; sendStatus?: { status: 'SUCCESS' | 'PENDING' | 'FAIL_RETRIABLE' | 'FAIL_PERMANENT'; timestamp: string; deliveredToUsers?: string[]; internalError?: string; message?: string; reason?: string; }; text?: string; type?: string; }`\n\n - `id: string`\n - `accountID: string`\n - `chatID: string`\n - `senderID: string`\n - `sortKey: string`\n - `timestamp: string`\n - `attachments?: { type: 'unknown' | 'img' | 'video' | 'audio'; id?: string; duration?: number; fileName?: string; fileSize?: number; isGif?: boolean; isSticker?: boolean; isVoiceNote?: boolean; mimeType?: string; posterImg?: string; size?: { height?: number; width?: number; }; srcURL?: string; transcription?: { engine: string; transcription: string; language?: string; }; }[]`\n - `editedTimestamp?: string`\n - `isDeleted?: boolean`\n - `isHidden?: boolean`\n - `isSender?: boolean`\n - `isUnread?: boolean`\n - `linkedMessageID?: string`\n - `links?: { title: string; url: string; favicon?: string; img?: string; imgSize?: { height?: number; width?: number; }; originalURL?: string; summary?: string; }[]`\n - `mentions?: string[]`\n - `reactions?: { id: string; participantID: string; reactionKey: string; emoji?: boolean; imgURL?: string; }[]`\n - `seen?: boolean | string | object`\n - `senderName?: string`\n - `sendStatus?: { status: 'SUCCESS' | 'PENDING' | 'FAIL_RETRIABLE' | 'FAIL_PERMANENT'; timestamp: string; deliveredToUsers?: string[]; internalError?: string; message?: string; reason?: string; }`\n - `text?: string`\n - `type?: string`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\n// Automatically fetches more pages as needed.\nfor await (const message of client.messages.list('!NCdzlIaMjZUmvmvyHU:beeper.com')) {\n console.log(message);\n}\n```",
+ "## list\n\n`client.messages.list(chatID: string, cursor?: string, direction?: 'after' | 'before'): { id: string; accountID: string; chatID: string; senderID: string; sortKey: string; timestamp: string; attachments?: attachment[]; editedTimestamp?: string; isDeleted?: boolean; isHidden?: boolean; isSender?: boolean; isUnread?: boolean; linkedMessageID?: string; links?: object[]; mentions?: string[]; reactions?: reaction[]; seen?: boolean | string | object; senderName?: string; sendStatus?: object; text?: string; type?: string; }`\n\n**get** `/v1/chats/{chatID}/messages`\n\nList all messages in a chat with cursor-based pagination. Sorted by timestamp.\n\n### Parameters\n\n- `chatID: string`\n Chat ID. Input routes also accept the local chat ID from this installation when available.\n\n- `cursor?: string`\n Opaque pagination cursor; do not inspect. Use together with 'direction'.\n\n- `direction?: 'after' | 'before'`\n Pagination direction used with 'cursor': 'before' fetches older results, 'after' fetches newer results. Defaults to 'before' when only 'cursor' is provided.\n\n### Returns\n\n- `{ id: string; accountID: string; chatID: string; senderID: string; sortKey: string; timestamp: string; attachments?: { type: 'unknown' | 'img' | 'video' | 'audio'; id?: string; duration?: number; fileName?: string; fileSize?: number; isGif?: boolean; isSticker?: boolean; isVoiceNote?: boolean; mimeType?: string; posterImg?: string; size?: object; srcURL?: string; transcription?: object; }[]; editedTimestamp?: string; isDeleted?: boolean; isHidden?: boolean; isSender?: boolean; isUnread?: boolean; linkedMessageID?: string; links?: { title: string; url: string; favicon?: string; img?: string; imgSize?: { height?: number; width?: number; }; originalURL?: string; summary?: string; }[]; mentions?: string[]; reactions?: { id: string; participantID: string; reactionKey: string; emoji?: boolean; imgURL?: string; }[]; seen?: boolean | string | object; senderName?: string; sendStatus?: { status: 'SUCCESS' | 'PENDING' | 'FAIL_RETRIABLE' | 'FAIL_PERMANENT'; timestamp: string; deliveredToUsers?: string[]; internalError?: string; message?: string; reason?: string; }; text?: string; type?: string; }`\n\n - `id: string`\n - `accountID: string`\n - `chatID: string`\n - `senderID: string`\n - `sortKey: string`\n - `timestamp: string`\n - `attachments?: { type: 'unknown' | 'img' | 'video' | 'audio'; id?: string; duration?: number; fileName?: string; fileSize?: number; isGif?: boolean; isSticker?: boolean; isVoiceNote?: boolean; mimeType?: string; posterImg?: string; size?: { height?: number; width?: number; }; srcURL?: string; transcription?: { engine: string; transcription: string; language?: string; }; }[]`\n - `editedTimestamp?: string`\n - `isDeleted?: boolean`\n - `isHidden?: boolean`\n - `isSender?: boolean`\n - `isUnread?: boolean`\n - `linkedMessageID?: string`\n - `links?: { title: string; url: string; favicon?: string; img?: string; imgSize?: { height?: number; width?: number; }; originalURL?: string; summary?: string; }[]`\n - `mentions?: string[]`\n - `reactions?: { id: string; participantID: string; reactionKey: string; emoji?: boolean; imgURL?: string; }[]`\n - `seen?: boolean | string | object`\n - `senderName?: string`\n - `sendStatus?: { status: 'SUCCESS' | 'PENDING' | 'FAIL_RETRIABLE' | 'FAIL_PERMANENT'; timestamp: string; deliveredToUsers?: string[]; internalError?: string; message?: string; reason?: string; }`\n - `text?: string`\n - `type?: string`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\n// Automatically fetches more pages as needed.\nfor await (const message of client.messages.list('!NCdzlIaMjZUmvmvyHU:beeper.com')) {\n console.log(message);\n}\n```",
perLanguage: {
typescript: {
method: 'client.messages.list',
@@ -1036,7 +1449,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
cli: {
method: 'messages list',
example:
- "beeper-desktop-cli messages list \\\n --access-token 'My Access Token' \\\n --chat-id '!NCdzlIaMjZUmvmvyHU:beeper.com'",
+ "beeper-desktop messages list \\\n --access-token 'My Access Token' \\\n --chat-id '!NCdzlIaMjZUmvmvyHU:beeper.com'",
},
php: {
method: 'messages->list',
@@ -1066,7 +1479,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
],
response: '{ chatID: string; pendingMessageID: string; }',
markdown:
- "## send\n\n`client.messages.send(chatID: string, attachment?: { uploadID: string; duration?: number; fileName?: string; mimeType?: string; size?: { height: number; width: number; }; type?: 'image' | 'video' | 'audio' | 'file' | 'gif' | 'voice-note' | 'sticker'; }, replyToMessageID?: string, text?: string): { chatID: string; pendingMessageID: string; }`\n\n**post** `/v1/chats/{chatID}/messages`\n\nSend a text message to a specific chat. Supports replying to existing messages. Returns a pending message ID.\n\n### Parameters\n\n- `chatID: string`\n Chat ID. Input routes also accept the local chat ID from this Beeper Desktop installation when available.\n\n- `attachment?: { uploadID: string; duration?: number; fileName?: string; mimeType?: string; size?: { height: number; width: number; }; type?: 'image' | 'video' | 'audio' | 'file' | 'gif' | 'voice-note' | 'sticker'; }`\n Single attachment to send with the message\n - `uploadID: string`\n Upload ID from uploadAsset endpoint. Required to reference uploaded files.\n - `duration?: number`\n Duration in seconds (optional override of cached value)\n - `fileName?: string`\n Filename (optional override of cached value)\n - `mimeType?: string`\n MIME type (optional override of cached value)\n - `size?: { height: number; width: number; }`\n Dimensions (optional override of cached value)\n - `type?: 'image' | 'video' | 'audio' | 'file' | 'gif' | 'voice-note' | 'sticker'`\n Attachment type hint (image, video, audio, file, gif, voice-note, sticker). If omitted, auto-detected from mimeType\n\n- `replyToMessageID?: string`\n Provide a message ID to send this as a reply to an existing message\n\n- `text?: string`\n Draft text. Plain text and Markdown are converted to Matrix HTML with the same rules used by send and edit.\n\n### Returns\n\n- `{ chatID: string; pendingMessageID: string; }`\n\n - `chatID: string`\n - `pendingMessageID: string`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.messages.send('!NCdzlIaMjZUmvmvyHU:beeper.com');\n\nconsole.log(response);\n```",
+ "## send\n\n`client.messages.send(chatID: string, attachment?: { uploadID: string; duration?: number; fileName?: string; mimeType?: string; size?: { height: number; width: number; }; type?: 'image' | 'video' | 'audio' | 'file' | 'gif' | 'voice-note' | 'sticker'; }, replyToMessageID?: string, text?: string): { chatID: string; pendingMessageID: string; }`\n\n**post** `/v1/chats/{chatID}/messages`\n\nSend a text message to a specific chat. Supports replying to existing messages. Returns a pending message ID.\n\n### Parameters\n\n- `chatID: string`\n Chat ID. Input routes also accept the local chat ID from this installation when available.\n\n- `attachment?: { uploadID: string; duration?: number; fileName?: string; mimeType?: string; size?: { height: number; width: number; }; type?: 'image' | 'video' | 'audio' | 'file' | 'gif' | 'voice-note' | 'sticker'; }`\n Single attachment to send with the message\n - `uploadID: string`\n Upload ID from uploadAsset endpoint. Required to reference uploaded files.\n - `duration?: number`\n Duration in seconds (optional override of cached value)\n - `fileName?: string`\n Filename (optional override of cached value)\n - `mimeType?: string`\n MIME type (optional override of cached value)\n - `size?: { height: number; width: number; }`\n Dimensions (optional override of cached value)\n - `type?: 'image' | 'video' | 'audio' | 'file' | 'gif' | 'voice-note' | 'sticker'`\n Attachment type hint (image, video, audio, file, gif, voice-note, sticker). If omitted, auto-detected from mimeType\n\n- `replyToMessageID?: string`\n Provide a message ID to send this as a reply to an existing message\n\n- `text?: string`\n Draft text. Plain text and Markdown are converted to Beeper rich text with the same rules used by send and edit.\n\n### Returns\n\n- `{ chatID: string; pendingMessageID: string; }`\n\n - `chatID: string`\n - `pendingMessageID: string`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.messages.send('!NCdzlIaMjZUmvmvyHU:beeper.com');\n\nconsole.log(response);\n```",
perLanguage: {
typescript: {
method: 'client.messages.send',
@@ -1086,7 +1499,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
cli: {
method: 'messages send',
example:
- "beeper-desktop-cli messages send \\\n --access-token 'My Access Token' \\\n --chat-id '!NCdzlIaMjZUmvmvyHU:beeper.com'",
+ "beeper-desktop messages send \\\n --access-token 'My Access Token' \\\n --chat-id '!NCdzlIaMjZUmvmvyHU:beeper.com'",
},
php: {
method: 'messages->send',
@@ -1105,14 +1518,14 @@ const EMBEDDED_METHODS: MethodEntry[] = [
httpMethod: 'get',
summary: 'Retrieve a message',
description:
- 'Retrieve a message by final message ID, pendingMessageID, or Matrix event ID. Chat ID may be a Beeper chat ID or local chat ID.',
+ 'Retrieve a message by final message ID, pendingMessageID, or Matrix event ID. chatID may be a Beeper chat ID or a local chat ID.',
stainlessPath: '(resource) messages > (method) retrieve',
qualified: 'client.messages.retrieve',
params: ['chatID: string;', 'messageID: string;'],
response:
"{ id: string; accountID: string; chatID: string; senderID: string; sortKey: string; timestamp: string; attachments?: { type: 'unknown' | 'img' | 'video' | 'audio'; id?: string; duration?: number; fileName?: string; fileSize?: number; isGif?: boolean; isSticker?: boolean; isVoiceNote?: boolean; mimeType?: string; posterImg?: string; size?: object; srcURL?: string; transcription?: object; }[]; editedTimestamp?: string; isDeleted?: boolean; isHidden?: boolean; isSender?: boolean; isUnread?: boolean; linkedMessageID?: string; links?: { title: string; url: string; favicon?: string; img?: string; imgSize?: { height?: number; width?: number; }; originalURL?: string; summary?: string; }[]; mentions?: string[]; reactions?: { id: string; participantID: string; reactionKey: string; emoji?: boolean; imgURL?: string; }[]; seen?: boolean | string | object; senderName?: string; sendStatus?: { status: 'SUCCESS' | 'PENDING' | 'FAIL_RETRIABLE' | 'FAIL_PERMANENT'; timestamp: string; deliveredToUsers?: string[]; internalError?: string; message?: string; reason?: string; }; text?: string; type?: string; }",
markdown:
- "## retrieve\n\n`client.messages.retrieve(chatID: string, messageID: string): { id: string; accountID: string; chatID: string; senderID: string; sortKey: string; timestamp: string; attachments?: attachment[]; editedTimestamp?: string; isDeleted?: boolean; isHidden?: boolean; isSender?: boolean; isUnread?: boolean; linkedMessageID?: string; links?: object[]; mentions?: string[]; reactions?: reaction[]; seen?: boolean | string | object; senderName?: string; sendStatus?: object; text?: string; type?: string; }`\n\n**get** `/v1/chats/{chatID}/messages/{messageID}`\n\nRetrieve a message by final message ID, pendingMessageID, or Matrix event ID. Chat ID may be a Beeper chat ID or local chat ID.\n\n### Parameters\n\n- `chatID: string`\n Chat ID. Input routes also accept the local chat ID from this Beeper Desktop installation when available.\n\n- `messageID: string`\n Message ID.\n\n### Returns\n\n- `{ id: string; accountID: string; chatID: string; senderID: string; sortKey: string; timestamp: string; attachments?: { type: 'unknown' | 'img' | 'video' | 'audio'; id?: string; duration?: number; fileName?: string; fileSize?: number; isGif?: boolean; isSticker?: boolean; isVoiceNote?: boolean; mimeType?: string; posterImg?: string; size?: object; srcURL?: string; transcription?: object; }[]; editedTimestamp?: string; isDeleted?: boolean; isHidden?: boolean; isSender?: boolean; isUnread?: boolean; linkedMessageID?: string; links?: { title: string; url: string; favicon?: string; img?: string; imgSize?: { height?: number; width?: number; }; originalURL?: string; summary?: string; }[]; mentions?: string[]; reactions?: { id: string; participantID: string; reactionKey: string; emoji?: boolean; imgURL?: string; }[]; seen?: boolean | string | object; senderName?: string; sendStatus?: { status: 'SUCCESS' | 'PENDING' | 'FAIL_RETRIABLE' | 'FAIL_PERMANENT'; timestamp: string; deliveredToUsers?: string[]; internalError?: string; message?: string; reason?: string; }; text?: string; type?: string; }`\n\n - `id: string`\n - `accountID: string`\n - `chatID: string`\n - `senderID: string`\n - `sortKey: string`\n - `timestamp: string`\n - `attachments?: { type: 'unknown' | 'img' | 'video' | 'audio'; id?: string; duration?: number; fileName?: string; fileSize?: number; isGif?: boolean; isSticker?: boolean; isVoiceNote?: boolean; mimeType?: string; posterImg?: string; size?: { height?: number; width?: number; }; srcURL?: string; transcription?: { engine: string; transcription: string; language?: string; }; }[]`\n - `editedTimestamp?: string`\n - `isDeleted?: boolean`\n - `isHidden?: boolean`\n - `isSender?: boolean`\n - `isUnread?: boolean`\n - `linkedMessageID?: string`\n - `links?: { title: string; url: string; favicon?: string; img?: string; imgSize?: { height?: number; width?: number; }; originalURL?: string; summary?: string; }[]`\n - `mentions?: string[]`\n - `reactions?: { id: string; participantID: string; reactionKey: string; emoji?: boolean; imgURL?: string; }[]`\n - `seen?: boolean | string | object`\n - `senderName?: string`\n - `sendStatus?: { status: 'SUCCESS' | 'PENDING' | 'FAIL_RETRIABLE' | 'FAIL_PERMANENT'; timestamp: string; deliveredToUsers?: string[]; internalError?: string; message?: string; reason?: string; }`\n - `text?: string`\n - `type?: string`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst message = await client.messages.retrieve('1343993', { chatID: '!NCdzlIaMjZUmvmvyHU:beeper.com' });\n\nconsole.log(message);\n```",
+ "## retrieve\n\n`client.messages.retrieve(chatID: string, messageID: string): { id: string; accountID: string; chatID: string; senderID: string; sortKey: string; timestamp: string; attachments?: attachment[]; editedTimestamp?: string; isDeleted?: boolean; isHidden?: boolean; isSender?: boolean; isUnread?: boolean; linkedMessageID?: string; links?: object[]; mentions?: string[]; reactions?: reaction[]; seen?: boolean | string | object; senderName?: string; sendStatus?: object; text?: string; type?: string; }`\n\n**get** `/v1/chats/{chatID}/messages/{messageID}`\n\nRetrieve a message by final message ID, pendingMessageID, or Matrix event ID. chatID may be a Beeper chat ID or a local chat ID.\n\n### Parameters\n\n- `chatID: string`\n Chat ID. Input routes also accept the local chat ID from this installation when available.\n\n- `messageID: string`\n Message ID.\n\n### Returns\n\n- `{ id: string; accountID: string; chatID: string; senderID: string; sortKey: string; timestamp: string; attachments?: { type: 'unknown' | 'img' | 'video' | 'audio'; id?: string; duration?: number; fileName?: string; fileSize?: number; isGif?: boolean; isSticker?: boolean; isVoiceNote?: boolean; mimeType?: string; posterImg?: string; size?: object; srcURL?: string; transcription?: object; }[]; editedTimestamp?: string; isDeleted?: boolean; isHidden?: boolean; isSender?: boolean; isUnread?: boolean; linkedMessageID?: string; links?: { title: string; url: string; favicon?: string; img?: string; imgSize?: { height?: number; width?: number; }; originalURL?: string; summary?: string; }[]; mentions?: string[]; reactions?: { id: string; participantID: string; reactionKey: string; emoji?: boolean; imgURL?: string; }[]; seen?: boolean | string | object; senderName?: string; sendStatus?: { status: 'SUCCESS' | 'PENDING' | 'FAIL_RETRIABLE' | 'FAIL_PERMANENT'; timestamp: string; deliveredToUsers?: string[]; internalError?: string; message?: string; reason?: string; }; text?: string; type?: string; }`\n\n - `id: string`\n - `accountID: string`\n - `chatID: string`\n - `senderID: string`\n - `sortKey: string`\n - `timestamp: string`\n - `attachments?: { type: 'unknown' | 'img' | 'video' | 'audio'; id?: string; duration?: number; fileName?: string; fileSize?: number; isGif?: boolean; isSticker?: boolean; isVoiceNote?: boolean; mimeType?: string; posterImg?: string; size?: { height?: number; width?: number; }; srcURL?: string; transcription?: { engine: string; transcription: string; language?: string; }; }[]`\n - `editedTimestamp?: string`\n - `isDeleted?: boolean`\n - `isHidden?: boolean`\n - `isSender?: boolean`\n - `isUnread?: boolean`\n - `linkedMessageID?: string`\n - `links?: { title: string; url: string; favicon?: string; img?: string; imgSize?: { height?: number; width?: number; }; originalURL?: string; summary?: string; }[]`\n - `mentions?: string[]`\n - `reactions?: { id: string; participantID: string; reactionKey: string; emoji?: boolean; imgURL?: string; }[]`\n - `seen?: boolean | string | object`\n - `senderName?: string`\n - `sendStatus?: { status: 'SUCCESS' | 'PENDING' | 'FAIL_RETRIABLE' | 'FAIL_PERMANENT'; timestamp: string; deliveredToUsers?: string[]; internalError?: string; message?: string; reason?: string; }`\n - `text?: string`\n - `type?: string`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst message = await client.messages.retrieve('1343993', { chatID: '!NCdzlIaMjZUmvmvyHU:beeper.com' });\n\nconsole.log(message);\n```",
perLanguage: {
typescript: {
method: 'client.messages.retrieve',
@@ -1132,7 +1545,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
cli: {
method: 'messages retrieve',
example:
- "beeper-desktop-cli messages retrieve \\\n --access-token 'My Access Token' \\\n --chat-id '!NCdzlIaMjZUmvmvyHU:beeper.com' \\\n --message-id 1343993",
+ "beeper-desktop messages retrieve \\\n --access-token 'My Access Token' \\\n --chat-id '!NCdzlIaMjZUmvmvyHU:beeper.com' \\\n --message-id 1343993",
},
php: {
method: 'messages->retrieve',
@@ -1157,7 +1570,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
response:
"{ id: string; accountID: string; chatID: string; senderID: string; sortKey: string; timestamp: string; attachments?: object[]; editedTimestamp?: string; isDeleted?: boolean; isHidden?: boolean; isSender?: boolean; isUnread?: boolean; linkedMessageID?: string; links?: { title: string; url: string; favicon?: string; img?: string; imgSize?: object; originalURL?: string; summary?: string; }[]; mentions?: string[]; reactions?: object[]; seen?: boolean | string | object; senderName?: string; sendStatus?: { status: 'SUCCESS' | 'PENDING' | 'FAIL_RETRIABLE' | 'FAIL_PERMANENT'; timestamp: string; deliveredToUsers?: string[]; internalError?: string; message?: string; reason?: string; }; text?: string; type?: string; }",
markdown:
- "## update\n\n`client.messages.update(chatID: string, messageID: string, text: string): object`\n\n**put** `/v1/chats/{chatID}/messages/{messageID}`\n\nEdit the text content of an existing message. Messages with attachments cannot be edited.\n\n### Parameters\n\n- `chatID: string`\n Chat ID. Input routes also accept the local chat ID from this Beeper Desktop installation when available.\n\n- `messageID: string`\n Message ID.\n\n- `text: string`\n New text content for the message\n\n### Returns\n\n- `{ id: string; accountID: string; chatID: string; senderID: string; sortKey: string; timestamp: string; attachments?: object[]; editedTimestamp?: string; isDeleted?: boolean; isHidden?: boolean; isSender?: boolean; isUnread?: boolean; linkedMessageID?: string; links?: { title: string; url: string; favicon?: string; img?: string; imgSize?: object; originalURL?: string; summary?: string; }[]; mentions?: string[]; reactions?: object[]; seen?: boolean | string | object; senderName?: string; sendStatus?: { status: 'SUCCESS' | 'PENDING' | 'FAIL_RETRIABLE' | 'FAIL_PERMANENT'; timestamp: string; deliveredToUsers?: string[]; internalError?: string; message?: string; reason?: string; }; text?: string; type?: string; }`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst message = await client.messages.update('1343993', { chatID: '!NCdzlIaMjZUmvmvyHU:beeper.com', text: 'x' });\n\nconsole.log(message);\n```",
+ "## update\n\n`client.messages.update(chatID: string, messageID: string, text: string): object`\n\n**put** `/v1/chats/{chatID}/messages/{messageID}`\n\nEdit the text content of an existing message. Messages with attachments cannot be edited.\n\n### Parameters\n\n- `chatID: string`\n Chat ID. Input routes also accept the local chat ID from this installation when available.\n\n- `messageID: string`\n Message ID.\n\n- `text: string`\n New text content for the message\n\n### Returns\n\n- `{ id: string; accountID: string; chatID: string; senderID: string; sortKey: string; timestamp: string; attachments?: object[]; editedTimestamp?: string; isDeleted?: boolean; isHidden?: boolean; isSender?: boolean; isUnread?: boolean; linkedMessageID?: string; links?: { title: string; url: string; favicon?: string; img?: string; imgSize?: object; originalURL?: string; summary?: string; }[]; mentions?: string[]; reactions?: object[]; seen?: boolean | string | object; senderName?: string; sendStatus?: { status: 'SUCCESS' | 'PENDING' | 'FAIL_RETRIABLE' | 'FAIL_PERMANENT'; timestamp: string; deliveredToUsers?: string[]; internalError?: string; message?: string; reason?: string; }; text?: string; type?: string; }`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst message = await client.messages.update('1343993', { chatID: '!NCdzlIaMjZUmvmvyHU:beeper.com', text: 'x' });\n\nconsole.log(message);\n```",
perLanguage: {
typescript: {
method: 'client.messages.update',
@@ -1177,7 +1590,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
cli: {
method: 'messages update',
example:
- "beeper-desktop-cli messages update \\\n --access-token 'My Access Token' \\\n --chat-id '!NCdzlIaMjZUmvmvyHU:beeper.com' \\\n --message-id 1343993 \\\n --text x",
+ "beeper-desktop messages update \\\n --access-token 'My Access Token' \\\n --chat-id '!NCdzlIaMjZUmvmvyHU:beeper.com' \\\n --message-id 1343993 \\\n --text x",
},
php: {
method: 'messages->update',
@@ -1201,7 +1614,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
qualified: 'client.messages.delete',
params: ['chatID: string;', 'messageID: string;', 'forEveryone?: boolean;'],
markdown:
- "## delete\n\n`client.messages.delete(chatID: string, messageID: string, forEveryone?: boolean): void`\n\n**delete** `/v1/chats/{chatID}/messages/{messageID}`\n\nDelete a message by final message ID. Pending message IDs are not accepted because messages cannot be deleted while sending.\n\n### Parameters\n\n- `chatID: string`\n Chat ID. Input routes also accept the local chat ID from this Beeper Desktop installation when available.\n\n- `messageID: string`\n Message ID.\n\n- `forEveryone?: boolean`\n True to request deletion for everyone when the network supports it; false to delete only for the authenticated user when supported.\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nawait client.messages.delete('1343993', { chatID: '!NCdzlIaMjZUmvmvyHU:beeper.com' })\n```",
+ "## delete\n\n`client.messages.delete(chatID: string, messageID: string, forEveryone?: boolean): void`\n\n**delete** `/v1/chats/{chatID}/messages/{messageID}`\n\nDelete a message by final message ID. Pending message IDs are not accepted because messages cannot be deleted while sending.\n\n### Parameters\n\n- `chatID: string`\n Chat ID. Input routes also accept the local chat ID from this installation when available.\n\n- `messageID: string`\n Message ID.\n\n- `forEveryone?: boolean`\n True to request deletion for everyone when the network supports it; false to delete only for the authenticated user when supported.\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nawait client.messages.delete('1343993', { chatID: '!NCdzlIaMjZUmvmvyHU:beeper.com' })\n```",
perLanguage: {
typescript: {
method: 'client.messages.delete',
@@ -1221,7 +1634,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
cli: {
method: 'messages delete',
example:
- "beeper-desktop-cli messages delete \\\n --access-token 'My Access Token' \\\n --chat-id '!NCdzlIaMjZUmvmvyHU:beeper.com' \\\n --message-id 1343993",
+ "beeper-desktop messages delete \\\n --access-token 'My Access Token' \\\n --chat-id '!NCdzlIaMjZUmvmvyHU:beeper.com' \\\n --message-id 1343993",
},
php: {
method: 'messages->delete',
@@ -1240,13 +1653,13 @@ const EMBEDDED_METHODS: MethodEntry[] = [
httpMethod: '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.',
+ 'Download a file from an mxc:// or localmxc:// URL to the device running the Beeper Client API and return the local file URL.',
stainlessPath: '(resource) assets > (method) download',
qualified: 'client.assets.download',
params: ['url: string;'],
response: '{ error?: string; srcURL?: string; }',
markdown:
- "## download\n\n`client.assets.download(url: string): { error?: string; srcURL?: string; }`\n\n**post** `/v1/assets/download`\n\nDownload a Matrix file using its mxc:// or localmxc:// URL to the device running Beeper Desktop and return the local file URL.\n\n### Parameters\n\n- `url: string`\n Matrix content URL (mxc:// or localmxc://) for the file to download.\n\n### Returns\n\n- `{ error?: string; srcURL?: string; }`\n\n - `error?: string`\n - `srcURL?: string`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.assets.download({ url: 'mxc://example.org/Q4x9CqGz1pB3Oa6XgJ' });\n\nconsole.log(response);\n```",
+ "## download\n\n`client.assets.download(url: string): { error?: string; srcURL?: string; }`\n\n**post** `/v1/assets/download`\n\nDownload a file from an mxc:// or localmxc:// URL to the device running the Beeper Client API and return the local file URL.\n\n### Parameters\n\n- `url: string`\n Beeper media URL (mxc:// or localmxc://) for the file to download.\n\n### Returns\n\n- `{ error?: string; srcURL?: string; }`\n\n - `error?: string`\n - `srcURL?: string`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.assets.download({ url: 'mxc://example.org/Q4x9CqGz1pB3Oa6XgJ' });\n\nconsole.log(response);\n```",
perLanguage: {
typescript: {
method: 'client.assets.download',
@@ -1266,7 +1679,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
cli: {
method: 'assets download',
example:
- "beeper-desktop-cli assets download \\\n --access-token 'My Access Token' \\\n --url mxc://example.org/Q4x9CqGz1pB3Oa6XgJ",
+ "beeper-desktop assets download \\\n --access-token 'My Access Token' \\\n --url mxc://example.org/Q4x9CqGz1pB3Oa6XgJ",
},
php: {
method: 'assets->download',
@@ -1285,14 +1698,14 @@ const EMBEDDED_METHODS: MethodEntry[] = [
httpMethod: '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.',
+ 'Upload a file to a temporary location using multipart/form-data. Returns an uploadID that can be referenced when sending a message or creating a draft attachment.',
stainlessPath: '(resource) assets > (method) upload',
qualified: 'client.assets.upload',
params: ['file: string;', 'fileName?: string;', 'mimeType?: string;'],
response:
'{ duration?: number; error?: string; fileName?: string; fileSize?: number; height?: number; mimeType?: string; srcURL?: string; uploadID?: string; width?: number; }',
markdown:
- "## upload\n\n`client.assets.upload(file: string, fileName?: string, mimeType?: string): { duration?: number; error?: string; fileName?: string; fileSize?: number; height?: number; mimeType?: string; srcURL?: string; uploadID?: string; width?: number; }`\n\n**post** `/v1/assets/upload`\n\nUpload 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.\n\n### Parameters\n\n- `file: string`\n The file to upload (max 500 MB).\n\n- `fileName?: string`\n Original filename. Defaults to the uploaded file name if omitted\n\n- `mimeType?: string`\n MIME type. Auto-detected from magic bytes if omitted\n\n### Returns\n\n- `{ duration?: number; error?: string; fileName?: string; fileSize?: number; height?: number; mimeType?: string; srcURL?: string; uploadID?: string; width?: number; }`\n\n - `duration?: number`\n - `error?: string`\n - `fileName?: string`\n - `fileSize?: number`\n - `height?: number`\n - `mimeType?: string`\n - `srcURL?: string`\n - `uploadID?: string`\n - `width?: number`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.assets.upload({ file: fs.createReadStream('path/to/file') });\n\nconsole.log(response);\n```",
+ "## upload\n\n`client.assets.upload(file: string, fileName?: string, mimeType?: string): { duration?: number; error?: string; fileName?: string; fileSize?: number; height?: number; mimeType?: string; srcURL?: string; uploadID?: string; width?: number; }`\n\n**post** `/v1/assets/upload`\n\nUpload a file to a temporary location using multipart/form-data. Returns an uploadID that can be referenced when sending a message or creating a draft attachment.\n\n### Parameters\n\n- `file: string`\n The file to upload (max 500 MB).\n\n- `fileName?: string`\n Original filename. Defaults to the uploaded file name if omitted\n\n- `mimeType?: string`\n MIME type. Auto-detected from magic bytes if omitted\n\n### Returns\n\n- `{ duration?: number; error?: string; fileName?: string; fileSize?: number; height?: number; mimeType?: string; srcURL?: string; uploadID?: string; width?: number; }`\n\n - `duration?: number`\n - `error?: string`\n - `fileName?: string`\n - `fileSize?: number`\n - `height?: number`\n - `mimeType?: string`\n - `srcURL?: string`\n - `uploadID?: string`\n - `width?: number`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.assets.upload({ file: fs.createReadStream('path/to/file') });\n\nconsole.log(response);\n```",
perLanguage: {
typescript: {
method: 'client.assets.upload',
@@ -1312,7 +1725,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
cli: {
method: 'assets upload',
example:
- "beeper-desktop-cli assets upload \\\n --access-token 'My Access Token' \\\n --file 'Example data'",
+ "beeper-desktop assets upload \\\n --access-token 'My Access Token' \\\n --file 'Example data'",
},
php: {
method: 'assets->upload',
@@ -1331,14 +1744,14 @@ const EMBEDDED_METHODS: MethodEntry[] = [
httpMethod: '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.',
+ 'Upload a file using a JSON body with base64-encoded content. Returns an uploadID that can be referenced when sending a message or creating a draft attachment. Alternative to the multipart upload endpoint.',
stainlessPath: '(resource) assets > (method) upload_base64',
qualified: 'client.assets.uploadBase64',
params: ['content: string;', 'fileName?: string;', 'mimeType?: string;'],
response:
'{ duration?: number; error?: string; fileName?: string; fileSize?: number; height?: number; mimeType?: string; srcURL?: string; uploadID?: string; width?: number; }',
markdown:
- "## upload_base64\n\n`client.assets.uploadBase64(content: string, fileName?: string, mimeType?: string): { duration?: number; error?: string; fileName?: string; fileSize?: number; height?: number; mimeType?: string; srcURL?: string; uploadID?: string; width?: number; }`\n\n**post** `/v1/assets/upload/base64`\n\nUpload 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.\n\n### Parameters\n\n- `content: string`\n Base64-encoded file content (max ~500MB decoded)\n\n- `fileName?: string`\n Original filename. Generated if omitted\n\n- `mimeType?: string`\n MIME type. Auto-detected from magic bytes if omitted\n\n### Returns\n\n- `{ duration?: number; error?: string; fileName?: string; fileSize?: number; height?: number; mimeType?: string; srcURL?: string; uploadID?: string; width?: number; }`\n\n - `duration?: number`\n - `error?: string`\n - `fileName?: string`\n - `fileSize?: number`\n - `height?: number`\n - `mimeType?: string`\n - `srcURL?: string`\n - `uploadID?: string`\n - `width?: number`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.assets.uploadBase64({ content: 'x' });\n\nconsole.log(response);\n```",
+ "## upload_base64\n\n`client.assets.uploadBase64(content: string, fileName?: string, mimeType?: string): { duration?: number; error?: string; fileName?: string; fileSize?: number; height?: number; mimeType?: string; srcURL?: string; uploadID?: string; width?: number; }`\n\n**post** `/v1/assets/upload/base64`\n\nUpload a file using a JSON body with base64-encoded content. Returns an uploadID that can be referenced when sending a message or creating a draft attachment. Alternative to the multipart upload endpoint.\n\n### Parameters\n\n- `content: string`\n Base64-encoded file content (max ~500MB decoded)\n\n- `fileName?: string`\n Original filename. Generated if omitted\n\n- `mimeType?: string`\n MIME type. Auto-detected from magic bytes if omitted\n\n### Returns\n\n- `{ duration?: number; error?: string; fileName?: string; fileSize?: number; height?: number; mimeType?: string; srcURL?: string; uploadID?: string; width?: number; }`\n\n - `duration?: number`\n - `error?: string`\n - `fileName?: string`\n - `fileSize?: number`\n - `height?: number`\n - `mimeType?: string`\n - `srcURL?: string`\n - `uploadID?: string`\n - `width?: number`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.assets.uploadBase64({ content: 'x' });\n\nconsole.log(response);\n```",
perLanguage: {
typescript: {
method: 'client.assets.uploadBase64',
@@ -1358,7 +1771,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
cli: {
method: 'assets upload_base64',
example:
- "beeper-desktop-cli assets upload-base64 \\\n --access-token 'My Access Token' \\\n --content x",
+ "beeper-desktop assets upload-base64 \\\n --access-token 'My Access Token' \\\n --content x",
},
php: {
method: 'assets->uploadBase64',
@@ -1402,7 +1815,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
},
cli: {
method: 'assets serve',
- example: "beeper-desktop-cli assets serve \\\n --access-token 'My Access Token' \\\n --url x",
+ example: "beeper-desktop assets serve \\\n --access-token 'My Access Token' \\\n --url x",
},
php: {
method: 'assets->serve',
@@ -1421,13 +1834,13 @@ const EMBEDDED_METHODS: MethodEntry[] = [
httpMethod: 'get',
summary: 'Retrieve server info',
description:
- 'Returns app, platform, server, endpoint discovery, OAuth, and WebSocket metadata for this Beeper Desktop instance.',
+ 'Returns app, platform, server, endpoint discovery, OAuth, and WebSocket metadata for this Beeper Client API server.',
stainlessPath: '(resource) info > (method) retrieve',
qualified: 'client.info.retrieve',
response:
'{ app: { bundle_id: string; name: string; version: string; }; endpoints: { mcp: string; oauth: { authorization_endpoint: string; introspection_endpoint: string; registration_endpoint: string; revocation_endpoint: string; token_endpoint: string; userinfo_endpoint: string; }; spec: string; ws_events: string; }; platform: { arch: string; os: string; release?: string; }; server: { base_url: string; hostname: string; mcp_enabled: boolean; port: number; remote_access: boolean; status: string; }; }',
markdown:
- "## retrieve\n\n`client.info.retrieve(): { app: object; endpoints: object; platform: object; server: object; }`\n\n**get** `/v1/info`\n\nReturns app, platform, server, endpoint discovery, OAuth, and WebSocket metadata for this Beeper Desktop instance.\n\n### Returns\n\n- `{ app: { bundle_id: string; name: string; version: string; }; endpoints: { mcp: string; oauth: { authorization_endpoint: string; introspection_endpoint: string; registration_endpoint: string; revocation_endpoint: string; token_endpoint: string; userinfo_endpoint: string; }; spec: string; ws_events: string; }; platform: { arch: string; os: string; release?: string; }; server: { base_url: string; hostname: string; mcp_enabled: boolean; port: number; remote_access: boolean; status: string; }; }`\n\n - `app: { bundle_id: string; name: string; version: string; }`\n - `endpoints: { mcp: string; oauth: { authorization_endpoint: string; introspection_endpoint: string; registration_endpoint: string; revocation_endpoint: string; token_endpoint: string; userinfo_endpoint: string; }; spec: string; ws_events: string; }`\n - `platform: { arch: string; os: string; release?: string; }`\n - `server: { base_url: string; hostname: string; mcp_enabled: boolean; port: number; remote_access: boolean; status: string; }`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst info = await client.info.retrieve();\n\nconsole.log(info);\n```",
+ "## retrieve\n\n`client.info.retrieve(): { app: object; endpoints: object; platform: object; server: object; }`\n\n**get** `/v1/info`\n\nReturns app, platform, server, endpoint discovery, OAuth, and WebSocket metadata for this Beeper Client API server.\n\n### Returns\n\n- `{ app: { bundle_id: string; name: string; version: string; }; endpoints: { mcp: string; oauth: { authorization_endpoint: string; introspection_endpoint: string; registration_endpoint: string; revocation_endpoint: string; token_endpoint: string; userinfo_endpoint: string; }; spec: string; ws_events: string; }; platform: { arch: string; os: string; release?: string; }; server: { base_url: string; hostname: string; mcp_enabled: boolean; port: number; remote_access: boolean; status: string; }; }`\n\n - `app: { bundle_id: string; name: string; version: string; }`\n - `endpoints: { mcp: string; oauth: { authorization_endpoint: string; introspection_endpoint: string; registration_endpoint: string; revocation_endpoint: string; token_endpoint: string; userinfo_endpoint: string; }; spec: string; ws_events: string; }`\n - `platform: { arch: string; os: string; release?: string; }`\n - `server: { base_url: string; hostname: string; mcp_enabled: boolean; port: number; remote_access: boolean; status: string; }`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst info = await client.info.retrieve();\n\nconsole.log(info);\n```",
perLanguage: {
typescript: {
method: 'client.info.retrieve',
@@ -1446,7 +1859,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
},
cli: {
method: 'info retrieve',
- example: "beeper-desktop-cli info retrieve \\\n --access-token 'My Access Token'",
+ example: "beeper-desktop info retrieve \\\n --access-token 'My Access Token'",
},
php: {
method: 'info->retrieve',
@@ -1459,13 +1872,772 @@ const EMBEDDED_METHODS: MethodEntry[] = [
},
},
},
+ {
+ name: 'session',
+ endpoint: '/v1/app/setup',
+ httpMethod: 'get',
+ summary: 'Get Beeper app setup state',
+ description:
+ 'Return the current Beeper Desktop or Beeper Server sign-in and encrypted messaging setup state. This endpoint is public before sign-in so apps can discover that sign-in is needed; after sign-in, pass a read token.',
+ stainlessPath: '(resource) app > (method) session',
+ qualified: 'client.app.session',
+ response:
+ "{ e2ee: { crossSigning: boolean; firstSyncDone: boolean; hasBackedUpRecoveryKey: boolean; initialized: boolean; keyBackup: boolean; secrets: { masterKey: boolean; megolmBackupKey: boolean; recoveryKey: boolean; selfSigningKey: boolean; userSigningKey: boolean; }; secretStorage: boolean; verified: boolean; recoveryKeyGeneratedAt?: number; }; state: string; matrix?: { deviceID: string; homeserver: string; userID: string; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }; }",
+ markdown:
+ "## session\n\n`client.app.session(): { e2ee: object; state: string; matrix?: object; verification?: object; }`\n\n**get** `/v1/app/setup`\n\nReturn the current Beeper Desktop or Beeper Server sign-in and encrypted messaging setup state. This endpoint is public before sign-in so apps can discover that sign-in is needed; after sign-in, pass a read token.\n\n### Returns\n\n- `{ e2ee: { crossSigning: boolean; firstSyncDone: boolean; hasBackedUpRecoveryKey: boolean; initialized: boolean; keyBackup: boolean; secrets: { masterKey: boolean; megolmBackupKey: boolean; recoveryKey: boolean; selfSigningKey: boolean; userSigningKey: boolean; }; secretStorage: boolean; verified: boolean; recoveryKeyGeneratedAt?: number; }; state: string; matrix?: { deviceID: string; homeserver: string; userID: string; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }; }`\n\n - `e2ee: { crossSigning: boolean; firstSyncDone: boolean; hasBackedUpRecoveryKey: boolean; initialized: boolean; keyBackup: boolean; secrets: { masterKey: boolean; megolmBackupKey: boolean; recoveryKey: boolean; selfSigningKey: boolean; userSigningKey: boolean; }; secretStorage: boolean; verified: boolean; recoveryKeyGeneratedAt?: number; }`\n - `state: string`\n - `matrix?: { deviceID: string; homeserver: string; userID: string; }`\n - `verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.app.session();\n\nconsole.log(response);\n```",
+ perLanguage: {
+ typescript: {
+ method: 'client.app.session',
+ example:
+ "import BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop({\n accessToken: process.env['BEEPER_ACCESS_TOKEN'], // This is the default and can be omitted\n});\n\nconst response = await client.app.session();\n\nconsole.log(response.e2ee);",
+ },
+ python: {
+ method: 'app.session',
+ example:
+ 'import os\nfrom beeper_desktop_api import BeeperDesktop\n\nclient = BeeperDesktop(\n access_token=os.environ.get("BEEPER_ACCESS_TOKEN"), # This is the default and can be omitted\n)\nresponse = client.app.session()\nprint(response.e2ee)',
+ },
+ go: {
+ method: 'client.App.Session',
+ example:
+ 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/beeper/desktop-api-go"\n\t"github.com/beeper/desktop-api-go/option"\n)\n\nfunc main() {\n\tclient := beeperdesktopapi.NewClient(\n\t\toption.WithAccessToken("My Access Token"),\n\t)\n\tresponse, err := client.App.Session(context.TODO())\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.E2EE)\n}\n',
+ },
+ cli: {
+ method: 'app session',
+ example: "beeper-desktop app session \\\n --access-token 'My Access Token'",
+ },
+ php: {
+ method: 'app->session',
+ example:
+ "app->session();\n\nvar_dump($response);",
+ },
+ http: {
+ example:
+ 'curl http://localhost:23373/v1/app/setup \\\n -H "Authorization: Bearer $BEEPER_ACCESS_TOKEN"',
+ },
+ },
+ },
+ {
+ name: 'start',
+ endpoint: '/v1/app/setup/start',
+ httpMethod: 'post',
+ summary: 'Start Beeper app setup',
+ description:
+ 'Start setting up Beeper Desktop or Beeper Server. The flow supports existing Beeper accounts and new account creation.',
+ stainlessPath: '(resource) app.login > (method) start',
+ qualified: 'client.app.login.start',
+ response: '{ setupRequestID: string; signInMethods: string[]; }',
+ markdown:
+ "## start\n\n`client.app.login.start(): { setupRequestID: string; signInMethods: string[]; }`\n\n**post** `/v1/app/setup/start`\n\nStart setting up Beeper Desktop or Beeper Server. The flow supports existing Beeper accounts and new account creation.\n\n### Returns\n\n- `{ setupRequestID: string; signInMethods: string[]; }`\n\n - `setupRequestID: string`\n - `signInMethods: string[]`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.app.login.start();\n\nconsole.log(response);\n```",
+ perLanguage: {
+ typescript: {
+ method: 'client.app.login.start',
+ example:
+ "import BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.app.login.start();\n\nconsole.log(response.setupRequestID);",
+ },
+ python: {
+ method: 'app.login.start',
+ example:
+ 'from beeper_desktop_api import BeeperDesktop\n\nclient = BeeperDesktop()\nresponse = client.app.login.start()\nprint(response.setup_request_id)',
+ },
+ go: {
+ method: 'client.App.Login.Start',
+ example:
+ 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/beeper/desktop-api-go"\n\t"github.com/beeper/desktop-api-go/option"\n)\n\nfunc main() {\n\tclient := beeperdesktopapi.NewClient(\n\t\toption.WithAccessToken("My Access Token"),\n\t)\n\tresponse, err := client.App.Login.Start(context.TODO())\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.SetupRequestID)\n}\n',
+ },
+ cli: {
+ method: 'login start',
+ example: "beeper-desktop app:login start \\\n --access-token 'My Access Token'",
+ },
+ php: {
+ method: 'app->login->start',
+ example:
+ "app->login->start();\n\nvar_dump($response);",
+ },
+ http: {
+ example:
+ 'curl http://localhost:23373/v1/app/setup/start \\\n -X POST \\\n -H "Authorization: Bearer $BEEPER_ACCESS_TOKEN"',
+ },
+ },
+ },
+ {
+ name: 'email',
+ endpoint: '/v1/app/setup/email',
+ httpMethod: 'post',
+ summary: 'Send setup sign-in code',
+ description: 'Send a sign-in code to the user email address for app setup.',
+ stainlessPath: '(resource) app.login > (method) email',
+ qualified: 'client.app.login.email',
+ params: ['email: string;', 'setupRequestID: string;'],
+ markdown:
+ "## email\n\n`client.app.login.email(email: string, setupRequestID: string): void`\n\n**post** `/v1/app/setup/email`\n\nSend a sign-in code to the user email address for app setup.\n\n### Parameters\n\n- `email: string`\n Email address to send the sign-in code to.\n\n- `setupRequestID: string`\n Setup request ID returned by the start step.\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nawait client.app.login.email({ email: 'dev@stainless.com', setupRequestID: 'setupRequestID' })\n```",
+ perLanguage: {
+ typescript: {
+ method: 'client.app.login.email',
+ example:
+ "import BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nawait client.app.login.email({ email: 'dev@stainless.com', setupRequestID: 'setupRequestID' });",
+ },
+ python: {
+ method: 'app.login.email',
+ example:
+ 'from beeper_desktop_api import BeeperDesktop\n\nclient = BeeperDesktop()\nclient.app.login.email(\n email="dev@stainless.com",\n setup_request_id="setupRequestID",\n)',
+ },
+ go: {
+ method: 'client.App.Login.Email',
+ example:
+ 'package main\n\nimport (\n\t"context"\n\n\t"github.com/beeper/desktop-api-go"\n\t"github.com/beeper/desktop-api-go/option"\n)\n\nfunc main() {\n\tclient := beeperdesktopapi.NewClient(\n\t\toption.WithAccessToken("My Access Token"),\n\t)\n\terr := client.App.Login.Email(context.TODO(), beeperdesktopapi.AppLoginEmailParams{\n\t\tEmail: "dev@stainless.com",\n\t\tSetupRequestID: "setupRequestID",\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n}\n',
+ },
+ cli: {
+ method: 'login email',
+ example:
+ "beeper-desktop app:login email \\\n --access-token 'My Access Token' \\\n --email dev@stainless.com \\\n --setup-request-id setupRequestID",
+ },
+ php: {
+ method: 'app->login->email',
+ example:
+ "app->login->email(\n email: 'dev@stainless.com', setupRequestID: 'setupRequestID'\n);\n\nvar_dump($result);",
+ },
+ http: {
+ example:
+ 'curl http://localhost:23373/v1/app/setup/email \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $BEEPER_ACCESS_TOKEN" \\\n -d \'{\n "email": "dev@stainless.com",\n "setupRequestID": "setupRequestID"\n }\'',
+ },
+ },
+ },
+ {
+ name: 'response',
+ endpoint: '/v1/app/setup/response',
+ httpMethod: 'post',
+ summary: 'Complete setup sign-in with code',
+ description:
+ 'Finish setup sign-in with the code sent to the user email address. If the user needs a new account, the response includes account creation copy and username suggestions.',
+ stainlessPath: '(resource) app.login > (method) response',
+ qualified: 'client.app.login.response',
+ params: ['response: string;', 'setupRequestID: string;'],
+ response:
+ "{ matrix: { accessToken: string; deviceID: string; homeserver: string; userID: string; }; session: { e2ee: { crossSigning: boolean; firstSyncDone: boolean; hasBackedUpRecoveryKey: boolean; initialized: boolean; keyBackup: boolean; secrets: object; secretStorage: boolean; verified: boolean; recoveryKeyGeneratedAt?: number; }; state: string; matrix?: { deviceID: string; homeserver: string; userID: string; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: object; otherDevice?: object; otherUserID?: string; qr?: object; sas?: object; }; }; } | { copy: { submit: 'Continue'; terms: 'By continuing, you agree to the Terms of Use and acknowledge the Privacy Policy.'; title: 'Choose your username'; usernamePlaceholder: 'Username'; }; leadToken: string; registrationRequired: true; setupRequestID: string; usernameSuggestions?: string[]; }",
+ markdown:
+ "## response\n\n`client.app.login.response(response: string, setupRequestID: string): { matrix: object; session: object; } | { copy: object; leadToken: string; registrationRequired: true; setupRequestID: string; usernameSuggestions?: string[]; }`\n\n**post** `/v1/app/setup/response`\n\nFinish setup sign-in with the code sent to the user email address. If the user needs a new account, the response includes account creation copy and username suggestions.\n\n### Parameters\n\n- `response: string`\n Sign-in code from the user email.\n\n- `setupRequestID: string`\n Setup request ID returned by the start step.\n\n### Returns\n\n- `{ matrix: { accessToken: string; deviceID: string; homeserver: string; userID: string; }; session: { e2ee: { crossSigning: boolean; firstSyncDone: boolean; hasBackedUpRecoveryKey: boolean; initialized: boolean; keyBackup: boolean; secrets: object; secretStorage: boolean; verified: boolean; recoveryKeyGeneratedAt?: number; }; state: string; matrix?: { deviceID: string; homeserver: string; userID: string; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: object; otherDevice?: object; otherUserID?: string; qr?: object; sas?: object; }; }; } | { copy: { submit: 'Continue'; terms: 'By continuing, you agree to the Terms of Use and acknowledge the Privacy Policy.'; title: 'Choose your username'; usernamePlaceholder: 'Username'; }; leadToken: string; registrationRequired: true; setupRequestID: string; usernameSuggestions?: string[]; }`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.app.login.response({ response: 'response', setupRequestID: 'setupRequestID' });\n\nconsole.log(response);\n```",
+ perLanguage: {
+ typescript: {
+ method: 'client.app.login.response',
+ example:
+ "import BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.app.login.response({\n response: 'response',\n setupRequestID: 'setupRequestID',\n});\n\nconsole.log(response);",
+ },
+ python: {
+ method: 'app.login.response',
+ example:
+ 'from beeper_desktop_api import BeeperDesktop\n\nclient = BeeperDesktop()\nresponse = client.app.login.response(\n response="response",\n setup_request_id="setupRequestID",\n)\nprint(response)',
+ },
+ go: {
+ method: 'client.App.Login.Response',
+ example:
+ 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/beeper/desktop-api-go"\n\t"github.com/beeper/desktop-api-go/option"\n)\n\nfunc main() {\n\tclient := beeperdesktopapi.NewClient(\n\t\toption.WithAccessToken("My Access Token"),\n\t)\n\tresponse, err := client.App.Login.Response(context.TODO(), beeperdesktopapi.AppLoginResponseParams{\n\t\tResponse: "response",\n\t\tSetupRequestID: "setupRequestID",\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response)\n}\n',
+ },
+ cli: {
+ method: 'login response',
+ example:
+ "beeper-desktop app:login response \\\n --access-token 'My Access Token' \\\n --response response \\\n --setup-request-id setupRequestID",
+ },
+ php: {
+ method: 'app->login->response',
+ example:
+ "app->login->response(\n response: 'response', setupRequestID: 'setupRequestID'\n);\n\nvar_dump($response);",
+ },
+ http: {
+ example:
+ 'curl http://localhost:23373/v1/app/setup/response \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $BEEPER_ACCESS_TOKEN" \\\n -d \'{\n "response": "response",\n "setupRequestID": "setupRequestID"\n }\'',
+ },
+ },
+ },
+ {
+ name: 'register',
+ endpoint: '/v1/app/setup/register',
+ httpMethod: 'post',
+ summary: 'Create account for setup',
+ description: 'Create a Beeper account after the user chooses a username and accepts the Terms of Use.',
+ stainlessPath: '(resource) app.login > (method) register',
+ qualified: 'client.app.login.register',
+ params: ['acceptTerms: true;', 'leadToken: string;', 'setupRequestID: string;', 'username: string;'],
+ response:
+ "{ matrix: { accessToken: string; deviceID: string; homeserver: string; userID: string; }; session: { e2ee: { crossSigning: boolean; firstSyncDone: boolean; hasBackedUpRecoveryKey: boolean; initialized: boolean; keyBackup: boolean; secrets: object; secretStorage: boolean; verified: boolean; recoveryKeyGeneratedAt?: number; }; state: string; matrix?: { deviceID: string; homeserver: string; userID: string; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: object; otherDevice?: object; otherUserID?: string; qr?: object; sas?: object; }; }; }",
+ markdown:
+ "## register\n\n`client.app.login.register(acceptTerms: true, leadToken: string, setupRequestID: string, username: string): { matrix: object; session: object; }`\n\n**post** `/v1/app/setup/register`\n\nCreate a Beeper account after the user chooses a username and accepts the Terms of Use.\n\n### Parameters\n\n- `acceptTerms: true`\n Confirms that the user agreed to our [terms of use](https://www.beeper.com/terms-onboarding) and has read our [privacy policy](https://www.beeper.com/privacy).\n\n- `leadToken: string`\n Registration token returned by Beeper.\n\n- `setupRequestID: string`\n Setup request ID returned by the start step.\n\n- `username: string`\n Username selected by the user.\n\n### Returns\n\n- `{ matrix: { accessToken: string; deviceID: string; homeserver: string; userID: string; }; session: { e2ee: { crossSigning: boolean; firstSyncDone: boolean; hasBackedUpRecoveryKey: boolean; initialized: boolean; keyBackup: boolean; secrets: object; secretStorage: boolean; verified: boolean; recoveryKeyGeneratedAt?: number; }; state: string; matrix?: { deviceID: string; homeserver: string; userID: string; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: object; otherDevice?: object; otherUserID?: string; qr?: object; sas?: object; }; }; }`\n\n - `matrix: { accessToken: string; deviceID: string; homeserver: string; userID: string; }`\n - `session: { e2ee: { crossSigning: boolean; firstSyncDone: boolean; hasBackedUpRecoveryKey: boolean; initialized: boolean; keyBackup: boolean; secrets: { masterKey: boolean; megolmBackupKey: boolean; recoveryKey: boolean; selfSigningKey: boolean; userSigningKey: boolean; }; secretStorage: boolean; verified: boolean; recoveryKeyGeneratedAt?: number; }; state: string; matrix?: { deviceID: string; homeserver: string; userID: string; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }; }`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.app.login.register({\n acceptTerms: true,\n leadToken: 'leadToken',\n setupRequestID: 'setupRequestID',\n username: 'x',\n});\n\nconsole.log(response);\n```",
+ perLanguage: {
+ typescript: {
+ method: 'client.app.login.register',
+ example:
+ "import BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.app.login.register({\n acceptTerms: true,\n leadToken: 'leadToken',\n setupRequestID: 'setupRequestID',\n username: 'x',\n});\n\nconsole.log(response.matrix);",
+ },
+ python: {
+ method: 'app.login.register',
+ example:
+ 'from beeper_desktop_api import BeeperDesktop\n\nclient = BeeperDesktop()\nresponse = client.app.login.register(\n accept_terms=True,\n lead_token="leadToken",\n setup_request_id="setupRequestID",\n username="x",\n)\nprint(response.matrix)',
+ },
+ go: {
+ method: 'client.App.Login.Register',
+ example:
+ 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/beeper/desktop-api-go"\n\t"github.com/beeper/desktop-api-go/option"\n)\n\nfunc main() {\n\tclient := beeperdesktopapi.NewClient(\n\t\toption.WithAccessToken("My Access Token"),\n\t)\n\tresponse, err := client.App.Login.Register(context.TODO(), beeperdesktopapi.AppLoginRegisterParams{\n\t\tAcceptTerms: true,\n\t\tLeadToken: "leadToken",\n\t\tSetupRequestID: "setupRequestID",\n\t\tUsername: "x",\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.Matrix)\n}\n',
+ },
+ cli: {
+ method: 'login register',
+ example:
+ "beeper-desktop app:login register \\\n --access-token 'My Access Token' \\\n --accept-terms true \\\n --lead-token leadToken \\\n --setup-request-id setupRequestID \\\n --username x",
+ },
+ php: {
+ method: 'app->login->register',
+ example:
+ "app->login->register(\n acceptTerms: true,\n leadToken: 'leadToken',\n setupRequestID: 'setupRequestID',\n username: 'x',\n);\n\nvar_dump($response);",
+ },
+ http: {
+ example:
+ 'curl http://localhost:23373/v1/app/setup/register \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $BEEPER_ACCESS_TOKEN" \\\n -d \'{\n "acceptTerms": true,\n "leadToken": "leadToken",\n "setupRequestID": "setupRequestID",\n "username": "x"\n }\'',
+ },
+ },
+ },
+ {
+ name: 'verify',
+ endpoint: '/v1/app/setup/verification/recovery-key',
+ httpMethod: 'post',
+ summary: 'Verify with recovery key',
+ description: 'Unlock encrypted messages with the user recovery key.',
+ stainlessPath: '(resource) app.login.verification.recovery_key > (method) verify',
+ qualified: 'client.app.login.verification.recoveryKey.verify',
+ params: ['recoveryKey: string;'],
+ response:
+ "{ session: { e2ee: { crossSigning: boolean; firstSyncDone: boolean; hasBackedUpRecoveryKey: boolean; initialized: boolean; keyBackup: boolean; secrets: object; secretStorage: boolean; verified: boolean; recoveryKeyGeneratedAt?: number; }; state: string; matrix?: { deviceID: string; homeserver: string; userID: string; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: object; otherDevice?: object; otherUserID?: string; qr?: object; sas?: object; }; }; }",
+ markdown:
+ "## verify\n\n`client.app.login.verification.recoveryKey.verify(recoveryKey: string): { session: object; }`\n\n**post** `/v1/app/setup/verification/recovery-key`\n\nUnlock encrypted messages with the user recovery key.\n\n### Parameters\n\n- `recoveryKey: string`\n Recovery key saved by the user.\n\n### Returns\n\n- `{ session: { e2ee: { crossSigning: boolean; firstSyncDone: boolean; hasBackedUpRecoveryKey: boolean; initialized: boolean; keyBackup: boolean; secrets: object; secretStorage: boolean; verified: boolean; recoveryKeyGeneratedAt?: number; }; state: string; matrix?: { deviceID: string; homeserver: string; userID: string; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: object; otherDevice?: object; otherUserID?: string; qr?: object; sas?: object; }; }; }`\n\n - `session: { e2ee: { crossSigning: boolean; firstSyncDone: boolean; hasBackedUpRecoveryKey: boolean; initialized: boolean; keyBackup: boolean; secrets: { masterKey: boolean; megolmBackupKey: boolean; recoveryKey: boolean; selfSigningKey: boolean; userSigningKey: boolean; }; secretStorage: boolean; verified: boolean; recoveryKeyGeneratedAt?: number; }; state: string; matrix?: { deviceID: string; homeserver: string; userID: string; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }; }`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.app.login.verification.recoveryKey.verify({ recoveryKey: 'x' });\n\nconsole.log(response);\n```",
+ perLanguage: {
+ typescript: {
+ method: 'client.app.login.verification.recoveryKey.verify',
+ example:
+ "import BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop({\n accessToken: process.env['BEEPER_ACCESS_TOKEN'], // This is the default and can be omitted\n});\n\nconst response = await client.app.login.verification.recoveryKey.verify({ recoveryKey: 'x' });\n\nconsole.log(response.session);",
+ },
+ python: {
+ method: 'app.login.verification.recovery_key.verify',
+ example:
+ 'import os\nfrom beeper_desktop_api import BeeperDesktop\n\nclient = BeeperDesktop(\n access_token=os.environ.get("BEEPER_ACCESS_TOKEN"), # This is the default and can be omitted\n)\nresponse = client.app.login.verification.recovery_key.verify(\n recovery_key="x",\n)\nprint(response.session)',
+ },
+ go: {
+ method: 'client.App.Login.Verification.RecoveryKey.Verify',
+ example:
+ 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/beeper/desktop-api-go"\n\t"github.com/beeper/desktop-api-go/option"\n)\n\nfunc main() {\n\tclient := beeperdesktopapi.NewClient(\n\t\toption.WithAccessToken("My Access Token"),\n\t)\n\tresponse, err := client.App.Login.Verification.RecoveryKey.Verify(context.TODO(), beeperdesktopapi.AppLoginVerificationRecoveryKeyVerifyParams{\n\t\tRecoveryKey: "x",\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.Session)\n}\n',
+ },
+ cli: {
+ method: 'recovery_key verify',
+ example:
+ "beeper-desktop app:login:verification:recovery-key verify \\\n --access-token 'My Access Token' \\\n --recovery-key x",
+ },
+ php: {
+ method: 'app->login->verification->recoveryKey->verify',
+ example:
+ "app->login->verification->recoveryKey->verify(\n recoveryKey: 'x'\n);\n\nvar_dump($response);",
+ },
+ http: {
+ example:
+ 'curl http://localhost:23373/v1/app/setup/verification/recovery-key \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $BEEPER_ACCESS_TOKEN" \\\n -d \'{\n "recoveryKey": "x"\n }\'',
+ },
+ },
+ },
+ {
+ name: 'create',
+ endpoint: '/v1/app/setup/verification/recovery-key/reset',
+ httpMethod: 'post',
+ summary: 'Create new recovery key',
+ description: 'Create a new recovery key when the user cannot use the existing one.',
+ stainlessPath: '(resource) app.login.verification.recovery_key.reset > (method) create',
+ qualified: 'client.app.login.verification.recoveryKey.reset.create',
+ params: ['existingRecoveryKey?: string;'],
+ response:
+ "{ recoveryKey: string; session: { e2ee: { crossSigning: boolean; firstSyncDone: boolean; hasBackedUpRecoveryKey: boolean; initialized: boolean; keyBackup: boolean; secrets: object; secretStorage: boolean; verified: boolean; recoveryKeyGeneratedAt?: number; }; state: string; matrix?: { deviceID: string; homeserver: string; userID: string; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: object; otherDevice?: object; otherUserID?: string; qr?: object; sas?: object; }; }; }",
+ markdown:
+ "## create\n\n`client.app.login.verification.recoveryKey.reset.create(existingRecoveryKey?: string): { recoveryKey: string; session: object; }`\n\n**post** `/v1/app/setup/verification/recovery-key/reset`\n\nCreate a new recovery key when the user cannot use the existing one.\n\n### Parameters\n\n- `existingRecoveryKey?: string`\n Existing recovery key, if the user has it.\n\n### Returns\n\n- `{ recoveryKey: string; session: { e2ee: { crossSigning: boolean; firstSyncDone: boolean; hasBackedUpRecoveryKey: boolean; initialized: boolean; keyBackup: boolean; secrets: object; secretStorage: boolean; verified: boolean; recoveryKeyGeneratedAt?: number; }; state: string; matrix?: { deviceID: string; homeserver: string; userID: string; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: object; otherDevice?: object; otherUserID?: string; qr?: object; sas?: object; }; }; }`\n\n - `recoveryKey: string`\n - `session: { e2ee: { crossSigning: boolean; firstSyncDone: boolean; hasBackedUpRecoveryKey: boolean; initialized: boolean; keyBackup: boolean; secrets: { masterKey: boolean; megolmBackupKey: boolean; recoveryKey: boolean; selfSigningKey: boolean; userSigningKey: boolean; }; secretStorage: boolean; verified: boolean; recoveryKeyGeneratedAt?: number; }; state: string; matrix?: { deviceID: string; homeserver: string; userID: string; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }; }`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst reset = await client.app.login.verification.recoveryKey.reset.create();\n\nconsole.log(reset);\n```",
+ perLanguage: {
+ typescript: {
+ method: 'client.app.login.verification.recoveryKey.reset.create',
+ example:
+ "import BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop({\n accessToken: process.env['BEEPER_ACCESS_TOKEN'], // This is the default and can be omitted\n});\n\nconst reset = await client.app.login.verification.recoveryKey.reset.create();\n\nconsole.log(reset.recoveryKey);",
+ },
+ python: {
+ method: 'app.login.verification.recovery_key.reset.create',
+ example:
+ 'import os\nfrom beeper_desktop_api import BeeperDesktop\n\nclient = BeeperDesktop(\n access_token=os.environ.get("BEEPER_ACCESS_TOKEN"), # This is the default and can be omitted\n)\nreset = client.app.login.verification.recovery_key.reset.create()\nprint(reset.recovery_key)',
+ },
+ go: {
+ method: 'client.App.Login.Verification.RecoveryKey.Reset.New',
+ example:
+ 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/beeper/desktop-api-go"\n\t"github.com/beeper/desktop-api-go/option"\n)\n\nfunc main() {\n\tclient := beeperdesktopapi.NewClient(\n\t\toption.WithAccessToken("My Access Token"),\n\t)\n\treset, err := client.App.Login.Verification.RecoveryKey.Reset.New(context.TODO(), beeperdesktopapi.AppLoginVerificationRecoveryKeyResetNewParams{})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", reset.RecoveryKey)\n}\n',
+ },
+ cli: {
+ method: 'reset create',
+ example:
+ "beeper-desktop app:login:verification:recovery-key:reset create \\\n --access-token 'My Access Token'",
+ },
+ php: {
+ method: 'app->login->verification->recoveryKey->reset->create',
+ example:
+ "app->login->verification->recoveryKey->reset->create(\n existingRecoveryKey: 'existingRecoveryKey'\n);\n\nvar_dump($reset);",
+ },
+ http: {
+ example:
+ 'curl http://localhost:23373/v1/app/setup/verification/recovery-key/reset \\\n -X POST \\\n -H "Authorization: Bearer $BEEPER_ACCESS_TOKEN"',
+ },
+ },
+ },
+ {
+ name: 'confirm',
+ endpoint: '/v1/app/setup/verification/recovery-key/reset/confirm',
+ httpMethod: 'post',
+ summary: 'Confirm new recovery key',
+ description: 'Confirm that the new recovery key should be used for this account.',
+ stainlessPath: '(resource) app.login.verification.recovery_key.reset > (method) confirm',
+ qualified: 'client.app.login.verification.recoveryKey.reset.confirm',
+ params: ['recoveryKey: string;'],
+ response:
+ "{ session: { e2ee: { crossSigning: boolean; firstSyncDone: boolean; hasBackedUpRecoveryKey: boolean; initialized: boolean; keyBackup: boolean; secrets: object; secretStorage: boolean; verified: boolean; recoveryKeyGeneratedAt?: number; }; state: string; matrix?: { deviceID: string; homeserver: string; userID: string; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: object; otherDevice?: object; otherUserID?: string; qr?: object; sas?: object; }; }; }",
+ markdown:
+ "## confirm\n\n`client.app.login.verification.recoveryKey.reset.confirm(recoveryKey: string): { session: object; }`\n\n**post** `/v1/app/setup/verification/recovery-key/reset/confirm`\n\nConfirm that the new recovery key should be used for this account.\n\n### Parameters\n\n- `recoveryKey: string`\n New recovery key returned by the reset step.\n\n### Returns\n\n- `{ session: { e2ee: { crossSigning: boolean; firstSyncDone: boolean; hasBackedUpRecoveryKey: boolean; initialized: boolean; keyBackup: boolean; secrets: object; secretStorage: boolean; verified: boolean; recoveryKeyGeneratedAt?: number; }; state: string; matrix?: { deviceID: string; homeserver: string; userID: string; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: object; otherDevice?: object; otherUserID?: string; qr?: object; sas?: object; }; }; }`\n\n - `session: { e2ee: { crossSigning: boolean; firstSyncDone: boolean; hasBackedUpRecoveryKey: boolean; initialized: boolean; keyBackup: boolean; secrets: { masterKey: boolean; megolmBackupKey: boolean; recoveryKey: boolean; selfSigningKey: boolean; userSigningKey: boolean; }; secretStorage: boolean; verified: boolean; recoveryKeyGeneratedAt?: number; }; state: string; matrix?: { deviceID: string; homeserver: string; userID: string; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }; }`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.app.login.verification.recoveryKey.reset.confirm({ recoveryKey: 'x' });\n\nconsole.log(response);\n```",
+ perLanguage: {
+ typescript: {
+ method: 'client.app.login.verification.recoveryKey.reset.confirm',
+ example:
+ "import BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop({\n accessToken: process.env['BEEPER_ACCESS_TOKEN'], // This is the default and can be omitted\n});\n\nconst response = await client.app.login.verification.recoveryKey.reset.confirm({\n recoveryKey: 'x',\n});\n\nconsole.log(response.session);",
+ },
+ python: {
+ method: 'app.login.verification.recovery_key.reset.confirm',
+ example:
+ 'import os\nfrom beeper_desktop_api import BeeperDesktop\n\nclient = BeeperDesktop(\n access_token=os.environ.get("BEEPER_ACCESS_TOKEN"), # This is the default and can be omitted\n)\nresponse = client.app.login.verification.recovery_key.reset.confirm(\n recovery_key="x",\n)\nprint(response.session)',
+ },
+ go: {
+ method: 'client.App.Login.Verification.RecoveryKey.Reset.Confirm',
+ example:
+ 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/beeper/desktop-api-go"\n\t"github.com/beeper/desktop-api-go/option"\n)\n\nfunc main() {\n\tclient := beeperdesktopapi.NewClient(\n\t\toption.WithAccessToken("My Access Token"),\n\t)\n\tresponse, err := client.App.Login.Verification.RecoveryKey.Reset.Confirm(context.TODO(), beeperdesktopapi.AppLoginVerificationRecoveryKeyResetConfirmParams{\n\t\tRecoveryKey: "x",\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.Session)\n}\n',
+ },
+ cli: {
+ method: 'reset confirm',
+ example:
+ "beeper-desktop app:login:verification:recovery-key:reset confirm \\\n --access-token 'My Access Token' \\\n --recovery-key x",
+ },
+ php: {
+ method: 'app->login->verification->recoveryKey->reset->confirm',
+ example:
+ "app->login->verification->recoveryKey->reset->confirm(\n recoveryKey: 'x'\n);\n\nvar_dump($response);",
+ },
+ http: {
+ example:
+ 'curl http://localhost:23373/v1/app/setup/verification/recovery-key/reset/confirm \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $BEEPER_ACCESS_TOKEN" \\\n -d \'{\n "recoveryKey": "x"\n }\'',
+ },
+ },
+ },
+ {
+ name: 'list',
+ endpoint: '/v1/app/setup/verifications',
+ httpMethod: 'get',
+ summary: 'List active verifications',
+ description:
+ 'List pending and active device verifications. Use this to recover state without a WebSocket connection.',
+ stainlessPath: '(resource) app.verifications > (method) list',
+ qualified: 'client.app.verifications.list',
+ response:
+ "{ items: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }[]; }",
+ markdown:
+ "## list\n\n`client.app.verifications.list(): { items: object[]; }`\n\n**get** `/v1/app/setup/verifications`\n\nList pending and active device verifications. Use this to recover state without a WebSocket connection.\n\n### Returns\n\n- `{ items: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }[]; }`\n\n - `items: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }[]`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst verifications = await client.app.verifications.list();\n\nconsole.log(verifications);\n```",
+ perLanguage: {
+ typescript: {
+ method: 'client.app.verifications.list',
+ example:
+ "import BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop({\n accessToken: process.env['BEEPER_ACCESS_TOKEN'], // This is the default and can be omitted\n});\n\nconst verifications = await client.app.verifications.list();\n\nconsole.log(verifications.items);",
+ },
+ python: {
+ method: 'app.verifications.list',
+ example:
+ 'import os\nfrom beeper_desktop_api import BeeperDesktop\n\nclient = BeeperDesktop(\n access_token=os.environ.get("BEEPER_ACCESS_TOKEN"), # This is the default and can be omitted\n)\nverifications = client.app.verifications.list()\nprint(verifications.items)',
+ },
+ go: {
+ method: 'client.App.Verifications.List',
+ example:
+ 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/beeper/desktop-api-go"\n\t"github.com/beeper/desktop-api-go/option"\n)\n\nfunc main() {\n\tclient := beeperdesktopapi.NewClient(\n\t\toption.WithAccessToken("My Access Token"),\n\t)\n\tverifications, err := client.App.Verifications.List(context.TODO())\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", verifications.Items)\n}\n',
+ },
+ cli: {
+ method: 'verifications list',
+ example: "beeper-desktop app:verifications list \\\n --access-token 'My Access Token'",
+ },
+ php: {
+ method: 'app->verifications->list',
+ example:
+ "app->verifications->list();\n\nvar_dump($verifications);",
+ },
+ http: {
+ example:
+ 'curl http://localhost:23373/v1/app/setup/verifications \\\n -H "Authorization: Bearer $BEEPER_ACCESS_TOKEN"',
+ },
+ },
+ },
+ {
+ name: 'create',
+ endpoint: '/v1/app/setup/verifications',
+ httpMethod: 'post',
+ summary: 'Start device verification',
+ description: 'Start verifying this device from another signed-in device.',
+ stainlessPath: '(resource) app.verifications > (method) create',
+ qualified: 'client.app.verifications.create',
+ params: ["purpose?: 'login' | 'device';", 'userID?: string;'],
+ response:
+ "{ session: { e2ee: object; state: string; matrix?: object; verification?: object; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: object; otherDevice?: object; otherUserID?: string; qr?: object; sas?: object; }; }",
+ markdown:
+ "## create\n\n`client.app.verifications.create(purpose?: 'login' | 'device', userID?: string): { session: object; verification?: object; }`\n\n**post** `/v1/app/setup/verifications`\n\nStart verifying this device from another signed-in device.\n\n### Parameters\n\n- `purpose?: 'login' | 'device'`\n Why this verification is being started.\n\n- `userID?: string`\n Beeper user ID to verify. Defaults to the signed-in user.\n\n### Returns\n\n- `{ session: { e2ee: { crossSigning: boolean; firstSyncDone: boolean; hasBackedUpRecoveryKey: boolean; initialized: boolean; keyBackup: boolean; secrets: object; secretStorage: boolean; verified: boolean; recoveryKeyGeneratedAt?: number; }; state: string; matrix?: { deviceID: string; homeserver: string; userID: string; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: object; otherDevice?: object; otherUserID?: string; qr?: object; sas?: object; }; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }; }`\n\n - `session: { e2ee: { crossSigning: boolean; firstSyncDone: boolean; hasBackedUpRecoveryKey: boolean; initialized: boolean; keyBackup: boolean; secrets: { masterKey: boolean; megolmBackupKey: boolean; recoveryKey: boolean; selfSigningKey: boolean; userSigningKey: boolean; }; secretStorage: boolean; verified: boolean; recoveryKeyGeneratedAt?: number; }; state: string; matrix?: { deviceID: string; homeserver: string; userID: string; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }; }`\n - `verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst verification = await client.app.verifications.create();\n\nconsole.log(verification);\n```",
+ perLanguage: {
+ typescript: {
+ method: 'client.app.verifications.create',
+ example:
+ "import BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop({\n accessToken: process.env['BEEPER_ACCESS_TOKEN'], // This is the default and can be omitted\n});\n\nconst verification = await client.app.verifications.create();\n\nconsole.log(verification.session);",
+ },
+ python: {
+ method: 'app.verifications.create',
+ example:
+ 'import os\nfrom beeper_desktop_api import BeeperDesktop\n\nclient = BeeperDesktop(\n access_token=os.environ.get("BEEPER_ACCESS_TOKEN"), # This is the default and can be omitted\n)\nverification = client.app.verifications.create()\nprint(verification.session)',
+ },
+ go: {
+ method: 'client.App.Verifications.New',
+ example:
+ 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/beeper/desktop-api-go"\n\t"github.com/beeper/desktop-api-go/option"\n)\n\nfunc main() {\n\tclient := beeperdesktopapi.NewClient(\n\t\toption.WithAccessToken("My Access Token"),\n\t)\n\tverification, err := client.App.Verifications.New(context.TODO(), beeperdesktopapi.AppVerificationNewParams{})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", verification.Session)\n}\n',
+ },
+ cli: {
+ method: 'verifications create',
+ example: "beeper-desktop app:verifications create \\\n --access-token 'My Access Token'",
+ },
+ php: {
+ method: 'app->verifications->create',
+ example:
+ "app->verifications->create(\n purpose: 'login', userID: 'userID'\n);\n\nvar_dump($verification);",
+ },
+ http: {
+ example:
+ 'curl http://localhost:23373/v1/app/setup/verifications \\\n -X POST \\\n -H "Authorization: Bearer $BEEPER_ACCESS_TOKEN"',
+ },
+ },
+ },
+ {
+ name: 'retrieve',
+ endpoint: '/v1/app/setup/verifications/{verificationID}',
+ httpMethod: 'get',
+ summary: 'Get verification',
+ description: 'Get the current state of a device verification transaction.',
+ stainlessPath: '(resource) app.verifications > (method) retrieve',
+ qualified: 'client.app.verifications.retrieve',
+ params: ['verificationID: string;'],
+ response:
+ "{ session: { e2ee: object; state: string; matrix?: object; verification?: object; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: object; otherDevice?: object; otherUserID?: string; qr?: object; sas?: object; }; }",
+ markdown:
+ "## retrieve\n\n`client.app.verifications.retrieve(verificationID: string): { session: object; verification?: object; }`\n\n**get** `/v1/app/setup/verifications/{verificationID}`\n\nGet the current state of a device verification transaction.\n\n### Parameters\n\n- `verificationID: string`\n Verification ID.\n\n### Returns\n\n- `{ session: { e2ee: { crossSigning: boolean; firstSyncDone: boolean; hasBackedUpRecoveryKey: boolean; initialized: boolean; keyBackup: boolean; secrets: object; secretStorage: boolean; verified: boolean; recoveryKeyGeneratedAt?: number; }; state: string; matrix?: { deviceID: string; homeserver: string; userID: string; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: object; otherDevice?: object; otherUserID?: string; qr?: object; sas?: object; }; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }; }`\n\n - `session: { e2ee: { crossSigning: boolean; firstSyncDone: boolean; hasBackedUpRecoveryKey: boolean; initialized: boolean; keyBackup: boolean; secrets: { masterKey: boolean; megolmBackupKey: boolean; recoveryKey: boolean; selfSigningKey: boolean; userSigningKey: boolean; }; secretStorage: boolean; verified: boolean; recoveryKeyGeneratedAt?: number; }; state: string; matrix?: { deviceID: string; homeserver: string; userID: string; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }; }`\n - `verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst verification = await client.app.verifications.retrieve('x');\n\nconsole.log(verification);\n```",
+ perLanguage: {
+ typescript: {
+ method: 'client.app.verifications.retrieve',
+ example:
+ "import BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop({\n accessToken: process.env['BEEPER_ACCESS_TOKEN'], // This is the default and can be omitted\n});\n\nconst verification = await client.app.verifications.retrieve('x');\n\nconsole.log(verification.session);",
+ },
+ python: {
+ method: 'app.verifications.retrieve',
+ example:
+ 'import os\nfrom beeper_desktop_api import BeeperDesktop\n\nclient = BeeperDesktop(\n access_token=os.environ.get("BEEPER_ACCESS_TOKEN"), # This is the default and can be omitted\n)\nverification = client.app.verifications.retrieve(\n "x",\n)\nprint(verification.session)',
+ },
+ go: {
+ method: 'client.App.Verifications.Get',
+ example:
+ 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/beeper/desktop-api-go"\n\t"github.com/beeper/desktop-api-go/option"\n)\n\nfunc main() {\n\tclient := beeperdesktopapi.NewClient(\n\t\toption.WithAccessToken("My Access Token"),\n\t)\n\tverification, err := client.App.Verifications.Get(context.TODO(), "x")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", verification.Session)\n}\n',
+ },
+ cli: {
+ method: 'verifications retrieve',
+ example:
+ "beeper-desktop app:verifications retrieve \\\n --access-token 'My Access Token' \\\n --verification-id x",
+ },
+ php: {
+ method: 'app->verifications->retrieve',
+ example:
+ "app->verifications->retrieve('x');\n\nvar_dump($verification);",
+ },
+ http: {
+ example:
+ 'curl http://localhost:23373/v1/app/setup/verifications/$VERIFICATION_ID \\\n -H "Authorization: Bearer $BEEPER_ACCESS_TOKEN"',
+ },
+ },
+ },
+ {
+ name: 'accept',
+ endpoint: '/v1/app/setup/verifications/{verificationID}/accept',
+ httpMethod: 'post',
+ summary: 'Accept device verification',
+ description: 'Accept an incoming device verification request.',
+ stainlessPath: '(resource) app.verifications > (method) accept',
+ qualified: 'client.app.verifications.accept',
+ params: ['verificationID: string;'],
+ response:
+ "{ session: { e2ee: object; state: string; matrix?: object; verification?: object; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: object; otherDevice?: object; otherUserID?: string; qr?: object; sas?: object; }; }",
+ markdown:
+ "## accept\n\n`client.app.verifications.accept(verificationID: string): { session: object; verification?: object; }`\n\n**post** `/v1/app/setup/verifications/{verificationID}/accept`\n\nAccept an incoming device verification request.\n\n### Parameters\n\n- `verificationID: string`\n Verification ID.\n\n### Returns\n\n- `{ session: { e2ee: { crossSigning: boolean; firstSyncDone: boolean; hasBackedUpRecoveryKey: boolean; initialized: boolean; keyBackup: boolean; secrets: object; secretStorage: boolean; verified: boolean; recoveryKeyGeneratedAt?: number; }; state: string; matrix?: { deviceID: string; homeserver: string; userID: string; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: object; otherDevice?: object; otherUserID?: string; qr?: object; sas?: object; }; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }; }`\n\n - `session: { e2ee: { crossSigning: boolean; firstSyncDone: boolean; hasBackedUpRecoveryKey: boolean; initialized: boolean; keyBackup: boolean; secrets: { masterKey: boolean; megolmBackupKey: boolean; recoveryKey: boolean; selfSigningKey: boolean; userSigningKey: boolean; }; secretStorage: boolean; verified: boolean; recoveryKeyGeneratedAt?: number; }; state: string; matrix?: { deviceID: string; homeserver: string; userID: string; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }; }`\n - `verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.app.verifications.accept('x');\n\nconsole.log(response);\n```",
+ perLanguage: {
+ typescript: {
+ method: 'client.app.verifications.accept',
+ example:
+ "import BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop({\n accessToken: process.env['BEEPER_ACCESS_TOKEN'], // This is the default and can be omitted\n});\n\nconst response = await client.app.verifications.accept('x');\n\nconsole.log(response.session);",
+ },
+ python: {
+ method: 'app.verifications.accept',
+ example:
+ 'import os\nfrom beeper_desktop_api import BeeperDesktop\n\nclient = BeeperDesktop(\n access_token=os.environ.get("BEEPER_ACCESS_TOKEN"), # This is the default and can be omitted\n)\nresponse = client.app.verifications.accept(\n "x",\n)\nprint(response.session)',
+ },
+ go: {
+ method: 'client.App.Verifications.Accept',
+ example:
+ 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/beeper/desktop-api-go"\n\t"github.com/beeper/desktop-api-go/option"\n)\n\nfunc main() {\n\tclient := beeperdesktopapi.NewClient(\n\t\toption.WithAccessToken("My Access Token"),\n\t)\n\tresponse, err := client.App.Verifications.Accept(context.TODO(), "x")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.Session)\n}\n',
+ },
+ cli: {
+ method: 'verifications accept',
+ example:
+ "beeper-desktop app:verifications accept \\\n --access-token 'My Access Token' \\\n --verification-id x",
+ },
+ php: {
+ method: 'app->verifications->accept',
+ example:
+ "app->verifications->accept('x');\n\nvar_dump($response);",
+ },
+ http: {
+ example:
+ 'curl http://localhost:23373/v1/app/setup/verifications/$VERIFICATION_ID/accept \\\n -X POST \\\n -H "Authorization: Bearer $BEEPER_ACCESS_TOKEN"',
+ },
+ },
+ },
+ {
+ name: 'cancel',
+ endpoint: '/v1/app/setup/verifications/{verificationID}/cancel',
+ httpMethod: 'post',
+ summary: 'Cancel device verification',
+ description: 'Cancel an active device verification request.',
+ stainlessPath: '(resource) app.verifications > (method) cancel',
+ qualified: 'client.app.verifications.cancel',
+ params: ['verificationID: string;', 'code?: string;', 'reason?: string;'],
+ response:
+ "{ session: { e2ee: object; state: string; matrix?: object; verification?: object; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: object; otherDevice?: object; otherUserID?: string; qr?: object; sas?: object; }; }",
+ markdown:
+ "## cancel\n\n`client.app.verifications.cancel(verificationID: string, code?: string, reason?: string): { session: object; verification?: object; }`\n\n**post** `/v1/app/setup/verifications/{verificationID}/cancel`\n\nCancel an active device verification request.\n\n### Parameters\n\n- `verificationID: string`\n Verification ID.\n\n- `code?: string`\n Optional cancellation code.\n\n- `reason?: string`\n Optional user-facing cancellation reason.\n\n### Returns\n\n- `{ session: { e2ee: { crossSigning: boolean; firstSyncDone: boolean; hasBackedUpRecoveryKey: boolean; initialized: boolean; keyBackup: boolean; secrets: object; secretStorage: boolean; verified: boolean; recoveryKeyGeneratedAt?: number; }; state: string; matrix?: { deviceID: string; homeserver: string; userID: string; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: object; otherDevice?: object; otherUserID?: string; qr?: object; sas?: object; }; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }; }`\n\n - `session: { e2ee: { crossSigning: boolean; firstSyncDone: boolean; hasBackedUpRecoveryKey: boolean; initialized: boolean; keyBackup: boolean; secrets: { masterKey: boolean; megolmBackupKey: boolean; recoveryKey: boolean; selfSigningKey: boolean; userSigningKey: boolean; }; secretStorage: boolean; verified: boolean; recoveryKeyGeneratedAt?: number; }; state: string; matrix?: { deviceID: string; homeserver: string; userID: string; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }; }`\n - `verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.app.verifications.cancel('x');\n\nconsole.log(response);\n```",
+ perLanguage: {
+ typescript: {
+ method: 'client.app.verifications.cancel',
+ example:
+ "import BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop({\n accessToken: process.env['BEEPER_ACCESS_TOKEN'], // This is the default and can be omitted\n});\n\nconst response = await client.app.verifications.cancel('x');\n\nconsole.log(response.session);",
+ },
+ python: {
+ method: 'app.verifications.cancel',
+ example:
+ 'import os\nfrom beeper_desktop_api import BeeperDesktop\n\nclient = BeeperDesktop(\n access_token=os.environ.get("BEEPER_ACCESS_TOKEN"), # This is the default and can be omitted\n)\nresponse = client.app.verifications.cancel(\n verification_id="x",\n)\nprint(response.session)',
+ },
+ go: {
+ method: 'client.App.Verifications.Cancel',
+ example:
+ 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/beeper/desktop-api-go"\n\t"github.com/beeper/desktop-api-go/option"\n)\n\nfunc main() {\n\tclient := beeperdesktopapi.NewClient(\n\t\toption.WithAccessToken("My Access Token"),\n\t)\n\tresponse, err := client.App.Verifications.Cancel(\n\t\tcontext.TODO(),\n\t\t"x",\n\t\tbeeperdesktopapi.AppVerificationCancelParams{},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.Session)\n}\n',
+ },
+ cli: {
+ method: 'verifications cancel',
+ example:
+ "beeper-desktop app:verifications cancel \\\n --access-token 'My Access Token' \\\n --verification-id x",
+ },
+ php: {
+ method: 'app->verifications->cancel',
+ example:
+ "app->verifications->cancel(\n 'x', code: 'code', reason: 'reason'\n);\n\nvar_dump($response);",
+ },
+ http: {
+ example:
+ 'curl http://localhost:23373/v1/app/setup/verifications/$VERIFICATION_ID/cancel \\\n -X POST \\\n -H "Authorization: Bearer $BEEPER_ACCESS_TOKEN"',
+ },
+ },
+ },
+ {
+ name: 'scan',
+ endpoint: '/v1/app/setup/verifications/qr/scan',
+ httpMethod: 'post',
+ summary: 'Scan verification QR code',
+ description: 'Submit the QR code scanned from another signed-in device.',
+ stainlessPath: '(resource) app.verifications.qr > (method) scan',
+ qualified: 'client.app.verifications.qr.scan',
+ params: ['data: string;'],
+ response:
+ "{ session: { e2ee: object; state: string; matrix?: object; verification?: object; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: object; otherDevice?: object; otherUserID?: string; qr?: object; sas?: object; }; }",
+ markdown:
+ "## scan\n\n`client.app.verifications.qr.scan(data: string): { session: object; verification?: object; }`\n\n**post** `/v1/app/setup/verifications/qr/scan`\n\nSubmit the QR code scanned from another signed-in device.\n\n### Parameters\n\n- `data: string`\n QR code payload scanned from the other device.\n\n### Returns\n\n- `{ session: { e2ee: { crossSigning: boolean; firstSyncDone: boolean; hasBackedUpRecoveryKey: boolean; initialized: boolean; keyBackup: boolean; secrets: object; secretStorage: boolean; verified: boolean; recoveryKeyGeneratedAt?: number; }; state: string; matrix?: { deviceID: string; homeserver: string; userID: string; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: object; otherDevice?: object; otherUserID?: string; qr?: object; sas?: object; }; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }; }`\n\n - `session: { e2ee: { crossSigning: boolean; firstSyncDone: boolean; hasBackedUpRecoveryKey: boolean; initialized: boolean; keyBackup: boolean; secrets: { masterKey: boolean; megolmBackupKey: boolean; recoveryKey: boolean; selfSigningKey: boolean; userSigningKey: boolean; }; secretStorage: boolean; verified: boolean; recoveryKeyGeneratedAt?: number; }; state: string; matrix?: { deviceID: string; homeserver: string; userID: string; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }; }`\n - `verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.app.verifications.qr.scan({ data: 'x' });\n\nconsole.log(response);\n```",
+ perLanguage: {
+ typescript: {
+ method: 'client.app.verifications.qr.scan',
+ example:
+ "import BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop({\n accessToken: process.env['BEEPER_ACCESS_TOKEN'], // This is the default and can be omitted\n});\n\nconst response = await client.app.verifications.qr.scan({ data: 'x' });\n\nconsole.log(response.session);",
+ },
+ python: {
+ method: 'app.verifications.qr.scan',
+ example:
+ 'import os\nfrom beeper_desktop_api import BeeperDesktop\n\nclient = BeeperDesktop(\n access_token=os.environ.get("BEEPER_ACCESS_TOKEN"), # This is the default and can be omitted\n)\nresponse = client.app.verifications.qr.scan(\n data="x",\n)\nprint(response.session)',
+ },
+ go: {
+ method: 'client.App.Verifications.Qr.Scan',
+ example:
+ 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/beeper/desktop-api-go"\n\t"github.com/beeper/desktop-api-go/option"\n)\n\nfunc main() {\n\tclient := beeperdesktopapi.NewClient(\n\t\toption.WithAccessToken("My Access Token"),\n\t)\n\tresponse, err := client.App.Verifications.Qr.Scan(context.TODO(), beeperdesktopapi.AppVerificationQrScanParams{\n\t\tData: "x",\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.Session)\n}\n',
+ },
+ cli: {
+ method: 'qr scan',
+ example:
+ "beeper-desktop app:verifications:qr scan \\\n --access-token 'My Access Token' \\\n --data x",
+ },
+ php: {
+ method: 'app->verifications->qr->scan',
+ example:
+ "app->verifications->qr->scan(data: 'x');\n\nvar_dump($response);",
+ },
+ http: {
+ example:
+ 'curl http://localhost:23373/v1/app/setup/verifications/qr/scan \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $BEEPER_ACCESS_TOKEN" \\\n -d \'{\n "data": "x"\n }\'',
+ },
+ },
+ },
+ {
+ name: 'confirm_scanned',
+ endpoint: '/v1/app/setup/verifications/{verificationID}/qr/confirm-scanned',
+ httpMethod: 'post',
+ summary: 'Confirm QR code scan',
+ description: 'Confirm that another device scanned this device QR code.',
+ stainlessPath: '(resource) app.verifications.qr > (method) confirm_scanned',
+ qualified: 'client.app.verifications.qr.confirmScanned',
+ params: ['verificationID: string;'],
+ response:
+ "{ session: { e2ee: object; state: string; matrix?: object; verification?: object; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: object; otherDevice?: object; otherUserID?: string; qr?: object; sas?: object; }; }",
+ markdown:
+ "## confirm_scanned\n\n`client.app.verifications.qr.confirmScanned(verificationID: string): { session: object; verification?: object; }`\n\n**post** `/v1/app/setup/verifications/{verificationID}/qr/confirm-scanned`\n\nConfirm that another device scanned this device QR code.\n\n### Parameters\n\n- `verificationID: string`\n Verification ID.\n\n### Returns\n\n- `{ session: { e2ee: { crossSigning: boolean; firstSyncDone: boolean; hasBackedUpRecoveryKey: boolean; initialized: boolean; keyBackup: boolean; secrets: object; secretStorage: boolean; verified: boolean; recoveryKeyGeneratedAt?: number; }; state: string; matrix?: { deviceID: string; homeserver: string; userID: string; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: object; otherDevice?: object; otherUserID?: string; qr?: object; sas?: object; }; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }; }`\n\n - `session: { e2ee: { crossSigning: boolean; firstSyncDone: boolean; hasBackedUpRecoveryKey: boolean; initialized: boolean; keyBackup: boolean; secrets: { masterKey: boolean; megolmBackupKey: boolean; recoveryKey: boolean; selfSigningKey: boolean; userSigningKey: boolean; }; secretStorage: boolean; verified: boolean; recoveryKeyGeneratedAt?: number; }; state: string; matrix?: { deviceID: string; homeserver: string; userID: string; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }; }`\n - `verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.app.verifications.qr.confirmScanned('x');\n\nconsole.log(response);\n```",
+ perLanguage: {
+ typescript: {
+ method: 'client.app.verifications.qr.confirmScanned',
+ example:
+ "import BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop({\n accessToken: process.env['BEEPER_ACCESS_TOKEN'], // This is the default and can be omitted\n});\n\nconst response = await client.app.verifications.qr.confirmScanned('x');\n\nconsole.log(response.session);",
+ },
+ python: {
+ method: 'app.verifications.qr.confirm_scanned',
+ example:
+ 'import os\nfrom beeper_desktop_api import BeeperDesktop\n\nclient = BeeperDesktop(\n access_token=os.environ.get("BEEPER_ACCESS_TOKEN"), # This is the default and can be omitted\n)\nresponse = client.app.verifications.qr.confirm_scanned(\n "x",\n)\nprint(response.session)',
+ },
+ go: {
+ method: 'client.App.Verifications.Qr.ConfirmScanned',
+ example:
+ 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/beeper/desktop-api-go"\n\t"github.com/beeper/desktop-api-go/option"\n)\n\nfunc main() {\n\tclient := beeperdesktopapi.NewClient(\n\t\toption.WithAccessToken("My Access Token"),\n\t)\n\tresponse, err := client.App.Verifications.Qr.ConfirmScanned(context.TODO(), "x")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.Session)\n}\n',
+ },
+ cli: {
+ method: 'qr confirm_scanned',
+ example:
+ "beeper-desktop app:verifications:qr confirm-scanned \\\n --access-token 'My Access Token' \\\n --verification-id x",
+ },
+ php: {
+ method: 'app->verifications->qr->confirmScanned',
+ example:
+ "app->verifications->qr->confirmScanned('x');\n\nvar_dump($response);",
+ },
+ http: {
+ example:
+ 'curl http://localhost:23373/v1/app/setup/verifications/$VERIFICATION_ID/qr/confirm-scanned \\\n -X POST \\\n -H "Authorization: Bearer $BEEPER_ACCESS_TOKEN"',
+ },
+ },
+ },
+ {
+ name: 'start',
+ endpoint: '/v1/app/setup/verifications/{verificationID}/sas/start',
+ httpMethod: 'post',
+ summary: 'Start emoji verification',
+ description: 'Start emoji comparison for device verification.',
+ stainlessPath: '(resource) app.verifications.sas > (method) start',
+ qualified: 'client.app.verifications.sas.start',
+ params: ['verificationID: string;'],
+ response:
+ "{ session: { e2ee: object; state: string; matrix?: object; verification?: object; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: object; otherDevice?: object; otherUserID?: string; qr?: object; sas?: object; }; }",
+ markdown:
+ "## start\n\n`client.app.verifications.sas.start(verificationID: string): { session: object; verification?: object; }`\n\n**post** `/v1/app/setup/verifications/{verificationID}/sas/start`\n\nStart emoji comparison for device verification.\n\n### Parameters\n\n- `verificationID: string`\n Verification ID.\n\n### Returns\n\n- `{ session: { e2ee: { crossSigning: boolean; firstSyncDone: boolean; hasBackedUpRecoveryKey: boolean; initialized: boolean; keyBackup: boolean; secrets: object; secretStorage: boolean; verified: boolean; recoveryKeyGeneratedAt?: number; }; state: string; matrix?: { deviceID: string; homeserver: string; userID: string; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: object; otherDevice?: object; otherUserID?: string; qr?: object; sas?: object; }; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }; }`\n\n - `session: { e2ee: { crossSigning: boolean; firstSyncDone: boolean; hasBackedUpRecoveryKey: boolean; initialized: boolean; keyBackup: boolean; secrets: { masterKey: boolean; megolmBackupKey: boolean; recoveryKey: boolean; selfSigningKey: boolean; userSigningKey: boolean; }; secretStorage: boolean; verified: boolean; recoveryKeyGeneratedAt?: number; }; state: string; matrix?: { deviceID: string; homeserver: string; userID: string; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }; }`\n - `verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.app.verifications.sas.start('x');\n\nconsole.log(response);\n```",
+ perLanguage: {
+ typescript: {
+ method: 'client.app.verifications.sas.start',
+ example:
+ "import BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop({\n accessToken: process.env['BEEPER_ACCESS_TOKEN'], // This is the default and can be omitted\n});\n\nconst response = await client.app.verifications.sas.start('x');\n\nconsole.log(response.session);",
+ },
+ python: {
+ method: 'app.verifications.sas.start',
+ example:
+ 'import os\nfrom beeper_desktop_api import BeeperDesktop\n\nclient = BeeperDesktop(\n access_token=os.environ.get("BEEPER_ACCESS_TOKEN"), # This is the default and can be omitted\n)\nresponse = client.app.verifications.sas.start(\n "x",\n)\nprint(response.session)',
+ },
+ go: {
+ method: 'client.App.Verifications.SAS.Start',
+ example:
+ 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/beeper/desktop-api-go"\n\t"github.com/beeper/desktop-api-go/option"\n)\n\nfunc main() {\n\tclient := beeperdesktopapi.NewClient(\n\t\toption.WithAccessToken("My Access Token"),\n\t)\n\tresponse, err := client.App.Verifications.SAS.Start(context.TODO(), "x")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.Session)\n}\n',
+ },
+ cli: {
+ method: 'sas start',
+ example:
+ "beeper-desktop app:verifications:sas start \\\n --access-token 'My Access Token' \\\n --verification-id x",
+ },
+ php: {
+ method: 'app->verifications->sas->start',
+ example:
+ "app->verifications->sas->start('x');\n\nvar_dump($response);",
+ },
+ http: {
+ example:
+ 'curl http://localhost:23373/v1/app/setup/verifications/$VERIFICATION_ID/sas/start \\\n -X POST \\\n -H "Authorization: Bearer $BEEPER_ACCESS_TOKEN"',
+ },
+ },
+ },
+ {
+ name: 'confirm',
+ endpoint: '/v1/app/setup/verifications/{verificationID}/sas/confirm',
+ httpMethod: 'post',
+ summary: 'Confirm emoji verification',
+ description: 'Confirm that the emoji or number sequence matches on both devices.',
+ stainlessPath: '(resource) app.verifications.sas > (method) confirm',
+ qualified: 'client.app.verifications.sas.confirm',
+ params: ['verificationID: string;'],
+ response:
+ "{ session: { e2ee: object; state: string; matrix?: object; verification?: object; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: object; otherDevice?: object; otherUserID?: string; qr?: object; sas?: object; }; }",
+ markdown:
+ "## confirm\n\n`client.app.verifications.sas.confirm(verificationID: string): { session: object; verification?: object; }`\n\n**post** `/v1/app/setup/verifications/{verificationID}/sas/confirm`\n\nConfirm that the emoji or number sequence matches on both devices.\n\n### Parameters\n\n- `verificationID: string`\n Verification ID.\n\n### Returns\n\n- `{ session: { e2ee: { crossSigning: boolean; firstSyncDone: boolean; hasBackedUpRecoveryKey: boolean; initialized: boolean; keyBackup: boolean; secrets: object; secretStorage: boolean; verified: boolean; recoveryKeyGeneratedAt?: number; }; state: string; matrix?: { deviceID: string; homeserver: string; userID: string; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: object; otherDevice?: object; otherUserID?: string; qr?: object; sas?: object; }; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }; }`\n\n - `session: { e2ee: { crossSigning: boolean; firstSyncDone: boolean; hasBackedUpRecoveryKey: boolean; initialized: boolean; keyBackup: boolean; secrets: { masterKey: boolean; megolmBackupKey: boolean; recoveryKey: boolean; selfSigningKey: boolean; userSigningKey: boolean; }; secretStorage: boolean; verified: boolean; recoveryKeyGeneratedAt?: number; }; state: string; matrix?: { deviceID: string; homeserver: string; userID: string; }; verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }; }`\n - `verification?: { id: string; availableActions: 'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'[]; direction: 'incoming' | 'outgoing'; methods: 'qr' | 'sas'[]; purpose: 'login' | 'device'; state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error'; error?: { code: string; reason: string; }; otherDevice?: { id: string; name?: string; }; otherUserID?: string; qr?: { data: string; }; sas?: { emojis: string; decimals?: string; }; }`\n\n### Example\n\n```typescript\nimport BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop();\n\nconst response = await client.app.verifications.sas.confirm('x');\n\nconsole.log(response);\n```",
+ perLanguage: {
+ typescript: {
+ method: 'client.app.verifications.sas.confirm',
+ example:
+ "import BeeperDesktop from '@beeper/desktop-api';\n\nconst client = new BeeperDesktop({\n accessToken: process.env['BEEPER_ACCESS_TOKEN'], // This is the default and can be omitted\n});\n\nconst response = await client.app.verifications.sas.confirm('x');\n\nconsole.log(response.session);",
+ },
+ python: {
+ method: 'app.verifications.sas.confirm',
+ example:
+ 'import os\nfrom beeper_desktop_api import BeeperDesktop\n\nclient = BeeperDesktop(\n access_token=os.environ.get("BEEPER_ACCESS_TOKEN"), # This is the default and can be omitted\n)\nresponse = client.app.verifications.sas.confirm(\n "x",\n)\nprint(response.session)',
+ },
+ go: {
+ method: 'client.App.Verifications.SAS.Confirm',
+ example:
+ 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/beeper/desktop-api-go"\n\t"github.com/beeper/desktop-api-go/option"\n)\n\nfunc main() {\n\tclient := beeperdesktopapi.NewClient(\n\t\toption.WithAccessToken("My Access Token"),\n\t)\n\tresponse, err := client.App.Verifications.SAS.Confirm(context.TODO(), "x")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.Session)\n}\n',
+ },
+ cli: {
+ method: 'sas confirm',
+ example:
+ "beeper-desktop app:verifications:sas confirm \\\n --access-token 'My Access Token' \\\n --verification-id x",
+ },
+ php: {
+ method: 'app->verifications->sas->confirm',
+ example:
+ "app->verifications->sas->confirm('x');\n\nvar_dump($response);",
+ },
+ http: {
+ example:
+ 'curl http://localhost:23373/v1/app/setup/verifications/$VERIFICATION_ID/sas/confirm \\\n -X POST \\\n -H "Authorization: Bearer $BEEPER_ACCESS_TOKEN"',
+ },
+ },
+ },
];
const EMBEDDED_READMES: { language: string; content: string }[] = [
{
language: 'cli',
content:
- "# Beeper Desktop CLI\n\nThe official CLI for the [Beeper Desktop REST API](https://developers.beeper.com/desktop-api/).\n\n\n\n## Installation\n\n### Installing with Homebrew\n\n~~~sh\nbrew install beeper/tap/beeper-desktop-cli\n~~~\n\n### Installing with Go\n\nTo test or install the CLI locally, you need [Go](https://go.dev/doc/install) version 1.22 or later installed.\n\n~~~sh\ngo install 'github.com/beeper/desktop-api-cli/cmd/beeper-desktop-cli@latest'\n~~~\n\nOnce you have run `go install`, the binary is placed in your Go bin directory:\n\n- **Default location**: `$HOME/go/bin` (or `$GOPATH/bin` if GOPATH is set)\n- **Check your path**: Run `go env GOPATH` to see the base directory\n\nIf commands aren't found after installation, add the Go bin directory to your PATH:\n\n~~~sh\n# Add to your shell profile (.zshrc, .bashrc, etc.)\nexport PATH=\"$PATH:$(go env GOPATH)/bin\"\n~~~\n\n\n\n### Running Locally\n\nAfter cloning the git repository for this project, you can use the\n`scripts/run` script to run the tool locally:\n\n~~~sh\n./scripts/run args...\n~~~\n\n## Usage\n\nThe CLI follows a resource-based command structure:\n\n~~~sh\nbeeper-desktop-cli [resource] [flags...]\n~~~\n\n~~~sh\nbeeper-desktop-cli chats search \\\n --access-token 'My Access Token' \\\n --account-id matrix \\\n --account-id discordgo \\\n --account-id local-whatsapp_ba_EvYDBBsZbRQAy3UOSWqG0LuTVkc \\\n --include-muted \\\n --limit 3 \\\n --type single\n~~~\n\nFor details about specific commands, use the `--help` flag.\n\n### Environment variables\n\n| Environment variable | Description | Required |\n| --------------------- | ----------------------------------------------------------------------------------------------------- | -------- |\n| `BEEPER_ACCESS_TOKEN` | Bearer access token obtained via OAuth2 PKCE flow or created in-app. Required for all API operations. | yes |\n\n### Global flags\n\n- `--access-token` - Bearer access token obtained via OAuth2 PKCE flow or created in-app. Required for all API operations. (can also be set with `BEEPER_ACCESS_TOKEN` env var)\n- `--help` - Show command line usage\n- `--debug` - Enable debug logging (includes HTTP request/response details)\n- `--version`, `-v` - Show the CLI version\n- `--base-url` - Use a custom API backend URL\n- `--format` - Change the output format (`auto`, `explore`, `json`, `jsonl`, `pretty`, `raw`, `yaml`)\n- `--format-error` - Change the output format for errors (`auto`, `explore`, `json`, `jsonl`, `pretty`, `raw`, `yaml`)\n- `--transform` - Transform the data output using [GJSON syntax](https://github.com/tidwall/gjson/blob/master/SYNTAX.md)\n- `--transform-error` - Transform the error output using [GJSON syntax](https://github.com/tidwall/gjson/blob/master/SYNTAX.md)\n\n### Passing files as arguments\n\nTo pass files to your API, you can use the `@myfile.ext` syntax:\n\n~~~bash\nbeeper-desktop-cli --arg @abe.jpg\n~~~\n\nFiles can also be passed inside JSON or YAML blobs:\n\n~~~bash\nbeeper-desktop-cli --arg '{image: \"@abe.jpg\"}'\n# Equivalent:\nbeeper-desktop-cli < --username '\\@abe'\n~~~\n\n#### Explicit encoding\n\nFor JSON endpoints, the CLI tool does filetype sniffing to determine whether the\nfile contents should be sent as a string literal (for plain text files) or as a\nbase64-encoded string literal (for binary files). If you need to explicitly send\nthe file as either plain text or base64-encoded data, you can use\n`@file://myfile.txt` (for string encoding) or `@data://myfile.dat` (for\nbase64-encoding). Note that absolute paths will begin with `@file://` or\n`@data://`, followed by a third `/` (for example, `@file:///tmp/file.txt`).\n\n~~~bash\nbeeper-desktop-cli --arg @data://file.txt\n~~~\n\n## Linking different Go SDK versions\n\nYou can link the CLI against a different version of the Beeper Desktop Go SDK\nfor development purposes using the `./scripts/link` script.\n\nTo link to a specific version from a repository (version can be a branch,\ngit tag, or commit hash):\n\n~~~bash\n./scripts/link github.com/org/repo@version\n~~~\n\nTo link to a local copy of the SDK:\n\n~~~bash\n./scripts/link ../path/to/beeperdesktopapi-go\n~~~\n\nIf you run the link script without any arguments, it will default to `../beeperdesktopapi-go`.\n",
+ "# CLI for Beeper Desktop\n\nThe official CLI for the [Beeper Desktop REST API](https://developers.beeper.com/desktop-api/).\n\n\n\n## Installation\n\n### Installing with Go\n\nTo test or install the CLI locally, you need [Go](https://go.dev/doc/install) version 1.22 or later installed.\n\n~~~sh\ngo install 'github.com/beeper/desktop-api-cli/cmd/beeper-desktop@latest'\n~~~\n\nOnce you have run `go install`, the binary is placed in your Go bin directory:\n\n- **Default location**: `$HOME/go/bin` (or `$GOPATH/bin` if GOPATH is set)\n- **Check your path**: Run `go env GOPATH` to see the base directory\n\nIf commands aren't found after installation, add the Go bin directory to your PATH:\n\n~~~sh\n# Add to your shell profile (.zshrc, .bashrc, etc.)\nexport PATH=\"$PATH:$(go env GOPATH)/bin\"\n~~~\n\n\n\n### Running Locally\n\nAfter cloning the git repository for this project, you can use the\n`scripts/run` script to run the tool locally:\n\n~~~sh\n./scripts/run args...\n~~~\n\n## Usage\n\nThe CLI follows a resource-based command structure:\n\n~~~sh\nbeeper-desktop [resource] [flags...]\n~~~\n\n~~~sh\nbeeper-desktop chats search \\\n --access-token 'My Access Token' \\\n --account-id matrix \\\n --account-id discordgo \\\n --account-id local-whatsapp_ba_EvYDBBsZbRQAy3UOSWqG0LuTVkc \\\n --include-muted \\\n --limit 3 \\\n --type single\n~~~\n\nFor details about specific commands, use the `--help` flag.\n\n### Environment variables\n\n| Environment variable | Description | Required |\n| --------------------- | --------------------------------------------------------------------------------------------------------------- | -------- |\n| `BEEPER_ACCESS_TOKEN` | Bearer access token obtained via OAuth2 PKCE flow or created in-app. Required for authenticated API operations. | yes |\n\n### Global flags\n\n- `--access-token` - Bearer access token obtained via OAuth2 PKCE flow or created in-app. Required for authenticated API operations. (can also be set with `BEEPER_ACCESS_TOKEN` env var)\n- `--help` - Show command line usage\n- `--debug` - Enable debug logging (includes HTTP request/response details)\n- `--version`, `-v` - Show the CLI version\n- `--base-url` - Use a custom API backend URL\n- `--format` - Change the output format (`auto`, `explore`, `json`, `jsonl`, `pretty`, `raw`, `yaml`)\n- `--format-error` - Change the output format for errors (`auto`, `explore`, `json`, `jsonl`, `pretty`, `raw`, `yaml`)\n- `--transform` - Transform the data output using [GJSON syntax](https://github.com/tidwall/gjson/blob/master/SYNTAX.md)\n- `--transform-error` - Transform the error output using [GJSON syntax](https://github.com/tidwall/gjson/blob/master/SYNTAX.md)\n\n### Passing files as arguments\n\nTo pass files to your API, you can use the `@myfile.ext` syntax:\n\n~~~bash\nbeeper-desktop --arg @abe.jpg\n~~~\n\nFiles can also be passed inside JSON or YAML blobs:\n\n~~~bash\nbeeper-desktop --arg '{image: \"@abe.jpg\"}'\n# Equivalent:\nbeeper-desktop < --username '\\@abe'\n~~~\n\n#### Explicit encoding\n\nFor JSON endpoints, the CLI tool does filetype sniffing to determine whether the\nfile contents should be sent as a string literal (for plain text files) or as a\nbase64-encoded string literal (for binary files). If you need to explicitly send\nthe file as either plain text or base64-encoded data, you can use\n`@file://myfile.txt` (for string encoding) or `@data://myfile.dat` (for\nbase64-encoding). Note that absolute paths will begin with `@file://` or\n`@data://`, followed by a third `/` (for example, `@file:///tmp/file.txt`).\n\n~~~bash\nbeeper-desktop --arg @data://file.txt\n~~~\n\n## Linking different Go SDK versions\n\nYou can link the CLI against a different version of the Beeper Desktop Go SDK\nfor development purposes using the `./scripts/link` script.\n\nTo link to a specific version from a repository (version can be a branch,\ngit tag, or commit hash):\n\n~~~bash\n./scripts/link github.com/org/repo@version\n~~~\n\nTo link to a local copy of the SDK:\n\n~~~bash\n./scripts/link ../path/to/beeperdesktopapi-go\n~~~\n\nIf you run the link script without any arguments, it will default to `../beeperdesktopapi-go`.\n",
},
{
language: 'go',
diff --git a/packages/mcp-server/src/methods.ts b/packages/mcp-server/src/methods.ts
index 509a854..6dfb3ad 100644
--- a/packages/mcp-server/src/methods.ts
+++ b/packages/mcp-server/src/methods.ts
@@ -22,6 +22,12 @@ export const sdkMethods: SdkMethod[] = [
httpMethod: 'get',
httpPath: '/v1/search',
},
+ {
+ clientCallName: 'client.accounts.retrieve',
+ fullyQualifiedName: 'accounts.retrieve',
+ httpMethod: 'get',
+ httpPath: '/v1/accounts/{accountID}',
+ },
{
clientCallName: 'client.accounts.list',
fullyQualifiedName: 'accounts.list',
@@ -40,6 +46,54 @@ export const sdkMethods: SdkMethod[] = [
httpMethod: 'get',
httpPath: '/v1/accounts/{accountID}/contacts',
},
+ {
+ clientCallName: 'client.bridges.retrieve',
+ fullyQualifiedName: 'bridges.retrieve',
+ httpMethod: 'get',
+ httpPath: '/v1/bridges/{bridgeID}',
+ },
+ {
+ clientCallName: 'client.bridges.list',
+ fullyQualifiedName: 'bridges.list',
+ httpMethod: 'get',
+ httpPath: '/v1/bridges',
+ },
+ {
+ clientCallName: 'client.bridges.retrieveCapabilities',
+ fullyQualifiedName: 'bridges.retrieveCapabilities',
+ httpMethod: 'get',
+ httpPath: '/v1/bridges/{bridgeID}/capabilities',
+ },
+ {
+ clientCallName: 'client.bridges.loginFlows.list',
+ fullyQualifiedName: 'bridges.loginFlows.list',
+ httpMethod: 'get',
+ httpPath: '/v1/bridges/{bridgeID}/login-flows',
+ },
+ {
+ clientCallName: 'client.bridges.loginSessions.create',
+ fullyQualifiedName: 'bridges.loginSessions.create',
+ httpMethod: 'post',
+ httpPath: '/v1/bridges/{bridgeID}/login-sessions',
+ },
+ {
+ clientCallName: 'client.bridges.loginSessions.retrieve',
+ fullyQualifiedName: 'bridges.loginSessions.retrieve',
+ httpMethod: 'get',
+ httpPath: '/v1/bridges/{bridgeID}/login-sessions/{loginSessionID}',
+ },
+ {
+ clientCallName: 'client.bridges.loginSessions.cancel',
+ fullyQualifiedName: 'bridges.loginSessions.cancel',
+ httpMethod: 'delete',
+ httpPath: '/v1/bridges/{bridgeID}/login-sessions/{loginSessionID}',
+ },
+ {
+ clientCallName: 'client.bridges.loginSessions.steps.submit',
+ fullyQualifiedName: 'bridges.loginSessions.steps.submit',
+ httpMethod: 'post',
+ httpPath: '/v1/bridges/{bridgeID}/login-sessions/{loginSessionID}/steps/{stepID}',
+ },
{
clientCallName: 'client.chats.create',
fullyQualifiedName: 'chats.create',
@@ -190,6 +244,108 @@ export const sdkMethods: SdkMethod[] = [
httpMethod: 'get',
httpPath: '/v1/info',
},
+ {
+ clientCallName: 'client.app.session',
+ fullyQualifiedName: 'app.session',
+ httpMethod: 'get',
+ httpPath: '/v1/app/setup',
+ },
+ {
+ clientCallName: 'client.app.login.email',
+ fullyQualifiedName: 'app.login.email',
+ httpMethod: 'post',
+ httpPath: '/v1/app/setup/email',
+ },
+ {
+ clientCallName: 'client.app.login.register',
+ fullyQualifiedName: 'app.login.register',
+ httpMethod: 'post',
+ httpPath: '/v1/app/setup/register',
+ },
+ {
+ clientCallName: 'client.app.login.response',
+ fullyQualifiedName: 'app.login.response',
+ httpMethod: 'post',
+ httpPath: '/v1/app/setup/response',
+ },
+ {
+ clientCallName: 'client.app.login.start',
+ fullyQualifiedName: 'app.login.start',
+ httpMethod: 'post',
+ httpPath: '/v1/app/setup/start',
+ },
+ {
+ clientCallName: 'client.app.login.verification.recoveryKey.verify',
+ fullyQualifiedName: 'app.login.verification.recoveryKey.verify',
+ httpMethod: 'post',
+ httpPath: '/v1/app/setup/verification/recovery-key',
+ },
+ {
+ clientCallName: 'client.app.login.verification.recoveryKey.reset.create',
+ fullyQualifiedName: 'app.login.verification.recoveryKey.reset.create',
+ httpMethod: 'post',
+ httpPath: '/v1/app/setup/verification/recovery-key/reset',
+ },
+ {
+ clientCallName: 'client.app.login.verification.recoveryKey.reset.confirm',
+ fullyQualifiedName: 'app.login.verification.recoveryKey.reset.confirm',
+ httpMethod: 'post',
+ httpPath: '/v1/app/setup/verification/recovery-key/reset/confirm',
+ },
+ {
+ clientCallName: 'client.app.verifications.create',
+ fullyQualifiedName: 'app.verifications.create',
+ httpMethod: 'post',
+ httpPath: '/v1/app/setup/verifications',
+ },
+ {
+ clientCallName: 'client.app.verifications.retrieve',
+ fullyQualifiedName: 'app.verifications.retrieve',
+ httpMethod: 'get',
+ httpPath: '/v1/app/setup/verifications/{verificationID}',
+ },
+ {
+ clientCallName: 'client.app.verifications.list',
+ fullyQualifiedName: 'app.verifications.list',
+ httpMethod: 'get',
+ httpPath: '/v1/app/setup/verifications',
+ },
+ {
+ clientCallName: 'client.app.verifications.accept',
+ fullyQualifiedName: 'app.verifications.accept',
+ httpMethod: 'post',
+ httpPath: '/v1/app/setup/verifications/{verificationID}/accept',
+ },
+ {
+ clientCallName: 'client.app.verifications.cancel',
+ fullyQualifiedName: 'app.verifications.cancel',
+ httpMethod: 'post',
+ httpPath: '/v1/app/setup/verifications/{verificationID}/cancel',
+ },
+ {
+ clientCallName: 'client.app.verifications.qr.confirmScanned',
+ fullyQualifiedName: 'app.verifications.qr.confirmScanned',
+ httpMethod: 'post',
+ httpPath: '/v1/app/setup/verifications/{verificationID}/qr/confirm-scanned',
+ },
+ {
+ clientCallName: 'client.app.verifications.qr.scan',
+ fullyQualifiedName: 'app.verifications.qr.scan',
+ httpMethod: 'post',
+ httpPath: '/v1/app/setup/verifications/qr/scan',
+ },
+ {
+ clientCallName: 'client.app.verifications.sas.confirm',
+ fullyQualifiedName: 'app.verifications.sas.confirm',
+ httpMethod: 'post',
+ httpPath: '/v1/app/setup/verifications/{verificationID}/sas/confirm',
+ },
+ {
+ clientCallName: 'client.app.verifications.sas.start',
+ fullyQualifiedName: 'app.verifications.sas.start',
+ httpMethod: 'post',
+ httpPath: '/v1/app/setup/verifications/{verificationID}/sas/start',
+ },
];
function allowedMethodsForCodeTool(options: McpOptions | undefined): SdkMethod[] | undefined {
diff --git a/packages/mcp-server/src/server.ts b/packages/mcp-server/src/server.ts
index 293ee94..3fdacca 100644
--- a/packages/mcp-server/src/server.ts
+++ b/packages/mcp-server/src/server.ts
@@ -28,7 +28,7 @@ export const newMcpServer = async ({
new McpServer(
{
name: 'beeper_desktop_api_api',
- version: '5.0.0',
+ version: '5.1.0',
},
{
instructions: await getInstructions({ stainlessApiKey, customInstructionsPath }),
diff --git a/packages/mcp-server/tests/auth.test.ts b/packages/mcp-server/tests/auth.test.ts
new file mode 100644
index 0000000..c01dde0
--- /dev/null
+++ b/packages/mcp-server/tests/auth.test.ts
@@ -0,0 +1,24 @@
+import { IncomingMessage } from 'node:http';
+import { parseClientAuthHeaders } from '../src/auth';
+
+const reqWithHeaders = (headers: IncomingMessage['headers']) => ({ headers }) as IncomingMessage;
+
+describe('parseClientAuthHeaders', () => {
+ it('returns bearer access token from Authorization header', () => {
+ expect(parseClientAuthHeaders(reqWithHeaders({ authorization: 'Bearer token' }), true)).toEqual({
+ accessToken: 'token',
+ });
+ });
+
+ it('returns x-beeper-access-token when auth is required', () => {
+ expect(parseClientAuthHeaders(reqWithHeaders({ 'x-beeper-access-token': 'token' }), true)).toEqual({
+ accessToken: 'token',
+ });
+ });
+
+ it('throws when auth is required and no token is present', () => {
+ expect(() => parseClientAuthHeaders(reqWithHeaders({}), true)).toThrow(
+ 'Missing required Authorization header',
+ );
+ });
+});
diff --git a/packages/mcp-server/yarn.lock b/packages/mcp-server/yarn.lock
index c7e3769..c6b17b0 100644
--- a/packages/mcp-server/yarn.lock
+++ b/packages/mcp-server/yarn.lock
@@ -3921,9 +3921,9 @@ ts-node@^10.5.0:
v8-compile-cache-lib "^3.0.1"
yn "3.1.1"
-"tsc-multi@https://github.com/stainless-api/tsc-multi/releases/download/v1.1.9/tsc-multi.tgz":
- version "1.1.9"
- resolved "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.9/tsc-multi.tgz#777f6f5d9e26bf0e94e5170990dd3a841d6707cd"
+"tsc-multi@https://github.com/stainless-api/tsc-multi/releases/download/v1.1.11/tsc-multi.tgz":
+ version "1.1.11"
+ resolved "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.11/tsc-multi.tgz#010247051be13b55abdc98f787c017285149f4f2"
dependencies:
debug "^4.3.7"
fast-glob "^3.3.2"
diff --git a/src/client.ts b/src/client.ts
index 90ff33e..edbc1e3 100644
--- a/src/client.ts
+++ b/src/client.ts
@@ -49,7 +49,29 @@ import {
MessageUpdateResponse,
Messages,
} from './resources/messages';
-import { Account, AccountListResponse, Accounts } from './resources/accounts/accounts';
+import {
+ Account,
+ AccountBridge,
+ AccountListResponse,
+ AccountRetrieveResponse,
+ Accounts,
+} from './resources/accounts/accounts';
+import { App, AppSessionResponse, Verification } from './resources/app/app';
+import {
+ Bridge,
+ BridgeListResponse,
+ BridgeRetrieveResponse,
+ Bridges,
+ CookieField,
+ DisappearingTimerCapability,
+ GroupFieldCapability,
+ GroupTypeCapabilities,
+ LoginFlow,
+ LoginInputField,
+ LoginSession,
+ ProvisioningCapabilities,
+ ResolveIdentifierCapabilities,
+} from './resources/bridges/bridges';
import {
Chat,
ChatArchiveParams,
@@ -84,7 +106,7 @@ import { isEmptyObj } from './internal/utils/values';
export interface ClientOptions {
/**
- * Bearer access token obtained via OAuth2 PKCE flow or created in-app. Required for all API operations.
+ * Bearer access token obtained via OAuth2 PKCE flow or created in-app. Required for authenticated API operations.
*/
accessToken?: string | undefined;
@@ -263,8 +285,8 @@ export class BaseBeeperDesktop {
}
/**
- * Focus Beeper Desktop and optionally navigate to a specific chat, message, or
- * pre-fill plain text and an image path.
+ * Focus Beeper Desktop and optionally open a specific chat, jump to a message, or
+ * pre-fill text and an image.
*
* @example
* ```ts
@@ -279,9 +301,9 @@ export class BaseBeeperDesktop {
}
/**
- * Returns matching chats, participant name matches in groups, and the first page
- * of messages in one call. Paginate messages via search-messages. Paginate chats
- * via search-chats.
+ * Return matching chats, participant matches in group chats, and the first page of
+ * message results in one call. Use the dedicated chat and message search endpoints
+ * for pagination.
*
* @example
* ```ts
@@ -849,6 +871,10 @@ export class BeeperDesktop extends BaseBeeperDesktop {
* Manage connected chat accounts
*/
accounts: API.Accounts = new API.Accounts(this);
+ /**
+ * Manage bridge-backed account types, connections, and login sessions
+ */
+ bridges: API.Bridges = new API.Bridges(this);
/**
* Manage chats
*/
@@ -865,13 +891,19 @@ export class BeeperDesktop extends BaseBeeperDesktop {
* Server discovery and capability metadata. Use /v1/info before authentication setup.
*/
info: API.Info = new API.Info(this);
+ /**
+ * Manage Beeper app login and encrypted messaging setup
+ */
+ app: API.App = new API.App(this);
}
BeeperDesktop.Accounts = Accounts;
+BeeperDesktop.Bridges = Bridges;
BeeperDesktop.Chats = Chats;
BeeperDesktop.Messages = Messages;
BeeperDesktop.Assets = Assets;
BeeperDesktop.Info = Info;
+BeeperDesktop.App = App;
export declare namespace BeeperDesktop {
export type RequestOptions = Opts.RequestOptions;
@@ -892,7 +924,29 @@ export declare namespace BeeperDesktop {
type SearchParams as SearchParams,
};
- export { Accounts as Accounts, type Account as Account, type AccountListResponse as AccountListResponse };
+ export {
+ Accounts as Accounts,
+ type Account as Account,
+ type AccountBridge as AccountBridge,
+ type AccountRetrieveResponse as AccountRetrieveResponse,
+ type AccountListResponse as AccountListResponse,
+ };
+
+ export {
+ Bridges as Bridges,
+ type Bridge as Bridge,
+ type CookieField as CookieField,
+ type DisappearingTimerCapability as DisappearingTimerCapability,
+ type GroupFieldCapability as GroupFieldCapability,
+ type GroupTypeCapabilities as GroupTypeCapabilities,
+ type LoginFlow as LoginFlow,
+ type LoginInputField as LoginInputField,
+ type LoginSession as LoginSession,
+ type ProvisioningCapabilities as ProvisioningCapabilities,
+ type ResolveIdentifierCapabilities as ResolveIdentifierCapabilities,
+ type BridgeRetrieveResponse as BridgeRetrieveResponse,
+ type BridgeListResponse as BridgeListResponse,
+ };
export {
Chats as Chats,
@@ -939,6 +993,10 @@ export declare namespace BeeperDesktop {
export { Info as Info, type InfoRetrieveResponse as InfoRetrieveResponse };
+ export { App as App, type Verification as Verification, type AppSessionResponse as AppSessionResponse };
+
+ export type APIError = API.APIError;
+ export type AppStateSnapshot = API.AppStateSnapshot;
export type Attachment = API.Attachment;
export type Error = API.Error;
export type Message = API.Message;
diff --git a/src/internal/utils/log.ts b/src/internal/utils/log.ts
index 41b8cfd..2c61df7 100644
--- a/src/internal/utils/log.ts
+++ b/src/internal/utils/log.ts
@@ -107,6 +107,8 @@ export const formatRequestDetails = (details: {
name,
(
name.toLowerCase() === 'authorization' ||
+ name.toLowerCase() === 'api-key' ||
+ name.toLowerCase() === 'x-api-key' ||
name.toLowerCase() === 'cookie' ||
name.toLowerCase() === 'set-cookie'
) ?
diff --git a/src/resources/accounts/accounts.ts b/src/resources/accounts/accounts.ts
index c3c997f..0be35e7 100644
--- a/src/resources/accounts/accounts.ts
+++ b/src/resources/accounts/accounts.ts
@@ -12,6 +12,7 @@ import {
} from './contacts';
import { APIPromise } from '../../core/api-promise';
import { RequestOptions } from '../../internal/request-options';
+import { path } from '../../internal/utils/path';
/**
* Manage connected chat accounts
@@ -20,8 +21,20 @@ export class BaseAccounts extends APIResource {
static override readonly _key: readonly ['accounts'] = Object.freeze(['accounts'] as const);
/**
- * List Chat Accounts connected to this Beeper Desktop instance, including bridge
- * metadata and network identity.
+ * Get one chat account connected to this Beeper Client API server.
+ *
+ * @example
+ * ```ts
+ * const account = await client.accounts.retrieve('accountID');
+ * ```
+ */
+ retrieve(accountID: string, options?: RequestOptions): APIPromise {
+ return this._client.get(path`/v1/accounts/${accountID}`, options);
+ }
+
+ /**
+ * List chat accounts connected to this Beeper Client API server, including bridge,
+ * network, user identity, and connection status.
*
* @example
* ```ts
@@ -54,47 +67,133 @@ export interface Account {
/**
* Bridge metadata for the account. Available in Beeper Desktop v4.2.785+.
*/
- bridge: Account.Bridge;
+ bridge: AccountBridge;
+
+ /**
+ * Current connection status for this account.
+ */
+ status:
+ | 'connected'
+ | 'connecting'
+ | 'backfilling'
+ | 'connection_required'
+ | 'reconnect_required'
+ | 'attention_required'
+ | 'disconnected'
+ | 'disabled';
/**
* User the account belongs to.
*/
user: Shared.User;
+ /**
+ * Runtime chat/message capabilities for this connected account, when available.
+ */
+ capabilities?: { [key: string]: unknown };
+
+ /**
+ * Bridge login ID for this account, when known. One bridge login can contain
+ * multiple chat accounts.
+ */
+ loginID?: string;
+
/**
* Human-friendly network name for the account. Omitted when the network is
* unknown.
*/
network?: string;
+
+ /**
+ * Human-friendly account status text.
+ */
+ statusText?: string;
}
-export namespace Account {
+/**
+ * Bridge metadata for the account. Available in Beeper Desktop v4.2.785+.
+ */
+export interface AccountBridge {
+ /**
+ * Bridge identifier. Beeper Cloud accounts often use the network type (for example
+ * matrix or discordgo); on-device accounts use a local bridge ID (for example
+ * local-whatsapp). Available in Beeper Desktop v4.2.785+.
+ */
+ id: string;
+
+ /**
+ * Where this account runs: on this device or in Beeper Cloud. Available in Beeper
+ * Desktop v4.2.785+.
+ */
+ provider: 'cloud' | 'self-hosted' | 'local' | 'platform-sdk';
+
+ /**
+ * Bridge type, such as matrix, discordgo, slackgo, whatsapp, telegram, or twitter.
+ * Available in Beeper Desktop v4.2.785+.
+ */
+ type: string;
+}
+
+/**
+ * A chat account added to Beeper.
+ */
+export interface AccountRetrieveResponse {
+ /**
+ * Chat account added to Beeper. Use this to route account-scoped actions. Examples
+ * include matrix for Beeper/Matrix, discordgo for a cloud bridge,
+ * slackgo.TEAM-USER for workspace-scoped cloud bridges, and local-whatsapp*ba*...
+ * for local bridges.
+ */
+ accountID: string;
+
/**
* Bridge metadata for the account. Available in Beeper Desktop v4.2.785+.
*/
- export interface Bridge {
- /**
- * Bridge instance identifier. Matrix and cloud bridges often use the bridge type
- * (for example matrix or discordgo); local bridges use a local bridge ID (for
- * example local-whatsapp). Available in Beeper Desktop v4.2.785+.
- */
- id: string;
-
- /**
- * Bridge provider for the account. Available in Beeper Desktop v4.2.785+.
- */
- provider: 'cloud' | 'self-hosted' | 'local' | 'platform-sdk';
-
- /**
- * Bridge type, such as matrix, discordgo, slackgo, whatsapp, telegram, or twitter.
- * Available in Beeper Desktop v4.2.785+.
- */
- type: string;
- }
+ bridge: AccountBridge;
+
+ /**
+ * Current connection status for this account.
+ */
+ status:
+ | 'connected'
+ | 'connecting'
+ | 'backfilling'
+ | 'connection_required'
+ | 'reconnect_required'
+ | 'attention_required'
+ | 'disconnected'
+ | 'disabled';
+
+ /**
+ * User the account belongs to.
+ */
+ user: Shared.User;
+
+ /**
+ * Runtime chat/message capabilities for this connected account, when available.
+ */
+ capabilities?: { [key: string]: unknown };
+
+ /**
+ * Bridge login ID for this account, when known. One bridge login can contain
+ * multiple chat accounts.
+ */
+ loginID?: string;
+
+ /**
+ * Human-friendly network name for the account. Omitted when the network is
+ * unknown.
+ */
+ network?: string;
+
+ /**
+ * Human-friendly account status text.
+ */
+ statusText?: string;
}
/**
- * Accounts configured on this device. Includes accountID, bridge metadata,
+ * Chat accounts configured on this device. Includes accountID, bridge metadata,
* optional network name, and user identity.
*/
export type AccountListResponse = Array;
@@ -103,7 +202,12 @@ Accounts.Contacts = Contacts;
Accounts.BaseContacts = BaseContacts;
export declare namespace Accounts {
- export { type Account as Account, type AccountListResponse as AccountListResponse };
+ export {
+ type Account as Account,
+ type AccountBridge as AccountBridge,
+ type AccountRetrieveResponse as AccountRetrieveResponse,
+ type AccountListResponse as AccountListResponse,
+ };
export {
Contacts as Contacts,
diff --git a/src/resources/accounts/contacts.ts b/src/resources/accounts/contacts.ts
index 42bd754..18ab023 100644
--- a/src/resources/accounts/contacts.ts
+++ b/src/resources/accounts/contacts.ts
@@ -72,14 +72,14 @@ export interface ContactSearchResponse {
export interface ContactListParams extends CursorSearchParams {
/**
- * Optional search query for blended contact lookup.
+ * Optional search query for contact lookup.
*/
query?: string;
}
export interface ContactSearchParams {
/**
- * Text to search users by. Network-specific behavior.
+ * Text to search contacts by. Matching behavior depends on the network.
*/
query: string;
}
diff --git a/src/resources/accounts/index.ts b/src/resources/accounts/index.ts
index 1249a9b..c63c2c5 100644
--- a/src/resources/accounts/index.ts
+++ b/src/resources/accounts/index.ts
@@ -1,6 +1,13 @@
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-export { Accounts, BaseAccounts, type Account, type AccountListResponse } from './accounts';
+export {
+ Accounts,
+ BaseAccounts,
+ type Account,
+ type AccountBridge,
+ type AccountRetrieveResponse,
+ type AccountListResponse,
+} from './accounts';
export {
Contacts,
BaseContacts,
diff --git a/src/resources/app.ts b/src/resources/app.ts
new file mode 100644
index 0000000..eed68d3
--- /dev/null
+++ b/src/resources/app.ts
@@ -0,0 +1,3 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+export * from './app/index';
diff --git a/src/resources/app/app.ts b/src/resources/app/app.ts
new file mode 100644
index 0000000..e55e7c0
--- /dev/null
+++ b/src/resources/app/app.ts
@@ -0,0 +1,451 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { APIResource } from '../../core/resource';
+import * as LoginAPI from './login/login';
+import {
+ BaseLogin,
+ Login,
+ LoginEmailParams,
+ LoginRegisterParams,
+ LoginRegisterResponse,
+ LoginResponseParams,
+ LoginResponseResponse,
+ LoginStartResponse,
+} from './login/login';
+import * as VerificationsAPI from './verifications/verifications';
+import {
+ BaseVerifications,
+ VerificationAcceptResponse,
+ VerificationCancelParams,
+ VerificationCancelResponse,
+ VerificationCreateParams,
+ VerificationCreateResponse,
+ VerificationListResponse,
+ VerificationRetrieveResponse,
+ Verifications,
+} from './verifications/verifications';
+import { APIPromise } from '../../core/api-promise';
+import { RequestOptions } from '../../internal/request-options';
+
+/**
+ * Manage Beeper app login and encrypted messaging setup
+ */
+export class BaseApp extends APIResource {
+ static override readonly _key: readonly ['app'] = Object.freeze(['app'] as const);
+
+ /**
+ * Return the current Beeper Desktop or Beeper Server sign-in and encrypted
+ * messaging setup state. This endpoint is public before sign-in so apps can
+ * discover that sign-in is needed; after sign-in, pass a read token.
+ */
+ session(options?: RequestOptions): APIPromise {
+ return this._client.get('/v1/app/setup', options);
+ }
+}
+/**
+ * Manage Beeper app login and encrypted messaging setup
+ */
+export class App extends BaseApp {
+ login: LoginAPI.Login = new LoginAPI.Login(this._client);
+ verifications: VerificationsAPI.Verifications = new VerificationsAPI.Verifications(this._client);
+}
+
+/**
+ * Trusted device verification progress.
+ */
+export interface Verification {
+ /**
+ * Verification ID to pass in verification action paths.
+ */
+ id: string;
+
+ /**
+ * Verification actions that are valid for the current state.
+ */
+ availableActions: Array<'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'>;
+
+ /**
+ * Whether this device started or received the verification.
+ */
+ direction: 'incoming' | 'outgoing';
+
+ /**
+ * Verification methods supported for this transaction.
+ */
+ methods: Array<'qr' | 'sas'>;
+
+ /**
+ * Why this verification exists.
+ */
+ purpose: 'login' | 'device';
+
+ /**
+ * Current trusted-device verification state.
+ */
+ state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error';
+
+ /**
+ * Verification error details, if verification stopped.
+ */
+ error?: Verification.Error;
+
+ /**
+ * Other device participating in verification.
+ */
+ otherDevice?: Verification.OtherDevice;
+
+ /**
+ * Other Beeper user participating in verification.
+ */
+ otherUserID?: string;
+
+ /**
+ * QR verification data.
+ */
+ qr?: Verification.Qr;
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ sas?: Verification.SAS;
+}
+
+export namespace Verification {
+ /**
+ * Verification error details, if verification stopped.
+ */
+ export interface Error {
+ /**
+ * Verification error code.
+ */
+ code: string;
+
+ /**
+ * User-facing verification error message.
+ */
+ reason: string;
+ }
+
+ /**
+ * Other device participating in verification.
+ */
+ export interface OtherDevice {
+ /**
+ * Other device ID.
+ */
+ id: string;
+
+ /**
+ * Other device display name, if known.
+ */
+ name?: string;
+ }
+
+ /**
+ * QR verification data.
+ */
+ export interface Qr {
+ /**
+ * QR code payload to display for verification.
+ */
+ data: string;
+ }
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ export interface SAS {
+ /**
+ * Emoji sequence to compare on both devices.
+ */
+ emojis: string;
+
+ /**
+ * Number sequence to compare on both devices.
+ */
+ decimals?: string;
+ }
+}
+
+export interface AppSessionResponse {
+ /**
+ * Encrypted messaging setup status.
+ */
+ e2ee: AppSessionResponse.E2EE;
+
+ /**
+ * Current sign-in and encrypted messaging setup state for Beeper Desktop or Beeper
+ * Server.
+ */
+ state:
+ | 'needs-login'
+ | 'initializing'
+ | 'needs-cross-signing-setup'
+ | 'needs-verification'
+ | 'needs-secrets'
+ | 'needs-first-sync'
+ | 'ready';
+
+ /**
+ * Signed-in account details. Omitted until sign-in is complete.
+ */
+ matrix?: AppSessionResponse.Matrix;
+
+ /**
+ * Trusted device verification progress.
+ */
+ verification?: AppSessionResponse.Verification;
+}
+
+export namespace AppSessionResponse {
+ /**
+ * Encrypted messaging setup status.
+ */
+ export interface E2EE {
+ /**
+ * Whether this account can verify trusted devices.
+ */
+ crossSigning: boolean;
+
+ /**
+ * Whether the first encrypted message sync is complete.
+ */
+ firstSyncDone: boolean;
+
+ /**
+ * Whether the user confirmed that they saved their recovery key.
+ */
+ hasBackedUpRecoveryKey: boolean;
+
+ /**
+ * Whether encrypted messaging setup has started.
+ */
+ initialized: boolean;
+
+ /**
+ * Whether encrypted message backup is available.
+ */
+ keyBackup: boolean;
+
+ /**
+ * Encrypted messaging keys available on this device.
+ */
+ secrets: E2EE.Secrets;
+
+ /**
+ * Whether secure key storage is available.
+ */
+ secretStorage: boolean;
+
+ /**
+ * Whether this device is trusted for encrypted messages.
+ */
+ verified: boolean;
+
+ /**
+ * Unix timestamp for when the recovery key was created.
+ */
+ recoveryKeyGeneratedAt?: number;
+ }
+
+ export namespace E2EE {
+ /**
+ * Encrypted messaging keys available on this device.
+ */
+ export interface Secrets {
+ /**
+ * Whether the account identity key is available.
+ */
+ masterKey: boolean;
+
+ /**
+ * Whether the encrypted message backup key is available.
+ */
+ megolmBackupKey: boolean;
+
+ /**
+ * Whether a recovery key is available.
+ */
+ recoveryKey: boolean;
+
+ /**
+ * Whether the device trust key is available.
+ */
+ selfSigningKey: boolean;
+
+ /**
+ * Whether the user trust key is available.
+ */
+ userSigningKey: boolean;
+ }
+ }
+
+ /**
+ * Signed-in account details. Omitted until sign-in is complete.
+ */
+ export interface Matrix {
+ /**
+ * Current device ID.
+ */
+ deviceID: string;
+
+ /**
+ * Beeper homeserver URL for this account.
+ */
+ homeserver: string;
+
+ /**
+ * Signed-in Beeper user ID.
+ */
+ userID: string;
+ }
+
+ /**
+ * Trusted device verification progress.
+ */
+ export interface Verification {
+ /**
+ * Verification ID to pass in verification action paths.
+ */
+ id: string;
+
+ /**
+ * Verification actions that are valid for the current state.
+ */
+ availableActions: Array<'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'>;
+
+ /**
+ * Whether this device started or received the verification.
+ */
+ direction: 'incoming' | 'outgoing';
+
+ /**
+ * Verification methods supported for this transaction.
+ */
+ methods: Array<'qr' | 'sas'>;
+
+ /**
+ * Why this verification exists.
+ */
+ purpose: 'login' | 'device';
+
+ /**
+ * Current trusted-device verification state.
+ */
+ state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error';
+
+ /**
+ * Verification error details, if verification stopped.
+ */
+ error?: Verification.Error;
+
+ /**
+ * Other device participating in verification.
+ */
+ otherDevice?: Verification.OtherDevice;
+
+ /**
+ * Other Beeper user participating in verification.
+ */
+ otherUserID?: string;
+
+ /**
+ * QR verification data.
+ */
+ qr?: Verification.Qr;
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ sas?: Verification.SAS;
+ }
+
+ export namespace Verification {
+ /**
+ * Verification error details, if verification stopped.
+ */
+ export interface Error {
+ /**
+ * Verification error code.
+ */
+ code: string;
+
+ /**
+ * User-facing verification error message.
+ */
+ reason: string;
+ }
+
+ /**
+ * Other device participating in verification.
+ */
+ export interface OtherDevice {
+ /**
+ * Other device ID.
+ */
+ id: string;
+
+ /**
+ * Other device display name, if known.
+ */
+ name?: string;
+ }
+
+ /**
+ * QR verification data.
+ */
+ export interface Qr {
+ /**
+ * QR code payload to display for verification.
+ */
+ data: string;
+ }
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ export interface SAS {
+ /**
+ * Emoji sequence to compare on both devices.
+ */
+ emojis: string;
+
+ /**
+ * Number sequence to compare on both devices.
+ */
+ decimals?: string;
+ }
+ }
+}
+
+App.Login = Login;
+App.BaseLogin = BaseLogin;
+App.Verifications = Verifications;
+App.BaseVerifications = BaseVerifications;
+
+export declare namespace App {
+ export { type Verification as Verification, type AppSessionResponse as AppSessionResponse };
+
+ export {
+ Login as Login,
+ BaseLogin as BaseLogin,
+ type LoginRegisterResponse as LoginRegisterResponse,
+ type LoginResponseResponse as LoginResponseResponse,
+ type LoginStartResponse as LoginStartResponse,
+ type LoginEmailParams as LoginEmailParams,
+ type LoginRegisterParams as LoginRegisterParams,
+ type LoginResponseParams as LoginResponseParams,
+ };
+
+ export {
+ Verifications as Verifications,
+ BaseVerifications as BaseVerifications,
+ type VerificationCreateResponse as VerificationCreateResponse,
+ type VerificationRetrieveResponse as VerificationRetrieveResponse,
+ type VerificationListResponse as VerificationListResponse,
+ type VerificationAcceptResponse as VerificationAcceptResponse,
+ type VerificationCancelResponse as VerificationCancelResponse,
+ type VerificationCreateParams as VerificationCreateParams,
+ type VerificationCancelParams as VerificationCancelParams,
+ };
+}
diff --git a/src/resources/app/index.ts b/src/resources/app/index.ts
new file mode 100644
index 0000000..d1fd301
--- /dev/null
+++ b/src/resources/app/index.ts
@@ -0,0 +1,24 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+export { App, BaseApp, type Verification, type AppSessionResponse } from './app';
+export {
+ Login,
+ BaseLogin,
+ type LoginRegisterResponse,
+ type LoginResponseResponse,
+ type LoginStartResponse,
+ type LoginEmailParams,
+ type LoginRegisterParams,
+ type LoginResponseParams,
+} from './login/index';
+export {
+ Verifications,
+ BaseVerifications,
+ type VerificationCreateResponse,
+ type VerificationRetrieveResponse,
+ type VerificationListResponse,
+ type VerificationAcceptResponse,
+ type VerificationCancelResponse,
+ type VerificationCreateParams,
+ type VerificationCancelParams,
+} from './verifications/index';
diff --git a/src/resources/app/login.ts b/src/resources/app/login.ts
new file mode 100644
index 0000000..8809991
--- /dev/null
+++ b/src/resources/app/login.ts
@@ -0,0 +1,3 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+export * from './login/index';
diff --git a/src/resources/app/login/index.ts b/src/resources/app/login/index.ts
new file mode 100644
index 0000000..b1a5c5b
--- /dev/null
+++ b/src/resources/app/login/index.ts
@@ -0,0 +1,13 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+export {
+ Login,
+ BaseLogin,
+ type LoginRegisterResponse,
+ type LoginResponseResponse,
+ type LoginStartResponse,
+ type LoginEmailParams,
+ type LoginRegisterParams,
+ type LoginResponseParams,
+} from './login';
+export { Verification, BaseVerification } from './verification/index';
diff --git a/src/resources/app/login/login.ts b/src/resources/app/login/login.ts
new file mode 100644
index 0000000..359f2be
--- /dev/null
+++ b/src/resources/app/login/login.ts
@@ -0,0 +1,780 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { APIResource } from '../../../core/resource';
+import * as VerificationAPI from './verification/verification';
+import { BaseVerification, Verification as VerificationAPIVerification } from './verification/verification';
+import { APIPromise } from '../../../core/api-promise';
+import { buildHeaders } from '../../../internal/headers';
+import { RequestOptions } from '../../../internal/request-options';
+
+/**
+ * Complete first-party Beeper app login
+ */
+export class BaseLogin extends APIResource {
+ static override readonly _key: readonly ['app', 'login'] = Object.freeze(['app', 'login'] as const);
+
+ /**
+ * Send a sign-in code to the user email address for app setup.
+ */
+ email(body: LoginEmailParams, options?: RequestOptions): APIPromise {
+ return this._client.post('/v1/app/setup/email', {
+ body,
+ ...options,
+ headers: buildHeaders([{ Accept: '*/*' }, options?.headers]),
+ __security: {},
+ });
+ }
+
+ /**
+ * Create a Beeper account after the user chooses a username and accepts the Terms
+ * of Use.
+ */
+ register(body: LoginRegisterParams, options?: RequestOptions): APIPromise {
+ return this._client.post('/v1/app/setup/register', { body, ...options, __security: {} });
+ }
+
+ /**
+ * Finish setup sign-in with the code sent to the user email address. If the user
+ * needs a new account, the response includes account creation copy and username
+ * suggestions.
+ */
+ response(body: LoginResponseParams, options?: RequestOptions): APIPromise {
+ return this._client.post('/v1/app/setup/response', { body, ...options, __security: {} });
+ }
+
+ /**
+ * Start setting up Beeper Desktop or Beeper Server. The flow supports existing
+ * Beeper accounts and new account creation.
+ */
+ start(options?: RequestOptions): APIPromise {
+ return this._client.post('/v1/app/setup/start', { ...options, __security: {} });
+ }
+}
+/**
+ * Complete first-party Beeper app login
+ */
+export class Login extends BaseLogin {
+ verification: VerificationAPI.Verification = new VerificationAPI.Verification(this._client);
+}
+
+export interface LoginRegisterResponse {
+ /**
+ * Account credentials for first-party app setup.
+ */
+ matrix: LoginRegisterResponse.Matrix;
+
+ /**
+ * Current app sign-in and encrypted messaging setup state after sign-in.
+ */
+ session: LoginRegisterResponse.Session;
+}
+
+export namespace LoginRegisterResponse {
+ /**
+ * Account credentials for first-party app setup.
+ */
+ export interface Matrix {
+ /**
+ * Beeper account access token. Returned once for first-party app setup.
+ */
+ accessToken: string;
+
+ /**
+ * Current device ID.
+ */
+ deviceID: string;
+
+ /**
+ * Beeper homeserver URL for this account.
+ */
+ homeserver: string;
+
+ /**
+ * Signed-in Beeper user ID.
+ */
+ userID: string;
+ }
+
+ /**
+ * Current app sign-in and encrypted messaging setup state after sign-in.
+ */
+ export interface Session {
+ /**
+ * Encrypted messaging setup status.
+ */
+ e2ee: Session.E2EE;
+
+ /**
+ * Current sign-in and encrypted messaging setup state for Beeper Desktop or Beeper
+ * Server.
+ */
+ state:
+ | 'needs-login'
+ | 'initializing'
+ | 'needs-cross-signing-setup'
+ | 'needs-verification'
+ | 'needs-secrets'
+ | 'needs-first-sync'
+ | 'ready';
+
+ /**
+ * Signed-in account details. Omitted until sign-in is complete.
+ */
+ matrix?: Session.Matrix;
+
+ /**
+ * Trusted device verification progress.
+ */
+ verification?: Session.Verification;
+ }
+
+ export namespace Session {
+ /**
+ * Encrypted messaging setup status.
+ */
+ export interface E2EE {
+ /**
+ * Whether this account can verify trusted devices.
+ */
+ crossSigning: boolean;
+
+ /**
+ * Whether the first encrypted message sync is complete.
+ */
+ firstSyncDone: boolean;
+
+ /**
+ * Whether the user confirmed that they saved their recovery key.
+ */
+ hasBackedUpRecoveryKey: boolean;
+
+ /**
+ * Whether encrypted messaging setup has started.
+ */
+ initialized: boolean;
+
+ /**
+ * Whether encrypted message backup is available.
+ */
+ keyBackup: boolean;
+
+ /**
+ * Encrypted messaging keys available on this device.
+ */
+ secrets: E2EE.Secrets;
+
+ /**
+ * Whether secure key storage is available.
+ */
+ secretStorage: boolean;
+
+ /**
+ * Whether this device is trusted for encrypted messages.
+ */
+ verified: boolean;
+
+ /**
+ * Unix timestamp for when the recovery key was created.
+ */
+ recoveryKeyGeneratedAt?: number;
+ }
+
+ export namespace E2EE {
+ /**
+ * Encrypted messaging keys available on this device.
+ */
+ export interface Secrets {
+ /**
+ * Whether the account identity key is available.
+ */
+ masterKey: boolean;
+
+ /**
+ * Whether the encrypted message backup key is available.
+ */
+ megolmBackupKey: boolean;
+
+ /**
+ * Whether a recovery key is available.
+ */
+ recoveryKey: boolean;
+
+ /**
+ * Whether the device trust key is available.
+ */
+ selfSigningKey: boolean;
+
+ /**
+ * Whether the user trust key is available.
+ */
+ userSigningKey: boolean;
+ }
+ }
+
+ /**
+ * Signed-in account details. Omitted until sign-in is complete.
+ */
+ export interface Matrix {
+ /**
+ * Current device ID.
+ */
+ deviceID: string;
+
+ /**
+ * Beeper homeserver URL for this account.
+ */
+ homeserver: string;
+
+ /**
+ * Signed-in Beeper user ID.
+ */
+ userID: string;
+ }
+
+ /**
+ * Trusted device verification progress.
+ */
+ export interface Verification {
+ /**
+ * Verification ID to pass in verification action paths.
+ */
+ id: string;
+
+ /**
+ * Verification actions that are valid for the current state.
+ */
+ availableActions: Array<'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'>;
+
+ /**
+ * Whether this device started or received the verification.
+ */
+ direction: 'incoming' | 'outgoing';
+
+ /**
+ * Verification methods supported for this transaction.
+ */
+ methods: Array<'qr' | 'sas'>;
+
+ /**
+ * Why this verification exists.
+ */
+ purpose: 'login' | 'device';
+
+ /**
+ * Current trusted-device verification state.
+ */
+ state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error';
+
+ /**
+ * Verification error details, if verification stopped.
+ */
+ error?: Verification.Error;
+
+ /**
+ * Other device participating in verification.
+ */
+ otherDevice?: Verification.OtherDevice;
+
+ /**
+ * Other Beeper user participating in verification.
+ */
+ otherUserID?: string;
+
+ /**
+ * QR verification data.
+ */
+ qr?: Verification.Qr;
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ sas?: Verification.SAS;
+ }
+
+ export namespace Verification {
+ /**
+ * Verification error details, if verification stopped.
+ */
+ export interface Error {
+ /**
+ * Verification error code.
+ */
+ code: string;
+
+ /**
+ * User-facing verification error message.
+ */
+ reason: string;
+ }
+
+ /**
+ * Other device participating in verification.
+ */
+ export interface OtherDevice {
+ /**
+ * Other device ID.
+ */
+ id: string;
+
+ /**
+ * Other device display name, if known.
+ */
+ name?: string;
+ }
+
+ /**
+ * QR verification data.
+ */
+ export interface Qr {
+ /**
+ * QR code payload to display for verification.
+ */
+ data: string;
+ }
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ export interface SAS {
+ /**
+ * Emoji sequence to compare on both devices.
+ */
+ emojis: string;
+
+ /**
+ * Number sequence to compare on both devices.
+ */
+ decimals?: string;
+ }
+ }
+ }
+}
+
+export type LoginResponseResponse =
+ | LoginResponseResponse.Success
+ | LoginResponseResponse.RegistrationRequired;
+
+export namespace LoginResponseResponse {
+ export interface Success {
+ /**
+ * Account credentials for first-party app setup.
+ */
+ matrix: Success.Matrix;
+
+ /**
+ * Current app sign-in and encrypted messaging setup state after sign-in.
+ */
+ session: Success.Session;
+ }
+
+ export namespace Success {
+ /**
+ * Account credentials for first-party app setup.
+ */
+ export interface Matrix {
+ /**
+ * Beeper account access token. Returned once for first-party app setup.
+ */
+ accessToken: string;
+
+ /**
+ * Current device ID.
+ */
+ deviceID: string;
+
+ /**
+ * Beeper homeserver URL for this account.
+ */
+ homeserver: string;
+
+ /**
+ * Signed-in Beeper user ID.
+ */
+ userID: string;
+ }
+
+ /**
+ * Current app sign-in and encrypted messaging setup state after sign-in.
+ */
+ export interface Session {
+ /**
+ * Encrypted messaging setup status.
+ */
+ e2ee: Session.E2EE;
+
+ /**
+ * Current sign-in and encrypted messaging setup state for Beeper Desktop or Beeper
+ * Server.
+ */
+ state:
+ | 'needs-login'
+ | 'initializing'
+ | 'needs-cross-signing-setup'
+ | 'needs-verification'
+ | 'needs-secrets'
+ | 'needs-first-sync'
+ | 'ready';
+
+ /**
+ * Signed-in account details. Omitted until sign-in is complete.
+ */
+ matrix?: Session.Matrix;
+
+ /**
+ * Trusted device verification progress.
+ */
+ verification?: Session.Verification;
+ }
+
+ export namespace Session {
+ /**
+ * Encrypted messaging setup status.
+ */
+ export interface E2EE {
+ /**
+ * Whether this account can verify trusted devices.
+ */
+ crossSigning: boolean;
+
+ /**
+ * Whether the first encrypted message sync is complete.
+ */
+ firstSyncDone: boolean;
+
+ /**
+ * Whether the user confirmed that they saved their recovery key.
+ */
+ hasBackedUpRecoveryKey: boolean;
+
+ /**
+ * Whether encrypted messaging setup has started.
+ */
+ initialized: boolean;
+
+ /**
+ * Whether encrypted message backup is available.
+ */
+ keyBackup: boolean;
+
+ /**
+ * Encrypted messaging keys available on this device.
+ */
+ secrets: E2EE.Secrets;
+
+ /**
+ * Whether secure key storage is available.
+ */
+ secretStorage: boolean;
+
+ /**
+ * Whether this device is trusted for encrypted messages.
+ */
+ verified: boolean;
+
+ /**
+ * Unix timestamp for when the recovery key was created.
+ */
+ recoveryKeyGeneratedAt?: number;
+ }
+
+ export namespace E2EE {
+ /**
+ * Encrypted messaging keys available on this device.
+ */
+ export interface Secrets {
+ /**
+ * Whether the account identity key is available.
+ */
+ masterKey: boolean;
+
+ /**
+ * Whether the encrypted message backup key is available.
+ */
+ megolmBackupKey: boolean;
+
+ /**
+ * Whether a recovery key is available.
+ */
+ recoveryKey: boolean;
+
+ /**
+ * Whether the device trust key is available.
+ */
+ selfSigningKey: boolean;
+
+ /**
+ * Whether the user trust key is available.
+ */
+ userSigningKey: boolean;
+ }
+ }
+
+ /**
+ * Signed-in account details. Omitted until sign-in is complete.
+ */
+ export interface Matrix {
+ /**
+ * Current device ID.
+ */
+ deviceID: string;
+
+ /**
+ * Beeper homeserver URL for this account.
+ */
+ homeserver: string;
+
+ /**
+ * Signed-in Beeper user ID.
+ */
+ userID: string;
+ }
+
+ /**
+ * Trusted device verification progress.
+ */
+ export interface Verification {
+ /**
+ * Verification ID to pass in verification action paths.
+ */
+ id: string;
+
+ /**
+ * Verification actions that are valid for the current state.
+ */
+ availableActions: Array<'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'>;
+
+ /**
+ * Whether this device started or received the verification.
+ */
+ direction: 'incoming' | 'outgoing';
+
+ /**
+ * Verification methods supported for this transaction.
+ */
+ methods: Array<'qr' | 'sas'>;
+
+ /**
+ * Why this verification exists.
+ */
+ purpose: 'login' | 'device';
+
+ /**
+ * Current trusted-device verification state.
+ */
+ state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error';
+
+ /**
+ * Verification error details, if verification stopped.
+ */
+ error?: Verification.Error;
+
+ /**
+ * Other device participating in verification.
+ */
+ otherDevice?: Verification.OtherDevice;
+
+ /**
+ * Other Beeper user participating in verification.
+ */
+ otherUserID?: string;
+
+ /**
+ * QR verification data.
+ */
+ qr?: Verification.Qr;
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ sas?: Verification.SAS;
+ }
+
+ export namespace Verification {
+ /**
+ * Verification error details, if verification stopped.
+ */
+ export interface Error {
+ /**
+ * Verification error code.
+ */
+ code: string;
+
+ /**
+ * User-facing verification error message.
+ */
+ reason: string;
+ }
+
+ /**
+ * Other device participating in verification.
+ */
+ export interface OtherDevice {
+ /**
+ * Other device ID.
+ */
+ id: string;
+
+ /**
+ * Other device display name, if known.
+ */
+ name?: string;
+ }
+
+ /**
+ * QR verification data.
+ */
+ export interface Qr {
+ /**
+ * QR code payload to display for verification.
+ */
+ data: string;
+ }
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ export interface SAS {
+ /**
+ * Emoji sequence to compare on both devices.
+ */
+ emojis: string;
+
+ /**
+ * Number sequence to compare on both devices.
+ */
+ decimals?: string;
+ }
+ }
+ }
+ }
+
+ export interface RegistrationRequired {
+ /**
+ * Copy to display during account creation.
+ */
+ copy: RegistrationRequired.Copy;
+
+ /**
+ * Registration token returned by Beeper.
+ */
+ leadToken: string;
+
+ /**
+ * Indicates that the user needs to create a Beeper account.
+ */
+ registrationRequired: true;
+
+ /**
+ * Setup request ID to use when creating the account.
+ */
+ setupRequestID: string;
+
+ /**
+ * Suggested usernames for the new account.
+ */
+ usernameSuggestions?: Array;
+ }
+
+ export namespace RegistrationRequired {
+ /**
+ * Copy to display during account creation.
+ */
+ export interface Copy {
+ /**
+ * Submit button label.
+ */
+ submit: 'Continue';
+
+ /**
+ * Terms and privacy notice to show before account creation.
+ */
+ terms: 'By continuing, you agree to the Terms of Use and acknowledge the Privacy Policy.';
+
+ /**
+ * Title for the username step.
+ */
+ title: 'Choose your username';
+
+ /**
+ * Placeholder for the username field.
+ */
+ usernamePlaceholder: 'Username';
+ }
+ }
+}
+
+export interface LoginStartResponse {
+ /**
+ * Setup request ID to use in the next sign-in step.
+ */
+ setupRequestID: string;
+
+ /**
+ * Available sign-in methods for this setup request.
+ */
+ signInMethods: Array;
+}
+
+export interface LoginEmailParams {
+ /**
+ * Email address to send the sign-in code to.
+ */
+ email: string;
+
+ /**
+ * Setup request ID returned by the start step.
+ */
+ setupRequestID: string;
+}
+
+export interface LoginRegisterParams {
+ /**
+ * Confirms that the user agreed to our
+ * [terms of use](https://www.beeper.com/terms-onboarding) and has read our
+ * [privacy policy](https://www.beeper.com/privacy).
+ */
+ acceptTerms: true;
+
+ /**
+ * Registration token returned by Beeper.
+ */
+ leadToken: string;
+
+ /**
+ * Setup request ID returned by the start step.
+ */
+ setupRequestID: string;
+
+ /**
+ * Username selected by the user.
+ */
+ username: string;
+}
+
+export interface LoginResponseParams {
+ /**
+ * Sign-in code from the user email.
+ */
+ response: string;
+
+ /**
+ * Setup request ID returned by the start step.
+ */
+ setupRequestID: string;
+}
+
+Login.Verification = VerificationAPIVerification;
+Login.BaseVerification = BaseVerification;
+
+export declare namespace Login {
+ export {
+ type LoginRegisterResponse as LoginRegisterResponse,
+ type LoginResponseResponse as LoginResponseResponse,
+ type LoginStartResponse as LoginStartResponse,
+ type LoginEmailParams as LoginEmailParams,
+ type LoginRegisterParams as LoginRegisterParams,
+ type LoginResponseParams as LoginResponseParams,
+ };
+
+ export { VerificationAPIVerification as Verification, BaseVerification as BaseVerification };
+}
diff --git a/src/resources/app/login/verification.ts b/src/resources/app/login/verification.ts
new file mode 100644
index 0000000..d46fce2
--- /dev/null
+++ b/src/resources/app/login/verification.ts
@@ -0,0 +1,3 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+export * from './verification/index';
diff --git a/src/resources/app/login/verification/index.ts b/src/resources/app/login/verification/index.ts
new file mode 100644
index 0000000..a24d5e5
--- /dev/null
+++ b/src/resources/app/login/verification/index.ts
@@ -0,0 +1,9 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+export {
+ RecoveryKey,
+ BaseRecoveryKey,
+ type RecoveryKeyVerifyResponse,
+ type RecoveryKeyVerifyParams,
+} from './recovery-key/index';
+export { Verification, BaseVerification } from './verification';
diff --git a/src/resources/app/login/verification/recovery-key.ts b/src/resources/app/login/verification/recovery-key.ts
new file mode 100644
index 0000000..670c484
--- /dev/null
+++ b/src/resources/app/login/verification/recovery-key.ts
@@ -0,0 +1,3 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+export * from './recovery-key/index';
diff --git a/src/resources/app/login/verification/recovery-key/index.ts b/src/resources/app/login/verification/recovery-key/index.ts
new file mode 100644
index 0000000..e0dbac2
--- /dev/null
+++ b/src/resources/app/login/verification/recovery-key/index.ts
@@ -0,0 +1,16 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+export {
+ RecoveryKey,
+ BaseRecoveryKey,
+ type RecoveryKeyVerifyResponse,
+ type RecoveryKeyVerifyParams,
+} from './recovery-key';
+export {
+ Reset,
+ BaseReset,
+ type ResetCreateResponse,
+ type ResetConfirmResponse,
+ type ResetCreateParams,
+ type ResetConfirmParams,
+} from './reset';
diff --git a/src/resources/app/login/verification/recovery-key/recovery-key.ts b/src/resources/app/login/verification/recovery-key/recovery-key.ts
new file mode 100644
index 0000000..306da97
--- /dev/null
+++ b/src/resources/app/login/verification/recovery-key/recovery-key.ts
@@ -0,0 +1,328 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { APIResource } from '../../../../../core/resource';
+import * as ResetAPI from './reset';
+import {
+ BaseReset,
+ Reset,
+ ResetConfirmParams,
+ ResetConfirmResponse,
+ ResetCreateParams,
+ ResetCreateResponse,
+} from './reset';
+import { APIPromise } from '../../../../../core/api-promise';
+import { RequestOptions } from '../../../../../internal/request-options';
+
+/**
+ * First-party sign-in and encrypted messaging setup for Beeper Desktop and Beeper Server.
+ */
+export class BaseRecoveryKey extends APIResource {
+ static override readonly _key: readonly ['app', 'login', 'verification', 'recoveryKey'] = Object.freeze([
+ 'app',
+ 'login',
+ 'verification',
+ 'recoveryKey',
+ ] as const);
+
+ /**
+ * Unlock encrypted messages with the user recovery key.
+ */
+ verify(body: RecoveryKeyVerifyParams, options?: RequestOptions): APIPromise {
+ return this._client.post('/v1/app/setup/verification/recovery-key', { body, ...options });
+ }
+}
+/**
+ * First-party sign-in and encrypted messaging setup for Beeper Desktop and Beeper Server.
+ */
+export class RecoveryKey extends BaseRecoveryKey {
+ reset: ResetAPI.Reset = new ResetAPI.Reset(this._client);
+}
+
+export interface RecoveryKeyVerifyResponse {
+ /**
+ * Current app sign-in and encrypted messaging setup state.
+ */
+ session: RecoveryKeyVerifyResponse.Session;
+}
+
+export namespace RecoveryKeyVerifyResponse {
+ /**
+ * Current app sign-in and encrypted messaging setup state.
+ */
+ export interface Session {
+ /**
+ * Encrypted messaging setup status.
+ */
+ e2ee: Session.E2EE;
+
+ /**
+ * Current sign-in and encrypted messaging setup state for Beeper Desktop or Beeper
+ * Server.
+ */
+ state:
+ | 'needs-login'
+ | 'initializing'
+ | 'needs-cross-signing-setup'
+ | 'needs-verification'
+ | 'needs-secrets'
+ | 'needs-first-sync'
+ | 'ready';
+
+ /**
+ * Signed-in account details. Omitted until sign-in is complete.
+ */
+ matrix?: Session.Matrix;
+
+ /**
+ * Trusted device verification progress.
+ */
+ verification?: Session.Verification;
+ }
+
+ export namespace Session {
+ /**
+ * Encrypted messaging setup status.
+ */
+ export interface E2EE {
+ /**
+ * Whether this account can verify trusted devices.
+ */
+ crossSigning: boolean;
+
+ /**
+ * Whether the first encrypted message sync is complete.
+ */
+ firstSyncDone: boolean;
+
+ /**
+ * Whether the user confirmed that they saved their recovery key.
+ */
+ hasBackedUpRecoveryKey: boolean;
+
+ /**
+ * Whether encrypted messaging setup has started.
+ */
+ initialized: boolean;
+
+ /**
+ * Whether encrypted message backup is available.
+ */
+ keyBackup: boolean;
+
+ /**
+ * Encrypted messaging keys available on this device.
+ */
+ secrets: E2EE.Secrets;
+
+ /**
+ * Whether secure key storage is available.
+ */
+ secretStorage: boolean;
+
+ /**
+ * Whether this device is trusted for encrypted messages.
+ */
+ verified: boolean;
+
+ /**
+ * Unix timestamp for when the recovery key was created.
+ */
+ recoveryKeyGeneratedAt?: number;
+ }
+
+ export namespace E2EE {
+ /**
+ * Encrypted messaging keys available on this device.
+ */
+ export interface Secrets {
+ /**
+ * Whether the account identity key is available.
+ */
+ masterKey: boolean;
+
+ /**
+ * Whether the encrypted message backup key is available.
+ */
+ megolmBackupKey: boolean;
+
+ /**
+ * Whether a recovery key is available.
+ */
+ recoveryKey: boolean;
+
+ /**
+ * Whether the device trust key is available.
+ */
+ selfSigningKey: boolean;
+
+ /**
+ * Whether the user trust key is available.
+ */
+ userSigningKey: boolean;
+ }
+ }
+
+ /**
+ * Signed-in account details. Omitted until sign-in is complete.
+ */
+ export interface Matrix {
+ /**
+ * Current device ID.
+ */
+ deviceID: string;
+
+ /**
+ * Beeper homeserver URL for this account.
+ */
+ homeserver: string;
+
+ /**
+ * Signed-in Beeper user ID.
+ */
+ userID: string;
+ }
+
+ /**
+ * Trusted device verification progress.
+ */
+ export interface Verification {
+ /**
+ * Verification ID to pass in verification action paths.
+ */
+ id: string;
+
+ /**
+ * Verification actions that are valid for the current state.
+ */
+ availableActions: Array<'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'>;
+
+ /**
+ * Whether this device started or received the verification.
+ */
+ direction: 'incoming' | 'outgoing';
+
+ /**
+ * Verification methods supported for this transaction.
+ */
+ methods: Array<'qr' | 'sas'>;
+
+ /**
+ * Why this verification exists.
+ */
+ purpose: 'login' | 'device';
+
+ /**
+ * Current trusted-device verification state.
+ */
+ state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error';
+
+ /**
+ * Verification error details, if verification stopped.
+ */
+ error?: Verification.Error;
+
+ /**
+ * Other device participating in verification.
+ */
+ otherDevice?: Verification.OtherDevice;
+
+ /**
+ * Other Beeper user participating in verification.
+ */
+ otherUserID?: string;
+
+ /**
+ * QR verification data.
+ */
+ qr?: Verification.Qr;
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ sas?: Verification.SAS;
+ }
+
+ export namespace Verification {
+ /**
+ * Verification error details, if verification stopped.
+ */
+ export interface Error {
+ /**
+ * Verification error code.
+ */
+ code: string;
+
+ /**
+ * User-facing verification error message.
+ */
+ reason: string;
+ }
+
+ /**
+ * Other device participating in verification.
+ */
+ export interface OtherDevice {
+ /**
+ * Other device ID.
+ */
+ id: string;
+
+ /**
+ * Other device display name, if known.
+ */
+ name?: string;
+ }
+
+ /**
+ * QR verification data.
+ */
+ export interface Qr {
+ /**
+ * QR code payload to display for verification.
+ */
+ data: string;
+ }
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ export interface SAS {
+ /**
+ * Emoji sequence to compare on both devices.
+ */
+ emojis: string;
+
+ /**
+ * Number sequence to compare on both devices.
+ */
+ decimals?: string;
+ }
+ }
+ }
+}
+
+export interface RecoveryKeyVerifyParams {
+ /**
+ * Recovery key saved by the user.
+ */
+ recoveryKey: string;
+}
+
+RecoveryKey.Reset = Reset;
+RecoveryKey.BaseReset = BaseReset;
+
+export declare namespace RecoveryKey {
+ export {
+ type RecoveryKeyVerifyResponse as RecoveryKeyVerifyResponse,
+ type RecoveryKeyVerifyParams as RecoveryKeyVerifyParams,
+ };
+
+ export {
+ Reset as Reset,
+ BaseReset as BaseReset,
+ type ResetCreateResponse as ResetCreateResponse,
+ type ResetConfirmResponse as ResetConfirmResponse,
+ type ResetCreateParams as ResetCreateParams,
+ type ResetConfirmParams as ResetConfirmParams,
+ };
+}
diff --git a/src/resources/app/login/verification/recovery-key/reset.ts b/src/resources/app/login/verification/recovery-key/reset.ts
new file mode 100644
index 0000000..7f801b3
--- /dev/null
+++ b/src/resources/app/login/verification/recovery-key/reset.ts
@@ -0,0 +1,590 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { APIResource } from '../../../../../core/resource';
+import { APIPromise } from '../../../../../core/api-promise';
+import { RequestOptions } from '../../../../../internal/request-options';
+
+/**
+ * First-party sign-in and encrypted messaging setup for Beeper Desktop and Beeper Server.
+ */
+export class BaseReset extends APIResource {
+ static override readonly _key: readonly ['app', 'login', 'verification', 'recoveryKey', 'reset'] =
+ Object.freeze(['app', 'login', 'verification', 'recoveryKey', 'reset'] as const);
+
+ /**
+ * Create a new recovery key when the user cannot use the existing one.
+ */
+ create(
+ body: ResetCreateParams | null | undefined = {},
+ options?: RequestOptions,
+ ): APIPromise {
+ return this._client.post('/v1/app/setup/verification/recovery-key/reset', { body, ...options });
+ }
+
+ /**
+ * Confirm that the new recovery key should be used for this account.
+ */
+ confirm(body: ResetConfirmParams, options?: RequestOptions): APIPromise {
+ return this._client.post('/v1/app/setup/verification/recovery-key/reset/confirm', { body, ...options });
+ }
+}
+/**
+ * First-party sign-in and encrypted messaging setup for Beeper Desktop and Beeper Server.
+ */
+export class Reset extends BaseReset {}
+
+export interface ResetCreateResponse {
+ /**
+ * New recovery key. Show it once and ask the user to save it.
+ */
+ recoveryKey: string;
+
+ /**
+ * Current app sign-in and encrypted messaging setup state after creating the new
+ * recovery key.
+ */
+ session: ResetCreateResponse.Session;
+}
+
+export namespace ResetCreateResponse {
+ /**
+ * Current app sign-in and encrypted messaging setup state after creating the new
+ * recovery key.
+ */
+ export interface Session {
+ /**
+ * Encrypted messaging setup status.
+ */
+ e2ee: Session.E2EE;
+
+ /**
+ * Current sign-in and encrypted messaging setup state for Beeper Desktop or Beeper
+ * Server.
+ */
+ state:
+ | 'needs-login'
+ | 'initializing'
+ | 'needs-cross-signing-setup'
+ | 'needs-verification'
+ | 'needs-secrets'
+ | 'needs-first-sync'
+ | 'ready';
+
+ /**
+ * Signed-in account details. Omitted until sign-in is complete.
+ */
+ matrix?: Session.Matrix;
+
+ /**
+ * Trusted device verification progress.
+ */
+ verification?: Session.Verification;
+ }
+
+ export namespace Session {
+ /**
+ * Encrypted messaging setup status.
+ */
+ export interface E2EE {
+ /**
+ * Whether this account can verify trusted devices.
+ */
+ crossSigning: boolean;
+
+ /**
+ * Whether the first encrypted message sync is complete.
+ */
+ firstSyncDone: boolean;
+
+ /**
+ * Whether the user confirmed that they saved their recovery key.
+ */
+ hasBackedUpRecoveryKey: boolean;
+
+ /**
+ * Whether encrypted messaging setup has started.
+ */
+ initialized: boolean;
+
+ /**
+ * Whether encrypted message backup is available.
+ */
+ keyBackup: boolean;
+
+ /**
+ * Encrypted messaging keys available on this device.
+ */
+ secrets: E2EE.Secrets;
+
+ /**
+ * Whether secure key storage is available.
+ */
+ secretStorage: boolean;
+
+ /**
+ * Whether this device is trusted for encrypted messages.
+ */
+ verified: boolean;
+
+ /**
+ * Unix timestamp for when the recovery key was created.
+ */
+ recoveryKeyGeneratedAt?: number;
+ }
+
+ export namespace E2EE {
+ /**
+ * Encrypted messaging keys available on this device.
+ */
+ export interface Secrets {
+ /**
+ * Whether the account identity key is available.
+ */
+ masterKey: boolean;
+
+ /**
+ * Whether the encrypted message backup key is available.
+ */
+ megolmBackupKey: boolean;
+
+ /**
+ * Whether a recovery key is available.
+ */
+ recoveryKey: boolean;
+
+ /**
+ * Whether the device trust key is available.
+ */
+ selfSigningKey: boolean;
+
+ /**
+ * Whether the user trust key is available.
+ */
+ userSigningKey: boolean;
+ }
+ }
+
+ /**
+ * Signed-in account details. Omitted until sign-in is complete.
+ */
+ export interface Matrix {
+ /**
+ * Current device ID.
+ */
+ deviceID: string;
+
+ /**
+ * Beeper homeserver URL for this account.
+ */
+ homeserver: string;
+
+ /**
+ * Signed-in Beeper user ID.
+ */
+ userID: string;
+ }
+
+ /**
+ * Trusted device verification progress.
+ */
+ export interface Verification {
+ /**
+ * Verification ID to pass in verification action paths.
+ */
+ id: string;
+
+ /**
+ * Verification actions that are valid for the current state.
+ */
+ availableActions: Array<'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'>;
+
+ /**
+ * Whether this device started or received the verification.
+ */
+ direction: 'incoming' | 'outgoing';
+
+ /**
+ * Verification methods supported for this transaction.
+ */
+ methods: Array<'qr' | 'sas'>;
+
+ /**
+ * Why this verification exists.
+ */
+ purpose: 'login' | 'device';
+
+ /**
+ * Current trusted-device verification state.
+ */
+ state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error';
+
+ /**
+ * Verification error details, if verification stopped.
+ */
+ error?: Verification.Error;
+
+ /**
+ * Other device participating in verification.
+ */
+ otherDevice?: Verification.OtherDevice;
+
+ /**
+ * Other Beeper user participating in verification.
+ */
+ otherUserID?: string;
+
+ /**
+ * QR verification data.
+ */
+ qr?: Verification.Qr;
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ sas?: Verification.SAS;
+ }
+
+ export namespace Verification {
+ /**
+ * Verification error details, if verification stopped.
+ */
+ export interface Error {
+ /**
+ * Verification error code.
+ */
+ code: string;
+
+ /**
+ * User-facing verification error message.
+ */
+ reason: string;
+ }
+
+ /**
+ * Other device participating in verification.
+ */
+ export interface OtherDevice {
+ /**
+ * Other device ID.
+ */
+ id: string;
+
+ /**
+ * Other device display name, if known.
+ */
+ name?: string;
+ }
+
+ /**
+ * QR verification data.
+ */
+ export interface Qr {
+ /**
+ * QR code payload to display for verification.
+ */
+ data: string;
+ }
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ export interface SAS {
+ /**
+ * Emoji sequence to compare on both devices.
+ */
+ emojis: string;
+
+ /**
+ * Number sequence to compare on both devices.
+ */
+ decimals?: string;
+ }
+ }
+ }
+}
+
+export interface ResetConfirmResponse {
+ /**
+ * Current app sign-in and encrypted messaging setup state.
+ */
+ session: ResetConfirmResponse.Session;
+}
+
+export namespace ResetConfirmResponse {
+ /**
+ * Current app sign-in and encrypted messaging setup state.
+ */
+ export interface Session {
+ /**
+ * Encrypted messaging setup status.
+ */
+ e2ee: Session.E2EE;
+
+ /**
+ * Current sign-in and encrypted messaging setup state for Beeper Desktop or Beeper
+ * Server.
+ */
+ state:
+ | 'needs-login'
+ | 'initializing'
+ | 'needs-cross-signing-setup'
+ | 'needs-verification'
+ | 'needs-secrets'
+ | 'needs-first-sync'
+ | 'ready';
+
+ /**
+ * Signed-in account details. Omitted until sign-in is complete.
+ */
+ matrix?: Session.Matrix;
+
+ /**
+ * Trusted device verification progress.
+ */
+ verification?: Session.Verification;
+ }
+
+ export namespace Session {
+ /**
+ * Encrypted messaging setup status.
+ */
+ export interface E2EE {
+ /**
+ * Whether this account can verify trusted devices.
+ */
+ crossSigning: boolean;
+
+ /**
+ * Whether the first encrypted message sync is complete.
+ */
+ firstSyncDone: boolean;
+
+ /**
+ * Whether the user confirmed that they saved their recovery key.
+ */
+ hasBackedUpRecoveryKey: boolean;
+
+ /**
+ * Whether encrypted messaging setup has started.
+ */
+ initialized: boolean;
+
+ /**
+ * Whether encrypted message backup is available.
+ */
+ keyBackup: boolean;
+
+ /**
+ * Encrypted messaging keys available on this device.
+ */
+ secrets: E2EE.Secrets;
+
+ /**
+ * Whether secure key storage is available.
+ */
+ secretStorage: boolean;
+
+ /**
+ * Whether this device is trusted for encrypted messages.
+ */
+ verified: boolean;
+
+ /**
+ * Unix timestamp for when the recovery key was created.
+ */
+ recoveryKeyGeneratedAt?: number;
+ }
+
+ export namespace E2EE {
+ /**
+ * Encrypted messaging keys available on this device.
+ */
+ export interface Secrets {
+ /**
+ * Whether the account identity key is available.
+ */
+ masterKey: boolean;
+
+ /**
+ * Whether the encrypted message backup key is available.
+ */
+ megolmBackupKey: boolean;
+
+ /**
+ * Whether a recovery key is available.
+ */
+ recoveryKey: boolean;
+
+ /**
+ * Whether the device trust key is available.
+ */
+ selfSigningKey: boolean;
+
+ /**
+ * Whether the user trust key is available.
+ */
+ userSigningKey: boolean;
+ }
+ }
+
+ /**
+ * Signed-in account details. Omitted until sign-in is complete.
+ */
+ export interface Matrix {
+ /**
+ * Current device ID.
+ */
+ deviceID: string;
+
+ /**
+ * Beeper homeserver URL for this account.
+ */
+ homeserver: string;
+
+ /**
+ * Signed-in Beeper user ID.
+ */
+ userID: string;
+ }
+
+ /**
+ * Trusted device verification progress.
+ */
+ export interface Verification {
+ /**
+ * Verification ID to pass in verification action paths.
+ */
+ id: string;
+
+ /**
+ * Verification actions that are valid for the current state.
+ */
+ availableActions: Array<'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'>;
+
+ /**
+ * Whether this device started or received the verification.
+ */
+ direction: 'incoming' | 'outgoing';
+
+ /**
+ * Verification methods supported for this transaction.
+ */
+ methods: Array<'qr' | 'sas'>;
+
+ /**
+ * Why this verification exists.
+ */
+ purpose: 'login' | 'device';
+
+ /**
+ * Current trusted-device verification state.
+ */
+ state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error';
+
+ /**
+ * Verification error details, if verification stopped.
+ */
+ error?: Verification.Error;
+
+ /**
+ * Other device participating in verification.
+ */
+ otherDevice?: Verification.OtherDevice;
+
+ /**
+ * Other Beeper user participating in verification.
+ */
+ otherUserID?: string;
+
+ /**
+ * QR verification data.
+ */
+ qr?: Verification.Qr;
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ sas?: Verification.SAS;
+ }
+
+ export namespace Verification {
+ /**
+ * Verification error details, if verification stopped.
+ */
+ export interface Error {
+ /**
+ * Verification error code.
+ */
+ code: string;
+
+ /**
+ * User-facing verification error message.
+ */
+ reason: string;
+ }
+
+ /**
+ * Other device participating in verification.
+ */
+ export interface OtherDevice {
+ /**
+ * Other device ID.
+ */
+ id: string;
+
+ /**
+ * Other device display name, if known.
+ */
+ name?: string;
+ }
+
+ /**
+ * QR verification data.
+ */
+ export interface Qr {
+ /**
+ * QR code payload to display for verification.
+ */
+ data: string;
+ }
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ export interface SAS {
+ /**
+ * Emoji sequence to compare on both devices.
+ */
+ emojis: string;
+
+ /**
+ * Number sequence to compare on both devices.
+ */
+ decimals?: string;
+ }
+ }
+ }
+}
+
+export interface ResetCreateParams {
+ /**
+ * Existing recovery key, if the user has it.
+ */
+ existingRecoveryKey?: string;
+}
+
+export interface ResetConfirmParams {
+ /**
+ * New recovery key returned by the reset step.
+ */
+ recoveryKey: string;
+}
+
+export declare namespace Reset {
+ export {
+ type ResetCreateResponse as ResetCreateResponse,
+ type ResetConfirmResponse as ResetConfirmResponse,
+ type ResetCreateParams as ResetCreateParams,
+ type ResetConfirmParams as ResetConfirmParams,
+ };
+}
diff --git a/src/resources/app/login/verification/verification.ts b/src/resources/app/login/verification/verification.ts
new file mode 100644
index 0000000..0583568
--- /dev/null
+++ b/src/resources/app/login/verification/verification.ts
@@ -0,0 +1,33 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { APIResource } from '../../../../core/resource';
+import * as RecoveryKeyAPI from './recovery-key/recovery-key';
+import {
+ BaseRecoveryKey,
+ RecoveryKey,
+ RecoveryKeyVerifyParams,
+ RecoveryKeyVerifyResponse,
+} from './recovery-key/recovery-key';
+
+export class BaseVerification extends APIResource {
+ static override readonly _key: readonly ['app', 'login', 'verification'] = Object.freeze([
+ 'app',
+ 'login',
+ 'verification',
+ ] as const);
+}
+export class Verification extends BaseVerification {
+ recoveryKey: RecoveryKeyAPI.RecoveryKey = new RecoveryKeyAPI.RecoveryKey(this._client);
+}
+
+Verification.RecoveryKey = RecoveryKey;
+Verification.BaseRecoveryKey = BaseRecoveryKey;
+
+export declare namespace Verification {
+ export {
+ RecoveryKey as RecoveryKey,
+ BaseRecoveryKey as BaseRecoveryKey,
+ type RecoveryKeyVerifyResponse as RecoveryKeyVerifyResponse,
+ type RecoveryKeyVerifyParams as RecoveryKeyVerifyParams,
+ };
+}
diff --git a/src/resources/app/verifications.ts b/src/resources/app/verifications.ts
new file mode 100644
index 0000000..6d82890
--- /dev/null
+++ b/src/resources/app/verifications.ts
@@ -0,0 +1,3 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+export * from './verifications/index';
diff --git a/src/resources/app/verifications/index.ts b/src/resources/app/verifications/index.ts
new file mode 100644
index 0000000..a8a8aac
--- /dev/null
+++ b/src/resources/app/verifications/index.ts
@@ -0,0 +1,15 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+export { Qr, BaseQr, type QrConfirmScannedResponse, type QrScanResponse, type QrScanParams } from './qr';
+export { SAS, BaseSAS, type SASConfirmResponse, type SASStartResponse } from './sas';
+export {
+ Verifications,
+ BaseVerifications,
+ type VerificationCreateResponse,
+ type VerificationRetrieveResponse,
+ type VerificationListResponse,
+ type VerificationAcceptResponse,
+ type VerificationCancelResponse,
+ type VerificationCreateParams,
+ type VerificationCancelParams,
+} from './verifications';
diff --git a/src/resources/app/verifications/qr.ts b/src/resources/app/verifications/qr.ts
new file mode 100644
index 0000000..0950844
--- /dev/null
+++ b/src/resources/app/verifications/qr.ts
@@ -0,0 +1,820 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { APIResource } from '../../../core/resource';
+import { APIPromise } from '../../../core/api-promise';
+import { RequestOptions } from '../../../internal/request-options';
+import { path } from '../../../internal/utils/path';
+
+/**
+ * First-party sign-in and encrypted messaging setup for Beeper Desktop and Beeper Server.
+ */
+export class BaseQr extends APIResource {
+ static override readonly _key: readonly ['app', 'verifications', 'qr'] = Object.freeze([
+ 'app',
+ 'verifications',
+ 'qr',
+ ] as const);
+
+ /**
+ * Confirm that another device scanned this device QR code.
+ */
+ confirmScanned(verificationID: string, options?: RequestOptions): APIPromise {
+ return this._client.post(path`/v1/app/setup/verifications/${verificationID}/qr/confirm-scanned`, options);
+ }
+
+ /**
+ * Submit the QR code scanned from another signed-in device.
+ */
+ scan(body: QrScanParams, options?: RequestOptions): APIPromise {
+ return this._client.post('/v1/app/setup/verifications/qr/scan', { body, ...options });
+ }
+}
+/**
+ * First-party sign-in and encrypted messaging setup for Beeper Desktop and Beeper Server.
+ */
+export class Qr extends BaseQr {}
+
+export interface QrConfirmScannedResponse {
+ /**
+ * Current app sign-in and encrypted messaging setup state.
+ */
+ session: QrConfirmScannedResponse.Session;
+
+ /**
+ * Trusted device verification progress.
+ */
+ verification?: QrConfirmScannedResponse.Verification;
+}
+
+export namespace QrConfirmScannedResponse {
+ /**
+ * Current app sign-in and encrypted messaging setup state.
+ */
+ export interface Session {
+ /**
+ * Encrypted messaging setup status.
+ */
+ e2ee: Session.E2EE;
+
+ /**
+ * Current sign-in and encrypted messaging setup state for Beeper Desktop or Beeper
+ * Server.
+ */
+ state:
+ | 'needs-login'
+ | 'initializing'
+ | 'needs-cross-signing-setup'
+ | 'needs-verification'
+ | 'needs-secrets'
+ | 'needs-first-sync'
+ | 'ready';
+
+ /**
+ * Signed-in account details. Omitted until sign-in is complete.
+ */
+ matrix?: Session.Matrix;
+
+ /**
+ * Trusted device verification progress.
+ */
+ verification?: Session.Verification;
+ }
+
+ export namespace Session {
+ /**
+ * Encrypted messaging setup status.
+ */
+ export interface E2EE {
+ /**
+ * Whether this account can verify trusted devices.
+ */
+ crossSigning: boolean;
+
+ /**
+ * Whether the first encrypted message sync is complete.
+ */
+ firstSyncDone: boolean;
+
+ /**
+ * Whether the user confirmed that they saved their recovery key.
+ */
+ hasBackedUpRecoveryKey: boolean;
+
+ /**
+ * Whether encrypted messaging setup has started.
+ */
+ initialized: boolean;
+
+ /**
+ * Whether encrypted message backup is available.
+ */
+ keyBackup: boolean;
+
+ /**
+ * Encrypted messaging keys available on this device.
+ */
+ secrets: E2EE.Secrets;
+
+ /**
+ * Whether secure key storage is available.
+ */
+ secretStorage: boolean;
+
+ /**
+ * Whether this device is trusted for encrypted messages.
+ */
+ verified: boolean;
+
+ /**
+ * Unix timestamp for when the recovery key was created.
+ */
+ recoveryKeyGeneratedAt?: number;
+ }
+
+ export namespace E2EE {
+ /**
+ * Encrypted messaging keys available on this device.
+ */
+ export interface Secrets {
+ /**
+ * Whether the account identity key is available.
+ */
+ masterKey: boolean;
+
+ /**
+ * Whether the encrypted message backup key is available.
+ */
+ megolmBackupKey: boolean;
+
+ /**
+ * Whether a recovery key is available.
+ */
+ recoveryKey: boolean;
+
+ /**
+ * Whether the device trust key is available.
+ */
+ selfSigningKey: boolean;
+
+ /**
+ * Whether the user trust key is available.
+ */
+ userSigningKey: boolean;
+ }
+ }
+
+ /**
+ * Signed-in account details. Omitted until sign-in is complete.
+ */
+ export interface Matrix {
+ /**
+ * Current device ID.
+ */
+ deviceID: string;
+
+ /**
+ * Beeper homeserver URL for this account.
+ */
+ homeserver: string;
+
+ /**
+ * Signed-in Beeper user ID.
+ */
+ userID: string;
+ }
+
+ /**
+ * Trusted device verification progress.
+ */
+ export interface Verification {
+ /**
+ * Verification ID to pass in verification action paths.
+ */
+ id: string;
+
+ /**
+ * Verification actions that are valid for the current state.
+ */
+ availableActions: Array<'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'>;
+
+ /**
+ * Whether this device started or received the verification.
+ */
+ direction: 'incoming' | 'outgoing';
+
+ /**
+ * Verification methods supported for this transaction.
+ */
+ methods: Array<'qr' | 'sas'>;
+
+ /**
+ * Why this verification exists.
+ */
+ purpose: 'login' | 'device';
+
+ /**
+ * Current trusted-device verification state.
+ */
+ state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error';
+
+ /**
+ * Verification error details, if verification stopped.
+ */
+ error?: Verification.Error;
+
+ /**
+ * Other device participating in verification.
+ */
+ otherDevice?: Verification.OtherDevice;
+
+ /**
+ * Other Beeper user participating in verification.
+ */
+ otherUserID?: string;
+
+ /**
+ * QR verification data.
+ */
+ qr?: Verification.Qr;
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ sas?: Verification.SAS;
+ }
+
+ export namespace Verification {
+ /**
+ * Verification error details, if verification stopped.
+ */
+ export interface Error {
+ /**
+ * Verification error code.
+ */
+ code: string;
+
+ /**
+ * User-facing verification error message.
+ */
+ reason: string;
+ }
+
+ /**
+ * Other device participating in verification.
+ */
+ export interface OtherDevice {
+ /**
+ * Other device ID.
+ */
+ id: string;
+
+ /**
+ * Other device display name, if known.
+ */
+ name?: string;
+ }
+
+ /**
+ * QR verification data.
+ */
+ export interface Qr {
+ /**
+ * QR code payload to display for verification.
+ */
+ data: string;
+ }
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ export interface SAS {
+ /**
+ * Emoji sequence to compare on both devices.
+ */
+ emojis: string;
+
+ /**
+ * Number sequence to compare on both devices.
+ */
+ decimals?: string;
+ }
+ }
+ }
+
+ /**
+ * Trusted device verification progress.
+ */
+ export interface Verification {
+ /**
+ * Verification ID to pass in verification action paths.
+ */
+ id: string;
+
+ /**
+ * Verification actions that are valid for the current state.
+ */
+ availableActions: Array<'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'>;
+
+ /**
+ * Whether this device started or received the verification.
+ */
+ direction: 'incoming' | 'outgoing';
+
+ /**
+ * Verification methods supported for this transaction.
+ */
+ methods: Array<'qr' | 'sas'>;
+
+ /**
+ * Why this verification exists.
+ */
+ purpose: 'login' | 'device';
+
+ /**
+ * Current trusted-device verification state.
+ */
+ state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error';
+
+ /**
+ * Verification error details, if verification stopped.
+ */
+ error?: Verification.Error;
+
+ /**
+ * Other device participating in verification.
+ */
+ otherDevice?: Verification.OtherDevice;
+
+ /**
+ * Other Beeper user participating in verification.
+ */
+ otherUserID?: string;
+
+ /**
+ * QR verification data.
+ */
+ qr?: Verification.Qr;
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ sas?: Verification.SAS;
+ }
+
+ export namespace Verification {
+ /**
+ * Verification error details, if verification stopped.
+ */
+ export interface Error {
+ /**
+ * Verification error code.
+ */
+ code: string;
+
+ /**
+ * User-facing verification error message.
+ */
+ reason: string;
+ }
+
+ /**
+ * Other device participating in verification.
+ */
+ export interface OtherDevice {
+ /**
+ * Other device ID.
+ */
+ id: string;
+
+ /**
+ * Other device display name, if known.
+ */
+ name?: string;
+ }
+
+ /**
+ * QR verification data.
+ */
+ export interface Qr {
+ /**
+ * QR code payload to display for verification.
+ */
+ data: string;
+ }
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ export interface SAS {
+ /**
+ * Emoji sequence to compare on both devices.
+ */
+ emojis: string;
+
+ /**
+ * Number sequence to compare on both devices.
+ */
+ decimals?: string;
+ }
+ }
+}
+
+export interface QrScanResponse {
+ /**
+ * Current app sign-in and encrypted messaging setup state.
+ */
+ session: QrScanResponse.Session;
+
+ /**
+ * Trusted device verification progress.
+ */
+ verification?: QrScanResponse.Verification;
+}
+
+export namespace QrScanResponse {
+ /**
+ * Current app sign-in and encrypted messaging setup state.
+ */
+ export interface Session {
+ /**
+ * Encrypted messaging setup status.
+ */
+ e2ee: Session.E2EE;
+
+ /**
+ * Current sign-in and encrypted messaging setup state for Beeper Desktop or Beeper
+ * Server.
+ */
+ state:
+ | 'needs-login'
+ | 'initializing'
+ | 'needs-cross-signing-setup'
+ | 'needs-verification'
+ | 'needs-secrets'
+ | 'needs-first-sync'
+ | 'ready';
+
+ /**
+ * Signed-in account details. Omitted until sign-in is complete.
+ */
+ matrix?: Session.Matrix;
+
+ /**
+ * Trusted device verification progress.
+ */
+ verification?: Session.Verification;
+ }
+
+ export namespace Session {
+ /**
+ * Encrypted messaging setup status.
+ */
+ export interface E2EE {
+ /**
+ * Whether this account can verify trusted devices.
+ */
+ crossSigning: boolean;
+
+ /**
+ * Whether the first encrypted message sync is complete.
+ */
+ firstSyncDone: boolean;
+
+ /**
+ * Whether the user confirmed that they saved their recovery key.
+ */
+ hasBackedUpRecoveryKey: boolean;
+
+ /**
+ * Whether encrypted messaging setup has started.
+ */
+ initialized: boolean;
+
+ /**
+ * Whether encrypted message backup is available.
+ */
+ keyBackup: boolean;
+
+ /**
+ * Encrypted messaging keys available on this device.
+ */
+ secrets: E2EE.Secrets;
+
+ /**
+ * Whether secure key storage is available.
+ */
+ secretStorage: boolean;
+
+ /**
+ * Whether this device is trusted for encrypted messages.
+ */
+ verified: boolean;
+
+ /**
+ * Unix timestamp for when the recovery key was created.
+ */
+ recoveryKeyGeneratedAt?: number;
+ }
+
+ export namespace E2EE {
+ /**
+ * Encrypted messaging keys available on this device.
+ */
+ export interface Secrets {
+ /**
+ * Whether the account identity key is available.
+ */
+ masterKey: boolean;
+
+ /**
+ * Whether the encrypted message backup key is available.
+ */
+ megolmBackupKey: boolean;
+
+ /**
+ * Whether a recovery key is available.
+ */
+ recoveryKey: boolean;
+
+ /**
+ * Whether the device trust key is available.
+ */
+ selfSigningKey: boolean;
+
+ /**
+ * Whether the user trust key is available.
+ */
+ userSigningKey: boolean;
+ }
+ }
+
+ /**
+ * Signed-in account details. Omitted until sign-in is complete.
+ */
+ export interface Matrix {
+ /**
+ * Current device ID.
+ */
+ deviceID: string;
+
+ /**
+ * Beeper homeserver URL for this account.
+ */
+ homeserver: string;
+
+ /**
+ * Signed-in Beeper user ID.
+ */
+ userID: string;
+ }
+
+ /**
+ * Trusted device verification progress.
+ */
+ export interface Verification {
+ /**
+ * Verification ID to pass in verification action paths.
+ */
+ id: string;
+
+ /**
+ * Verification actions that are valid for the current state.
+ */
+ availableActions: Array<'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'>;
+
+ /**
+ * Whether this device started or received the verification.
+ */
+ direction: 'incoming' | 'outgoing';
+
+ /**
+ * Verification methods supported for this transaction.
+ */
+ methods: Array<'qr' | 'sas'>;
+
+ /**
+ * Why this verification exists.
+ */
+ purpose: 'login' | 'device';
+
+ /**
+ * Current trusted-device verification state.
+ */
+ state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error';
+
+ /**
+ * Verification error details, if verification stopped.
+ */
+ error?: Verification.Error;
+
+ /**
+ * Other device participating in verification.
+ */
+ otherDevice?: Verification.OtherDevice;
+
+ /**
+ * Other Beeper user participating in verification.
+ */
+ otherUserID?: string;
+
+ /**
+ * QR verification data.
+ */
+ qr?: Verification.Qr;
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ sas?: Verification.SAS;
+ }
+
+ export namespace Verification {
+ /**
+ * Verification error details, if verification stopped.
+ */
+ export interface Error {
+ /**
+ * Verification error code.
+ */
+ code: string;
+
+ /**
+ * User-facing verification error message.
+ */
+ reason: string;
+ }
+
+ /**
+ * Other device participating in verification.
+ */
+ export interface OtherDevice {
+ /**
+ * Other device ID.
+ */
+ id: string;
+
+ /**
+ * Other device display name, if known.
+ */
+ name?: string;
+ }
+
+ /**
+ * QR verification data.
+ */
+ export interface Qr {
+ /**
+ * QR code payload to display for verification.
+ */
+ data: string;
+ }
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ export interface SAS {
+ /**
+ * Emoji sequence to compare on both devices.
+ */
+ emojis: string;
+
+ /**
+ * Number sequence to compare on both devices.
+ */
+ decimals?: string;
+ }
+ }
+ }
+
+ /**
+ * Trusted device verification progress.
+ */
+ export interface Verification {
+ /**
+ * Verification ID to pass in verification action paths.
+ */
+ id: string;
+
+ /**
+ * Verification actions that are valid for the current state.
+ */
+ availableActions: Array<'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'>;
+
+ /**
+ * Whether this device started or received the verification.
+ */
+ direction: 'incoming' | 'outgoing';
+
+ /**
+ * Verification methods supported for this transaction.
+ */
+ methods: Array<'qr' | 'sas'>;
+
+ /**
+ * Why this verification exists.
+ */
+ purpose: 'login' | 'device';
+
+ /**
+ * Current trusted-device verification state.
+ */
+ state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error';
+
+ /**
+ * Verification error details, if verification stopped.
+ */
+ error?: Verification.Error;
+
+ /**
+ * Other device participating in verification.
+ */
+ otherDevice?: Verification.OtherDevice;
+
+ /**
+ * Other Beeper user participating in verification.
+ */
+ otherUserID?: string;
+
+ /**
+ * QR verification data.
+ */
+ qr?: Verification.Qr;
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ sas?: Verification.SAS;
+ }
+
+ export namespace Verification {
+ /**
+ * Verification error details, if verification stopped.
+ */
+ export interface Error {
+ /**
+ * Verification error code.
+ */
+ code: string;
+
+ /**
+ * User-facing verification error message.
+ */
+ reason: string;
+ }
+
+ /**
+ * Other device participating in verification.
+ */
+ export interface OtherDevice {
+ /**
+ * Other device ID.
+ */
+ id: string;
+
+ /**
+ * Other device display name, if known.
+ */
+ name?: string;
+ }
+
+ /**
+ * QR verification data.
+ */
+ export interface Qr {
+ /**
+ * QR code payload to display for verification.
+ */
+ data: string;
+ }
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ export interface SAS {
+ /**
+ * Emoji sequence to compare on both devices.
+ */
+ emojis: string;
+
+ /**
+ * Number sequence to compare on both devices.
+ */
+ decimals?: string;
+ }
+ }
+}
+
+export interface QrScanParams {
+ /**
+ * QR code payload scanned from the other device.
+ */
+ data: string;
+}
+
+export declare namespace Qr {
+ export {
+ type QrConfirmScannedResponse as QrConfirmScannedResponse,
+ type QrScanResponse as QrScanResponse,
+ type QrScanParams as QrScanParams,
+ };
+}
diff --git a/src/resources/app/verifications/sas.ts b/src/resources/app/verifications/sas.ts
new file mode 100644
index 0000000..9adfdcf
--- /dev/null
+++ b/src/resources/app/verifications/sas.ts
@@ -0,0 +1,809 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { APIResource } from '../../../core/resource';
+import { APIPromise } from '../../../core/api-promise';
+import { RequestOptions } from '../../../internal/request-options';
+import { path } from '../../../internal/utils/path';
+
+/**
+ * First-party sign-in and encrypted messaging setup for Beeper Desktop and Beeper Server.
+ */
+export class BaseSAS extends APIResource {
+ static override readonly _key: readonly ['app', 'verifications', 'sas'] = Object.freeze([
+ 'app',
+ 'verifications',
+ 'sas',
+ ] as const);
+
+ /**
+ * Confirm that the emoji or number sequence matches on both devices.
+ */
+ confirm(verificationID: string, options?: RequestOptions): APIPromise {
+ return this._client.post(path`/v1/app/setup/verifications/${verificationID}/sas/confirm`, options);
+ }
+
+ /**
+ * Start emoji comparison for device verification.
+ */
+ start(verificationID: string, options?: RequestOptions): APIPromise {
+ return this._client.post(path`/v1/app/setup/verifications/${verificationID}/sas/start`, options);
+ }
+}
+/**
+ * First-party sign-in and encrypted messaging setup for Beeper Desktop and Beeper Server.
+ */
+export class SAS extends BaseSAS {}
+
+export interface SASConfirmResponse {
+ /**
+ * Current app sign-in and encrypted messaging setup state.
+ */
+ session: SASConfirmResponse.Session;
+
+ /**
+ * Trusted device verification progress.
+ */
+ verification?: SASConfirmResponse.Verification;
+}
+
+export namespace SASConfirmResponse {
+ /**
+ * Current app sign-in and encrypted messaging setup state.
+ */
+ export interface Session {
+ /**
+ * Encrypted messaging setup status.
+ */
+ e2ee: Session.E2EE;
+
+ /**
+ * Current sign-in and encrypted messaging setup state for Beeper Desktop or Beeper
+ * Server.
+ */
+ state:
+ | 'needs-login'
+ | 'initializing'
+ | 'needs-cross-signing-setup'
+ | 'needs-verification'
+ | 'needs-secrets'
+ | 'needs-first-sync'
+ | 'ready';
+
+ /**
+ * Signed-in account details. Omitted until sign-in is complete.
+ */
+ matrix?: Session.Matrix;
+
+ /**
+ * Trusted device verification progress.
+ */
+ verification?: Session.Verification;
+ }
+
+ export namespace Session {
+ /**
+ * Encrypted messaging setup status.
+ */
+ export interface E2EE {
+ /**
+ * Whether this account can verify trusted devices.
+ */
+ crossSigning: boolean;
+
+ /**
+ * Whether the first encrypted message sync is complete.
+ */
+ firstSyncDone: boolean;
+
+ /**
+ * Whether the user confirmed that they saved their recovery key.
+ */
+ hasBackedUpRecoveryKey: boolean;
+
+ /**
+ * Whether encrypted messaging setup has started.
+ */
+ initialized: boolean;
+
+ /**
+ * Whether encrypted message backup is available.
+ */
+ keyBackup: boolean;
+
+ /**
+ * Encrypted messaging keys available on this device.
+ */
+ secrets: E2EE.Secrets;
+
+ /**
+ * Whether secure key storage is available.
+ */
+ secretStorage: boolean;
+
+ /**
+ * Whether this device is trusted for encrypted messages.
+ */
+ verified: boolean;
+
+ /**
+ * Unix timestamp for when the recovery key was created.
+ */
+ recoveryKeyGeneratedAt?: number;
+ }
+
+ export namespace E2EE {
+ /**
+ * Encrypted messaging keys available on this device.
+ */
+ export interface Secrets {
+ /**
+ * Whether the account identity key is available.
+ */
+ masterKey: boolean;
+
+ /**
+ * Whether the encrypted message backup key is available.
+ */
+ megolmBackupKey: boolean;
+
+ /**
+ * Whether a recovery key is available.
+ */
+ recoveryKey: boolean;
+
+ /**
+ * Whether the device trust key is available.
+ */
+ selfSigningKey: boolean;
+
+ /**
+ * Whether the user trust key is available.
+ */
+ userSigningKey: boolean;
+ }
+ }
+
+ /**
+ * Signed-in account details. Omitted until sign-in is complete.
+ */
+ export interface Matrix {
+ /**
+ * Current device ID.
+ */
+ deviceID: string;
+
+ /**
+ * Beeper homeserver URL for this account.
+ */
+ homeserver: string;
+
+ /**
+ * Signed-in Beeper user ID.
+ */
+ userID: string;
+ }
+
+ /**
+ * Trusted device verification progress.
+ */
+ export interface Verification {
+ /**
+ * Verification ID to pass in verification action paths.
+ */
+ id: string;
+
+ /**
+ * Verification actions that are valid for the current state.
+ */
+ availableActions: Array<'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'>;
+
+ /**
+ * Whether this device started or received the verification.
+ */
+ direction: 'incoming' | 'outgoing';
+
+ /**
+ * Verification methods supported for this transaction.
+ */
+ methods: Array<'qr' | 'sas'>;
+
+ /**
+ * Why this verification exists.
+ */
+ purpose: 'login' | 'device';
+
+ /**
+ * Current trusted-device verification state.
+ */
+ state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error';
+
+ /**
+ * Verification error details, if verification stopped.
+ */
+ error?: Verification.Error;
+
+ /**
+ * Other device participating in verification.
+ */
+ otherDevice?: Verification.OtherDevice;
+
+ /**
+ * Other Beeper user participating in verification.
+ */
+ otherUserID?: string;
+
+ /**
+ * QR verification data.
+ */
+ qr?: Verification.Qr;
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ sas?: Verification.SAS;
+ }
+
+ export namespace Verification {
+ /**
+ * Verification error details, if verification stopped.
+ */
+ export interface Error {
+ /**
+ * Verification error code.
+ */
+ code: string;
+
+ /**
+ * User-facing verification error message.
+ */
+ reason: string;
+ }
+
+ /**
+ * Other device participating in verification.
+ */
+ export interface OtherDevice {
+ /**
+ * Other device ID.
+ */
+ id: string;
+
+ /**
+ * Other device display name, if known.
+ */
+ name?: string;
+ }
+
+ /**
+ * QR verification data.
+ */
+ export interface Qr {
+ /**
+ * QR code payload to display for verification.
+ */
+ data: string;
+ }
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ export interface SAS {
+ /**
+ * Emoji sequence to compare on both devices.
+ */
+ emojis: string;
+
+ /**
+ * Number sequence to compare on both devices.
+ */
+ decimals?: string;
+ }
+ }
+ }
+
+ /**
+ * Trusted device verification progress.
+ */
+ export interface Verification {
+ /**
+ * Verification ID to pass in verification action paths.
+ */
+ id: string;
+
+ /**
+ * Verification actions that are valid for the current state.
+ */
+ availableActions: Array<'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'>;
+
+ /**
+ * Whether this device started or received the verification.
+ */
+ direction: 'incoming' | 'outgoing';
+
+ /**
+ * Verification methods supported for this transaction.
+ */
+ methods: Array<'qr' | 'sas'>;
+
+ /**
+ * Why this verification exists.
+ */
+ purpose: 'login' | 'device';
+
+ /**
+ * Current trusted-device verification state.
+ */
+ state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error';
+
+ /**
+ * Verification error details, if verification stopped.
+ */
+ error?: Verification.Error;
+
+ /**
+ * Other device participating in verification.
+ */
+ otherDevice?: Verification.OtherDevice;
+
+ /**
+ * Other Beeper user participating in verification.
+ */
+ otherUserID?: string;
+
+ /**
+ * QR verification data.
+ */
+ qr?: Verification.Qr;
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ sas?: Verification.SAS;
+ }
+
+ export namespace Verification {
+ /**
+ * Verification error details, if verification stopped.
+ */
+ export interface Error {
+ /**
+ * Verification error code.
+ */
+ code: string;
+
+ /**
+ * User-facing verification error message.
+ */
+ reason: string;
+ }
+
+ /**
+ * Other device participating in verification.
+ */
+ export interface OtherDevice {
+ /**
+ * Other device ID.
+ */
+ id: string;
+
+ /**
+ * Other device display name, if known.
+ */
+ name?: string;
+ }
+
+ /**
+ * QR verification data.
+ */
+ export interface Qr {
+ /**
+ * QR code payload to display for verification.
+ */
+ data: string;
+ }
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ export interface SAS {
+ /**
+ * Emoji sequence to compare on both devices.
+ */
+ emojis: string;
+
+ /**
+ * Number sequence to compare on both devices.
+ */
+ decimals?: string;
+ }
+ }
+}
+
+export interface SASStartResponse {
+ /**
+ * Current app sign-in and encrypted messaging setup state.
+ */
+ session: SASStartResponse.Session;
+
+ /**
+ * Trusted device verification progress.
+ */
+ verification?: SASStartResponse.Verification;
+}
+
+export namespace SASStartResponse {
+ /**
+ * Current app sign-in and encrypted messaging setup state.
+ */
+ export interface Session {
+ /**
+ * Encrypted messaging setup status.
+ */
+ e2ee: Session.E2EE;
+
+ /**
+ * Current sign-in and encrypted messaging setup state for Beeper Desktop or Beeper
+ * Server.
+ */
+ state:
+ | 'needs-login'
+ | 'initializing'
+ | 'needs-cross-signing-setup'
+ | 'needs-verification'
+ | 'needs-secrets'
+ | 'needs-first-sync'
+ | 'ready';
+
+ /**
+ * Signed-in account details. Omitted until sign-in is complete.
+ */
+ matrix?: Session.Matrix;
+
+ /**
+ * Trusted device verification progress.
+ */
+ verification?: Session.Verification;
+ }
+
+ export namespace Session {
+ /**
+ * Encrypted messaging setup status.
+ */
+ export interface E2EE {
+ /**
+ * Whether this account can verify trusted devices.
+ */
+ crossSigning: boolean;
+
+ /**
+ * Whether the first encrypted message sync is complete.
+ */
+ firstSyncDone: boolean;
+
+ /**
+ * Whether the user confirmed that they saved their recovery key.
+ */
+ hasBackedUpRecoveryKey: boolean;
+
+ /**
+ * Whether encrypted messaging setup has started.
+ */
+ initialized: boolean;
+
+ /**
+ * Whether encrypted message backup is available.
+ */
+ keyBackup: boolean;
+
+ /**
+ * Encrypted messaging keys available on this device.
+ */
+ secrets: E2EE.Secrets;
+
+ /**
+ * Whether secure key storage is available.
+ */
+ secretStorage: boolean;
+
+ /**
+ * Whether this device is trusted for encrypted messages.
+ */
+ verified: boolean;
+
+ /**
+ * Unix timestamp for when the recovery key was created.
+ */
+ recoveryKeyGeneratedAt?: number;
+ }
+
+ export namespace E2EE {
+ /**
+ * Encrypted messaging keys available on this device.
+ */
+ export interface Secrets {
+ /**
+ * Whether the account identity key is available.
+ */
+ masterKey: boolean;
+
+ /**
+ * Whether the encrypted message backup key is available.
+ */
+ megolmBackupKey: boolean;
+
+ /**
+ * Whether a recovery key is available.
+ */
+ recoveryKey: boolean;
+
+ /**
+ * Whether the device trust key is available.
+ */
+ selfSigningKey: boolean;
+
+ /**
+ * Whether the user trust key is available.
+ */
+ userSigningKey: boolean;
+ }
+ }
+
+ /**
+ * Signed-in account details. Omitted until sign-in is complete.
+ */
+ export interface Matrix {
+ /**
+ * Current device ID.
+ */
+ deviceID: string;
+
+ /**
+ * Beeper homeserver URL for this account.
+ */
+ homeserver: string;
+
+ /**
+ * Signed-in Beeper user ID.
+ */
+ userID: string;
+ }
+
+ /**
+ * Trusted device verification progress.
+ */
+ export interface Verification {
+ /**
+ * Verification ID to pass in verification action paths.
+ */
+ id: string;
+
+ /**
+ * Verification actions that are valid for the current state.
+ */
+ availableActions: Array<'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'>;
+
+ /**
+ * Whether this device started or received the verification.
+ */
+ direction: 'incoming' | 'outgoing';
+
+ /**
+ * Verification methods supported for this transaction.
+ */
+ methods: Array<'qr' | 'sas'>;
+
+ /**
+ * Why this verification exists.
+ */
+ purpose: 'login' | 'device';
+
+ /**
+ * Current trusted-device verification state.
+ */
+ state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error';
+
+ /**
+ * Verification error details, if verification stopped.
+ */
+ error?: Verification.Error;
+
+ /**
+ * Other device participating in verification.
+ */
+ otherDevice?: Verification.OtherDevice;
+
+ /**
+ * Other Beeper user participating in verification.
+ */
+ otherUserID?: string;
+
+ /**
+ * QR verification data.
+ */
+ qr?: Verification.Qr;
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ sas?: Verification.SAS;
+ }
+
+ export namespace Verification {
+ /**
+ * Verification error details, if verification stopped.
+ */
+ export interface Error {
+ /**
+ * Verification error code.
+ */
+ code: string;
+
+ /**
+ * User-facing verification error message.
+ */
+ reason: string;
+ }
+
+ /**
+ * Other device participating in verification.
+ */
+ export interface OtherDevice {
+ /**
+ * Other device ID.
+ */
+ id: string;
+
+ /**
+ * Other device display name, if known.
+ */
+ name?: string;
+ }
+
+ /**
+ * QR verification data.
+ */
+ export interface Qr {
+ /**
+ * QR code payload to display for verification.
+ */
+ data: string;
+ }
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ export interface SAS {
+ /**
+ * Emoji sequence to compare on both devices.
+ */
+ emojis: string;
+
+ /**
+ * Number sequence to compare on both devices.
+ */
+ decimals?: string;
+ }
+ }
+ }
+
+ /**
+ * Trusted device verification progress.
+ */
+ export interface Verification {
+ /**
+ * Verification ID to pass in verification action paths.
+ */
+ id: string;
+
+ /**
+ * Verification actions that are valid for the current state.
+ */
+ availableActions: Array<'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'>;
+
+ /**
+ * Whether this device started or received the verification.
+ */
+ direction: 'incoming' | 'outgoing';
+
+ /**
+ * Verification methods supported for this transaction.
+ */
+ methods: Array<'qr' | 'sas'>;
+
+ /**
+ * Why this verification exists.
+ */
+ purpose: 'login' | 'device';
+
+ /**
+ * Current trusted-device verification state.
+ */
+ state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error';
+
+ /**
+ * Verification error details, if verification stopped.
+ */
+ error?: Verification.Error;
+
+ /**
+ * Other device participating in verification.
+ */
+ otherDevice?: Verification.OtherDevice;
+
+ /**
+ * Other Beeper user participating in verification.
+ */
+ otherUserID?: string;
+
+ /**
+ * QR verification data.
+ */
+ qr?: Verification.Qr;
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ sas?: Verification.SAS;
+ }
+
+ export namespace Verification {
+ /**
+ * Verification error details, if verification stopped.
+ */
+ export interface Error {
+ /**
+ * Verification error code.
+ */
+ code: string;
+
+ /**
+ * User-facing verification error message.
+ */
+ reason: string;
+ }
+
+ /**
+ * Other device participating in verification.
+ */
+ export interface OtherDevice {
+ /**
+ * Other device ID.
+ */
+ id: string;
+
+ /**
+ * Other device display name, if known.
+ */
+ name?: string;
+ }
+
+ /**
+ * QR verification data.
+ */
+ export interface Qr {
+ /**
+ * QR code payload to display for verification.
+ */
+ data: string;
+ }
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ export interface SAS {
+ /**
+ * Emoji sequence to compare on both devices.
+ */
+ emojis: string;
+
+ /**
+ * Number sequence to compare on both devices.
+ */
+ decimals?: string;
+ }
+ }
+}
+
+export declare namespace SAS {
+ export { type SASConfirmResponse as SASConfirmResponse, type SASStartResponse as SASStartResponse };
+}
diff --git a/src/resources/app/verifications/verifications.ts b/src/resources/app/verifications/verifications.ts
new file mode 100644
index 0000000..6749911
--- /dev/null
+++ b/src/resources/app/verifications/verifications.ts
@@ -0,0 +1,1792 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { APIResource } from '../../../core/resource';
+import * as QrAPI from './qr';
+import { BaseQr, Qr as QrAPIQr, QrConfirmScannedResponse, QrScanParams, QrScanResponse } from './qr';
+import * as SASAPI from './sas';
+import { BaseSAS, SAS as SasapiSAS, SASConfirmResponse, SASStartResponse } from './sas';
+import { APIPromise } from '../../../core/api-promise';
+import { RequestOptions } from '../../../internal/request-options';
+import { path } from '../../../internal/utils/path';
+
+/**
+ * Manage device verification transactions
+ */
+export class BaseVerifications extends APIResource {
+ static override readonly _key: readonly ['app', 'verifications'] = Object.freeze([
+ 'app',
+ 'verifications',
+ ] as const);
+
+ /**
+ * Start verifying this device from another signed-in device.
+ */
+ create(
+ body: VerificationCreateParams | null | undefined = {},
+ options?: RequestOptions,
+ ): APIPromise {
+ return this._client.post('/v1/app/setup/verifications', { body, ...options });
+ }
+
+ /**
+ * Get the current state of a device verification transaction.
+ */
+ retrieve(verificationID: string, options?: RequestOptions): APIPromise {
+ return this._client.get(path`/v1/app/setup/verifications/${verificationID}`, options);
+ }
+
+ /**
+ * List pending and active device verifications. Use this to recover state without
+ * a WebSocket connection.
+ */
+ list(options?: RequestOptions): APIPromise {
+ return this._client.get('/v1/app/setup/verifications', options);
+ }
+
+ /**
+ * Accept an incoming device verification request.
+ */
+ accept(verificationID: string, options?: RequestOptions): APIPromise {
+ return this._client.post(path`/v1/app/setup/verifications/${verificationID}/accept`, options);
+ }
+
+ /**
+ * Cancel an active device verification request.
+ */
+ cancel(
+ verificationID: string,
+ body: VerificationCancelParams | null | undefined = {},
+ options?: RequestOptions,
+ ): APIPromise {
+ return this._client.post(path`/v1/app/setup/verifications/${verificationID}/cancel`, {
+ body,
+ ...options,
+ });
+ }
+}
+/**
+ * Manage device verification transactions
+ */
+export class Verifications extends BaseVerifications {
+ qr: QrAPI.Qr = new QrAPI.Qr(this._client);
+ sas: SASAPI.SAS = new SASAPI.SAS(this._client);
+}
+
+export interface VerificationCreateResponse {
+ /**
+ * Current app sign-in and encrypted messaging setup state.
+ */
+ session: VerificationCreateResponse.Session;
+
+ /**
+ * Trusted device verification progress.
+ */
+ verification?: VerificationCreateResponse.Verification;
+}
+
+export namespace VerificationCreateResponse {
+ /**
+ * Current app sign-in and encrypted messaging setup state.
+ */
+ export interface Session {
+ /**
+ * Encrypted messaging setup status.
+ */
+ e2ee: Session.E2EE;
+
+ /**
+ * Current sign-in and encrypted messaging setup state for Beeper Desktop or Beeper
+ * Server.
+ */
+ state:
+ | 'needs-login'
+ | 'initializing'
+ | 'needs-cross-signing-setup'
+ | 'needs-verification'
+ | 'needs-secrets'
+ | 'needs-first-sync'
+ | 'ready';
+
+ /**
+ * Signed-in account details. Omitted until sign-in is complete.
+ */
+ matrix?: Session.Matrix;
+
+ /**
+ * Trusted device verification progress.
+ */
+ verification?: Session.Verification;
+ }
+
+ export namespace Session {
+ /**
+ * Encrypted messaging setup status.
+ */
+ export interface E2EE {
+ /**
+ * Whether this account can verify trusted devices.
+ */
+ crossSigning: boolean;
+
+ /**
+ * Whether the first encrypted message sync is complete.
+ */
+ firstSyncDone: boolean;
+
+ /**
+ * Whether the user confirmed that they saved their recovery key.
+ */
+ hasBackedUpRecoveryKey: boolean;
+
+ /**
+ * Whether encrypted messaging setup has started.
+ */
+ initialized: boolean;
+
+ /**
+ * Whether encrypted message backup is available.
+ */
+ keyBackup: boolean;
+
+ /**
+ * Encrypted messaging keys available on this device.
+ */
+ secrets: E2EE.Secrets;
+
+ /**
+ * Whether secure key storage is available.
+ */
+ secretStorage: boolean;
+
+ /**
+ * Whether this device is trusted for encrypted messages.
+ */
+ verified: boolean;
+
+ /**
+ * Unix timestamp for when the recovery key was created.
+ */
+ recoveryKeyGeneratedAt?: number;
+ }
+
+ export namespace E2EE {
+ /**
+ * Encrypted messaging keys available on this device.
+ */
+ export interface Secrets {
+ /**
+ * Whether the account identity key is available.
+ */
+ masterKey: boolean;
+
+ /**
+ * Whether the encrypted message backup key is available.
+ */
+ megolmBackupKey: boolean;
+
+ /**
+ * Whether a recovery key is available.
+ */
+ recoveryKey: boolean;
+
+ /**
+ * Whether the device trust key is available.
+ */
+ selfSigningKey: boolean;
+
+ /**
+ * Whether the user trust key is available.
+ */
+ userSigningKey: boolean;
+ }
+ }
+
+ /**
+ * Signed-in account details. Omitted until sign-in is complete.
+ */
+ export interface Matrix {
+ /**
+ * Current device ID.
+ */
+ deviceID: string;
+
+ /**
+ * Beeper homeserver URL for this account.
+ */
+ homeserver: string;
+
+ /**
+ * Signed-in Beeper user ID.
+ */
+ userID: string;
+ }
+
+ /**
+ * Trusted device verification progress.
+ */
+ export interface Verification {
+ /**
+ * Verification ID to pass in verification action paths.
+ */
+ id: string;
+
+ /**
+ * Verification actions that are valid for the current state.
+ */
+ availableActions: Array<'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'>;
+
+ /**
+ * Whether this device started or received the verification.
+ */
+ direction: 'incoming' | 'outgoing';
+
+ /**
+ * Verification methods supported for this transaction.
+ */
+ methods: Array<'qr' | 'sas'>;
+
+ /**
+ * Why this verification exists.
+ */
+ purpose: 'login' | 'device';
+
+ /**
+ * Current trusted-device verification state.
+ */
+ state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error';
+
+ /**
+ * Verification error details, if verification stopped.
+ */
+ error?: Verification.Error;
+
+ /**
+ * Other device participating in verification.
+ */
+ otherDevice?: Verification.OtherDevice;
+
+ /**
+ * Other Beeper user participating in verification.
+ */
+ otherUserID?: string;
+
+ /**
+ * QR verification data.
+ */
+ qr?: Verification.Qr;
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ sas?: Verification.SAS;
+ }
+
+ export namespace Verification {
+ /**
+ * Verification error details, if verification stopped.
+ */
+ export interface Error {
+ /**
+ * Verification error code.
+ */
+ code: string;
+
+ /**
+ * User-facing verification error message.
+ */
+ reason: string;
+ }
+
+ /**
+ * Other device participating in verification.
+ */
+ export interface OtherDevice {
+ /**
+ * Other device ID.
+ */
+ id: string;
+
+ /**
+ * Other device display name, if known.
+ */
+ name?: string;
+ }
+
+ /**
+ * QR verification data.
+ */
+ export interface Qr {
+ /**
+ * QR code payload to display for verification.
+ */
+ data: string;
+ }
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ export interface SAS {
+ /**
+ * Emoji sequence to compare on both devices.
+ */
+ emojis: string;
+
+ /**
+ * Number sequence to compare on both devices.
+ */
+ decimals?: string;
+ }
+ }
+ }
+
+ /**
+ * Trusted device verification progress.
+ */
+ export interface Verification {
+ /**
+ * Verification ID to pass in verification action paths.
+ */
+ id: string;
+
+ /**
+ * Verification actions that are valid for the current state.
+ */
+ availableActions: Array<'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'>;
+
+ /**
+ * Whether this device started or received the verification.
+ */
+ direction: 'incoming' | 'outgoing';
+
+ /**
+ * Verification methods supported for this transaction.
+ */
+ methods: Array<'qr' | 'sas'>;
+
+ /**
+ * Why this verification exists.
+ */
+ purpose: 'login' | 'device';
+
+ /**
+ * Current trusted-device verification state.
+ */
+ state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error';
+
+ /**
+ * Verification error details, if verification stopped.
+ */
+ error?: Verification.Error;
+
+ /**
+ * Other device participating in verification.
+ */
+ otherDevice?: Verification.OtherDevice;
+
+ /**
+ * Other Beeper user participating in verification.
+ */
+ otherUserID?: string;
+
+ /**
+ * QR verification data.
+ */
+ qr?: Verification.Qr;
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ sas?: Verification.SAS;
+ }
+
+ export namespace Verification {
+ /**
+ * Verification error details, if verification stopped.
+ */
+ export interface Error {
+ /**
+ * Verification error code.
+ */
+ code: string;
+
+ /**
+ * User-facing verification error message.
+ */
+ reason: string;
+ }
+
+ /**
+ * Other device participating in verification.
+ */
+ export interface OtherDevice {
+ /**
+ * Other device ID.
+ */
+ id: string;
+
+ /**
+ * Other device display name, if known.
+ */
+ name?: string;
+ }
+
+ /**
+ * QR verification data.
+ */
+ export interface Qr {
+ /**
+ * QR code payload to display for verification.
+ */
+ data: string;
+ }
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ export interface SAS {
+ /**
+ * Emoji sequence to compare on both devices.
+ */
+ emojis: string;
+
+ /**
+ * Number sequence to compare on both devices.
+ */
+ decimals?: string;
+ }
+ }
+}
+
+export interface VerificationRetrieveResponse {
+ /**
+ * Current app sign-in and encrypted messaging setup state.
+ */
+ session: VerificationRetrieveResponse.Session;
+
+ /**
+ * Trusted device verification progress.
+ */
+ verification?: VerificationRetrieveResponse.Verification;
+}
+
+export namespace VerificationRetrieveResponse {
+ /**
+ * Current app sign-in and encrypted messaging setup state.
+ */
+ export interface Session {
+ /**
+ * Encrypted messaging setup status.
+ */
+ e2ee: Session.E2EE;
+
+ /**
+ * Current sign-in and encrypted messaging setup state for Beeper Desktop or Beeper
+ * Server.
+ */
+ state:
+ | 'needs-login'
+ | 'initializing'
+ | 'needs-cross-signing-setup'
+ | 'needs-verification'
+ | 'needs-secrets'
+ | 'needs-first-sync'
+ | 'ready';
+
+ /**
+ * Signed-in account details. Omitted until sign-in is complete.
+ */
+ matrix?: Session.Matrix;
+
+ /**
+ * Trusted device verification progress.
+ */
+ verification?: Session.Verification;
+ }
+
+ export namespace Session {
+ /**
+ * Encrypted messaging setup status.
+ */
+ export interface E2EE {
+ /**
+ * Whether this account can verify trusted devices.
+ */
+ crossSigning: boolean;
+
+ /**
+ * Whether the first encrypted message sync is complete.
+ */
+ firstSyncDone: boolean;
+
+ /**
+ * Whether the user confirmed that they saved their recovery key.
+ */
+ hasBackedUpRecoveryKey: boolean;
+
+ /**
+ * Whether encrypted messaging setup has started.
+ */
+ initialized: boolean;
+
+ /**
+ * Whether encrypted message backup is available.
+ */
+ keyBackup: boolean;
+
+ /**
+ * Encrypted messaging keys available on this device.
+ */
+ secrets: E2EE.Secrets;
+
+ /**
+ * Whether secure key storage is available.
+ */
+ secretStorage: boolean;
+
+ /**
+ * Whether this device is trusted for encrypted messages.
+ */
+ verified: boolean;
+
+ /**
+ * Unix timestamp for when the recovery key was created.
+ */
+ recoveryKeyGeneratedAt?: number;
+ }
+
+ export namespace E2EE {
+ /**
+ * Encrypted messaging keys available on this device.
+ */
+ export interface Secrets {
+ /**
+ * Whether the account identity key is available.
+ */
+ masterKey: boolean;
+
+ /**
+ * Whether the encrypted message backup key is available.
+ */
+ megolmBackupKey: boolean;
+
+ /**
+ * Whether a recovery key is available.
+ */
+ recoveryKey: boolean;
+
+ /**
+ * Whether the device trust key is available.
+ */
+ selfSigningKey: boolean;
+
+ /**
+ * Whether the user trust key is available.
+ */
+ userSigningKey: boolean;
+ }
+ }
+
+ /**
+ * Signed-in account details. Omitted until sign-in is complete.
+ */
+ export interface Matrix {
+ /**
+ * Current device ID.
+ */
+ deviceID: string;
+
+ /**
+ * Beeper homeserver URL for this account.
+ */
+ homeserver: string;
+
+ /**
+ * Signed-in Beeper user ID.
+ */
+ userID: string;
+ }
+
+ /**
+ * Trusted device verification progress.
+ */
+ export interface Verification {
+ /**
+ * Verification ID to pass in verification action paths.
+ */
+ id: string;
+
+ /**
+ * Verification actions that are valid for the current state.
+ */
+ availableActions: Array<'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'>;
+
+ /**
+ * Whether this device started or received the verification.
+ */
+ direction: 'incoming' | 'outgoing';
+
+ /**
+ * Verification methods supported for this transaction.
+ */
+ methods: Array<'qr' | 'sas'>;
+
+ /**
+ * Why this verification exists.
+ */
+ purpose: 'login' | 'device';
+
+ /**
+ * Current trusted-device verification state.
+ */
+ state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error';
+
+ /**
+ * Verification error details, if verification stopped.
+ */
+ error?: Verification.Error;
+
+ /**
+ * Other device participating in verification.
+ */
+ otherDevice?: Verification.OtherDevice;
+
+ /**
+ * Other Beeper user participating in verification.
+ */
+ otherUserID?: string;
+
+ /**
+ * QR verification data.
+ */
+ qr?: Verification.Qr;
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ sas?: Verification.SAS;
+ }
+
+ export namespace Verification {
+ /**
+ * Verification error details, if verification stopped.
+ */
+ export interface Error {
+ /**
+ * Verification error code.
+ */
+ code: string;
+
+ /**
+ * User-facing verification error message.
+ */
+ reason: string;
+ }
+
+ /**
+ * Other device participating in verification.
+ */
+ export interface OtherDevice {
+ /**
+ * Other device ID.
+ */
+ id: string;
+
+ /**
+ * Other device display name, if known.
+ */
+ name?: string;
+ }
+
+ /**
+ * QR verification data.
+ */
+ export interface Qr {
+ /**
+ * QR code payload to display for verification.
+ */
+ data: string;
+ }
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ export interface SAS {
+ /**
+ * Emoji sequence to compare on both devices.
+ */
+ emojis: string;
+
+ /**
+ * Number sequence to compare on both devices.
+ */
+ decimals?: string;
+ }
+ }
+ }
+
+ /**
+ * Trusted device verification progress.
+ */
+ export interface Verification {
+ /**
+ * Verification ID to pass in verification action paths.
+ */
+ id: string;
+
+ /**
+ * Verification actions that are valid for the current state.
+ */
+ availableActions: Array<'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'>;
+
+ /**
+ * Whether this device started or received the verification.
+ */
+ direction: 'incoming' | 'outgoing';
+
+ /**
+ * Verification methods supported for this transaction.
+ */
+ methods: Array<'qr' | 'sas'>;
+
+ /**
+ * Why this verification exists.
+ */
+ purpose: 'login' | 'device';
+
+ /**
+ * Current trusted-device verification state.
+ */
+ state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error';
+
+ /**
+ * Verification error details, if verification stopped.
+ */
+ error?: Verification.Error;
+
+ /**
+ * Other device participating in verification.
+ */
+ otherDevice?: Verification.OtherDevice;
+
+ /**
+ * Other Beeper user participating in verification.
+ */
+ otherUserID?: string;
+
+ /**
+ * QR verification data.
+ */
+ qr?: Verification.Qr;
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ sas?: Verification.SAS;
+ }
+
+ export namespace Verification {
+ /**
+ * Verification error details, if verification stopped.
+ */
+ export interface Error {
+ /**
+ * Verification error code.
+ */
+ code: string;
+
+ /**
+ * User-facing verification error message.
+ */
+ reason: string;
+ }
+
+ /**
+ * Other device participating in verification.
+ */
+ export interface OtherDevice {
+ /**
+ * Other device ID.
+ */
+ id: string;
+
+ /**
+ * Other device display name, if known.
+ */
+ name?: string;
+ }
+
+ /**
+ * QR verification data.
+ */
+ export interface Qr {
+ /**
+ * QR code payload to display for verification.
+ */
+ data: string;
+ }
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ export interface SAS {
+ /**
+ * Emoji sequence to compare on both devices.
+ */
+ emojis: string;
+
+ /**
+ * Number sequence to compare on both devices.
+ */
+ decimals?: string;
+ }
+ }
+}
+
+export interface VerificationListResponse {
+ items: Array;
+}
+
+export namespace VerificationListResponse {
+ /**
+ * Trusted device verification progress.
+ */
+ export interface Item {
+ /**
+ * Verification ID to pass in verification action paths.
+ */
+ id: string;
+
+ /**
+ * Verification actions that are valid for the current state.
+ */
+ availableActions: Array<'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'>;
+
+ /**
+ * Whether this device started or received the verification.
+ */
+ direction: 'incoming' | 'outgoing';
+
+ /**
+ * Verification methods supported for this transaction.
+ */
+ methods: Array<'qr' | 'sas'>;
+
+ /**
+ * Why this verification exists.
+ */
+ purpose: 'login' | 'device';
+
+ /**
+ * Current trusted-device verification state.
+ */
+ state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error';
+
+ /**
+ * Verification error details, if verification stopped.
+ */
+ error?: Item.Error;
+
+ /**
+ * Other device participating in verification.
+ */
+ otherDevice?: Item.OtherDevice;
+
+ /**
+ * Other Beeper user participating in verification.
+ */
+ otherUserID?: string;
+
+ /**
+ * QR verification data.
+ */
+ qr?: Item.Qr;
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ sas?: Item.SAS;
+ }
+
+ export namespace Item {
+ /**
+ * Verification error details, if verification stopped.
+ */
+ export interface Error {
+ /**
+ * Verification error code.
+ */
+ code: string;
+
+ /**
+ * User-facing verification error message.
+ */
+ reason: string;
+ }
+
+ /**
+ * Other device participating in verification.
+ */
+ export interface OtherDevice {
+ /**
+ * Other device ID.
+ */
+ id: string;
+
+ /**
+ * Other device display name, if known.
+ */
+ name?: string;
+ }
+
+ /**
+ * QR verification data.
+ */
+ export interface Qr {
+ /**
+ * QR code payload to display for verification.
+ */
+ data: string;
+ }
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ export interface SAS {
+ /**
+ * Emoji sequence to compare on both devices.
+ */
+ emojis: string;
+
+ /**
+ * Number sequence to compare on both devices.
+ */
+ decimals?: string;
+ }
+ }
+}
+
+export interface VerificationAcceptResponse {
+ /**
+ * Current app sign-in and encrypted messaging setup state.
+ */
+ session: VerificationAcceptResponse.Session;
+
+ /**
+ * Trusted device verification progress.
+ */
+ verification?: VerificationAcceptResponse.Verification;
+}
+
+export namespace VerificationAcceptResponse {
+ /**
+ * Current app sign-in and encrypted messaging setup state.
+ */
+ export interface Session {
+ /**
+ * Encrypted messaging setup status.
+ */
+ e2ee: Session.E2EE;
+
+ /**
+ * Current sign-in and encrypted messaging setup state for Beeper Desktop or Beeper
+ * Server.
+ */
+ state:
+ | 'needs-login'
+ | 'initializing'
+ | 'needs-cross-signing-setup'
+ | 'needs-verification'
+ | 'needs-secrets'
+ | 'needs-first-sync'
+ | 'ready';
+
+ /**
+ * Signed-in account details. Omitted until sign-in is complete.
+ */
+ matrix?: Session.Matrix;
+
+ /**
+ * Trusted device verification progress.
+ */
+ verification?: Session.Verification;
+ }
+
+ export namespace Session {
+ /**
+ * Encrypted messaging setup status.
+ */
+ export interface E2EE {
+ /**
+ * Whether this account can verify trusted devices.
+ */
+ crossSigning: boolean;
+
+ /**
+ * Whether the first encrypted message sync is complete.
+ */
+ firstSyncDone: boolean;
+
+ /**
+ * Whether the user confirmed that they saved their recovery key.
+ */
+ hasBackedUpRecoveryKey: boolean;
+
+ /**
+ * Whether encrypted messaging setup has started.
+ */
+ initialized: boolean;
+
+ /**
+ * Whether encrypted message backup is available.
+ */
+ keyBackup: boolean;
+
+ /**
+ * Encrypted messaging keys available on this device.
+ */
+ secrets: E2EE.Secrets;
+
+ /**
+ * Whether secure key storage is available.
+ */
+ secretStorage: boolean;
+
+ /**
+ * Whether this device is trusted for encrypted messages.
+ */
+ verified: boolean;
+
+ /**
+ * Unix timestamp for when the recovery key was created.
+ */
+ recoveryKeyGeneratedAt?: number;
+ }
+
+ export namespace E2EE {
+ /**
+ * Encrypted messaging keys available on this device.
+ */
+ export interface Secrets {
+ /**
+ * Whether the account identity key is available.
+ */
+ masterKey: boolean;
+
+ /**
+ * Whether the encrypted message backup key is available.
+ */
+ megolmBackupKey: boolean;
+
+ /**
+ * Whether a recovery key is available.
+ */
+ recoveryKey: boolean;
+
+ /**
+ * Whether the device trust key is available.
+ */
+ selfSigningKey: boolean;
+
+ /**
+ * Whether the user trust key is available.
+ */
+ userSigningKey: boolean;
+ }
+ }
+
+ /**
+ * Signed-in account details. Omitted until sign-in is complete.
+ */
+ export interface Matrix {
+ /**
+ * Current device ID.
+ */
+ deviceID: string;
+
+ /**
+ * Beeper homeserver URL for this account.
+ */
+ homeserver: string;
+
+ /**
+ * Signed-in Beeper user ID.
+ */
+ userID: string;
+ }
+
+ /**
+ * Trusted device verification progress.
+ */
+ export interface Verification {
+ /**
+ * Verification ID to pass in verification action paths.
+ */
+ id: string;
+
+ /**
+ * Verification actions that are valid for the current state.
+ */
+ availableActions: Array<'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'>;
+
+ /**
+ * Whether this device started or received the verification.
+ */
+ direction: 'incoming' | 'outgoing';
+
+ /**
+ * Verification methods supported for this transaction.
+ */
+ methods: Array<'qr' | 'sas'>;
+
+ /**
+ * Why this verification exists.
+ */
+ purpose: 'login' | 'device';
+
+ /**
+ * Current trusted-device verification state.
+ */
+ state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error';
+
+ /**
+ * Verification error details, if verification stopped.
+ */
+ error?: Verification.Error;
+
+ /**
+ * Other device participating in verification.
+ */
+ otherDevice?: Verification.OtherDevice;
+
+ /**
+ * Other Beeper user participating in verification.
+ */
+ otherUserID?: string;
+
+ /**
+ * QR verification data.
+ */
+ qr?: Verification.Qr;
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ sas?: Verification.SAS;
+ }
+
+ export namespace Verification {
+ /**
+ * Verification error details, if verification stopped.
+ */
+ export interface Error {
+ /**
+ * Verification error code.
+ */
+ code: string;
+
+ /**
+ * User-facing verification error message.
+ */
+ reason: string;
+ }
+
+ /**
+ * Other device participating in verification.
+ */
+ export interface OtherDevice {
+ /**
+ * Other device ID.
+ */
+ id: string;
+
+ /**
+ * Other device display name, if known.
+ */
+ name?: string;
+ }
+
+ /**
+ * QR verification data.
+ */
+ export interface Qr {
+ /**
+ * QR code payload to display for verification.
+ */
+ data: string;
+ }
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ export interface SAS {
+ /**
+ * Emoji sequence to compare on both devices.
+ */
+ emojis: string;
+
+ /**
+ * Number sequence to compare on both devices.
+ */
+ decimals?: string;
+ }
+ }
+ }
+
+ /**
+ * Trusted device verification progress.
+ */
+ export interface Verification {
+ /**
+ * Verification ID to pass in verification action paths.
+ */
+ id: string;
+
+ /**
+ * Verification actions that are valid for the current state.
+ */
+ availableActions: Array<'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'>;
+
+ /**
+ * Whether this device started or received the verification.
+ */
+ direction: 'incoming' | 'outgoing';
+
+ /**
+ * Verification methods supported for this transaction.
+ */
+ methods: Array<'qr' | 'sas'>;
+
+ /**
+ * Why this verification exists.
+ */
+ purpose: 'login' | 'device';
+
+ /**
+ * Current trusted-device verification state.
+ */
+ state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error';
+
+ /**
+ * Verification error details, if verification stopped.
+ */
+ error?: Verification.Error;
+
+ /**
+ * Other device participating in verification.
+ */
+ otherDevice?: Verification.OtherDevice;
+
+ /**
+ * Other Beeper user participating in verification.
+ */
+ otherUserID?: string;
+
+ /**
+ * QR verification data.
+ */
+ qr?: Verification.Qr;
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ sas?: Verification.SAS;
+ }
+
+ export namespace Verification {
+ /**
+ * Verification error details, if verification stopped.
+ */
+ export interface Error {
+ /**
+ * Verification error code.
+ */
+ code: string;
+
+ /**
+ * User-facing verification error message.
+ */
+ reason: string;
+ }
+
+ /**
+ * Other device participating in verification.
+ */
+ export interface OtherDevice {
+ /**
+ * Other device ID.
+ */
+ id: string;
+
+ /**
+ * Other device display name, if known.
+ */
+ name?: string;
+ }
+
+ /**
+ * QR verification data.
+ */
+ export interface Qr {
+ /**
+ * QR code payload to display for verification.
+ */
+ data: string;
+ }
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ export interface SAS {
+ /**
+ * Emoji sequence to compare on both devices.
+ */
+ emojis: string;
+
+ /**
+ * Number sequence to compare on both devices.
+ */
+ decimals?: string;
+ }
+ }
+}
+
+export interface VerificationCancelResponse {
+ /**
+ * Current app sign-in and encrypted messaging setup state.
+ */
+ session: VerificationCancelResponse.Session;
+
+ /**
+ * Trusted device verification progress.
+ */
+ verification?: VerificationCancelResponse.Verification;
+}
+
+export namespace VerificationCancelResponse {
+ /**
+ * Current app sign-in and encrypted messaging setup state.
+ */
+ export interface Session {
+ /**
+ * Encrypted messaging setup status.
+ */
+ e2ee: Session.E2EE;
+
+ /**
+ * Current sign-in and encrypted messaging setup state for Beeper Desktop or Beeper
+ * Server.
+ */
+ state:
+ | 'needs-login'
+ | 'initializing'
+ | 'needs-cross-signing-setup'
+ | 'needs-verification'
+ | 'needs-secrets'
+ | 'needs-first-sync'
+ | 'ready';
+
+ /**
+ * Signed-in account details. Omitted until sign-in is complete.
+ */
+ matrix?: Session.Matrix;
+
+ /**
+ * Trusted device verification progress.
+ */
+ verification?: Session.Verification;
+ }
+
+ export namespace Session {
+ /**
+ * Encrypted messaging setup status.
+ */
+ export interface E2EE {
+ /**
+ * Whether this account can verify trusted devices.
+ */
+ crossSigning: boolean;
+
+ /**
+ * Whether the first encrypted message sync is complete.
+ */
+ firstSyncDone: boolean;
+
+ /**
+ * Whether the user confirmed that they saved their recovery key.
+ */
+ hasBackedUpRecoveryKey: boolean;
+
+ /**
+ * Whether encrypted messaging setup has started.
+ */
+ initialized: boolean;
+
+ /**
+ * Whether encrypted message backup is available.
+ */
+ keyBackup: boolean;
+
+ /**
+ * Encrypted messaging keys available on this device.
+ */
+ secrets: E2EE.Secrets;
+
+ /**
+ * Whether secure key storage is available.
+ */
+ secretStorage: boolean;
+
+ /**
+ * Whether this device is trusted for encrypted messages.
+ */
+ verified: boolean;
+
+ /**
+ * Unix timestamp for when the recovery key was created.
+ */
+ recoveryKeyGeneratedAt?: number;
+ }
+
+ export namespace E2EE {
+ /**
+ * Encrypted messaging keys available on this device.
+ */
+ export interface Secrets {
+ /**
+ * Whether the account identity key is available.
+ */
+ masterKey: boolean;
+
+ /**
+ * Whether the encrypted message backup key is available.
+ */
+ megolmBackupKey: boolean;
+
+ /**
+ * Whether a recovery key is available.
+ */
+ recoveryKey: boolean;
+
+ /**
+ * Whether the device trust key is available.
+ */
+ selfSigningKey: boolean;
+
+ /**
+ * Whether the user trust key is available.
+ */
+ userSigningKey: boolean;
+ }
+ }
+
+ /**
+ * Signed-in account details. Omitted until sign-in is complete.
+ */
+ export interface Matrix {
+ /**
+ * Current device ID.
+ */
+ deviceID: string;
+
+ /**
+ * Beeper homeserver URL for this account.
+ */
+ homeserver: string;
+
+ /**
+ * Signed-in Beeper user ID.
+ */
+ userID: string;
+ }
+
+ /**
+ * Trusted device verification progress.
+ */
+ export interface Verification {
+ /**
+ * Verification ID to pass in verification action paths.
+ */
+ id: string;
+
+ /**
+ * Verification actions that are valid for the current state.
+ */
+ availableActions: Array<'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'>;
+
+ /**
+ * Whether this device started or received the verification.
+ */
+ direction: 'incoming' | 'outgoing';
+
+ /**
+ * Verification methods supported for this transaction.
+ */
+ methods: Array<'qr' | 'sas'>;
+
+ /**
+ * Why this verification exists.
+ */
+ purpose: 'login' | 'device';
+
+ /**
+ * Current trusted-device verification state.
+ */
+ state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error';
+
+ /**
+ * Verification error details, if verification stopped.
+ */
+ error?: Verification.Error;
+
+ /**
+ * Other device participating in verification.
+ */
+ otherDevice?: Verification.OtherDevice;
+
+ /**
+ * Other Beeper user participating in verification.
+ */
+ otherUserID?: string;
+
+ /**
+ * QR verification data.
+ */
+ qr?: Verification.Qr;
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ sas?: Verification.SAS;
+ }
+
+ export namespace Verification {
+ /**
+ * Verification error details, if verification stopped.
+ */
+ export interface Error {
+ /**
+ * Verification error code.
+ */
+ code: string;
+
+ /**
+ * User-facing verification error message.
+ */
+ reason: string;
+ }
+
+ /**
+ * Other device participating in verification.
+ */
+ export interface OtherDevice {
+ /**
+ * Other device ID.
+ */
+ id: string;
+
+ /**
+ * Other device display name, if known.
+ */
+ name?: string;
+ }
+
+ /**
+ * QR verification data.
+ */
+ export interface Qr {
+ /**
+ * QR code payload to display for verification.
+ */
+ data: string;
+ }
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ export interface SAS {
+ /**
+ * Emoji sequence to compare on both devices.
+ */
+ emojis: string;
+
+ /**
+ * Number sequence to compare on both devices.
+ */
+ decimals?: string;
+ }
+ }
+ }
+
+ /**
+ * Trusted device verification progress.
+ */
+ export interface Verification {
+ /**
+ * Verification ID to pass in verification action paths.
+ */
+ id: string;
+
+ /**
+ * Verification actions that are valid for the current state.
+ */
+ availableActions: Array<'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'>;
+
+ /**
+ * Whether this device started or received the verification.
+ */
+ direction: 'incoming' | 'outgoing';
+
+ /**
+ * Verification methods supported for this transaction.
+ */
+ methods: Array<'qr' | 'sas'>;
+
+ /**
+ * Why this verification exists.
+ */
+ purpose: 'login' | 'device';
+
+ /**
+ * Current trusted-device verification state.
+ */
+ state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error';
+
+ /**
+ * Verification error details, if verification stopped.
+ */
+ error?: Verification.Error;
+
+ /**
+ * Other device participating in verification.
+ */
+ otherDevice?: Verification.OtherDevice;
+
+ /**
+ * Other Beeper user participating in verification.
+ */
+ otherUserID?: string;
+
+ /**
+ * QR verification data.
+ */
+ qr?: Verification.Qr;
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ sas?: Verification.SAS;
+ }
+
+ export namespace Verification {
+ /**
+ * Verification error details, if verification stopped.
+ */
+ export interface Error {
+ /**
+ * Verification error code.
+ */
+ code: string;
+
+ /**
+ * User-facing verification error message.
+ */
+ reason: string;
+ }
+
+ /**
+ * Other device participating in verification.
+ */
+ export interface OtherDevice {
+ /**
+ * Other device ID.
+ */
+ id: string;
+
+ /**
+ * Other device display name, if known.
+ */
+ name?: string;
+ }
+
+ /**
+ * QR verification data.
+ */
+ export interface Qr {
+ /**
+ * QR code payload to display for verification.
+ */
+ data: string;
+ }
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ export interface SAS {
+ /**
+ * Emoji sequence to compare on both devices.
+ */
+ emojis: string;
+
+ /**
+ * Number sequence to compare on both devices.
+ */
+ decimals?: string;
+ }
+ }
+}
+
+export interface VerificationCreateParams {
+ /**
+ * Why this verification is being started.
+ */
+ purpose?: 'login' | 'device';
+
+ /**
+ * Beeper user ID to verify. Defaults to the signed-in user.
+ */
+ userID?: string;
+}
+
+export interface VerificationCancelParams {
+ /**
+ * Optional cancellation code.
+ */
+ code?: string;
+
+ /**
+ * Optional user-facing cancellation reason.
+ */
+ reason?: string;
+}
+
+Verifications.Qr = QrAPIQr;
+Verifications.BaseQr = BaseQr;
+Verifications.SAS = SasapiSAS;
+Verifications.BaseSAS = BaseSAS;
+
+export declare namespace Verifications {
+ export {
+ type VerificationCreateResponse as VerificationCreateResponse,
+ type VerificationRetrieveResponse as VerificationRetrieveResponse,
+ type VerificationListResponse as VerificationListResponse,
+ type VerificationAcceptResponse as VerificationAcceptResponse,
+ type VerificationCancelResponse as VerificationCancelResponse,
+ type VerificationCreateParams as VerificationCreateParams,
+ type VerificationCancelParams as VerificationCancelParams,
+ };
+
+ export {
+ QrAPIQr as Qr,
+ BaseQr as BaseQr,
+ type QrConfirmScannedResponse as QrConfirmScannedResponse,
+ type QrScanResponse as QrScanResponse,
+ type QrScanParams as QrScanParams,
+ };
+
+ export {
+ SasapiSAS as SAS,
+ BaseSAS as BaseSAS,
+ type SASConfirmResponse as SASConfirmResponse,
+ type SASStartResponse as SASStartResponse,
+ };
+}
diff --git a/src/resources/assets.ts b/src/resources/assets.ts
index 93203cf..95d907a 100644
--- a/src/resources/assets.ts
+++ b/src/resources/assets.ts
@@ -14,8 +14,8 @@ export class BaseAssets extends APIResource {
static override readonly _key: readonly ['assets'] = Object.freeze(['assets'] as const);
/**
- * Download a Matrix file using its mxc:// or localmxc:// URL to the device running
- * Beeper Desktop and return the local file URL.
+ * Download a file from an mxc:// or localmxc:// URL to the device running the
+ * Beeper Client API and return the local file URL.
*
* @example
* ```ts
@@ -51,7 +51,7 @@ export class BaseAssets extends APIResource {
/**
* 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
+ * uploadID that can be referenced when sending a message or creating a draft
* attachment.
*
* @example
@@ -70,8 +70,8 @@ export class BaseAssets extends APIResource {
/**
* 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.
+ * that can be referenced when sending a message or creating a draft attachment.
+ * Alternative to the multipart upload endpoint.
*
* @example
* ```ts
@@ -200,7 +200,7 @@ export interface AssetUploadBase64Response {
export interface AssetDownloadParams {
/**
- * Matrix content URL (mxc:// or localmxc://) for the file to download.
+ * Beeper media URL (mxc:// or localmxc://) for the file to download.
*/
url: string;
}
diff --git a/src/resources/bridges.ts b/src/resources/bridges.ts
new file mode 100644
index 0000000..3a874ef
--- /dev/null
+++ b/src/resources/bridges.ts
@@ -0,0 +1,3 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+export * from './bridges/index';
diff --git a/src/resources/bridges/bridges.ts b/src/resources/bridges/bridges.ts
new file mode 100644
index 0000000..e1d63ac
--- /dev/null
+++ b/src/resources/bridges/bridges.ts
@@ -0,0 +1,625 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { APIResource } from '../../core/resource';
+import * as BridgesAPI from './bridges';
+import * as Shared from '../shared';
+import * as AccountsAPI from '../accounts/accounts';
+import * as ConnectionsAPI from './connections';
+import { BaseConnections, Connections } from './connections';
+import * as LoginFlowsAPI from './login-flows';
+import { BaseLoginFlows, LoginFlowListResponse, LoginFlows } from './login-flows';
+import * as LoginSessionsAPI from './login-sessions/login-sessions';
+import {
+ BaseLoginSessions,
+ LoginSessionCancelParams,
+ LoginSessionCancelResponse,
+ LoginSessionCreateParams,
+ LoginSessionRetrieveParams,
+ LoginSessions,
+} from './login-sessions/login-sessions';
+import { APIPromise } from '../../core/api-promise';
+import { RequestOptions } from '../../internal/request-options';
+import { path } from '../../internal/utils/path';
+
+/**
+ * Manage bridge-backed account types, connections, and login sessions
+ */
+export class BaseBridges extends APIResource {
+ static override readonly _key: readonly ['bridges'] = Object.freeze(['bridges'] as const);
+
+ /**
+ * Get one bridge, including the chat accounts connected through it.
+ */
+ retrieve(bridgeID: string, options?: RequestOptions): APIPromise {
+ return this._client.get(path`/v1/bridges/${bridgeID}`, options);
+ }
+
+ /**
+ * List available bridges. A bridge is a chat-network connector that can connect or
+ * reconnect chat accounts. Connected accounts use the same Account schema as GET
+ * /v1/accounts.
+ */
+ list(options?: RequestOptions): APIPromise {
+ return this._client.get('/v1/bridges', options);
+ }
+
+ /**
+ * Get advanced network capabilities for a bridge. This endpoint is intended for
+ * clients that build custom connect or chat-creation flows.
+ */
+ retrieveCapabilities(bridgeID: string, options?: RequestOptions): APIPromise {
+ return this._client.get(path`/v1/bridges/${bridgeID}/capabilities`, options);
+ }
+}
+/**
+ * Manage bridge-backed account types, connections, and login sessions
+ */
+export class Bridges extends BaseBridges {
+ loginFlows: LoginFlowsAPI.LoginFlows = new LoginFlowsAPI.LoginFlows(this._client);
+ connections: ConnectionsAPI.Connections = new ConnectionsAPI.Connections(this._client);
+ loginSessions: LoginSessionsAPI.LoginSessions = new LoginSessionsAPI.LoginSessions(this._client);
+}
+
+/**
+ * Available bridge that can connect or reconnect chat accounts.
+ */
+export interface Bridge {
+ /**
+ * Bridge ID. Use with bridge endpoints.
+ */
+ id: string;
+
+ /**
+ * Connected accounts for this bridge. Uses the same Account schema as GET
+ * /v1/accounts.
+ */
+ accounts: Array;
+
+ /**
+ * Number of active accounts for this network on this device.
+ */
+ activeAccountCount: number;
+
+ /**
+ * Human-friendly bridge name shown in Beeper.
+ */
+ displayName: string;
+
+ /**
+ * Where accounts for this bridge run: on this device or in Beeper Cloud.
+ */
+ provider: 'cloud' | 'self-hosted' | 'local' | 'platform-sdk';
+
+ /**
+ * Whether this bridge can currently be used to connect new accounts.
+ */
+ status: 'available' | 'connected' | 'limit_reached' | 'temporarily_unavailable' | 'disabled';
+
+ /**
+ * Whether this bridge can have multiple active accounts for the same network.
+ */
+ supportsMultipleAccounts: boolean;
+
+ /**
+ * Underlying bridge type, such as matrix, discordgo, slackgo, whatsapp, telegram,
+ * or twitter.
+ */
+ type: string;
+
+ /**
+ * Network grouping used for account counts and limits.
+ */
+ network?: string;
+
+ /**
+ * Human-friendly status text matching Beeper account management language.
+ */
+ statusText?: string;
+}
+
+export interface CookieField {
+ /**
+ * Field ID to send back in the fields object.
+ */
+ id: string;
+
+ /**
+ * Cookie, header, or local storage key to collect.
+ */
+ name?: string;
+
+ /**
+ * Browser storage source for this value.
+ */
+ type?: 'cookie' | 'header' | 'local_storage';
+}
+
+/**
+ * Disappearing-message timer capability.
+ */
+export interface DisappearingTimerCapability {
+ types: Array<'' | 'after_read' | 'after_send'>;
+
+ omit_empty_timer?: true;
+
+ timers?: Array;
+}
+
+/**
+ * Group creation field capability.
+ */
+export interface GroupFieldCapability {
+ allowed: boolean;
+
+ max_length?: number;
+
+ min_length?: number;
+
+ required?: boolean;
+
+ /**
+ * Disappearing-message timer capability.
+ */
+ settings?: DisappearingTimerCapability;
+}
+
+/**
+ * Group creation capabilities for one group type.
+ */
+export interface GroupTypeCapabilities {
+ type_description: string;
+
+ /**
+ * Group creation field capability.
+ */
+ avatar?: GroupFieldCapability;
+
+ /**
+ * Group creation field capability.
+ */
+ disappear?: GroupFieldCapability;
+
+ /**
+ * Group creation field capability.
+ */
+ name?: GroupFieldCapability;
+
+ /**
+ * Group creation field capability.
+ */
+ parent?: GroupFieldCapability;
+
+ /**
+ * Group creation field capability.
+ */
+ participants?: GroupFieldCapability;
+
+ /**
+ * Group creation field capability.
+ */
+ topic?: GroupFieldCapability;
+
+ /**
+ * Group creation field capability.
+ */
+ username?: GroupFieldCapability;
+}
+
+/**
+ * Connect or reconnect flow option for a bridge.
+ */
+export interface LoginFlow {
+ /**
+ * Flow ID to pass when creating a bridge login session.
+ */
+ id: string;
+
+ /**
+ * Short explanation for when to use this flow, when provided.
+ */
+ description?: string;
+
+ /**
+ * Display name for the flow, when provided.
+ */
+ name?: string;
+}
+
+export interface LoginInputField {
+ /**
+ * Field ID to send back in the fields object.
+ */
+ id: string;
+
+ /**
+ * Initial field value, when provided by the network.
+ */
+ initialValue?: string;
+
+ /**
+ * Field label to show to the user.
+ */
+ label?: string;
+
+ /**
+ * True if the user can leave this field empty.
+ */
+ optional?: boolean;
+
+ /**
+ * Placeholder text to show when the field is empty.
+ */
+ placeholder?: string;
+
+ /**
+ * Suggested input type, such as text, password, or email.
+ */
+ type?: string;
+}
+
+export interface LoginSession {
+ /**
+ * Bridge ID.
+ */
+ bridgeID: string;
+
+ /**
+ * Temporary bridge login session ID.
+ */
+ loginSessionID: string;
+
+ status:
+ | 'waiting_for_input'
+ | 'waiting_for_cookies'
+ | 'waiting_for_display'
+ | 'complete'
+ | 'cancelled'
+ | 'failed';
+
+ /**
+ * A chat account added to Beeper.
+ */
+ account?: AccountsAPI.Account;
+
+ /**
+ * Chat account ID for reconnect flows, when known.
+ */
+ accountID?: string;
+
+ /**
+ * Step the client should show or complete next. Omitted when the session is
+ * complete, cancelled, or failed.
+ */
+ currentStep?:
+ | LoginSession.UserInput
+ | LoginSession.Cookies
+ | LoginSession.DisplayAndWait
+ | LoginSession.Complete;
+
+ error?: Shared.APIError;
+
+ /**
+ * Signed-in identity for a bridge. One bridge login can contain multiple chat
+ * accounts.
+ */
+ login?: LoginSession.Login;
+
+ /**
+ * Bridge login ID for reconnect flows, when known.
+ */
+ loginID?: string;
+}
+
+export namespace LoginSession {
+ export interface UserInput {
+ fields: Array;
+
+ stepID: string;
+
+ type: 'user_input';
+
+ attachments?: Array;
+
+ /**
+ * User-facing instructions for this step.
+ */
+ instructions?: string;
+ }
+
+ export interface Cookies {
+ fields: Array;
+
+ stepID: string;
+
+ type: 'cookies';
+
+ /**
+ * URL to open for the user.
+ */
+ url: string;
+
+ /**
+ * Regular expression that identifies the final URL after sign-in.
+ */
+ expectedFinalURLRegex?: string;
+
+ /**
+ * Optional extraction script for browser-based sign-in helpers. Treat as an opaque
+ * helper value.
+ */
+ extractJS?: string;
+
+ /**
+ * User-facing instructions for this browser step.
+ */
+ instructions?: string;
+
+ /**
+ * Suggested user agent for the browser session.
+ */
+ userAgent?: string;
+ }
+
+ export interface DisplayAndWait {
+ display: DisplayAndWait.QrCode | DisplayAndWait.Emoji | DisplayAndWait.Empty;
+
+ stepID: string;
+
+ type: 'display_and_wait';
+
+ /**
+ * User-facing instructions for this step.
+ */
+ instructions?: string;
+ }
+
+ export namespace DisplayAndWait {
+ export interface QrCode {
+ data: string;
+
+ type: 'qr';
+ }
+
+ export interface Emoji {
+ imageURL: string;
+
+ type: 'emoji';
+ }
+
+ export interface Empty {
+ type: 'nothing';
+ }
+ }
+
+ export interface Complete {
+ type: 'complete';
+
+ /**
+ * A chat account added to Beeper.
+ */
+ account?: AccountsAPI.Account;
+
+ /**
+ * Completion instructions, when provided.
+ */
+ instructions?: string;
+
+ /**
+ * Signed-in identity for a bridge. One bridge login can contain multiple chat
+ * accounts.
+ */
+ login?: Complete.Login;
+
+ stepID?: string;
+ }
+
+ export namespace Complete {
+ /**
+ * Signed-in identity for a bridge. One bridge login can contain multiple chat
+ * accounts.
+ */
+ export interface Login {
+ /**
+ * Bridge ID.
+ */
+ bridgeID: string;
+
+ /**
+ * Bridge login ID.
+ */
+ loginID: string;
+
+ removeScopes: Array<'current-device' | 'all-devices'>;
+
+ status: 'connected' | 'connecting' | 'needs_login' | 'logged_out' | 'unknown';
+
+ /**
+ * Chat accounts that belong to this bridge login, when known.
+ */
+ accountIDs?: Array;
+
+ /**
+ * Human-friendly bridge login status text.
+ */
+ statusText?: string;
+
+ /**
+ * User the account belongs to.
+ */
+ user?: Shared.User;
+ }
+ }
+
+ /**
+ * Signed-in identity for a bridge. One bridge login can contain multiple chat
+ * accounts.
+ */
+ export interface Login {
+ /**
+ * Bridge ID.
+ */
+ bridgeID: string;
+
+ /**
+ * Bridge login ID.
+ */
+ loginID: string;
+
+ removeScopes: Array<'current-device' | 'all-devices'>;
+
+ status: 'connected' | 'connecting' | 'needs_login' | 'logged_out' | 'unknown';
+
+ /**
+ * Chat accounts that belong to this bridge login, when known.
+ */
+ accountIDs?: Array;
+
+ /**
+ * Human-friendly bridge login status text.
+ */
+ statusText?: string;
+
+ /**
+ * User the account belongs to.
+ */
+ user?: Shared.User;
+ }
+}
+
+/**
+ * Advanced network capabilities for account lookup and group creation.
+ */
+export interface ProvisioningCapabilities {
+ group_creation: { [key: string]: GroupTypeCapabilities };
+
+ /**
+ * Identifier lookup capabilities for this bridge.
+ */
+ resolve_identifier: ResolveIdentifierCapabilities;
+
+ image_pack_import?: boolean;
+}
+
+/**
+ * Identifier lookup capabilities for this bridge.
+ */
+export interface ResolveIdentifierCapabilities {
+ any_phone: boolean;
+
+ contact_list: boolean;
+
+ create_dm: boolean;
+
+ lookup_email: boolean;
+
+ lookup_phone: boolean;
+
+ lookup_username: boolean;
+
+ search: boolean;
+}
+
+/**
+ * Available bridge that can connect or reconnect chat accounts.
+ */
+export interface BridgeRetrieveResponse {
+ /**
+ * Bridge ID. Use with bridge endpoints.
+ */
+ id: string;
+
+ /**
+ * Connected accounts for this bridge. Uses the same Account schema as GET
+ * /v1/accounts.
+ */
+ accounts: Array;
+
+ /**
+ * Number of active accounts for this network on this device.
+ */
+ activeAccountCount: number;
+
+ /**
+ * Human-friendly bridge name shown in Beeper.
+ */
+ displayName: string;
+
+ /**
+ * Where accounts for this bridge run: on this device or in Beeper Cloud.
+ */
+ provider: 'cloud' | 'self-hosted' | 'local' | 'platform-sdk';
+
+ /**
+ * Whether this bridge can currently be used to connect new accounts.
+ */
+ status: 'available' | 'connected' | 'limit_reached' | 'temporarily_unavailable' | 'disabled';
+
+ /**
+ * Whether this bridge can have multiple active accounts for the same network.
+ */
+ supportsMultipleAccounts: boolean;
+
+ /**
+ * Underlying bridge type, such as matrix, discordgo, slackgo, whatsapp, telegram,
+ * or twitter.
+ */
+ type: string;
+
+ /**
+ * Network grouping used for account counts and limits.
+ */
+ network?: string;
+
+ /**
+ * Human-friendly status text matching Beeper account management language.
+ */
+ statusText?: string;
+}
+
+/**
+ * Available bridges and their connected accounts.
+ */
+export interface BridgeListResponse {
+ items: Array;
+}
+
+Bridges.LoginFlows = LoginFlows;
+Bridges.BaseLoginFlows = BaseLoginFlows;
+Bridges.Connections = Connections;
+Bridges.BaseConnections = BaseConnections;
+Bridges.LoginSessions = LoginSessions;
+Bridges.BaseLoginSessions = BaseLoginSessions;
+
+export declare namespace Bridges {
+ export {
+ type Bridge as Bridge,
+ type CookieField as CookieField,
+ type DisappearingTimerCapability as DisappearingTimerCapability,
+ type GroupFieldCapability as GroupFieldCapability,
+ type GroupTypeCapabilities as GroupTypeCapabilities,
+ type LoginFlow as LoginFlow,
+ type LoginInputField as LoginInputField,
+ type LoginSession as LoginSession,
+ type ProvisioningCapabilities as ProvisioningCapabilities,
+ type ResolveIdentifierCapabilities as ResolveIdentifierCapabilities,
+ type BridgeRetrieveResponse as BridgeRetrieveResponse,
+ type BridgeListResponse as BridgeListResponse,
+ };
+
+ export {
+ LoginFlows as LoginFlows,
+ BaseLoginFlows as BaseLoginFlows,
+ type LoginFlowListResponse as LoginFlowListResponse,
+ };
+
+ export { Connections as Connections, BaseConnections as BaseConnections };
+
+ export {
+ LoginSessions as LoginSessions,
+ BaseLoginSessions as BaseLoginSessions,
+ type LoginSessionCancelResponse as LoginSessionCancelResponse,
+ type LoginSessionCreateParams as LoginSessionCreateParams,
+ type LoginSessionRetrieveParams as LoginSessionRetrieveParams,
+ type LoginSessionCancelParams as LoginSessionCancelParams,
+ };
+}
diff --git a/src/resources/bridges/connections.ts b/src/resources/bridges/connections.ts
new file mode 100644
index 0000000..cee8241
--- /dev/null
+++ b/src/resources/bridges/connections.ts
@@ -0,0 +1,11 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { APIResource } from '../../core/resource';
+
+export class BaseConnections extends APIResource {
+ static override readonly _key: readonly ['bridges', 'connections'] = Object.freeze([
+ 'bridges',
+ 'connections',
+ ] as const);
+}
+export class Connections extends BaseConnections {}
diff --git a/src/resources/bridges/index.ts b/src/resources/bridges/index.ts
new file mode 100644
index 0000000..1ecd230
--- /dev/null
+++ b/src/resources/bridges/index.ts
@@ -0,0 +1,28 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+export {
+ Bridges,
+ BaseBridges,
+ type Bridge,
+ type CookieField,
+ type DisappearingTimerCapability,
+ type GroupFieldCapability,
+ type GroupTypeCapabilities,
+ type LoginFlow,
+ type LoginInputField,
+ type LoginSession,
+ type ProvisioningCapabilities,
+ type ResolveIdentifierCapabilities,
+ type BridgeRetrieveResponse,
+ type BridgeListResponse,
+} from './bridges';
+export { Connections, BaseConnections } from './connections';
+export { LoginFlows, BaseLoginFlows, type LoginFlowListResponse } from './login-flows';
+export {
+ LoginSessions,
+ BaseLoginSessions,
+ type LoginSessionCancelResponse,
+ type LoginSessionCreateParams,
+ type LoginSessionRetrieveParams,
+ type LoginSessionCancelParams,
+} from './login-sessions/index';
diff --git a/src/resources/bridges/login-flows.ts b/src/resources/bridges/login-flows.ts
new file mode 100644
index 0000000..aeb4c96
--- /dev/null
+++ b/src/resources/bridges/login-flows.ts
@@ -0,0 +1,37 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { APIResource } from '../../core/resource';
+import * as BridgesAPI from './bridges';
+import { APIPromise } from '../../core/api-promise';
+import { RequestOptions } from '../../internal/request-options';
+import { path } from '../../internal/utils/path';
+
+/**
+ * Available bridges, bridge logins, login sessions for connect and reconnect flows, and advanced network capabilities.
+ */
+export class BaseLoginFlows extends APIResource {
+ static override readonly _key: readonly ['bridges', 'loginFlows'] = Object.freeze([
+ 'bridges',
+ 'loginFlows',
+ ] as const);
+
+ /**
+ * List connect and reconnect flow options for a bridge. Use a flowID when creating
+ * a bridge login session.
+ */
+ list(bridgeID: string, options?: RequestOptions): APIPromise {
+ return this._client.get(path`/v1/bridges/${bridgeID}/login-flows`, options);
+ }
+}
+/**
+ * Available bridges, bridge logins, login sessions for connect and reconnect flows, and advanced network capabilities.
+ */
+export class LoginFlows extends BaseLoginFlows {}
+
+export interface LoginFlowListResponse {
+ items: Array;
+}
+
+export declare namespace LoginFlows {
+ export { type LoginFlowListResponse as LoginFlowListResponse };
+}
diff --git a/src/resources/bridges/login-sessions.ts b/src/resources/bridges/login-sessions.ts
new file mode 100644
index 0000000..91a3fd1
--- /dev/null
+++ b/src/resources/bridges/login-sessions.ts
@@ -0,0 +1,3 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+export * from './login-sessions/index';
diff --git a/src/resources/bridges/login-sessions/index.ts b/src/resources/bridges/login-sessions/index.ts
new file mode 100644
index 0000000..bddb004
--- /dev/null
+++ b/src/resources/bridges/login-sessions/index.ts
@@ -0,0 +1,11 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+export {
+ LoginSessions,
+ BaseLoginSessions,
+ type LoginSessionCancelResponse,
+ type LoginSessionCreateParams,
+ type LoginSessionRetrieveParams,
+ type LoginSessionCancelParams,
+} from './login-sessions';
+export { Steps, BaseSteps, type StepSubmitParams } from './steps';
diff --git a/src/resources/bridges/login-sessions/login-sessions.ts b/src/resources/bridges/login-sessions/login-sessions.ts
new file mode 100644
index 0000000..ecd5290
--- /dev/null
+++ b/src/resources/bridges/login-sessions/login-sessions.ts
@@ -0,0 +1,116 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { APIResource } from '../../../core/resource';
+import * as BridgesAPI from '../bridges';
+import * as StepsAPI from './steps';
+import { BaseSteps, StepSubmitParams, Steps } from './steps';
+import { APIPromise } from '../../../core/api-promise';
+import { RequestOptions } from '../../../internal/request-options';
+import { path } from '../../../internal/utils/path';
+
+/**
+ * Available bridges, bridge logins, login sessions for connect and reconnect flows, and advanced network capabilities.
+ */
+export class BaseLoginSessions extends APIResource {
+ static override readonly _key: readonly ['bridges', 'loginSessions'] = Object.freeze([
+ 'bridges',
+ 'loginSessions',
+ ] as const);
+
+ /**
+ * Start a temporary bridge login session to connect a new chat account or
+ * reconnect an existing bridge login. Omit loginID and accountID to connect a new
+ * account.
+ */
+ create(
+ bridgeID: string,
+ body: LoginSessionCreateParams | null | undefined = {},
+ options?: RequestOptions,
+ ): APIPromise {
+ return this._client.post(path`/v1/bridges/${bridgeID}/login-sessions`, { body, ...options });
+ }
+
+ /**
+ * Get the current state of a temporary bridge login session.
+ */
+ retrieve(
+ loginSessionID: string,
+ params: LoginSessionRetrieveParams,
+ options?: RequestOptions,
+ ): APIPromise {
+ const { bridgeID } = params;
+ return this._client.get(path`/v1/bridges/${bridgeID}/login-sessions/${loginSessionID}`, options);
+ }
+
+ /**
+ * Cancel a temporary bridge login session.
+ */
+ cancel(
+ loginSessionID: string,
+ params: LoginSessionCancelParams,
+ options?: RequestOptions,
+ ): APIPromise {
+ const { bridgeID } = params;
+ return this._client.delete(path`/v1/bridges/${bridgeID}/login-sessions/${loginSessionID}`, options);
+ }
+}
+/**
+ * Available bridges, bridge logins, login sessions for connect and reconnect flows, and advanced network capabilities.
+ */
+export class LoginSessions extends BaseLoginSessions {
+ steps: StepsAPI.Steps = new StepsAPI.Steps(this._client);
+}
+
+export interface LoginSessionCancelResponse {
+ bridgeID: string;
+
+ loginSessionID: string;
+
+ status: 'cancelled';
+}
+
+export interface LoginSessionCreateParams {
+ /**
+ * Existing chat account ID to reconnect. Omit to connect a new account.
+ */
+ accountID?: string;
+
+ /**
+ * Optional flow ID returned by the list login flows endpoint. If omitted, Beeper
+ * chooses the default flow.
+ */
+ flowID?: string;
+
+ /**
+ * Existing bridge login ID to reconnect. Omit to connect a new account.
+ */
+ loginID?: string;
+}
+
+export interface LoginSessionRetrieveParams {
+ /**
+ * Bridge ID.
+ */
+ bridgeID: string;
+}
+
+export interface LoginSessionCancelParams {
+ /**
+ * Bridge ID.
+ */
+ bridgeID: string;
+}
+
+LoginSessions.Steps = Steps;
+LoginSessions.BaseSteps = BaseSteps;
+
+export declare namespace LoginSessions {
+ export {
+ type LoginSessionCancelResponse as LoginSessionCancelResponse,
+ type LoginSessionCreateParams as LoginSessionCreateParams,
+ type LoginSessionRetrieveParams as LoginSessionRetrieveParams,
+ type LoginSessionCancelParams as LoginSessionCancelParams,
+ };
+
+ export { Steps as Steps, BaseSteps as BaseSteps, type StepSubmitParams as StepSubmitParams };
+}
diff --git a/src/resources/bridges/login-sessions/steps.ts b/src/resources/bridges/login-sessions/steps.ts
new file mode 100644
index 0000000..bfffab1
--- /dev/null
+++ b/src/resources/bridges/login-sessions/steps.ts
@@ -0,0 +1,74 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { APIResource } from '../../../core/resource';
+import * as BridgesAPI from '../bridges';
+import { APIPromise } from '../../../core/api-promise';
+import { RequestOptions } from '../../../internal/request-options';
+import { path } from '../../../internal/utils/path';
+
+/**
+ * Available bridges, bridge logins, login sessions for connect and reconnect flows, and advanced network capabilities.
+ */
+export class BaseSteps extends APIResource {
+ static override readonly _key: readonly ['bridges', 'loginSessions', 'steps'] = Object.freeze([
+ 'bridges',
+ 'loginSessions',
+ 'steps',
+ ] as const);
+
+ /**
+ * Submit input for the current step of a bridge login session.
+ */
+ submit(
+ stepID: string,
+ params: StepSubmitParams,
+ options?: RequestOptions,
+ ): APIPromise {
+ const { bridgeID, loginSessionID, ...body } = params;
+ return this._client.post(path`/v1/bridges/${bridgeID}/login-sessions/${loginSessionID}/steps/${stepID}`, {
+ body,
+ ...options,
+ });
+ }
+}
+/**
+ * Available bridges, bridge logins, login sessions for connect and reconnect flows, and advanced network capabilities.
+ */
+export class Steps extends BaseSteps {}
+
+export interface StepSubmitParams {
+ /**
+ * Path param: Bridge ID.
+ */
+ bridgeID: string;
+
+ /**
+ * Path param: Temporary bridge login session ID.
+ */
+ loginSessionID: string;
+
+ /**
+ * Body param
+ */
+ type: 'user_input' | 'cookies' | 'display_and_wait';
+
+ /**
+ * Body param: Field values keyed by the field IDs from the current step.
+ */
+ fields?: { [key: string]: string };
+
+ /**
+ * Body param: Last browser URL reached during a cookies step, if available.
+ */
+ lastURL?: string;
+
+ /**
+ * Body param: How the step was completed. Omit unless the client needs to
+ * distinguish an embedded webview or browser extension.
+ */
+ source?: 'api' | 'webview' | 'browser_extension';
+}
+
+export declare namespace Steps {
+ export { type StepSubmitParams as StepSubmitParams };
+}
diff --git a/src/resources/chats/chats.ts b/src/resources/chats/chats.ts
index 03f7ade..851cd42 100644
--- a/src/resources/chats/chats.ts
+++ b/src/resources/chats/chats.ts
@@ -41,7 +41,7 @@ export class BaseChats extends APIResource {
}
/**
- * Retrieve chat details including metadata, participants, and latest message
+ * Retrieve chat details, including metadata, participants, and the latest message.
*
* @example
* ```ts
@@ -59,7 +59,7 @@ export class BaseChats extends APIResource {
}
/**
- * Update supported chat fields. Non-empty draft objects are accepted only when the
+ * Update supported chat fields. Non-empty drafts are accepted only when the
* current draft is empty. Send draft=null to clear the draft before setting new
* draft text or attachments.
*
@@ -98,8 +98,8 @@ export class BaseChats extends APIResource {
}
/**
- * Archive or unarchive a chat. Set archived=true to move to archive,
- * archived=false to move back to inbox
+ * Archive or unarchive a chat. Set archived=true to move it to Archive, or
+ * archived=false to move it back to the inbox.
*
* @example
* ```ts
@@ -157,8 +157,9 @@ export class BaseChats extends APIResource {
}
/**
- * Force a delivery notification when supported by the underlying network.
- * Currently intended for iMessage on macOS; unsupported networks return an error.
+ * Send a notification despite the recipient focus state when the network supports
+ * it. Currently intended for iMessage on macOS; unsupported networks return an
+ * error.
*
* @example
* ```ts
@@ -195,7 +196,7 @@ export class BaseChats extends APIResource {
/**
* Resolve a user/contact and open a direct chat. Reuses and returns an existing
- * direct chat when one is found. Available in Beeper Desktop v4.2.808+.
+ * direct chat when one is found. Available in Beeper v4.2.808+.
*
* @example
* ```ts
@@ -318,7 +319,7 @@ export interface Chat {
lastReadMessageSortKey?: string;
/**
- * Local chat ID specific to this Beeper Desktop installation.
+ * Local chat ID specific to this installation.
*/
localChatID?: string | null;
@@ -375,7 +376,7 @@ export namespace Chat {
isAdmin?: boolean;
/**
- * True if this participant represents a network or bridge bot.
+ * True if this participant represents an automated network account.
*/
isNetworkBot?: boolean;
@@ -735,7 +736,7 @@ export namespace Chat {
*/
export interface Draft {
/**
- * Matrix HTML draft body.
+ * Rich-text draft body as returned by Beeper.
*/
text: string;
@@ -838,13 +839,12 @@ export namespace Chat {
export interface ChatCreateResponse extends Chat {
/**
- * @deprecated DEPRECATED - use id instead. Compatibility alias for older clients.
+ * @deprecated Use id instead.
*/
chatID: string;
/**
- * @deprecated DEPRECATED - legacy start-chat status for older clients. New clients
- * should inspect the returned Chat instead.
+ * @deprecated Inspect the returned Chat instead.
*/
status?: 'existing' | 'created';
}
@@ -861,13 +861,12 @@ export interface ChatListResponse extends Chat {
export interface ChatStartResponse extends Chat {
/**
- * @deprecated DEPRECATED - use id instead. Compatibility alias for older clients.
+ * @deprecated Use id instead.
*/
chatID: string;
/**
- * @deprecated DEPRECATED - legacy start-chat status for older clients. New clients
- * should inspect the returned Chat instead.
+ * @deprecated Inspect the returned Chat instead.
*/
status?: 'existing' | 'created';
}
@@ -968,8 +967,8 @@ export namespace ChatUpdateParams {
*/
export interface Draft {
/**
- * Draft text. Plain text and Markdown are converted to Matrix HTML with the same
- * rules used by send and edit.
+ * Draft text. Plain text and Markdown are converted to Beeper rich text with the
+ * same rules used by send and edit.
*/
text: string;
@@ -1064,8 +1063,7 @@ export interface ChatNotifyAnywayParams {}
export interface ChatSearchParams extends CursorSearchParams {
/**
- * Provide an array of account IDs to filter chats from specific messaging accounts
- * only
+ * Limit results to specific chat accounts.
*/
accountIDs?: Array;
@@ -1082,20 +1080,18 @@ export interface ChatSearchParams extends CursorSearchParams {
includeMuted?: boolean | null;
/**
- * Provide an ISO datetime string to only retrieve chats with last activity after
- * this time
+ * Only include chats with last activity after this ISO 8601 datetime.
*/
lastActivityAfter?: string;
/**
- * Provide an ISO datetime string to only retrieve chats with last activity before
- * this time
+ * Only include chats with last activity before this ISO 8601 datetime.
*/
lastActivityBefore?: string;
/**
- * Literal token search (non-semantic). Use single words users type (e.g.,
- * "dinner"). When multiple words provided, ALL must match. Case-insensitive.
+ * Literal chat search. Use words the user typed, such as "dinner". When multiple
+ * words are provided, all must match. Case-insensitive.
*/
query?: string;
@@ -1124,7 +1120,7 @@ export interface ChatStartParams {
accountID: string;
/**
- * Merged user-like contact payload used to resolve the best identifier.
+ * Contact-like user payload used to resolve the best identifier.
*/
user: ChatStartParams.User;
@@ -1141,7 +1137,7 @@ export interface ChatStartParams {
export namespace ChatStartParams {
/**
- * Merged user-like contact payload used to resolve the best identifier.
+ * Contact-like user payload used to resolve the best identifier.
*/
export interface User {
/**
diff --git a/src/resources/chats/messages/reactions.ts b/src/resources/chats/messages/reactions.ts
index ae24698..97d4b94 100644
--- a/src/resources/chats/messages/reactions.ts
+++ b/src/resources/chats/messages/reactions.ts
@@ -69,8 +69,8 @@ export class Reactions extends BaseReactions {}
export interface ReactionDeleteResponse {
/**
- * Chat ID. Input routes also accept the local chat ID from this Beeper Desktop
- * installation when available.
+ * Chat ID. Input routes also accept the local chat ID from this installation when
+ * available.
*/
chatID: string;
@@ -93,8 +93,8 @@ export interface ReactionDeleteResponse {
export interface ReactionAddResponse {
/**
- * Chat ID. Input routes also accept the local chat ID from this Beeper Desktop
- * installation when available.
+ * Chat ID. Input routes also accept the local chat ID from this installation when
+ * available.
*/
chatID: string;
@@ -122,8 +122,8 @@ export interface ReactionAddResponse {
export interface ReactionDeleteParams {
/**
- * Chat ID. Input routes also accept the local chat ID from this Beeper Desktop
- * installation when available.
+ * Chat ID. Input routes also accept the local chat ID from this installation when
+ * available.
*/
chatID: string;
@@ -135,8 +135,8 @@ export interface ReactionDeleteParams {
export interface ReactionAddParams {
/**
- * Path param: Chat ID. Input routes also accept the local chat ID from this Beeper
- * Desktop installation when available.
+ * Path param: Chat ID. Input routes also accept the local chat ID from this
+ * installation when available.
*/
chatID: string;
diff --git a/src/resources/chats/reminders.ts b/src/resources/chats/reminders.ts
index ae959be..904a6ec 100644
--- a/src/resources/chats/reminders.ts
+++ b/src/resources/chats/reminders.ts
@@ -16,7 +16,7 @@ export class BaseReminders extends APIResource {
] as const);
/**
- * Set a reminder for a chat at a specific time
+ * Set a reminder for a chat at a specific time.
*
* @example
* ```ts
@@ -35,7 +35,7 @@ export class BaseReminders extends APIResource {
}
/**
- * Clear an existing reminder from a chat
+ * Clear an existing reminder from a chat.
*
* @example
* ```ts
diff --git a/src/resources/index.ts b/src/resources/index.ts
index 7e82418..0aadd8d 100644
--- a/src/resources/index.ts
+++ b/src/resources/index.ts
@@ -1,7 +1,15 @@
// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
export * from './shared';
-export { Accounts, BaseAccounts, type Account, type AccountListResponse } from './accounts/accounts';
+export {
+ Accounts,
+ BaseAccounts,
+ type Account,
+ type AccountBridge,
+ type AccountRetrieveResponse,
+ type AccountListResponse,
+} from './accounts/accounts';
+export { App, BaseApp, type Verification, type AppSessionResponse } from './app/app';
export {
Assets,
BaseAssets,
@@ -13,6 +21,22 @@ export {
type AssetUploadParams,
type AssetUploadBase64Params,
} from './assets';
+export {
+ Bridges,
+ BaseBridges,
+ type Bridge,
+ type CookieField,
+ type DisappearingTimerCapability,
+ type GroupFieldCapability,
+ type GroupTypeCapabilities,
+ type LoginFlow,
+ type LoginInputField,
+ type LoginSession,
+ type ProvisioningCapabilities,
+ type ResolveIdentifierCapabilities,
+ type BridgeRetrieveResponse,
+ type BridgeListResponse,
+} from './bridges/bridges';
export {
Chats,
BaseChats,
diff --git a/src/resources/info.ts b/src/resources/info.ts
index f405a62..263e7fe 100644
--- a/src/resources/info.ts
+++ b/src/resources/info.ts
@@ -12,7 +12,7 @@ export class BaseInfo extends APIResource {
/**
* Returns app, platform, server, endpoint discovery, OAuth, and WebSocket metadata
- * for this Beeper Desktop instance.
+ * for this Beeper Client API server.
*/
retrieve(options?: RequestOptions): APIPromise {
return this._client.get('/v1/info', { ...options, __security: {} });
@@ -123,7 +123,7 @@ export namespace InfoRetrieveResponse {
export interface Server {
/**
- * Base URL of the Beeper Desktop API server
+ * Base URL of the Beeper Client API server
*/
base_url: string;
diff --git a/src/resources/messages.ts b/src/resources/messages.ts
index 607df98..3e034b4 100644
--- a/src/resources/messages.ts
+++ b/src/resources/messages.ts
@@ -23,7 +23,7 @@ export class BaseMessages extends APIResource {
/**
* Retrieve a message by final message ID, pendingMessageID, or Matrix event ID.
- * Chat ID may be a Beeper chat ID or local chat ID.
+ * chatID may be a Beeper chat ID or a local chat ID.
*
* @example
* ```ts
@@ -153,21 +153,20 @@ export class Messages extends BaseMessages {}
export interface MessageUpdateResponse extends Shared.Message {
/**
- * @deprecated DEPRECATED - use id instead. Compatibility alias for older clients.
+ * @deprecated Use id instead.
*/
messageID: string;
/**
- * @deprecated DEPRECATED - compatibility field. Successful responses are already
- * represented by the 200 status code.
+ * @deprecated Use the HTTP 200 response status instead.
*/
success: true;
}
export interface MessageSendResponse {
/**
- * Chat ID. Input routes also accept the local chat ID from this Beeper Desktop
- * installation when available.
+ * Chat ID. Input routes also accept the local chat ID from this installation when
+ * available.
*/
chatID: string;
@@ -181,16 +180,16 @@ export interface MessageSendResponse {
export interface MessageRetrieveParams {
/**
- * Chat ID. Input routes also accept the local chat ID from this Beeper Desktop
- * installation when available.
+ * Chat ID. Input routes also accept the local chat ID from this installation when
+ * available.
*/
chatID: string;
}
export interface MessageUpdateParams {
/**
- * Path param: Chat ID. Input routes also accept the local chat ID from this Beeper
- * Desktop installation when available.
+ * Path param: Chat ID. Input routes also accept the local chat ID from this
+ * installation when available.
*/
chatID: string;
@@ -204,8 +203,8 @@ export interface MessageListParams extends CursorNoLimitParams {}
export interface MessageDeleteParams {
/**
- * Path param: Chat ID. Input routes also accept the local chat ID from this Beeper
- * Desktop installation when available.
+ * Path param: Chat ID. Input routes also accept the local chat ID from this
+ * installation when available.
*/
chatID: string;
@@ -263,10 +262,10 @@ export interface MessageSearchParams extends CursorSearchParams {
mediaTypes?: Array<'any' | 'video' | 'image' | 'link' | 'file'>;
/**
- * Literal word search (non-semantic). Finds messages containing these EXACT words
- * in any order. Use single words users actually type, not concepts or phrases.
- * Example: use "dinner" not "dinner plans", use "sick" not "health issues". If
- * omitted, returns results filtered only by other parameters.
+ * Literal word search. Finds messages containing these words in any order. Use
+ * words the user actually typed, not inferred concepts. Example: use "dinner"
+ * rather than "dinner plans". If omitted, returns results filtered only by the
+ * other parameters.
*/
query?: string;
@@ -289,8 +288,8 @@ export interface MessageSendParams {
replyToMessageID?: string;
/**
- * Draft text. Plain text and Markdown are converted to Matrix HTML with the same
- * rules used by send and edit.
+ * Draft text. Plain text and Markdown are converted to Beeper rich text with the
+ * same rules used by send and edit.
*/
text?: string;
}
diff --git a/src/resources/shared.ts b/src/resources/shared.ts
index 63fda68..e431675 100644
--- a/src/resources/shared.ts
+++ b/src/resources/shared.ts
@@ -2,6 +2,265 @@
import { CursorNoLimit, CursorSearch } from '../core/pagination';
+export interface APIError {
+ code: string;
+
+ message: string;
+
+ details?: { [key: string]: unknown };
+}
+
+export interface AppStateSnapshot {
+ /**
+ * Encrypted messaging setup status.
+ */
+ e2ee: AppStateSnapshot.E2EE;
+
+ /**
+ * Current sign-in and encrypted messaging setup state for Beeper Desktop or Beeper
+ * Server.
+ */
+ state:
+ | 'needs-login'
+ | 'initializing'
+ | 'needs-cross-signing-setup'
+ | 'needs-verification'
+ | 'needs-secrets'
+ | 'needs-first-sync'
+ | 'ready';
+
+ /**
+ * Signed-in account details. Omitted until sign-in is complete.
+ */
+ matrix?: AppStateSnapshot.Matrix;
+
+ /**
+ * Trusted device verification progress.
+ */
+ verification?: AppStateSnapshot.Verification;
+}
+
+export namespace AppStateSnapshot {
+ /**
+ * Encrypted messaging setup status.
+ */
+ export interface E2EE {
+ /**
+ * Whether this account can verify trusted devices.
+ */
+ crossSigning: boolean;
+
+ /**
+ * Whether the first encrypted message sync is complete.
+ */
+ firstSyncDone: boolean;
+
+ /**
+ * Whether the user confirmed that they saved their recovery key.
+ */
+ hasBackedUpRecoveryKey: boolean;
+
+ /**
+ * Whether encrypted messaging setup has started.
+ */
+ initialized: boolean;
+
+ /**
+ * Whether encrypted message backup is available.
+ */
+ keyBackup: boolean;
+
+ /**
+ * Encrypted messaging keys available on this device.
+ */
+ secrets: E2EE.Secrets;
+
+ /**
+ * Whether secure key storage is available.
+ */
+ secretStorage: boolean;
+
+ /**
+ * Whether this device is trusted for encrypted messages.
+ */
+ verified: boolean;
+
+ /**
+ * Unix timestamp for when the recovery key was created.
+ */
+ recoveryKeyGeneratedAt?: number;
+ }
+
+ export namespace E2EE {
+ /**
+ * Encrypted messaging keys available on this device.
+ */
+ export interface Secrets {
+ /**
+ * Whether the account identity key is available.
+ */
+ masterKey: boolean;
+
+ /**
+ * Whether the encrypted message backup key is available.
+ */
+ megolmBackupKey: boolean;
+
+ /**
+ * Whether a recovery key is available.
+ */
+ recoveryKey: boolean;
+
+ /**
+ * Whether the device trust key is available.
+ */
+ selfSigningKey: boolean;
+
+ /**
+ * Whether the user trust key is available.
+ */
+ userSigningKey: boolean;
+ }
+ }
+
+ /**
+ * Signed-in account details. Omitted until sign-in is complete.
+ */
+ export interface Matrix {
+ /**
+ * Current device ID.
+ */
+ deviceID: string;
+
+ /**
+ * Beeper homeserver URL for this account.
+ */
+ homeserver: string;
+
+ /**
+ * Signed-in Beeper user ID.
+ */
+ userID: string;
+ }
+
+ /**
+ * Trusted device verification progress.
+ */
+ export interface Verification {
+ /**
+ * Verification ID to pass in verification action paths.
+ */
+ id: string;
+
+ /**
+ * Verification actions that are valid for the current state.
+ */
+ availableActions: Array<'accept' | 'cancel' | 'qr.confirmScanned' | 'sas.start' | 'sas.confirm'>;
+
+ /**
+ * Whether this device started or received the verification.
+ */
+ direction: 'incoming' | 'outgoing';
+
+ /**
+ * Verification methods supported for this transaction.
+ */
+ methods: Array<'qr' | 'sas'>;
+
+ /**
+ * Why this verification exists.
+ */
+ purpose: 'login' | 'device';
+
+ /**
+ * Current trusted-device verification state.
+ */
+ state: 'requested' | 'ready' | 'sas_ready' | 'qr_scanned' | 'done' | 'cancelled' | 'error';
+
+ /**
+ * Verification error details, if verification stopped.
+ */
+ error?: Verification.Error;
+
+ /**
+ * Other device participating in verification.
+ */
+ otherDevice?: Verification.OtherDevice;
+
+ /**
+ * Other Beeper user participating in verification.
+ */
+ otherUserID?: string;
+
+ /**
+ * QR verification data.
+ */
+ qr?: Verification.Qr;
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ sas?: Verification.SAS;
+ }
+
+ export namespace Verification {
+ /**
+ * Verification error details, if verification stopped.
+ */
+ export interface Error {
+ /**
+ * Verification error code.
+ */
+ code: string;
+
+ /**
+ * User-facing verification error message.
+ */
+ reason: string;
+ }
+
+ /**
+ * Other device participating in verification.
+ */
+ export interface OtherDevice {
+ /**
+ * Other device ID.
+ */
+ id: string;
+
+ /**
+ * Other device display name, if known.
+ */
+ name?: string;
+ }
+
+ /**
+ * QR verification data.
+ */
+ export interface Qr {
+ /**
+ * QR code payload to display for verification.
+ */
+ data: string;
+ }
+
+ /**
+ * Emoji or number comparison data for verification.
+ */
+ export interface SAS {
+ /**
+ * Emoji sequence to compare on both devices.
+ */
+ emojis: string;
+
+ /**
+ * Number sequence to compare on both devices.
+ */
+ decimals?: string;
+ }
+ }
+}
+
export interface Attachment {
/**
* Attachment type.
@@ -9,7 +268,7 @@ export interface Attachment {
type: 'unknown' | 'img' | 'video' | 'audio';
/**
- * Attachment identifier (typically an mxc:// URL). Use the download file endpoint
+ * Attachment identifier, typically an mxc:// URL. Use the download file endpoint
* to get a local file path.
*/
id?: string;
@@ -51,7 +310,7 @@ export interface Attachment {
/**
* Preview image URL for video attachments (poster frame). May be temporary or
- * local-only to this device; download promptly if durable access is needed.
+ * available only on this device; download promptly if durable access is needed.
*/
posterImg?: string;
@@ -61,8 +320,8 @@ export interface Attachment {
size?: Attachment.Size;
/**
- * Public URL or local file path to fetch the file. May be temporary or local-only
- * to this device; download promptly if durable access is needed.
+ * Public URL or local file path to fetch the file. May be temporary or available
+ * only on this device; download promptly if durable access is needed.
*/
srcURL?: string;
@@ -163,14 +422,14 @@ export interface Message {
accountID: string;
/**
- * Chat ID. Input routes also accept the local chat ID from this Beeper Desktop
- * installation when available.
+ * Chat ID. Input routes also accept the local chat ID from this installation when
+ * available.
*/
chatID: string;
/**
- * Matrix-style fully-qualified sender user ID, usually including a bridge prefix
- * and homeserver.
+ * Fully qualified sender user ID. Network-backed IDs usually include the network
+ * prefix and homeserver.
*/
senderID: string;
@@ -241,7 +500,7 @@ export interface Message {
seen?: boolean | string | { [key: string]: boolean | string };
/**
- * Resolved sender display name (impersonator/full name/username/participant name).
+ * Resolved sender display name.
*/
senderName?: string;
@@ -251,7 +510,7 @@ export interface Message {
sendStatus?: Message.SendStatus;
/**
- * Matrix HTML body if present.
+ * Rich-text message body if present.
*/
text?: string;
@@ -288,14 +547,14 @@ export namespace Message {
url: string;
/**
- * Favicon URL if available. May be temporary or local-only to this device;
+ * Favicon URL if available. May be temporary or available only on this device;
* download promptly if durable access is needed.
*/
favicon?: string;
/**
- * Preview image URL if available. May be temporary or local-only to this device;
- * download promptly if durable access is needed.
+ * Preview image URL if available. May be temporary or available only on this
+ * device; download promptly if durable access is needed.
*/
img?: string;
@@ -346,7 +605,8 @@ export namespace Message {
deliveredToUsers?: Array;
/**
- * Internal bridge error detail. Intended for diagnostics, not end-user display.
+ * Diagnostic error detail from the messaging network adapter. Do not show directly
+ * to users.
*/
internalError?: string;
@@ -387,7 +647,7 @@ export interface Reaction {
emoji?: boolean;
/**
- * URL to the reaction's image. May be temporary or local-only to this device;
+ * URL to the reaction's image. May be temporary or available only on this device;
* download promptly if durable access is needed.
*/
imgURL?: string;
@@ -419,9 +679,9 @@ export interface User {
fullName?: string;
/**
- * Avatar image URL if available. This may be a remote URL, Matrix media URL, data
- * URL, or local filesystem URL depending on source and endpoint. May be temporary
- * or local-only to this device; download promptly if durable access is needed.
+ * Avatar image URL if available. This may be a remote URL, media URL, data URL, or
+ * local file URL depending on the source. May be temporary or available only on
+ * this device; download promptly if durable access is needed.
*/
imgURL?: string;
diff --git a/src/resources/top-level.ts b/src/resources/top-level.ts
index 0cd89f4..a95fffa 100644
--- a/src/resources/top-level.ts
+++ b/src/resources/top-level.ts
@@ -72,7 +72,7 @@ export interface FocusParams {
chatID?: string;
/**
- * Optional image path to populate in the message input field.
+ * Optional local image path to populate in the message input field.
*/
draftAttachmentPath?: string;
@@ -89,7 +89,7 @@ export interface FocusParams {
export interface SearchParams {
/**
- * User-typed search text. Literal word matching (non-semantic).
+ * User-typed search text. Uses literal word matching.
*/
query: string;
}
diff --git a/src/version.ts b/src/version.ts
index e156b0e..0d43855 100644
--- a/src/version.ts
+++ b/src/version.ts
@@ -1 +1 @@
-export const VERSION = '5.0.0'; // x-release-please-version
+export const VERSION = '5.1.0'; // x-release-please-version
diff --git a/tests/api-resources/accounts/accounts.test.ts b/tests/api-resources/accounts/accounts.test.ts
index aa78a86..d8a98ef 100644
--- a/tests/api-resources/accounts/accounts.test.ts
+++ b/tests/api-resources/accounts/accounts.test.ts
@@ -17,6 +17,17 @@ const partialClient = createClient({
});
const runTests = (client: PartialBeeperDesktop<{ accounts: BaseAccounts }>) => {
+ test('retrieve', async () => {
+ const responsePromise = client.accounts.retrieve('accountID');
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
test('list', async () => {
const responsePromise = client.accounts.list();
const rawResponse = await responsePromise.asResponse();
diff --git a/tests/api-resources/app/app.test.ts b/tests/api-resources/app/app.test.ts
new file mode 100644
index 0000000..d433c3b
--- /dev/null
+++ b/tests/api-resources/app/app.test.ts
@@ -0,0 +1,32 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { BaseApp } from '@beeper/desktop-api/resources/app/app';
+
+import BeeperDesktop from '@beeper/desktop-api';
+import { createClient, type PartialBeeperDesktop } from '@beeper/desktop-api/tree-shakable';
+
+const client = new BeeperDesktop({
+ accessToken: 'My Access Token',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+});
+
+const partialClient = createClient({
+ accessToken: 'My Access Token',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+ resources: [BaseApp],
+});
+
+const runTests = (client: PartialBeeperDesktop<{ app: BaseApp }>) => {
+ test('session', async () => {
+ const responsePromise = client.app.session();
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+};
+describe('resource app', () => runTests(client));
+describe('resource app (tree shakable, base)', () => runTests(partialClient));
diff --git a/tests/api-resources/app/login/login.test.ts b/tests/api-resources/app/login/login.test.ts
new file mode 100644
index 0000000..5dfb7c7
--- /dev/null
+++ b/tests/api-resources/app/login/login.test.ts
@@ -0,0 +1,107 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { App } from '@beeper/desktop-api/resources/app/app';
+import { BaseLogin } from '@beeper/desktop-api/resources/app/login/login';
+
+import BeeperDesktop from '@beeper/desktop-api';
+import { createClient, type PartialBeeperDesktop } from '@beeper/desktop-api/tree-shakable';
+
+const client = new BeeperDesktop({
+ accessToken: 'My Access Token',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+});
+
+const partialClient = createClient({
+ accessToken: 'My Access Token',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+ resources: [BaseLogin],
+});
+
+const parentPartialClient = createClient({
+ accessToken: 'My Access Token',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+ resources: [App],
+});
+
+const runTests = (client: PartialBeeperDesktop<{ app: { login: BaseLogin } }>) => {
+ test('email: only required params', async () => {
+ const responsePromise = client.app.login.email({
+ email: 'dev@stainless.com',
+ setupRequestID: 'setupRequestID',
+ });
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('email: required and optional params', async () => {
+ const response = await client.app.login.email({
+ email: 'dev@stainless.com',
+ setupRequestID: 'setupRequestID',
+ });
+ });
+
+ test('register: only required params', async () => {
+ const responsePromise = client.app.login.register({
+ acceptTerms: true,
+ leadToken: 'leadToken',
+ setupRequestID: 'setupRequestID',
+ username: 'x',
+ });
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('register: required and optional params', async () => {
+ const response = await client.app.login.register({
+ acceptTerms: true,
+ leadToken: 'leadToken',
+ setupRequestID: 'setupRequestID',
+ username: 'x',
+ });
+ });
+
+ test('response: only required params', async () => {
+ const responsePromise = client.app.login.response({
+ response: 'response',
+ setupRequestID: 'setupRequestID',
+ });
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('response: required and optional params', async () => {
+ const response = await client.app.login.response({
+ response: 'response',
+ setupRequestID: 'setupRequestID',
+ });
+ });
+
+ test('start', async () => {
+ const responsePromise = client.app.login.start();
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+};
+describe('resource login', () => runTests(client));
+describe('resource login (tree shakable, base)', () => runTests(partialClient));
+describe('resource login (tree shakable, subresource)', () => runTests(parentPartialClient));
diff --git a/tests/api-resources/app/login/verification/recovery-key/recovery-key.test.ts b/tests/api-resources/app/login/verification/recovery-key/recovery-key.test.ts
new file mode 100644
index 0000000..e54a055
--- /dev/null
+++ b/tests/api-resources/app/login/verification/recovery-key/recovery-key.test.ts
@@ -0,0 +1,46 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { Verification } from '@beeper/desktop-api/resources/app/login/verification/verification';
+import { BaseRecoveryKey } from '@beeper/desktop-api/resources/app/login/verification/recovery-key/recovery-key';
+
+import BeeperDesktop from '@beeper/desktop-api';
+import { createClient, type PartialBeeperDesktop } from '@beeper/desktop-api/tree-shakable';
+
+const client = new BeeperDesktop({
+ accessToken: 'My Access Token',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+});
+
+const partialClient = createClient({
+ accessToken: 'My Access Token',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+ resources: [BaseRecoveryKey],
+});
+
+const parentPartialClient = createClient({
+ accessToken: 'My Access Token',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+ resources: [Verification],
+});
+
+const runTests = (
+ client: PartialBeeperDesktop<{ app: { login: { verification: { recoveryKey: BaseRecoveryKey } } } }>,
+) => {
+ test('verify: only required params', async () => {
+ const responsePromise = client.app.login.verification.recoveryKey.verify({ recoveryKey: 'x' });
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('verify: required and optional params', async () => {
+ const response = await client.app.login.verification.recoveryKey.verify({ recoveryKey: 'x' });
+ });
+};
+describe('resource recoveryKey', () => runTests(client));
+describe('resource recoveryKey (tree shakable, base)', () => runTests(partialClient));
+describe('resource recoveryKey (tree shakable, subresource)', () => runTests(parentPartialClient));
diff --git a/tests/api-resources/app/login/verification/recovery-key/reset.test.ts b/tests/api-resources/app/login/verification/recovery-key/reset.test.ts
new file mode 100644
index 0000000..178d978
--- /dev/null
+++ b/tests/api-resources/app/login/verification/recovery-key/reset.test.ts
@@ -0,0 +1,67 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { RecoveryKey } from '@beeper/desktop-api/resources/app/login/verification/recovery-key/recovery-key';
+import { BaseReset } from '@beeper/desktop-api/resources/app/login/verification/recovery-key/reset';
+
+import BeeperDesktop from '@beeper/desktop-api';
+import { createClient, type PartialBeeperDesktop } from '@beeper/desktop-api/tree-shakable';
+
+const client = new BeeperDesktop({
+ accessToken: 'My Access Token',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+});
+
+const partialClient = createClient({
+ accessToken: 'My Access Token',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+ resources: [BaseReset],
+});
+
+const parentPartialClient = createClient({
+ accessToken: 'My Access Token',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+ resources: [RecoveryKey],
+});
+
+const runTests = (
+ client: PartialBeeperDesktop<{ app: { login: { verification: { recoveryKey: { reset: BaseReset } } } } }>,
+) => {
+ test('create', async () => {
+ const responsePromise = client.app.login.verification.recoveryKey.reset.create();
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('create: request options and params are passed correctly', async () => {
+ // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
+ await expect(
+ client.app.login.verification.recoveryKey.reset.create(
+ { existingRecoveryKey: 'existingRecoveryKey' },
+ { path: '/_stainless_unknown_path' },
+ ),
+ ).rejects.toThrow(BeeperDesktop.NotFoundError);
+ });
+
+ test('confirm: only required params', async () => {
+ const responsePromise = client.app.login.verification.recoveryKey.reset.confirm({ recoveryKey: 'x' });
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('confirm: required and optional params', async () => {
+ const response = await client.app.login.verification.recoveryKey.reset.confirm({ recoveryKey: 'x' });
+ });
+};
+describe('resource reset', () => runTests(client));
+describe('resource reset (tree shakable, base)', () => runTests(partialClient));
+describe('resource reset (tree shakable, subresource)', () => runTests(parentPartialClient));
diff --git a/tests/api-resources/app/verifications/qr.test.ts b/tests/api-resources/app/verifications/qr.test.ts
new file mode 100644
index 0000000..fc09226
--- /dev/null
+++ b/tests/api-resources/app/verifications/qr.test.ts
@@ -0,0 +1,55 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { BaseQr } from '@beeper/desktop-api/resources/app/verifications/qr';
+import { Verifications } from '@beeper/desktop-api/resources/app/verifications/verifications';
+
+import BeeperDesktop from '@beeper/desktop-api';
+import { createClient, type PartialBeeperDesktop } from '@beeper/desktop-api/tree-shakable';
+
+const client = new BeeperDesktop({
+ accessToken: 'My Access Token',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+});
+
+const partialClient = createClient({
+ accessToken: 'My Access Token',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+ resources: [BaseQr],
+});
+
+const parentPartialClient = createClient({
+ accessToken: 'My Access Token',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+ resources: [Verifications],
+});
+
+const runTests = (client: PartialBeeperDesktop<{ app: { verifications: { qr: BaseQr } } }>) => {
+ test('confirmScanned', async () => {
+ const responsePromise = client.app.verifications.qr.confirmScanned('x');
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('scan: only required params', async () => {
+ const responsePromise = client.app.verifications.qr.scan({ data: 'x' });
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('scan: required and optional params', async () => {
+ const response = await client.app.verifications.qr.scan({ data: 'x' });
+ });
+};
+describe('resource qr', () => runTests(client));
+describe('resource qr (tree shakable, base)', () => runTests(partialClient));
+describe('resource qr (tree shakable, subresource)', () => runTests(parentPartialClient));
diff --git a/tests/api-resources/app/verifications/sas.test.ts b/tests/api-resources/app/verifications/sas.test.ts
new file mode 100644
index 0000000..5564a78
--- /dev/null
+++ b/tests/api-resources/app/verifications/sas.test.ts
@@ -0,0 +1,51 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { BaseSAS } from '@beeper/desktop-api/resources/app/verifications/sas';
+import { Verifications } from '@beeper/desktop-api/resources/app/verifications/verifications';
+
+import BeeperDesktop from '@beeper/desktop-api';
+import { createClient, type PartialBeeperDesktop } from '@beeper/desktop-api/tree-shakable';
+
+const client = new BeeperDesktop({
+ accessToken: 'My Access Token',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+});
+
+const partialClient = createClient({
+ accessToken: 'My Access Token',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+ resources: [BaseSAS],
+});
+
+const parentPartialClient = createClient({
+ accessToken: 'My Access Token',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+ resources: [Verifications],
+});
+
+const runTests = (client: PartialBeeperDesktop<{ app: { verifications: { sas: BaseSAS } } }>) => {
+ test('confirm', async () => {
+ const responsePromise = client.app.verifications.sas.confirm('x');
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('start', async () => {
+ const responsePromise = client.app.verifications.sas.start('x');
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+};
+describe('resource sas', () => runTests(client));
+describe('resource sas (tree shakable, base)', () => runTests(partialClient));
+describe('resource sas (tree shakable, subresource)', () => runTests(parentPartialClient));
diff --git a/tests/api-resources/app/verifications/verifications.test.ts b/tests/api-resources/app/verifications/verifications.test.ts
new file mode 100644
index 0000000..076b9da
--- /dev/null
+++ b/tests/api-resources/app/verifications/verifications.test.ts
@@ -0,0 +1,105 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { App } from '@beeper/desktop-api/resources/app/app';
+import { BaseVerifications } from '@beeper/desktop-api/resources/app/verifications/verifications';
+
+import BeeperDesktop from '@beeper/desktop-api';
+import { createClient, type PartialBeeperDesktop } from '@beeper/desktop-api/tree-shakable';
+
+const client = new BeeperDesktop({
+ accessToken: 'My Access Token',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+});
+
+const partialClient = createClient({
+ accessToken: 'My Access Token',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+ resources: [BaseVerifications],
+});
+
+const parentPartialClient = createClient({
+ accessToken: 'My Access Token',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+ resources: [App],
+});
+
+const runTests = (client: PartialBeeperDesktop<{ app: { verifications: BaseVerifications } }>) => {
+ test('create', async () => {
+ const responsePromise = client.app.verifications.create();
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('create: request options and params are passed correctly', async () => {
+ // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
+ await expect(
+ client.app.verifications.create(
+ { purpose: 'login', userID: 'userID' },
+ { path: '/_stainless_unknown_path' },
+ ),
+ ).rejects.toThrow(BeeperDesktop.NotFoundError);
+ });
+
+ test('retrieve', async () => {
+ const responsePromise = client.app.verifications.retrieve('x');
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('list', async () => {
+ const responsePromise = client.app.verifications.list();
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('accept', async () => {
+ const responsePromise = client.app.verifications.accept('x');
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('cancel', async () => {
+ const responsePromise = client.app.verifications.cancel('x');
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('cancel: request options and params are passed correctly', async () => {
+ // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
+ await expect(
+ client.app.verifications.cancel(
+ 'x',
+ { code: 'code', reason: 'reason' },
+ { path: '/_stainless_unknown_path' },
+ ),
+ ).rejects.toThrow(BeeperDesktop.NotFoundError);
+ });
+};
+describe('resource verifications', () => runTests(client));
+describe('resource verifications (tree shakable, base)', () => runTests(partialClient));
+describe('resource verifications (tree shakable, subresource)', () => runTests(parentPartialClient));
diff --git a/tests/api-resources/bridges/bridges.test.ts b/tests/api-resources/bridges/bridges.test.ts
new file mode 100644
index 0000000..8fae5c3
--- /dev/null
+++ b/tests/api-resources/bridges/bridges.test.ts
@@ -0,0 +1,54 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { BaseBridges } from '@beeper/desktop-api/resources/bridges/bridges';
+
+import BeeperDesktop from '@beeper/desktop-api';
+import { createClient, type PartialBeeperDesktop } from '@beeper/desktop-api/tree-shakable';
+
+const client = new BeeperDesktop({
+ accessToken: 'My Access Token',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+});
+
+const partialClient = createClient({
+ accessToken: 'My Access Token',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+ resources: [BaseBridges],
+});
+
+const runTests = (client: PartialBeeperDesktop<{ bridges: BaseBridges }>) => {
+ test('retrieve', async () => {
+ const responsePromise = client.bridges.retrieve('local-whatsapp');
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('list', async () => {
+ const responsePromise = client.bridges.list();
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('retrieveCapabilities', async () => {
+ const responsePromise = client.bridges.retrieveCapabilities('local-whatsapp');
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+};
+describe('resource bridges', () => runTests(client));
+describe('resource bridges (tree shakable, base)', () => runTests(partialClient));
diff --git a/tests/api-resources/bridges/login-flows.test.ts b/tests/api-resources/bridges/login-flows.test.ts
new file mode 100644
index 0000000..50d9280
--- /dev/null
+++ b/tests/api-resources/bridges/login-flows.test.ts
@@ -0,0 +1,40 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { Bridges } from '@beeper/desktop-api/resources/bridges/bridges';
+import { BaseLoginFlows } from '@beeper/desktop-api/resources/bridges/login-flows';
+
+import BeeperDesktop from '@beeper/desktop-api';
+import { createClient, type PartialBeeperDesktop } from '@beeper/desktop-api/tree-shakable';
+
+const client = new BeeperDesktop({
+ accessToken: 'My Access Token',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+});
+
+const partialClient = createClient({
+ accessToken: 'My Access Token',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+ resources: [BaseLoginFlows],
+});
+
+const parentPartialClient = createClient({
+ accessToken: 'My Access Token',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+ resources: [Bridges],
+});
+
+const runTests = (client: PartialBeeperDesktop<{ bridges: { loginFlows: BaseLoginFlows } }>) => {
+ test('list', async () => {
+ const responsePromise = client.bridges.loginFlows.list('local-whatsapp');
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+};
+describe('resource loginFlows', () => runTests(client));
+describe('resource loginFlows (tree shakable, base)', () => runTests(partialClient));
+describe('resource loginFlows (tree shakable, subresource)', () => runTests(parentPartialClient));
diff --git a/tests/api-resources/bridges/login-sessions/login-sessions.test.ts b/tests/api-resources/bridges/login-sessions/login-sessions.test.ts
new file mode 100644
index 0000000..28d5de2
--- /dev/null
+++ b/tests/api-resources/bridges/login-sessions/login-sessions.test.ts
@@ -0,0 +1,85 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { Bridges } from '@beeper/desktop-api/resources/bridges/bridges';
+import { BaseLoginSessions } from '@beeper/desktop-api/resources/bridges/login-sessions/login-sessions';
+
+import BeeperDesktop from '@beeper/desktop-api';
+import { createClient, type PartialBeeperDesktop } from '@beeper/desktop-api/tree-shakable';
+
+const client = new BeeperDesktop({
+ accessToken: 'My Access Token',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+});
+
+const partialClient = createClient({
+ accessToken: 'My Access Token',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+ resources: [BaseLoginSessions],
+});
+
+const parentPartialClient = createClient({
+ accessToken: 'My Access Token',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+ resources: [Bridges],
+});
+
+const runTests = (client: PartialBeeperDesktop<{ bridges: { loginSessions: BaseLoginSessions } }>) => {
+ test('create', async () => {
+ const responsePromise = client.bridges.loginSessions.create('local-whatsapp');
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('create: request options and params are passed correctly', async () => {
+ // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
+ await expect(
+ client.bridges.loginSessions.create(
+ 'local-whatsapp',
+ {
+ accountID: 'x',
+ flowID: 'x',
+ loginID: 'x',
+ },
+ { path: '/_stainless_unknown_path' },
+ ),
+ ).rejects.toThrow(BeeperDesktop.NotFoundError);
+ });
+
+ test('retrieve: only required params', async () => {
+ const responsePromise = client.bridges.loginSessions.retrieve('123', { bridgeID: 'local-whatsapp' });
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('retrieve: required and optional params', async () => {
+ const response = await client.bridges.loginSessions.retrieve('123', { bridgeID: 'local-whatsapp' });
+ });
+
+ test('cancel: only required params', async () => {
+ const responsePromise = client.bridges.loginSessions.cancel('123', { bridgeID: 'local-whatsapp' });
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('cancel: required and optional params', async () => {
+ const response = await client.bridges.loginSessions.cancel('123', { bridgeID: 'local-whatsapp' });
+ });
+};
+describe('resource loginSessions', () => runTests(client));
+describe('resource loginSessions (tree shakable, base)', () => runTests(partialClient));
+describe('resource loginSessions (tree shakable, subresource)', () => runTests(parentPartialClient));
diff --git a/tests/api-resources/bridges/login-sessions/steps.test.ts b/tests/api-resources/bridges/login-sessions/steps.test.ts
new file mode 100644
index 0000000..8d742ef
--- /dev/null
+++ b/tests/api-resources/bridges/login-sessions/steps.test.ts
@@ -0,0 +1,55 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { LoginSessions } from '@beeper/desktop-api/resources/bridges/login-sessions/login-sessions';
+import { BaseSteps } from '@beeper/desktop-api/resources/bridges/login-sessions/steps';
+
+import BeeperDesktop from '@beeper/desktop-api';
+import { createClient, type PartialBeeperDesktop } from '@beeper/desktop-api/tree-shakable';
+
+const client = new BeeperDesktop({
+ accessToken: 'My Access Token',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+});
+
+const partialClient = createClient({
+ accessToken: 'My Access Token',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+ resources: [BaseSteps],
+});
+
+const parentPartialClient = createClient({
+ accessToken: 'My Access Token',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+ resources: [LoginSessions],
+});
+
+const runTests = (client: PartialBeeperDesktop<{ bridges: { loginSessions: { steps: BaseSteps } } }>) => {
+ test('submit: only required params', async () => {
+ const responsePromise = client.bridges.loginSessions.steps.submit('x', {
+ bridgeID: 'local-whatsapp',
+ loginSessionID: '123',
+ type: 'user_input',
+ });
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('submit: required and optional params', async () => {
+ const response = await client.bridges.loginSessions.steps.submit('x', {
+ bridgeID: 'local-whatsapp',
+ loginSessionID: '123',
+ type: 'user_input',
+ fields: { foo: 'string' },
+ lastURL: 'lastURL',
+ source: 'api',
+ });
+ });
+};
+describe('resource steps', () => runTests(client));
+describe('resource steps (tree shakable, base)', () => runTests(partialClient));
+describe('resource steps (tree shakable, subresource)', () => runTests(parentPartialClient));
diff --git a/tests/uploads.test.ts b/tests/uploads.test.ts
index e13ed28..3cbef94 100644
--- a/tests/uploads.test.ts
+++ b/tests/uploads.test.ts
@@ -1,7 +1,6 @@
import fs from 'fs';
import type { ResponseLike } from '@beeper/desktop-api/internal/to-file';
import { toFile } from '@beeper/desktop-api/core/uploads';
-import { File } from 'node:buffer';
class MyClass {
name: string = 'foo';
diff --git a/yarn.lock b/yarn.lock
index 18e7cbd..00842e3 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3192,9 +3192,9 @@ ts-node@^10.5.0:
v8-compile-cache-lib "^3.0.0"
yn "3.1.1"
-"tsc-multi@https://github.com/stainless-api/tsc-multi/releases/download/v1.1.9/tsc-multi.tgz":
- version "1.1.9"
- resolved "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.9/tsc-multi.tgz#777f6f5d9e26bf0e94e5170990dd3a841d6707cd"
+"tsc-multi@https://github.com/stainless-api/tsc-multi/releases/download/v1.1.11/tsc-multi.tgz":
+ version "1.1.11"
+ resolved "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.11/tsc-multi.tgz#010247051be13b55abdc98f787c017285149f4f2"
dependencies:
debug "^4.3.7"
fast-glob "^3.3.2"