👑 Subscribing for data with asmaster

Overview

asmaster is used to subscribe to data pertaining to accounts and devices stored on the cloud. By subscribing to accounts or devices, clients will automatically be pushed new data once it becomes available, via aschannel.

Important

The ricloud overview goes into detail on whether a client should be using asmaster or asapi. It is important to choose the right service for one’s use-case.

A typical request flow with asmaster could be:

  • Confirm that the required services are available with list-services
  • Confirm that a potential new user’s account isn’t already subscribed with list-subscriptions
  • Subscribe to an account using subscribe-account
  • Complete any 2FA steps with perform-2fa-challenge and submit-2fa-challenge
  • If device data is important, call list-devices to retrieve the devices associated
  • Subscribe to a device using subscribe-device
  • If aschannel reports that the account’s token has expired or is near expiry, direct the user to resubscribe-account
  • If the user wishes to cease monitoring of their device or account, call unsubscribe-device or unsubscribe-account

Throughout this request flow the client should maintain a process consuming data from aschannel.

Note

The sample client implementations handle much of asmaster‘s functionality without the developer needing to get involved. The examples below are shown for developers who wish to dig into the fundamentals of the API, or to build their own clients.

Service management and reporting

list-services

The list-services method returns information on the services available for the given authentication token.

Request

$ curl \
    -X POST \
    -H 'Authorization: Token <TOKEN>' \
    https://asmaster.reincubate.com/list-services/ -D -

Parameters:

  • None

Response

  • HTTP 200 A JSON dictionary containing available service information
{ "services": [{
    "name": "iCloud",
    "actions": [{
      "description": "",
      "parameters": [{
        "type": "string",
        "description": "",
        "optional": false,
        "name": "Device",
        "slug": "device"
      }, {
        "type": "date",
        "description": "",
        "optional": true,
        "name": "Since",
        "slug": "since"
      }],
      "name": "Fetch Data",
      "execution": "Asynchronous",
      "slug": "fetch-data",
      "permissions": {
        "data": ["sms"]
      }
    }],
    "slug": "icloud"
  }],
  "stream_endpoints": [{
    "host": "aschannel.reincubate.com",
    "protocol": "https",
    "uri": "/stream/"
  }]
}

Note

Unlike when performing service discovery with asapi, no task_submission_endpoint is provided, as asmaster clients receive results from automatically scheduled tasks but do not submit new ones. Consequently, understanding available tasks is interesting here only from a perspective of establishing what task results could be send down aschannel to the client.

list-subscriptions

The list-subscriptions method provides a client with a list of all subscribed accounts and devices, along with their statuses.

Request

$ curl \
    -X POST \
    -H 'Authorization: Token <TOKEN>' \
    -d "service=<SERVICE>" \
    https://asmaster.reincubate.com/list-subscriptions/ -D -

Here’s that same call in wget format, for reference:

$ wget \
    --header 'Authorization: Token <TOKEN>' \
    --post-data="service=<SERVICE>" \
    https://asmaster.reincubate.com/list-subscriptions/ -qO -

Parameters:

service:A service identifier, such as icloud

Response

  • HTTP 200 A JSON dictionary containing account and device subscription information
{
  "accounts": [
    {
      "status": "ok",
      "service": "icloud",
      "account_id": 133733,
      "devices": [
        {
          "status": "ok",
          "device_id": 2
        },
        {
          "status": "ok",
          "device_id": 3
        },
        {
          "status": "ok",
          "device_id": 4
        }
      ]
    }
  ]
}

Note

The API avoids storing excess metadata on accounts or devices, and consequently this method does not return any. Clients should store this when it is provided earlier in the subscription process.

Account subscription and unsubscription

The second part of working with asmaster is account subscription. An account can be subscribed to with the subscribe-account method. When this is called, asmaster creates and stores an internal authentication token, so that it can continue to access the account in future without the account’s primary credentials. Depending on the service being used, token life can vary from days to months, and aschannel will inform clients on and – depending on the service – near its expiry. Once expired, the resubscribe-account method must be used to renew the subscription.

When subscribe-account is called, it will return a list of all available devices if authentication is successful. However, the list-devices method exists to perform this function for accounts that are already subscribed.

Note

An account represents an end-user’s app account. This could represent an iCloud, Google or other account. Some app data is stored per account, rather than per device. This varies according to the app container, and the nature of the data stored. Often, live information is stored against an account, whereas more comprehensive backup information is stored against a device.

Accounts can be unsubscribed from with the unsubscribe-account method.

Note

When being used against the icloud service, the authentication methods and process is similar to that described under Apple iCloud Service: authentication.

subscribe-account

Request

$ curl \
    -X POST \
    -H 'Authorization: Token <TOKEN>' \
    -d "service=<SERVICE>" \
    -d "username=<ACCOUNT>" \
    -d "password=<PASSWORD>" \
    https://asmaster.reincubate.com/subscribe-account/ -D -

Parameters:

  • The service to interact with: like icloud
  • The account to subscribe to: like john.appleseed@reincubate.com
  • The password for the account: like joshua

Response

The call will return in one of a number of ways:

  • 201: Account registered Returns an account_id
{ "account_id": 1010
}
  • 429: Too many requests Indicates that too many requests have been made to subscribe to an account within the safety window. The API does this to prevent repeated login attempts to accounts.
{ "message": "Too many subscriptions for the same account in the safety window.",
  "account_id": 1010,
  "success": false,
  "error": "asmaster-account-too-many-subscriptions"}
  • 409: MFA process required Signals need for client to call perform-2fa-challenge. Returns list of trusted devices, and a temporary account_id
{ "message": "This account has Two Step Verification enabled, please select a device to challenge.",
  "data": {
    "trustedDevices": ["********12", "Renate's iPhone - iPhone 6s"],
  },
  "error": "2fa-required",
  "account_id": 1010
}
  • 400: Account already active Indicates that the account is already subscribed.
{ "message": "You are already subscribed to receive content for this account.",
  "account_id": 1010,
  "success": false,
  "error": "asmaster-account-already-active"}

perform-2fa-challenge

Request

$ curl \
    -X POST \
    -H 'Authorization: Token <TOKEN>' \
    -d "account_id=<TEMP-ACCOUNT-ID>" \
    -d "device_id=<DEVICE-ID>" \
    https://asmaster.reincubate.com/perform-2fa-challenge/ -D -

Parameters:

  • account_id
  • device_id

submit-2fa-challenge

Request

$ curl \
    -X POST \
    -H 'Authorization: Token <TOKEN>' \
    -d "account_id=<TEMP-ACCOUNT-ID>" \
    -d "code=<CODE>" \
    https://asmaster.reincubate.com/submit-2fa-challenge/ -D -

Parameters:

  • account_id
  • code

Response

{ "account_id": "1010"
}

resubscribe-account

Request

$ curl \
    -X POST \
    -H 'Authorization: Token <TOKEN>' \
    -d "account_id=<ACCOUNT-ID>" \
    -d "password=<PASSWORD>" \
    https://asmaster.reincubate.com/resubscribe-account/ -D -

Parameters:

  • account_id
  • password

Response

Response:

  • 200 Account refreshed
  • 400 Bad account_id
  • 409 MFA process required – similar to subscribe-account
  • 403 Other error as per service sign in errors.

unsubscribe-account

Unsubscribing an account will automatically unsubscribe any subscribed devices which belong to it.

Request

$ curl \
    -X POST \
    -H 'Authorization: Token <TOKEN>' \
    -d "account_id=<ACCOUNT-ID>" \
    https://asmaster.reincubate.com/unsubscribe-account/ -D -

Parameters:

  • account_id

Response

Response:

  • 200 Account deregistered
  • 400 Bad account_id
{ "success": true
}

reset-subscription-since

The reset-subscription-since method resets the metadata for an account and all of its devices on when it was last polled. Most feed modules will only return a delta of data since this last poll date. As such, by resetting it, a client can ensure they get older data during the next poll.

For example, if a client wishes to get the last week’s data again, they could use this method on an account, passing it a date 7 days prior.

Request

$ curl \
    -X POST \
    -H 'Authorization: Token <TOKEN>' \
    -d "account_id=<ACCOUNT-ID>" \
    -d "datetime=<DATETIME>" \
    https://asmaster.reincubate.com/reset-subscription-since/ -D -

Parameters:

  • account_id
  • datetime The date and time to reset the feed window to. The date format is as per the API’s standards.

Response

{ "success": true
}

Warning

This method is currently not available in production.

Device subscription and unsubscription

To register or unregister devices, users can use the subscribe-device and unsubscribe-device methods.

list-devices

Request

$ curl \
    -X POST \
    -H 'Authorization: Token <TOKEN>' \
    -d "account_id=<ACCOUNT-ID>" \
    https://asmaster.reincubate.com/list-devices/ -D -

Parameters:

  • account_id

Response

  • 200: Device list and other info
{
  "devices": [
    {
      "ios_version": "10.2",
      "name": "iPhone 7 Plus",
      "colour": "1",
      "device_name": "Johnny's iP7 iOS10 Black",
      "latest-backup": "2017-01-31 22:06:06.000000",
      "model": "D111AP",
      "device_tag": "3d0d7e5fb2ce288813306e4d4636395e047a3d28",
      "serial": "ABC123BBBBBB",
      "device_id": 2
    },
    {
      "ios_version": "10.3.1",
      "name": "iPad Pro",
      "colour": "#e4e7e8",
      "device_name": "Johnny's other iPhone",
      "latest-backup": "2017-04-22 15:39:25.000000",
      "model": "J127AP",
      "device_tag": "b39bac0d347adfaf172527f97c3a5fa3df726a3a",
      "serial": "ABC123BBBBBB",
      "device_id": 3
    },
    {
      "ios_version": "10.3.1",
      "name": "iPhone 7 Plus",
      "colour": "1",
      "device_name": "Johnny's white iPhone",
      "latest-backup": "2017-04-13 21:08:47.000000",
      "model": "D111AP",
      "device_tag": "a49bfab36504be1bf563c1d1813b05efd6076717",
      "serial": "ABC123AAAAAA",
      "device_id": 4
    }
  ],
  "success": true
}
  • 429: Too many requests Indicates that too many requests have been made to list devices within the safety window. The API does this to prevent repeated polling of this mechanism. Clients should locally cache this device list, and only call the method when a change in devices is expected.

subscribe-device

In order to subscribe to a device, the account it belongs to must first be subscribed.

Request

$ curl \
    -X POST \
    -H 'Authorization: Token <TOKEN>' \
    -d "account_id=<ACCOUNT-ID>" \
    -d "device_id=<DEVICE-ID>" \
    https://asmaster.reincubate.com/subscribe-device/ -D -

Parameters:

  • account_id
  • device_id

Response

{ "success": true
}

unsubscribe-device

Request

$ curl \
    -X POST \
    -H 'Authorization: Token <TOKEN>' \
    -d "device_id=<DEVICE-ID>" \
    https://asmaster.reincubate.com/unsubscribe-device/ -D -

Parameters:

  • device_id

Response

{ "success": true
}

Accessing data from account and device subscriptions

Once a subscription has been made to an account or to an account and its devices, the API will automatically establish the most appropriate polling frequency and timing for the account. It will generate tasks (as described in asapi and schedule them as appropriate. Clients of asmaster must subscribe to aschannel to receive the task results as they are generated.

Important

asmaster is designed to provide app data as soon as it is available and in doing so, not to overburden the originating services. Because it does not retain any data centrally, it is not possible to re-transmit any data that a client failed to read. Keeping a listener running on aschannel at all times is critical.

For an example on how to consume data from aschannel, see the Open Source sample library’s listener mode.