Using the Graph API with Account Kit

You can use the Account Kit Graph API to retrieve, verify and invalidate user access tokens, access basic account information, and delete accounts.

Access Tokens

Calls to these APIs use an Access Token for temporary, secure access to Account Kit APIs. The security model is the same as Facebook Access Tokens. There are two types of access tokens to be aware of for Account Kit, user access tokens and app access tokens.

User Access Tokens

User Access Tokens are obtained through the SDKs after a successful login. For the Android and iOS SDK, the access token also can be retrieved by calling the getCurrentAccessToken method while the session is still active.

You can use this token to validate the identity of a user when making server API calls. By using the validation method here on your API server, you can be sure of the identity of the user of your server APIs.

App Access Tokens

App Access Tokens allow you to make server calls on behalf of your application. These are useful for account management operations that a user may not have access to, such as reading a list of all users, and for protecting the initial login request.

App access tokens are the concatenation of your app ID and your Account Kit app secret. They take the form


You should not store your app secret on a mobile device, so these are reserved for server to server calls.

If you need to make server calls from a device, you should use the Account Kit client secret instead. App access tokens for calls originating from a device therefore take the form AA|<facebook_app_id>|<client_token>.

You can find both the app secret and the client token in the app dashboard for your app, under the Account Kit tab.

App Secret Proof

If you have enabled the Require App Secret setting in your app's dashboards, most calls that accept an account access token as a parameter will now require an additional appsecret_proof parameter to verify that these calls are coming from your own servers.

The app secret proof is a sha256 hash of your access token, using the app secret as the key. Here's what the call looks like in PHP:

$appsecret_proof = hash_hmac('sha256', $access_token, $app_secret); 

You add the result as an appsecret_proof parameter to each call you make. An example using curl:

curl \
  -F 'access_token=<access_token>' \
  -F 'appsecret_proof=<app secret proof>' \

Retrieving User Access Tokens with an Authorization Code

If your app is using the authorization code flow, your client application will not receive the User Access Token directly, but will instead receive an Authorization Code. This code is meant to be passed to your server, which will exchange it for a User Access Token. After the token is retrieved, it will continue to reside on the server and may be used to authenticate server-to-server calls.

The exchange of an Authorization Code for a User Access Token is done with an Account Kit API call.


The final argument of the URL query string is the App Access Token described above.

If the code is valid and not expired, the Account Kit API will respond with a User Access Token.

  "id" : <account_kit_user_id>,
  "access_token" : <user_access_token>,
  "token_refresh_interval_sec" : <refresh_interval>

Access Token Validation

When your app makes API calls to your server, validate the user's identity by verifying their access token. The User Access Token is available from each SDK while a user is logged in. Validate a User Access Token by accessing the Account Kit API on the Account ID edge and passing the User Access Token as a parameter.


Return type:

This returns the Account ID associated with this User Access Token if it's valid. Invalid access tokens will return an error. This response also includes the current associated login info, such as email or phone number, and it includes your app's ID. Check the returned ID against your app's ID to make sure the access token is valid for your app.

Account Kit Account IDs are guaranteed not to collide with Facebook User IDs.

   id: "1234512345123451",
   phone: {
     number: "+15551234567"
     country_prefix: "1",
     national_number: "5551234567"
   application: {
     id: "5432154321543210"

Logging Out of a Session

You can log specific sessions out, or you can log out all sessions for an account. To log an individual session out, call the following endpoint with the user access token. This call invalidates the specific user access token.


To log out all sessions for your account ID, call the following endpoint with the account ID and app secret. This call invalidates all user access tokens for that account.


Account Removal

You can delete an account from the database stored on Account Kit servers with a call to the DELETE endpoint.



Property Name Description Type


The App Access Token, required for server to server calls


Return type:

  "success": true

If the operation is unsuccessful, an error will be returned indicating the reason for the failure.

Removing Account Kit From Your App and Retrieving Your User Data

You can remove Account Kit from your app by way of the App Dashboard.

To remove Account Kit:

  1. Go to the App Dashboard and select your app.
  2. In the left-hand menu, select Account Kit.
  3. Click the Remove Account Kit button at the bottom left.
  4. In the Are You Sure? dialog, click Yes, Remove Account Kit.
  5. Enter your password, and click Submit.

For 30 days after you remove Account Kit, the Account Kit page for your app displays a button that let's you undo the removal.

Retrieving Your User Data

If you want to retrieve the Account Kit user data for your app, you need to call the Graph API endpoint with your Facebook app ID, Account Kit app secret, and the number of users you want per page of data.

You can still retrieve your user data by calling the provided endpoint within 30 days after you have removed Account Kit.

To activate the endpoint for retrieving Account Kit user data:

  1. Go to the Account Kit page for your app in the App Dashboard.
  2. Click the Request Account Kit Data button at the bottom of the page.
  3. Make a note of your Account Kit app secret. You will need it to retrieve your user data from the endpoint.

You retrieve your user data by calling the provided endpoint within 30 days of removing Account Kit.

Parameter Description


The Facebook app ID of your app


Your Account Kit – specific app secret


The number of users per page for whom data is returned. The range is 1–1000.

The data for each user is returned in the following format.

   "data": [
       "id": "<user ID>",
       "phone": {
                "number": "+<phone number>",
                "country_prefix": "<country_dialing_prefix>",
                "national_number": "<region_dialing_code>"
   "paging": {
             "cursors": {
                        "before": "<cursor_to_previous_page>",
                         "after": "<cursor_to_following_page>"
             "previous": "<URL_for_retrieving_the_previous_page>"
             "next": "<URL_for_retrieving_the_next_page>"

The previous URL doesn't appear on the first page of data, and the next URL doesn't appear on the last page.

You can also use the following script to retrieve your data and output it as a comma-separated list. Copy the script to a Python file and call it from the command line. The script prompts you for the following parameters:

  • Your app ID
  • You Account Kit app secret
  • The number of users per page of returned data
  • The file to which to write the data
  • The Account Kit API version number

To get help for the script, enter -h.

import ssl
import json
import urllib2

output_file_name = 'accountkit_export.csv'
url_fmt = '{version}/{app_id}/accounts/?access_token=AA|{app_id}|{app_secret}&limit={limit}'
header_string = 'ID, Phone, Email'
E_FAILED = 'failed'
E_RETRY = 'retry'

import argparse
def parse_args(parser):
    parser.add_argument('-a', '--appid', type=int, help='Your facebook application id', required=True)
    parser.add_argument('-s', '--appsecret', help='Your application secret', required=True)
    parser.add_argument('-l', '--limit', type=int, default=1000, help='Number of items per the page. Range 1 to 1000')
    parser.add_argument('-f', '--file', default=output_file_name, help='Name of the output file')
    parser.add_argument('-v', '--version', default='v1.3', help='Api version')
    return parser.parse_args()

import re
def verify_params(params):
    error_msg = ''
    if (params.limit < 1 or params.limit > 1000):
        error_msg = 'limit should be in the range 1-1000'
    elif (re.match(r'^v\d+\.\d+$', params.version) == None):
        error_msg = 'double check your api version number'
    return error_msg

def get_url_config(params):

    config = {
        'version':    params.version,
        'app_id':     params.appid,
        'app_secret': params.appsecret,
        'limit':      params.limit
    return config

def get_json_attrs(jdata, *names):
    if (not jdata):
        raise Exception('empty json data')

    val = jdata
    for name in names:
            val = val[name]
            if (not val):
                return None
            return None
    return val

def get_request_data_in_csv_format(url):
        response = urllib2.urlopen(url, context=get_request_data_in_csv_format.gcontext)
    except urllib2.HTTPError as e:
        print 'HTTPError = ' + str(e.code)
        raise Exception(E_RETRY)
    except urllib2.URLError as e:
        print 'URLError = ' + str(e.reason)
        raise Exception(E_FAILED)
    except Exception as e:
        print e
        raise Exception(E_FAILED)

        json_resp = json.loads(
    except Exception as e:
        print e
        raise Exception(E_FAILED)

        next_url = get_json_attrs(json_resp, 'paging', 'next')
    except Exception as e:
        print e
        raise Exception(E_FAILED)

    data = json_resp['data']
    result = ''
    for ditem in data:
            acc_id = get_json_attrs(ditem, 'id')
            ph_num = get_json_attrs(ditem, 'phone', 'number');
            email = get_json_attrs(ditem, 'email', 'address');
            result = result + '{},{},{}\n'.format(acc_id, ph_num, email)
        except Exception as e:
            print e
            raise Exception(E_FAILED)

    return {
        'next_url': next_url,
        'csv_data': result

def export_to_file(file, url):
    file.write(header_string + '\n')

    current_url = url
    retry = 0
    while current_url != None:
            print 'Quering url ' + current_url
            data = get_request_data_in_csv_format(current_url)

        except Exception as e:
            if (e[0] == E_RETRY and retry < 3):
                retry = retry + 1
                print 'retrying: ' + retry + ' with url ' + current_url
                raise Exception('abort')
            retry = 0
            current_url = data['next_url']

def main():
    parser = argparse.ArgumentParser()
    params = parse_args(parser)
    error_msg = verify_params(params)
    if (error_msg != ''):
        print 'ERROR:' + error_msg

    get_request_data_in_csv_format.gcontext = ssl.create_default_context()

    config = get_url_config(params)
    url = url_fmt.format(**config)
        file = open(params.file, 'w')
        print 'File opened for Write: ' + params.file
            export_to_file(file, url)
            print 'Could not export to a file'
        print 'Could not open file'
        print 'File closed'

if __name__ == "__main__":