You can use the Account Kit Graph API to retrieve, verify and invalidate user access tokens, access basic account information, and delete accounts.
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 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 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
AA|<facebook_app_id>|<app_secret>
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.
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>' \ https://graph.accountkit.com/v1.3/me
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.
GET https://graph.accountkit.com/v1.3/access_token?grant_type=authorization_code&code=<authorization_code>&access_token=AA|<facebook_app_id>|<app_secret>
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> }
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.
GET https://graph.accountkit.com/v1.3/me/?access_token=<access_token>
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" } }
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.
POST https://graph.accountkit.com/v1.3/logout?access_token={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.
POST https://graph.accountkit.com/v1.3/{account_id}/invalidate_all_tokens?access_token=AA|<facebook_app_id>|<app_secret>
You can delete an account from the database stored on Account Kit servers with a call to the DELETE
endpoint.
DELETE https://graph.accountkit.com/v1.3/<account_id>?access_token=AA|<facebook_app_id>|<app_secret>
Fields:
Property Name | Description | Type |
---|---|---|
access_token | The App Access Token, required for server to server calls | String |
Return type:
{ "success": true }
If the operation is unsuccessful, an error will be returned indicating the reason for the failure.
You can remove Account Kit from your app by way of the App Dashboard.
To remove Account Kit:
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.
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:
You retrieve your user data by calling the provided endpoint within 30 days of removing Account Kit.
GET https://graph.accountkit.com/v1.3/<app_id>/accounts/?&access_token=AA|<app_id>|<account_Kit_app_secret>&limit=<items_per_page>
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:
To get help for the script, enter -h
.
import ssl import json import urllib2 output_file_name = 'accountkit_export.csv' url_fmt = 'https://graph.accountkit.com/{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: try: val = val[name] if (not val): return None except: return None return val def get_request_data_in_csv_format(url): try: response = urllib2.urlopen(url, context=get_request_data_in_csv_format.gcontext) except urllib2.HTTPError as e: print 'HTTPError = ' + str(e.code) print e.read() 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) try: json_resp = json.loads(response.read()) except Exception as e: print e raise Exception(E_FAILED) try: 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: try: 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: try: 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 else: raise Exception('abort') else: file.write(data['csv_data']) 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 parser.print_help() return get_request_data_in_csv_format.gcontext = ssl.create_default_context() config = get_url_config(params) url = url_fmt.format(**config) try: file = open(params.file, 'w') print 'File opened for Write: ' + params.file try: export_to_file(file, url) except: print 'Could not export to a file' except: print 'Could not open file' else: print 'File closed' file.close(); if __name__ == "__main__": main()