Apple iCloud service

Updated
Cover image for: Apple iCloud service

The API supports retrieval of a variety of data and files from Apple's iCloud services.

Sessions

Setting up a session for the iCloud services on the API is as straightforward as a login into an iCloud account. The process can require multiple attempts at creating the session if the account has enabled multi-factor authentication, like 2FA or 2SV.

Creating a session for an account without 2FA/2SV

The session payload to create a session for an account without 2FA/2SV enabled contains the following parameters.

name type description
password string The iCloud account password.

Using cURL

curl https://ricloud-api.reincubate.com/sessions \
  -X POST \
  -H 'Authorization: Token <your key_token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "source": {
    "user": "1",
    "type": "icloud.account",
    "identifier": "<iCloud account username>"
  },
  "payload": {
    "password": "<iCloud account password>"
  }
}'

Response

{
  "id": "<session ID>",
  "resource": "session",
  ...
  "state": "succeeded",
  "error": null,
  ...
}

Creating a session for an account with 2FA

Creating a session for a 2FA enabled account is a two step process:

  1. Attempt to create a session using just the iCloud account password. This will trigger the 2FA process, which sends an authentication code to iOS and macOS devices associated with the account. The session creation attempt will fail with error="code-required".
  2. Use the iCloud account password and the authentication code received in (1) to create a session. If the code is accepted, the session will be successfully created.

Step 1: create session

name type description
password string The iCloud account password.

Using cURL

curl https://ricloud-api.reincubate.com/sessions \
  -X POST \
  -H 'Authorization: Token <your key_token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "source": {
    "user": "1",
    "type": "icloud.account",
    "identifier": "<iCloud account username>"
  },
  "payload": {
    "password": "<iCloud account password>"
  }
}'

Response

If the 2FA process is triggered as expected, the session should fail to be created with the error: code-required.

{
  "id": "<session ID>",
  "resource": "session",
  ...
  "state": "failed",
  "error": "code-required",
  ...
}

Step 2: create session with code

name type description
password string The iCloud account password.
code string The authentication code.

Using cURL

curl https://ricloud-api.reincubate.com/sessions \
  -X POST \
  -H 'Authorization: Token <your key_token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "source": {
    "user": "1",
    "type": "icloud.account",
    "identifier": "<iCloud account username>"
  },
  "payload": {
    "password": "<iCloud account password>",
    "code": "<authentication code>"
  }
}'

Response

{
  "id": "<session ID>",
  "resource": "session",
  ...
  "state": "succeeded",
  "error": null,
  ...
}

Creating a session for an account with 2SV

The process to create a session for a 2SV enabled account has three steps:

  1. Attempt to create a session using the iCloud account password. As 2SV is required, this will fail with error="choice-required" and error_info={"choices": [<2SV enabled devices>]}.
  2. Attempt to create a session again using the iCloud account password and a choice from the error_info["choices"] list. This time, the attempt will trigger the 2SV process which sends an authentication code to the chosen device. The attempt will fail with error="code-required".
  3. Use the iCloud account password and the authentication code received in (2) to create a session. If the code is accepted, the session will be successfully created.

This will trigger the 2SV process, which sends an authentication code to iOS and macOS devices associated with the account. The session creation attempt will fail with error="code-required".

Step 1: create session

name type description
password string The iCloud account password.

Using cURL

curl https://ricloud-api.reincubate.com/sessions \
  -X POST \
  -H 'Authorization: Token <your key_token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "source": {
    "user": "1",
    "type": "icloud.account",
    "identifier": "<iCloud account username>"
  },
  "payload": {
    "password": "<iCloud account password>"
  }
}'

Response

If 2SV is enabled on the account, the session creation attempt will fail with error choice-required.

{
  "id": "<session ID>",
  "resource": "session",
  ...
  "state": "failed",
  "error": "choice-required",
  "error_info": {
    "choices": [
      "********02 - SMS to Phone Number"
    ]
  }
  ...
}

Step 2: create session with choice

name type description
password string The iCloud account password.
choice string The chosen device to send an authentication code to.

Using cURL

curl https://ricloud-api.reincubate.com/sessions \
  -X POST \
  -H 'Authorization: Token <your key_token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "source": {
    "user": "1",
    "type": "icloud.account",
    "identifier": "<iCloud account username>"
  },
  "payload": {
    "password": "<iCloud account password>",
    "choice": "********02 - SMS to Phone Number"
  }
}'

Response

If the 2FA process is triggered as expected, the session should fail to be created with the error: code-required.

{
  "id": "<session ID>",
  "resource": "session",
  ...
  "state": "failed",
  "error": "code-required",
  ...
}

Step 3: create session with code

name type description
password string The iCloud account password.
code string The authentication code.

Using cURL

curl https://ricloud-api.reincubate.com/sessions \
  -X POST \
  -H 'Authorization: Token <your key_token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "source": {
    "user": "1",
    "type": "icloud.account",
    "identifier": "<iCloud account username>"
  },
  "payload": {
    "password": "<iCloud account password>",
    "code": "<authentication code>"
  }
}'

Response

{
  "id": "<session ID>",
  "resource": "session",
  ...
  "state": "succeeded",
  "error": null,
  ...
}

Source types

identifier description
icloud.account primary source Corresponds to an iCloud account.

Polls

The iCloud service supports all the poll payload schema attributes.

Retrieving source info

This poll type retrieves information on the targeted source. The results are published in JSON format.

Using cURL

curl https://ricloud-api.reincubate.com/polls \
  -X POST \
  -H 'Authorization: Token <your key_token>' \
  -H 'Content-Type: application/json' \
  -d '{
  "session": "<session ID>",
  "payload": {
    "info_types": ["*"]
  }
}'

Using *ricloud-py*

import ricloud

# The ID of a session we made earlier.
session_id = "<session ID>"

poll = ricloud.Poll.create(
  session=session_id,
  payload={
    "info_types": ["*"]
  }
)

Retrieving data

This poll type retrieves and processes data from the targeted session. The results are published in JSON format.

See the list of available data types for more information on specific data types.

Using cURL

curl https://ricloud-api.reincubate.com/polls \
  -X POST \
  -H 'Authorization: Token <your key_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "session": "<session ID>",
    "payload": {
        "data_types": ["icpl.photos"]
    }
}'

Using *ricloud-py*

import ricloud

# The ID of a session we made earlier.
session_id = "<session ID>"

poll_payload = {
    "data_types": ["icpl.photos"]
}

poll = ricloud.Poll.create(
  session=session_id,
  payload=poll_payload,
)

Retrieving files

The files poll payload attribute is used to request the retrieval of binary files from the targeted source.

The IDs will typically be retrieved from a previous poll for data types that include direct file references, like iCloud Photo Library, or that include attachments, like message data types.

Using cURL

curl https://ricloud-api.reincubate.com/polls \
  -X POST \
  -H 'Authorization: Token <your key_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "session": "<session ID>",
    "payload": {
        "files": [
            "icpl://ATnrIxddlwbCEjN33NBq8zXQwYgE",
            "icpl://AbfMRXQ55H4WfS5YguuUWxir4hq6"
        ]
    }
}'

Using *ricloud-py*

import ricloud

# The ID of a session we made earlier.
session_id = "<session ID>"

poll_payload = {
    'files': [
        'icpl://ATnrIxddlwbCEjN33NBq8zXQwYgE',
        'icpl://AbfMRXQ55H4WfS5YguuUWxir4hq6',
    ]
}

poll = ricloud.Poll.create(
    session=session_id,
    payload=poll_payload,
)

Data types

iCloud data types

identifier description
icpl.photos Retrieves iCloud Photo Library assets.
mme_contacts.contacts Retrieves iCloud stored iOS Contacts data.
mme_calendar.events Retrieves iCloud stored iOS Calendar data.
mme_notes.notes Retrieves iCloud stored iOS Notes data.
callkit.calls Retrieves CallKit synced iOS Phone data.
cloudkit_safari.history Retrieve iCloud stored Safari browser history data.
fmip.devices Retrieve Find My iPhone device and locations data.

iCloud Photo Library

Photos, videos and other media

Retrieves information on photos, videos and other media stored in iCloud Photo Library (ICPL).

This module requires that iCloud Photo Library is enabled on the user's iCloud account.

Data type ID icpl.photos
Associated setting Settings > [username] > iCloud > Photos > iCloud Photo Library

Data attributes

name type description
id string An identifier for the data item. Useful for deduplicating data across multiple polls.
filename string The name of the file as it is stored in ICPL.
files list of image, video, audio items Files associated with this ICPL asset. The original file, Live Photos, thumbnails will be included in this list.
date_created datetime When the file was originally created. In the case of photos or videos taken on an iOS device, this will be the date when they were taken. In the case of existing assets imported to ICPL, this will be the original import date.
date_uploaded datetime When the file was last uploaded to ICPL. This will correspond to when the file was first retrievable via the ricloud API.

Data filters

name type description
since datetime Only includes items with a date_uploaded later than the provided value.
until datetime Only includes items with a date_uploaded earlier than the provided value.

Sample data

[
  {
    "id": "4d475a7bba2c604",
    "data_type": "icpl.asset",
    "filename": "IMG_0123.PNG",
    "files": [
      {
        "id": "icpl://ATnrIxddlwbCEjN33NBq8zXQwYgE",
        "data_type": "image",
        "extension": "png",
        "size": 119842,
        "width": 750,
        "height": 1334
      },
      {
        "id": "icpl://AcXwu8/wH8s6lfiGBDEZah6KzQjC",
        "data_type": "image",
        "extension": "jpg",
        "size": 210680,
        "width": 750,
        "height": 1334
      },
      {
        "id": "icpl://AbfMRXQ55H4WfS5YguuUWxir4hq6",
        "data_type": "image",
        "extension": "jpg",
        "size": 71032,
        "width": 310,
        "height": 554
      }
    ],
    "date_created": "2020-01-01T00:00:00.000000Z",
    "date_uploaded": "2020-01-01T00:00:00.000000Z"
  }
]

MobileMe Contacts

Contacts

Retrieves iOS Contacts data stored in iCloud.

Data type ID mme_contacts.contacts
Associated setting Settings > [username] > iCloud > Contacts

Data attributes

The mme_contacts.contact data type inherits most attributes from the base contact data type. The table below outlines additional or differing attributes.

name type description
id string An identifier for the data item. Useful for deduplicating data across multiple polls.
data_type string, always mme_contacts.contact The data type of the item.
uid string A unique identifier that can be used to deduplicate across different sources of iOS Contacts data.
image nested image item, optional Profile image for the contact.

Sample data

[
  {
    "id": "2cf6a837304d6614",
    "data_type": "mme_contacts.contact",
    "uid": "NzNlNjkxYjctOTBmYi00MTYxLWI5YzYtZTk0ZDlhZjljMmE5",
    "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 Coring",
    "birthday": "1976-04-01",
    "image": {
      "id": "mme_contact_image://2cf6a837304d6614",
      "data_type": "image",
      "extension": "jpg"
    }
  }
]

MobileMe Calendar events mme_calendar.events

Retrieves iCloud stored iOS Calendar data.

MobileMe Notes notes mme_notes.notes

Retrieves iCloud stored iOS Notes data.

CallKit

Calls from CallKit callkit.calls

Retrieves call logs synced with the CallKit service.

Errors

callkit-uninitialised

Indicates that the CallKit service has not been setup for this account. The iCloud account owner can resolve this error using an iOS device associated with the iCloud account via the following steps: - Make sure the device is connected to Wi-Fi. - Navigate to Settings > [username] > iCloud. - Turn off iCloud Drive, waiting for 30 to 60 seconds for the change to take effect. - Turn on iCloud Drive once the previous change has completed. This should trigger initialisation.

If the error persists after performing this process, please contact support.

callkit-sync-disabled

In this case, the CallKit service has been initialised but the conditions necessary for devices to start syncing call history to the iCloud have not been met. The API will remotely resolve this via the iCloud, but device associated with the iCloud account may not re-evaluate their sync state as this is cached.

The iCloud account owner can trigger a device to re-check call history sync conditions via the following steps:

  • Navigate to Settings > [username] > iCloud.
  • Turn off iCloud Drive, waiting for 30 to 60 seconds for the change to take effect.
  • Turn on iCloud Drive once the previous change has completed. This should trigger initialisation.

Troubleshooting

  • Recent call history is not getting returned in poll results.

This is typically caused by the device not having synced its latest call history records with the iCloud. The CallKit service is an internal iOS service and cannot be turned on or off in the settings or triggered to sync manually. This can make it difficult to debug missing data as it unclear what the device has or has not synced to the iCloud.

This issue is more common for accounts which do not have much data to sync (less than ~3 calls), which can often be the case for testing accounts.

Recommendations:

  • Make sure the device has more than a handful of call history records to sync. Our testing has shown that a device with only a couple of call history records will not trigger the iCloud syncing process.
  • Wait for the device to perform a periodic sync. This can take up to 12 hours depending on how the device is being used, its connectivity state and its charge state.
  • Plug the device into power. The device is more likely to trigger a sync when in this state.

  • Old call history is not getting returned in poll results.

The CallKit service is designed for syncing call history records between devices and not for storing these records indefinitely. Typically, call history records will be retrievable from CallKit for about 3 months, but this may vary between accounts depending on internal cleanup processes in the iCloud.

CloudKit

Browser history from iCloud cloudkit_safari.history

Retrieve Safari browser history data stored in the iCloud sync service.

Find My and Find My iPhone

Device locations

Retrieve Find My device and location data.

Note that this data type may require multiple polls, with the second coming ~10-30 seconds after the first, in order to return complete data. This is due to how Find My operates: the first poll will trigger Find My to request new data from reachable devices but the data will not be available for another 10-30 seconds.

Data type ID fmip.devices
Associated setting Settings > [username] > Find My

Data attributes

name type description
id string An identifier for the data item. Useful for deduplicating data across multiple polls.
data_type string, always fmip.devices The data type of the item.
name string The user set name for the device.
model_name string Apple's marketing name for the device model.
model_identifier string Apple's identifier for the device model.
product_type string The product category of the device.
location optional nested location The last reported location for the device, if one is available.
battery_status string The current battery status of the device.
battery_level float If known, the percentage battery charge remaining.

Sample data

[
  {
    "id": "e7694d7a0d2ab6cf",
    "data_type": "fmip.device",
    "name": "John's iMac",
    "model_name": "iMac with Retina 5K display",
    "model_identifier": "iMac15,1",
    "product_type": "iMac",
    "location": null,
    "battery_status": "Unknown",
    "battery_level": 0.0
  },
  {
    "id": "4d86a6181808d152",
    "data_type": "fmip.device",
    "name": "John's iPhone 11",
    "model_name": "iPhone 11",
    "model_identifier": "iPhone6,2",
    "product_type": "iPhone",
    "location": {
      "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"
    },
    "battery_status": "Unknown",
    "battery_level": 0.0
  }
]

File types

identifier description
icpl A file from iCloud Photo Library.
mme_contact_image An mme_contacts.contacts contact profile image.

How can we help?

Our support team are here to help!

Our office hours are Monday to Friday, 9 AM to 5 PM GMT. The time is currently 12:05 PM GMT.

We aim to reply to all messages within one working day.

Go to support section › Contact the enterprise team ›
Our awesome support team

© 2008 - 2020 Reincubate Ltd. All rights reserved. Registered in England and Wales #5189175, VAT GB151788978. Reincubate and Camo are trademarks. Privacy policy & terms. We recommend 2FA. Built with in London.