Skip to main content

Apple DeviceCheck API. Reduce fraudulent use of your services by managing device state and asserting app integrity.

Project description

Apple DeviceCheck

Accessing and Modifying Per-Device Data

Use a token from your app to validate requests, query and modify two per-device binary digits stored on Apple servers.


  • Prevent API & Content abuse with validating requests via Apple device token
  • Query and modify two bits of data to achieve up to four remote states saved on Apple servers
  • Easy to use configuration
  • Examples
  • Integrations with modern web frameworks


Visit and create new Key with DeviceCheck permission


pip install devicecheck

Usage (Python)


from devicecheck import DeviceCheck

device_check = DeviceCheck(
    team_id="XX7AN23E0Z",  #
    key_id="JSAD983ENA",  # Generated at
    # Generated file at
    dev_environment=True,  # True if using development Apple environment, False if using in production.
    # Remember to set dev_environment=False in production!

Validate device

result = device_check.validate_device_token(device_token)

if result.is_ok:
    print('OK! Device is valid')
    print('Bad news. Unable to validate device')

Update bits data

# Can use both integers, strings and booleans. Will be converted with bool(value)
result = device_check.update_two_bits(device_token, bit_0=1, bit_1=False)

# Can update bits separately
result = device_check.update_two_bits(device_token, bit_0=True)

if result.is_ok:
    print('Bits updated')
    print(f'Something went wrong. {result}')

Query bits data

# Can use both integers, strings and booleans
result = device_check.query_two_bits(device_token)

if result.is_ok:
    print(f'First bit {result.bit_0}')  # True
    print(f'Second bit {result.bit_1}')  # False
    print(f'Last update time {result.bits_last_update_time}')  # 2020-04
    print(f'Something went wrong. {result}')

Web server decorators

You can easily integrate devicecheck to your webserver using a decorator. Specify a supported framework, or leave None to try universal parser.

from devicecheck.decorators import validate_device  # for sync code
from devicecheck.decorators import DCSupportedFrameworks
from devicecheck import DeviceCheck

device_check = DeviceCheck(...)

# Set response that will be returned on invalid token
INVALID_TOKEN_RESPONSE = ('Invalid device_token', 403)

@validate_device(device_check, framework=DCSupportedFrameworks.flask, on_invalid_token=INVALID_TOKEN_RESPONSE)
def endpoint():
    return 'Content'

Sync code

Use sync decorator

from devicecheck.decorators import validate_device
from devicecheck.decorators import DCSupportedFrameworks


INVALID_TOKEN_RESPONSE = ('Invalid device_token', 403)
framework = DCSupportedFrameworks.flask

Async code

Use Async decorator

from devicecheck.decorators import async_validate_device
from devicecheck.decorators import DCSupportedAsyncFrameworks


from sanic.response import text

INVALID_TOKEN_RESPONSE = text('Invalid device_token', status=403)
framework = DCSupportedAsyncFrameworks.sanic


from fastapi.responses import PlainTextResponse

INVALID_TOKEN_RESPONSE = PlainTextResponse('Invalid device_token', status_code=403)
framework = DCSupportedAsyncFrameworks.fastapi

Tests & Mock

Well, it's kinda hard to automate testing, because Devicecheck requires real device (Simulators won't work). In case you need to disable decorators, pass SKIP_DEVICE_CHECK_DECORATOR=True environment variable.

You can also mock validation, pass MOCK_DEVICE_CHECK_DECORATOR_TOKEN=XXXXXXXXXXXXX, it will be a hardcoded valid token value.

MOCK_DEVICE_CHECK_DECORATOR_TOKEN="device-check-token" python -m unittest tests/integrational/

For Debug logs, including requests body, pass a DEBUG environment variable.


Library represents an AppleException class with attributes status_code and description Requires raise_on_error=True parameter for DeviceCheck instance.

Usage (Swift)

Generate device token

import DeviceCheck

public func getDeviceToken(completion: @escaping (String?) -> ()) {
    if #available(iOS 11.0, *) {
        let currentDevice = DCDevice.current
        if currentDevice.isSupported
            currentDevice.generateToken(completionHandler: { (data, error) in
                if let tokenData = data {
                    let tokenString = tokenData.base64EncodedString()
                    print("Received device token")
                } else{
                    print("Error generating token: \(error!.localizedDescription)")
        } else {
            print("Device is not supported") // Simulators or etc.
    } else {
        print("Device OS is lower than iOS 11")

Pass device token in HTTP request

Header or Body

getDeviceToken { deviceToken in
    var request = URLRequest(url: "...")
    request.httpMethod = "POST"
    // Header
    request.setValue(deviceToken, forHTTPHeaderField: "Device-Token")
    // Body
    request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
    let json = ["device_token": deviceToken] as [String : Any]
    let jsonData = try! json)
    request.httpBody = jsonData as Data
    // Send it to server
    let downloadTask = URLSession.shared.dataTask(with: request, completionHandler: { data, response, error in



Project details

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

devicecheck-1.2.2.tar.gz (9.8 kB view hashes)

Uploaded source

Built Distribution

devicecheck-1.2.2-py3-none-any.whl (10.8 kB view hashes)

Uploaded py3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page