Method Signature
await sdk.messages.unsendMessage(options: {
messageGuid: string;
partIndex?: number;
}): Promise<MessageResponse>
Retracts (unsends) a previously sent message, removing it from the recipient’s device. This feature requires iOS 16+ / macOS Ventura+ and only works with iMessage (not SMS).
Message unsending only works with iMessage chats. SMS messages cannot be unsent.
Parameters
The unique identifier of the message to unsend
The part index for multi-part messages. Use 0 for single-part messages (most common).
Response
Returns a MessageResponse object:
The message GUID (unchanged)
Timestamp (milliseconds since epoch) when the message was retracted
The original message text (before unsending)
Whether the message was sent by you
Examples
Basic Unsend
const unsent = await sdk.messages.unsendMessage({
messageGuid: "iMessage;-;user@example.com;12345"
});
console.log(`Message unsent at: ${new Date(unsent.dateRetracted!)}`);
// Send a message
const message = await sdk.messages.sendMessage({
chatGuid: "iMessage;-;user@example.com",
message: "Oops, wrong chat!"
});
// Immediately unsend it
await sdk.messages.unsendMessage({
messageGuid: message.guid
});
console.log("Message unsent");
Unsend with Timeout
// Send a self-destructing message
const message = await sdk.messages.sendMessage({
chatGuid: "iMessage;-;user@example.com",
message: "This message will self-destruct in 10 seconds"
});
// Wait 10 seconds and unsend
setTimeout(async () => {
await sdk.messages.unsendMessage({
messageGuid: message.guid
});
console.log("Message self-destructed");
}, 10000);
Unsend Based on Condition
const message = await sdk.messages.sendMessage({
chatGuid: "iMessage;-;user@example.com",
message: "Payment confirmed!"
});
// Later: if payment fails, unsend the message
try {
await processPayment();
} catch (error) {
console.log("Payment failed, unsending confirmation message");
await sdk.messages.unsendMessage({
messageGuid: message.guid
});
// Send correction
await sdk.messages.sendMessage({
chatGuid: "iMessage;-;user@example.com",
message: "Payment failed. Please try again."
});
}
Check if Message Was Unsent
const message = await sdk.messages.getMessage(
"iMessage;-;user@example.com;12345"
);
if (message.dateRetracted) {
const timeSinceRetraction = Date.now() - message.dateRetracted;
console.log(`Message was unsent ${Math.floor(timeSinceRetraction / 1000)} seconds ago`);
} else {
console.log("Message is still active");
}
Bulk Unsend Recent Messages
// Get recent messages from the last hour
const oneHourAgo = Date.now() - (60 * 60 * 1000);
const recentMessages = await sdk.messages.getMessages({
chatGuid: "iMessage;-;user@example.com",
after: oneHourAgo
});
// Unsend all messages sent by me
for (const message of recentMessages) {
if (message.isFromMe && !message.dateRetracted) {
try {
await sdk.messages.unsendMessage({
messageGuid: message.guid
});
console.log(`Unsent: ${message.text}`);
// Add delay to avoid rate limiting
await new Promise(resolve => setTimeout(resolve, 500));
} catch (error) {
console.error(`Failed to unsend ${message.guid}:`, error.message);
}
}
}
Error Handling
try {
await sdk.messages.unsendMessage({
messageGuid: "iMessage;-;user@example.com;12345"
});
console.log("Message unsent successfully");
} catch (error) {
if (error.response?.status === 400) {
console.error("Invalid message GUID or format");
} else if (error.response?.status === 404) {
console.error("Message not found");
} else if (error.response?.data?.message?.includes("not supported")) {
console.error("Unsending not supported (SMS chat or old iOS version)");
} else if (error.response?.data?.message?.includes("already unsent")) {
console.error("Message was already unsent");
} else {
console.error("Failed to unsend message:", error.message);
}
}
Limitations
Message unsending has several limitations:
- Only works with iMessage (not SMS/MMS)
- Requires iOS 16+ / macOS Ventura+ for both sender and recipient
- You can only unsend your own messages (
isFromMe: true)
- There may be time limits on how long after sending you can unsend
- Recipients on older iOS/macOS versions may still see the original message
- If the recipient read the message before unsending, they saw the content
Unsend vs Delete
Unsending (this method) removes the message from both your device and the recipient’s device, as if it was never sent.
Deleting locally (different operation) only removes the message from your device’s view, but recipients still see it.
// Unsend - removes from both sides
await sdk.messages.unsendMessage({
messageGuid: message.guid
});
// Recipient's chat: message disappears
// Local delete - only removes from your view (not available in SDK)
// Recipient's chat: message remains
What Recipients See
On iOS 16+ / macOS Ventura+
Recipients see a placeholder indicating “[Sender] unsent a message” or similar system text.
On Older Versions
Recipients on iOS 15 or earlier may still see the original message, as unsending is not supported.