Skip to main content
Every resource in BlueBubbles — chats, messages, attachments, and handles — is identified by a globally unique identifier (GUID). These GUIDs are not random UUIDs; they follow a structured, human-readable format that encodes the resource type and the address or identifier of the participant involved. Understanding the format helps you construct correct identifiers when calling SDK methods and interpret the values you receive in API responses.

Chat GUID format

Chat GUIDs identify an iMessage conversation. They follow a three-part semicolon-separated format:
<service>;<type>;<address>
SegmentValuesDescription
serviceiMessage, SMSThe messaging service used for the conversation.
type+ (phone), - (email/other)Indicates whether the address is a phone number.
addressphone number or emailThe contact address, or a random ID for group chats.

Direct conversation GUIDs

For one-on-one conversations, the address is the phone number or Apple ID email of the other participant.
iMessage;+;+15550001234          ← phone number (with country code)
iMessage;-;tim@apple.com         ← Apple ID email address
SMS;+;+15550009876               ← SMS conversation
Always include the country code in phone numbers. For US numbers, the country code is +1, so a number like (555) 000-1234 becomes +15550001234.

Group chat GUIDs

Group chats use a server-generated random identifier in the address segment rather than a participant’s contact info. You cannot construct a group chat GUID yourself — you discover it by querying the chats list.
iMessage;+;chat012345678901234567      ← group chat
iMessage;-;chat987654321098765432      ← group chat (email-based service)

Message GUIDs

Individual messages within a chat each carry their own GUID. Message GUIDs are opaque strings assigned by the iMessage infrastructure and returned to you in API responses. You use them when reacting to a message, replying to it, or fetching a specific message.
p:0/ABCDEF01-2345-6789-ABCD-EF0123456789    ← typical message GUID format
You receive message GUIDs in the response body whenever you send or query messages. Store them if you need to reference a message later — for example, to send a reaction.
// Fetch a message by its GUID
const message = await client.messages.get({
  guid: "p:0/ABCDEF01-2345-6789-ABCD-EF0123456789",
});

Attachment GUIDs

Attachments — images, videos, audio messages, and files — each have a GUID returned when you query a message that contains one. Use the attachment GUID to fetch metadata or download the file.
// Download an attachment by its GUID
const file = await client.attachments.download({
  guid: "at_0_ABCDEF01-2345-6789-ABCD-EF0123456789",
});

Handle addresses

Handles represent individual participants — effectively a contact address used as an iMessage endpoint. The handle address is the raw phone number or email, without the iMessage;+; prefix that wraps a chat GUID.
+15550001234          ← handle address for a phone number
tim@apple.com         ← handle address for an Apple ID email
You use handle addresses when querying or fetching a specific contact record.
// Get a handle by its address
const handle = await client.handles.get({
  handleAddress: "+15550001234",
});

How GUIDs appear in SDK calls

Most SDK methods that target a specific chat accept a chatGuid parameter. Pass the full iMessage;+;... or iMessage;-;... string.
const chatGuid = "iMessage;+;+15550001234";

// Get chat details
const chat = await client.chats.get({ chatGuid });

// List messages in the chat
const messages = await client.chats.listMessages({ chatGuid });

// Mark the chat as read
await client.chats.markRead({ chatGuid, requestBody: {} });

// Send a text message to the chat
await client.messages.sendText({
  requestBody: {
    chatGuid,
    message: "Hello!",
    tempGuid: crypto.randomUUID(),
  },
});
When sending messages, you also provide a tempGuid — a client-generated identifier you create (typically a UUID v4) used to deduplicate the message on the server side. This prevents the same message from being delivered twice if your request is retried.
// Always generate a fresh tempGuid per send attempt
await client.messages.sendText({
  requestBody: {
    chatGuid: "iMessage;-;tim@apple.com",
    message: "Sending with deduplication",
    tempGuid: crypto.randomUUID(),
  },
});

Querying to discover GUIDs

If you don’t already know the GUID for a chat, query the chats list and filter the results.
// Discover chats and extract their GUIDs
const result = await client.chats.list({
  requestBody: {
    limit: 100,
    offset: 0,
    with: ["lastMessage", "participants"],
    sort: "lastmessage",
  },
});

for (const chat of result.data) {
  console.log(chat.guid, chat.displayName);
  // e.g. "iMessage;+;+15550001234"  "Tim Apple"
}
Cache chat GUIDs locally after the first query rather than fetching the full chat list on every request. GUIDs for direct conversations are stable — they won’t change as long as the conversation exists on the server.