Results returned for data type polls against the API will return information in one of the formats outlined below.
Result payload
Attributes
The root structure of the data JSON payload has the following attributes.
| name | type | description |
|---|---|---|
data | list of data objects | The data retrieved from the source. |
metadata | metadata object | Metadata related to data. |
Metadata
Attributes
| name | type | description |
|---|---|---|
count | int | The number of objects in data. |
File
The file data type is seen throughout the API, as it is a reference to a file that can be downloaded from the API through a files type poll.
Attributes
| name | type | description |
|---|---|---|
file_id | string | Identifier used to request the file from the API. The value is only guaranteed to be unique in the scope of the current source. |
type | string, always file | Data type specifier. |
name | string | The name of the file, excluding the extension. |
extension | string, optional | The extension of the file if available. |
mime_type | string, optional | The MIME type of the file if available. |
size | int, optional | The size of the file if available. |
checksum | string, optional | The md5 checksum if available. |
Example
{
"file_id": "abc123",
"type": "file",
"name": "IMG_0003",
"extension": "jpg",
"mime_type": "image/jpeg",
"size": 2505426,
}
Image
Extends file.
| name | type | description |
|---|---|---|
file_id | string | Identifier used to request the file from the API. The value is only guaranteed to be unique in the scope of the current source. |
type | string | Always image. |
filename | string | The original file name of the file. The extension in this filename need to match the extension of the file. |
file_path | string | The path of the file relative to other files within its service. For example, the path within a backup. |
width | int, optional | The width of the file if available. |
height | int, optional | The height of the file if available. |
Example
{
"file_id": "abc123",
"type": "image",
"filename": "IMG_0003.JPG",
"file_path": "Media/DCIM/100APPLE/IMG_0003.JPG",
"name": "IMG_0003",
"extension": "jpg",
"mime_type": "image/jpeg",
"width": 3000,
"height": 2002,
"size": 2505426,
}
Video
Extends file.
| name | type | description |
|---|---|---|
file_id | string | Identifier used to request the file from the API. The value is only guaranteed to be unique in the scope of the current source. |
type | string | Always video. |
filename | string | The original file name of the file. The extension in this filename need to match the extension of the file. |
file_path | string | The path of the file relative to other files within its service. For example, the path within a backup. |
width | int, optional | The width of the file if available. |
height | int, optional | The height of the file if available. |
duration | int, optional | The length of the video if available. |
Example
{
"file_id": "abc123",
"type": "video",
"filename": "IMG_0009.MOV",
"file_path": "Media/DCIM/100APPLE/IMG_0009.MOV",
"name": "IMG_0009",
"extension": "mov",
"mime_type": "video/quicktime",
"width": 1920,
"height": 1080,
"size": 5421796,
"duration": 9.135623
}
Video
Extends file.
| name | type | description |
|---|---|---|
file_id | string | Identifier used to request the file from the API. The value is only guaranteed to be unique in the scope of the current source. |
type | string | Always audio. |
filename | string | The original file name of the file. The extension in this filename need to match the extension of the file. |
file_path | string | The path of the file relative to other files within its service. For example, the path within a backup. |
transcription | string, optional | The text transcription for an audio message, if available. |
Example
{
"id": "abc123",
"type": "audio",
"filename": "Audio Message.caf",
"file_path": "Library/SMS/Attachments/.../Audio Message.caf",
"transcription": "Test voice message",
}
Audio transcriptions
When available in a backup's data, the transcription of audio messages is returned as part of the audio object. This is available on audio messages made in iOS Messages since iOS 17.
Message
Attributes
| name | type | description |
|---|---|---|
id | string | A unique identifier for the message. Use this to deduplicate returned data if necessary. |
data_type | string, always message | Data type specifier. |
type | string, optional | Used when a messaging service handles a variety of message types. For example SMS and iMessage in the case of iOS Messages. |
handle | string | The 2nd party of the conversation, often an identifier unique to the messaging app. |
handle_name | string, optional | Where available, a display name for the handle. |
contact | nested contact, optional | An object referencing an iOS contact of the 2nd party of the conversation. |
conversation_id | string | Identifier grouping messages by conversation. |
from_me | bool | Whether the message was sent or received. |
user | string, optional | The user of the messaging app in the case where multiple users/accounts may be using a messaging app from the device. |
text | string | The body of the message. |
message_type | string, optional | Classification of the message (e.g. text, attachment, group_event, phone_number_change, poll, calendar_event). Currently present on WhatsApp messages. Unrecognised database values are passed through as raw integers. |
group_event_type | string, optional | Sub-classification for group management events. Only present when message_type is group_event. See the WhatsApp group event types section below for the full list of values. |
group_event_participants | list of strings, optional | The people a group event was about, such as those added by participant_added and participants_batch_added. Only present on those events. |
group_event_description | string, optional | A readable sentence describing a group event, for events whose text is only identifiers or codes. Composed by the API, not stored by the app. See WhatsApp group event types. |
edits | list of edits, optional | A list of message content edits, for apps where message editing is supported and the history persisted in backups. |
translation | translation object, optional | Translation data if the message was translated using iOS's built-in translation feature. |
attachments | list of files, optional | An array of file_id values which can be used with the download_file method. If the message includes no attachment, an empty array is returned. |
group | string, optional | The name of the group at the time the message was sent. |
group_id | string, optional | The unique identifier for the group within the context of that app. This may not be an integer, and if present, only provides information in addition to conversation_id. |
group_handles | list of strings, optional | This value is null for person-to-person messages, and in group conversations is an array of strings representing phone numbers or iMessage email addresses. |
group_contacts | string, optional | An array of objects referencing iOS contacts in the group. |
deleted | bool, optional | A boolean value to indicate whether the message had been deleted. |
marked_unread | bool, optional | Whether the user marked the message as unread, if available. |
date | datetime | When the message was sent or received. |
date_read | datetime, optional | When a message was first read, if available. |
date_edited | datetime, optional | When a message was last edited, if applicable. |
date_deleted | datetime, optional | When a message was deleted, if applicable. |
line | string, optional | The device's own phone number or iMessage address the message was sent or received on. Currently present on iOS Messages from iOS 11.3. |
line_id | string, optional | On dual-SIM devices, the identifier of the SIM line the message went over. Use with the lines filter. |
line_label | string, optional | The name the user gave the SIM line, such as Work, if any. |
orphaned | bool, optional | Present and true when the message isn't linked to a conversation in the source data, and its conversation_id was inferred. See message handles and conversations. |
conversation_id_source | string, optional | Present on orphaned messages. How conversation_id was inferred. |
translation attributes
| name | type | description |
|---|---|---|
translated_text | string | The translated text content. |
source_language | string | The original language code (e.g., en_US). |
target_language | string | The language the message was translated to (e.g., es_ES). |
Example
{
"id": "a1b2c3d4",
"data_type": "message",
"type": "SMS",
"handle": "reincubate",
"handle_name": "Reincubate",
"conversation_id": "w6x7y8z9",
"from_me": false,
"text": "Hi from London!",
"edits": [{
"text": "Hi!",
"date": "2023-06-27T10:20:00.000000Z"
}, {
"text": "Hi from London!",
"date": "2023-06-27T10:21:00.000000Z"
}],
"attachments": [],
"group_handles": [
"+441234567890",
"renate@reincubate.com"
],
"deleted": false,
"date": "2023-06-27T10:20:00.000000Z",
"date_edited": "2023-06-27T10:21:00.000000Z"
}
Message handles and conversations
The API's data extractors support a historically broad range of source data, and will attempt to realign data that has become fragmented through app and iOS updates over time. As messaging apps add new features, they are not always careful to ensure the underlying data is migrated perfectly to the new structure. Therefore, the API must infer certain information in order to return consistent data.
One such case is for handles and conversation information returned from messaging apps, and most specifically the ios_messages.messages data module. The API will populate conversation_id with either a numeric identifier, if such information exists or can be inferred, or fallback to use the second-party's handle to set conversation_id. Therefore, using this field to tie together messages from the same chat is recommended.
When an iOS Messages message isn't linked to a conversation in the source data, it carries orphaned: true and a conversation_id_source saying how its conversation_id was inferred. Messages linked to a conversation carry neither attribute.
conversation_id_source | description |
|---|---|
inferred_handle_chat | The message was matched to the only one-to-one conversation with its handle. conversation_id is that conversation's ID. |
destination_caller_id | No conversation could be matched, so conversation_id is the address the message was sent to. |
handle | No conversation could be matched, so conversation_id is the message's handle. |
none | Nothing could be resolved. conversation_id is null. |
Recovered deleted messages are often orphaned, as their link to a conversation is usually lost with the deletion.
Edited and deleted messages
This section relates to apps that implement editing and deletion functionality as a feature, such as Messages as of iOS 16, and not to message undeletion whereby deleted or dereferenced database records are recovered from source files.
Information on edited and deleted messages is available for ios_messages.messages for backups made from devices running iOS 16 and later. For deleted messages, information is only expected to be available while the message is still recoverable at the point the backup was made, which Apple say is 30–40 days after deletion.
For edited messages, the history of edits is returned in the edits attribute. Each edit includes the state of text and the time when the edit was committed. The text attribute of the message itself will always be the same as that of the final edit.
Translated messages
When a user translates an incoming message using iOS's built-in translation feature (available since iOS 26), the translation data is preserved in the backup and returned in the translation attribute. This includes:
- The translated text content
- The source language of the original message
- The target language the message was translated into
Language codes follow the standard locale format (e.g., en_US for US English, es_ES for Spanish).
Note that translation data is only available for messages that were explicitly translated by the user on the device. The original message text is always returned in the text attribute.
WhatsApp message and group event types
WhatsApp messages include a message_type field classifying the message:
message_type | Description |
|---|---|
text | Plain text message. |
attachment | Image, video, audio, vcard, location, link, document, or gif. The specific type is in attachments[].type. |
group_event | Group management event (creation, name change, member add/remove, etc.). |
phone_number_change | User changed their phone number. |
poll | Poll (content not yet extracted into text). |
calendar_event | Calendar event (content not yet extracted into text). |
When message_type is group_event, the group_event_type field provides sub-classification:
group_event_type | Description |
|---|---|
group_created | A new group was created. |
icon_changed | Group icon was changed. |
participant_added | A participant was added. handle is the admin who added them, and group_event_participants lists the person added. |
participant_removed | A participant was removed. Not currently produced. |
participant_promoted | A participant was promoted to admin. |
participant_change_number | A participant changed their phone number. |
subject_changed | Group name/subject was changed. |
description_changed | Group or community description was changed. Not currently produced. |
community_subgroup_linked | A subgroup was linked to a community. |
community_subgroup_unlinked | A subgroup was unlinked from a community. |
group_membership_permission_changed | Who can add members was changed. |
participants_batch_added | Multiple participants were added at once. handle is the admin who added them, and group_event_participants lists the people added. |
community_subject_changed | Community name was changed. |
community_description_changed | Community description was changed. |
For most group events, text contains a human-readable value extracted from the event metadata. For example, a subject_changed event has the new group name as its text, and a community_subgroup_linked event has the linked subgroup's name. Unrecognised event types are passed through as raw integers.
For some events, WhatsApp stores only identifiers or codes, and text keeps them as stored. For example, a participant_added event's text is the admin's WhatsApp ID. These events also carry a group_event_description, a sentence composed from the event's fields:
group_event_type | Example group_event_description |
|---|---|
participant_added | Iphone 6 (40743660246@s.whatsapp.net) added Luci (40726367814@s.whatsapp.net) |
participants_batch_added | Iphone 6 (40743660246@s.whatsapp.net) added 40711111111@s.whatsapp.net and 40722222222@s.whatsapp.net |
icon_changed | Luci (40726367814@s.whatsapp.net) changed the group icon, or The group icon was changed when it isn't known who changed it |
group_membership_permission_changed | Iphone 6 (40743660246@s.whatsapp.net) changed the group so only admins can add members |
community_subject_changed | 61607749136585@lid changed the community name from "Old Name" to "New Name" |
Each person is written as their name followed by their WhatsApp ID in brackets, or as the bare ID when WhatsApp has no name for them. The ID always matches handle or an entry in group_event_participants, so people who share a name can still be told apart. The device's owner appears as you, or You when they performed the event. Names are those WhatsApp held at the time of extraction.
A WhatsApp sender or group member identified only by an unresolved LID (an ID ending @lid, which isn't a phone number) has no phone number in contact or group_contacts.
Conversation
A conversation thread.
| name | type | description |
|---|---|---|
id | string | Item ID. |
data_type | string, always conversation | Item data type ID. |
group | optional string | Name of group. |
members | list of contact items | Participants in the conversation. |
Contact
contact attributes
| name | type | description |
|---|---|---|
id | string | Item ID. |
data_type | string, always contact | Item data type ID. |
name | optional string | The contact's full name. |
first_name | optional string | The contact's first name. |
middle_name | optional string | The contact's middle name. |
last_name | optional string | The contact's last name. |
prefix | optional string | The contact's name prefix. |
suffix | optional string | The contact's name suffix. |
nickname | optional string | The contact's nickname. |
records | list of contact.record items | Contact records associated with the contact. |
organisation | optional string | The contact's organisation name. |
department | optional string | The contact's department within the organisation. |
jobtitle | optional string | The contact's job title within the organisation. |
birthday | optional date | The contact's birthday. |
contact.record attribute
There are 5 types of contact record items: Phone, Email, URL, Social, and Address. They correspond to a phone number, email address, website URL, social media account handle, and street address, respectively.
The first 4 have the same attributes:
| name | type | description |
|---|---|---|
type | string | One of: Phone, Email, URL, Social. |
name | optional string | The label associated with the record. |
value | string | The value of the record. |
The Address contact record type has additional address fields:
| name | type | description |
|---|---|---|
type | string, always Address | A phone number record. |
name | optional string | The label associated with the number. |
CountryCode | optional string | A country code. |
Country | optional string | A country name. |
ZIP | optional string | A zip or postal code. |
State | optional string | A state name or abbreviation. |
City | optional string | A city name. |
Municipality | optional string | A municipality name. |
SubLocality | optional string | A neighbourhood or area name. |
Street | optional string | A street address name. |
Sample data
{
"id": "2cf6a837304d6614",
"data_type": "contact",
"first_name": "John",
"middle_name": "'Gala'",
"last_name": "Appleseed",
"prefix": "Mr.",
"suffix": "Jr.",
"nickname": "John'o",
"records": [
{
"type": "Phone",
"name": "MAIN",
"value": "1-800-MY-APPLE"
},
{
"type": "Phone",
"name": "UK",
"value": "0800 039 1010"
},
{
"type": "URL",
"name": "HOMEPAGE",
"value": "http://www.apple.com"
},
{
"type": "URL",
"name": "HOMEPAGE",
"value": "http://www.apple.com/uk/"
},
{
"City": "Cupertino",
"State": "CA",
"ZIP": "95014",
"name": "WORK",
"CountryCode": "US",
"Country": "United States",
"Street": "1 Infinite Loop",
"type": "Address",
"SubLocality": null,
"Municipality": null
}
],
"organisation": "Apple Inc.",
"department": "Marketing",
"jobtitle": "VP Juicing",
"birthday": "1976-04-01"
}
Call
call attributes
| name | type | description |
|---|---|---|
id | string | Item ID. |
data_type | string, always call | Item data type ID. |
call_type | string | One of: Phone, FaceTime Video, FaceTime Audio. |
address | string | The second party of the call. Could be a phone number, Apple ID, or other identifier. For group calls, it will relate to the handle that started the call. |
participants | optional list of participant objects | For group calls, a list of all call participants. |
duration | float | The duration of the call. |
answered | bool | Whether the call was answered. |
from_me | bool | Whether the call was outgoing or incoming. |
video | bool | Whether the call was a video call or not. |
date | datetime | When the call was made. |
line_id | optional string | The identifier of the SIM line the call went over. Currently present on iOS Phone calls from iOS 14. Use with the lines filter. |
line | optional string | The phone number of that line, where the device has it. |
line_label | optional string | The name the user gave the line, such as Work, if any. |
call.participant attributes
| name | type | description |
|---|---|---|
handle | string | The handle associated with the participant, e.g. phone number, WhatsApp ID, Apple ID, etc. |
name | optional string | The name related to the handle. |
number | optional string | The phone number related to the handle. |
answered | bool | Whether or not the participant answered the call. |
Sample data
{
"id": "24116c5b16b85217",
"data_type": "call",
"call_type": "Phone",
"address": "07123456789",
"participants": [{
"handle": "01234567890",
"number": "01234567890",
"answered": true
}, {
"handle": "09876543210",
"number": "09876543210",
"answered": false
}],
"duration": 5.131359,
"answered": true,
"from_me": true,
"video": false,
"date": "2015-07-20 10:23:27.538011"
}
Event
event attributes
| name | type | description |
|---|---|---|
id | string | Item ID. |
data_type | string, always event | Item data type ID. |
unique_identifier | optional string | Item UID for deduplicating across multiple event data sources. |
calendar | optional string | Calendar name. |
calendar_uid | optional string | Calendar UID. |
calendar_store | optional string | Calendar store type, i.e. iCloud, Default. |
summary | optional string | The event summary or title. |
description | optional string | The event description. |
start_date | optional datetime | When the event begins. |
end_date | optional datetime | When the event finishes. |
start_time_zone | optional string | The timezone of start_date. |
end_time_zone | optional string | The timeone of end_date. |
all_day | boolean | Whether the event lasts an entire day. |
travel_time | optional duration | The event's travel time duration. |
recurrence | optional nested event.recurrence | The event's recurrence settings. |
location | optional string | Where the event is taking place. |
start_location | optional string | Where the event is starting from. |
attendees | optional list of strings | Names of event attendees. |
attached_url | optional string | A URL associated with the event. |
creation_date | optional datetime | When the event was created. Not set if default calendar entry, such as public holidays. |
event.recurrence attributes
| name | type | description |
|---|---|---|
interval | integer | The count of repeat to recurr at, i.e. 1 Yearly (once every 1 year). |
repeat | string | One of: OneTime, Daily, Weekly, Monthly, Yearly. |
repeat_end_date | optional datetime | When to stop recurring. |
Sample data
{
"id": "3",
"unique_identifier": "f5fcf872-34f6-3f60-ba03-74d5a7a3bbbb",
"calendar": "Home",
"calendar_id": "477a2001537fe178d6b77cdceb8bac2e",
"calendar_store": "Default",
"summary": "Christmas Day",
"description": "Bank holiday in the UK",
"start_date": "2017-12-25T00:00:00.000000",
"end_date": "2017-12-25T23:59:59.000000",
"start_time_zone": None,
"end_time_zone": None,
"all_day": True,
"travel_time": None,
"recurrence": {
"interval": 1,
"repeat": "Yearly",
"repeat_end_date": None,
"specifier": ""
},
"location": None,
"start_location": None,
"attendees": ["John Appleseed"],
"attached_url": None,
"creation_date": None
}
Note
{
"title": "Monday meeting:",
"note": "Monday meeting:\n Discuss X,\n discuss Y.",
"summary": null,
"folder": "icloud",
"sub_folder": "work",
"attachments": [
{
"type": "image",
"file_id": "8e22cf6e524357b4eb3da775d193072ebba9543f",
"file_path": "Media/80DDDEAD-B33F-37B2-7219432C0359/Image.jpeg"
}
],
"creation_date": "2016-06-06 13:23:20.000000",
"last_modified": "2016-06-07 15:21:25.000000"
}
Visit
A record of a website page visit.
Attributes
| name | type | description |
|---|---|---|
data_type | string, always visit | Item data type ID. |
url | string | The URL of the page visited. |
title | string | The visited page's title. |
date_created | datetime | When the visit occurred. |
{
"data_type": "visit",
"url": "https://reincubate.com/",
"title": "Reincubate: the app data company",
"date_created": "2020-01-01T00:00:00.000000Z"
}
Cookie
A HTTP cookie.
Attributes
| name | type | description |
|---|---|---|
data_type | string, always cookie | Item data type ID. |
name | string | The cookie's name. |
value | string | The cookie's value. |
domain | string | The cookie's domain specifier. |
path | string | The cookie's path specifier. |
flags | string | Any flags set on the cookie. |
creation_date | datetime | When the cookie was created. |
expiry_date | datetime | When the cookie expires. |
{
"data_type": "cookie",
"name": "sample_cookies",
"value": "sample_value",
"domain": "reincubate.com",
"path": "/",
"flags": "",
"creation_date": "2020-01-01T00:00:00.000000Z",
"expiry_date": "2020-01-01T00:00:00.000000Z"
}
Location
Data attributes
| name | type | description |
|---|---|---|
data_type | string, always location | A data type identifier. |
latitude | float | The location's latitude coordinate. |
longitude | float | The location's longitude coordinate. |
altitude | float | The location's altitude coordinate. |
horizontal_accuracy | float | The horizontal accuracy for the measurement. |
vertical_accuracy | float | The vertical accuracy for the measurement. |
position_type | string | Identifier for the measurement method used. |
date_created | datetime | When the measurement was made. |
Sample data
{
"data_type": "location",
"latitude": 51.507452392689146,
"longitude": -0.07398372304584414,
"altitude": 0.0,
"horizontal_accuracy": 65.0,
"vertical_accuracy": 0.0,
"positioning_type": "Wifi",
"date_created": "2020-01-01T00:00:00.000000Z"
}
Voicemail
Represents a voicemail message from the device.
Attributes
| name | type | description |
|---|---|---|
rowid | int | The unique identifier for the voicemail within its database. |
filename | string | The name of the audio file containing the voicemail. |
file_id | string | Identifier used to request the audio file from the API. |
file_path | string | The path of the voicemail file relative to the backup. |
date | string | The date and time the voicemail was received (ISO 8601 format). |
token | string | Status token for the voicemail (e.g., "Complete"). |
sender | string | The phone number of the caller who left the voicemail. |
callback_num | string | The callback number associated with the voicemail. |
duration | int | The duration of the voicemail in seconds. |
expiration | string, optional | The expiration date of the voicemail (ISO 8601 format). |
trashed_date | string or int | The date the voicemail was moved to trash, or 0 if not trashed. |
flags | int | System flags associated with the voicemail. |
sim_slot | string, optional | The SIM slot identifier for multi-SIM devices (e.g., "A-98ACC814-BDB0-51F8-A098-CB63A6A60E9F"). null for single-SIM devices or the default SIM slot. |
transcript | string, optional | The text transcript of the voicemail, if available. Transcripts are generated by iOS for visual voicemail. |
Example
{
"rowid": 50,
"filename": "50.amr",
"file_id": "4ff0327d0148e7fa175a12f5a25ed7148a29de6d",
"file_path": "Library/Voicemail/50.amr",
"date": "2024-01-15 14:30:00.000000",
"token": "Complete",
"sender": "+123456789",
"callback_num": "+123456789",
"duration": 45,
"expiration": "2024-02-14 14:30:00.000000",
"trashed_date": 0,
"flags": 3,
"sim_slot": null,
"transcript": "Hi, this is John. Please give me a call back when you get a chance. Thanks, bye."
}
Example (Multi-SIM device)
{
"rowid": 28,
"filename": "28.amr",
"file_id": "a1b2c3d4e5f6...",
"file_path": "Library/Voicemail/A-98ACC814-BDB0-51F8-A098-CB63A6A60E9F/28.amr",
"date": "2024-01-15 14:30:00.000000",
"token": "Complete",
"sender": "+123456789",
"callback_num": "+123456789",
"duration": 30,
"expiration": "2024-02-14 14:30:00.000000",
"trashed_date": 0,
"flags": 3,
"sim_slot": "A-98ACC814-BDB0-51F8-A098-CB63A6A60E9F"
}
