Skip to main content
BlueBubblesClient is the single entry point for every operation in the BlueBubbles SDK. You construct one instance, pass your server address and credentials, and then call methods on its resource-grouped properties — client.chats, client.messages, client.attachments, and so on — instead of managing URLs or HTTP headers yourself.

Constructing the client

The constructor accepts a partial OpenAPIConfig object so you only need to supply the fields that differ from the defaults. At a minimum, provide BASE (your BlueBubbles Server URL) and PASSWORD (your server password).
import { BlueBubblesClient } from "bluebubbles-sdk";

const client = new BlueBubblesClient({
  BASE: "https://your-server-address",
  PASSWORD: "your-server-password",
});

Full configuration reference

FieldTypeDefaultDescription
BASEstring"http://localhost"Base URL of your BlueBubbles Server instance.
VERSIONstring"1.0.0"API version string. You rarely need to change this.
PASSWORDstring | Resolver<string>undefinedServer password used for authentication.
TOKENstring | Resolver<string>undefinedBearer token, if your server is configured to use token auth.
USERNAMEstring | Resolver<string>undefinedUsername for HTTP Basic authentication.
WITH_CREDENTIALSbooleanfalseWhether to include cookies in cross-origin requests.
CREDENTIALS"include" | "omit" | "same-origin""include"Controls the credentials mode for fetch.
HEADERSRecord<string, string> | Resolver<...>undefinedCustom headers merged into every request.
ENCODE_PATH(path: string) => stringundefinedOverride path-segment encoding for special character handling.
PASSWORD, TOKEN, USERNAME, and HEADERS each accept either a static value or an async resolver function — (options: ApiRequestOptions) => Promise<T> — so you can fetch credentials dynamically at request time.
const client = new BlueBubblesClient({
  BASE: "https://your-server-address",
  // Resolve the password asynchronously (e.g., from a secrets manager)
  PASSWORD: async (_options) => {
    return await secretsManager.getSecret("bluebubbles-password");
  },
  // Attach a custom header to every request
  HEADERS: {
    "X-Client-Version": "1.0.0",
  },
});

Available services

The client exposes eleven service properties, each scoping methods to a particular resource domain. You access them directly on the client instance.

client.chats

Create, query, update, and delete chats. Manage participants, read status, typing indicators, and group icons.

client.messages

Send text messages and attachments, react to messages, query message history, and schedule future messages.

client.attachments

Fetch attachment metadata and download attachment files by GUID.

client.handles

Query and retrieve handle records — the contact addresses associated with iMessage conversations.

client.contacts

Access and search contacts stored on the macOS server.

client.server

Retrieve server metadata, check server health, and read diagnostic information.

client.backups

Manage server-side backups of your iMessage database and settings.

client.fcm

Configure Firebase Cloud Messaging for push notification delivery.

client.icloud

Access iCloud-related operations, including contact card sharing.

client.macos

Execute macOS-level operations on the host machine running BlueBubbles Server.

client.web

Manage web-facing features and webhook configurations.

Usage example

// Query the 20 most recent chats including last message and participants
const chats = await client.chats.list({
  requestBody: {
    limit: 20,
    offset: 0,
    with: ["lastMessage", "participants"],
    sort: "lastmessage",
  },
});

// Fetch messages for a specific chat
const messages = await client.chats.listMessages({
  chatGuid: "iMessage;+;+15550001234",
});

// Send a text message
await client.messages.sendText({
  requestBody: {
    chatGuid: "iMessage;+;+15550001234",
    message: "Hello from the SDK!",
    tempGuid: crypto.randomUUID(),
  },
});

// Get server info
const info = await client.server.getServerMetadata();

Custom HTTP request backend

The second argument to the constructor is an optional HttpRequest class — any class that extends BaseHttpRequest. By default the SDK uses an internal FetchHttpRequest implementation that calls the native fetch API. You can substitute your own implementation to add logging, retry logic, or use a different transport layer.
import {
  BlueBubblesClient,
  BaseHttpRequest,
  CancelablePromise,
} from "bluebubbles-sdk";
import type { OpenAPIConfig } from "bluebubbles-sdk";

class LoggingHttpRequest extends BaseHttpRequest {
  constructor(config: OpenAPIConfig) {
    super(config);
  }

  public request<T>(options: any): CancelablePromise<T> {
    console.log(`[BlueBubbles] ${options.method} ${options.url}`);
    // Delegate to your own fetch implementation or super if available
    return new CancelablePromise<T>((resolve, reject) => {
      fetch(`${this.config.BASE}${options.url}`, {
        method: options.method,
        headers: options.headers as HeadersInit,
        body: options.body ? JSON.stringify(options.body) : undefined,
      })
        .then((res) => res.json() as T)
        .then(resolve)
        .catch(reject);
    });
  }
}

const client = new BlueBubblesClient(
  { BASE: "https://your-server-address", PASSWORD: "secret" },
  LoggingHttpRequest,
);

The request property

Every BlueBubblesClient instance exposes a request property of type BaseHttpRequest. This gives you direct access to the configured HTTP layer so you can issue raw API calls to endpoints not yet covered by named service methods.
// Call a hypothetical endpoint not wrapped by a service method
const result = await client.request.request({
  method: "GET",
  url: "/api/v1/some/custom/endpoint",
  query: { password: "secret" },
});
The request property uses the same configuration (BASE URL, credentials, custom headers) you passed to the constructor, so you don’t need to repeat them for raw calls.

Error handling

All service methods return a CancelablePromise and throw an ApiError on non-2xx responses. The ApiError class extends Error and carries structured context about the failure.
import { ApiError } from "bluebubbles-sdk";

try {
  const chat = await client.chats.get({ chatGuid: "iMessage;+;+15550001234" });
} catch (err) {
  if (err instanceof ApiError) {
    console.error(`HTTP ${err.status}${err.statusText}`);
    console.error("Response body:", err.body);
    console.error("Request URL:", err.url);
  }
}
PropertyTypeDescription
statusnumberHTTP status code returned by the server.
statusTextstringHTTP status text (e.g., "Not Found").
urlstringThe full URL of the failed request.
bodyanyParsed response body from the server.
requestApiRequestOptionsThe original request options that caused the failure.