---
title: Implementing OAuth for the Apple School Manager and Apple Business API
framework: Apple School Manager and Apple Business APIs
role: article
role_heading: Article
path: apple-school-and-business-manager-api/implementing-oauth-for-the-apple-school-manager-and-apple-business-api
---

# Implementing OAuth for the Apple School Manager and Apple Business API

Manage secure access to Apple School Manager and Apple Business API accounts.

## Overview

Overview The Apple School Manager and Apple Business APIs support OAuth 2. With OAuth 2, apps authenticate with a set of credentials in exchange for an access token to make authenticated requests to the API. A user with the role of Administrator in Apple School Manager or the role of Organization Administrator in Apple Business creates these credentials. For information about creating an app account, see: Create an API account in Apple School Manager Create an API account in Apple Business To make API calls, you attach the access token as a bearer token in the authorization header. This implementation process guides you through the following steps to obtain that access token: Create a client assertion. Request an access token. Create a client assertion A client assertion is a JSON web token (JWT) that an app creates and signs using a private key. The client assertion obtains an access token by calling the authorization server. The example below is a Python script that generates, encodes, and signs a client assertion using an app’s private key. It expects PyJWT to be installed in the executing Python environment. If you decide to create your own JWT using a different programming language and open source library, be sure the library you use supports elliptic curve methods. important: Ensure that you copy the private key into your working directory. import datetime import uuid

import jwt

private_key_file = "private-key.pem" client_id = "BUSINESSAPI.c75c0a8a-a026-4dae-99aa-89ea1e1103e5" team_id = "BUSINESSAPI.c75c0a8a-a026-4dae-99aa-89ea1e1103e5" key_id = "e339d085-a821-438a-a527-d044edacf50a" audience = "https://account.apple.com/auth/oauth2/v2/token" alg = "ES256"

# Define the issue timestamp. issued_at_timestamp = int(datetime.datetime.utcnow().timestamp()) # Define the expiration timestamp, which may not exceed 180 days from the issue timestamp. expiration_timestamp = issued_at_timestamp + 86400*180

# Define the JWT headers. headers = {     "alg": alg,     "kid": key_id, }

# Define the JWT payload. payload = {     "aud": audience,     "exp": expiration_timestamp,     "iat": issued_at_timestamp,     "sub": client_id,     "jti": str(uuid.uuid4()),     "iss": team_id, }

# Open the private key. with open(private_key_file, 'rb') as file:     private_key_bytes = file.read()

# Encode the JWT and sign it with the private key. client_assertion = jwt.encode(     payload,     private_key_bytes,     headers=headers, )

# Save the client assertion to a file. with open('client_assertion.txt', 'wt') as output:     output.write(client_assertion) A client assertion header describes the type of the token and the hashing algorithm it uses.  |   |   |  The client assertion includes a payload with claims.  |   |   |   |   |   |  The following is an example of an unencoded payload and header encoded into a JWT: // Header { "alg": "ES256", "kid": "d136aa66-0c3b-4bd4-9892-c20e8db024ab" } // Payload { "iat": 2234567891, "exp": 2234567900, "aud": "https://account.apple.com/auth/oauth2/v2/token", "sub": "BUSINESSAPI.9703f56c-10ce-4876-8f59-e78e5e23a152" } The following is an example of a client assertion: eyJraWQiOiJiYWNhZWJkYS1lMjE5LTQxZWUtYTkwNy1lMmMyNWIyNGQxYjIiLCJhbGciOiJFUzI1NiJ9. eyJpc3MiOiJEcmVhbWNvbXBhbnkiLCJhdWQiOiJBdXRoZW50aWNhdG9yIiwiZXhwIjoxNTcxNjcwNjIx LCJuYmYiOjE1NzE2NjcwMjEsInN1YiI6Im11c3RlciIsImNsaWVudF9pZCI6ImFiY2QxMjM0IiwiYWRt aW4iOiJ0cnVlIn0.s4C3p9kVNFeRAB5tChatC3ldQX07v9mG7thL7FeEO6cClfNuiaLSgq8f8ymbfO3O QYW_KuwaA1KYRuoy1JmKk 4DBbYLcz6aoABe0pzI5Z_6wgMzAyqz8pQtwDAcd4Idoi8JdRbtzZce9o-0 nZiFA4hVAXqYwpEYC4UU8ZmJO_z8tY4juHPTV3nDugdtqyNnmAiBoLryOfGNngQZccdY1_QvkXS1y0bg1 a0k8cVVtnq- _93fYJIt9Z64CTvlH3uOeh7uaEv3nIxpXhvhkTySpUmY8e04TO09oTyZijiloByv3KFQ9 2OOJ8L 5N5_CeEc5p9LWjT1pcX8ATamOycZz2Q Request an access token To receive an access token, make a POST request to the authorization server using the client assertion above. When an access token expires, use the same process to obtain a new one. curl -X POST \ -H 'Host: account.apple.com' \ -H 'Content-Type: application/x-www-form-urlencoded' \ 'https://account.apple.com/auth/oauth2/token?grant_type=client_credentials& client_id=BUSINESSAPI.27478e71-3bb0-4588-998c-182e2b405577& client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer& client_assertion=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.zI1NiIsImprdSI6Imh0dHBzOi8 vYXV0aC5kZXYuYXBpLnJpY29oL3YxL2Rpc2NvdmVyeS9rZXlzIiwia2lkIjoiMmIyZTgyMTA2NzkxZGM4Zm FkNzgxNWQ3ZmI1NDRhNjJmNzJjMTZmYSJ9.eyJpc3MiOiJodHRwczovL2F1dGguZGV2LmFwaS5yaWNvaC8iL CJhdWQiOiJodHRwczovL2lwcy5kZXYuYXBpLnJpY29oLyIsImlhdCI6MTQ5MDg1Mjc0MSwiZXhwI joxNDkwODU2MzQxLCJjbGllbnRfaWQiOiI4ODQwMWU1MS05MzliLTQ3NzktYjdmNy03YzlmNGIzZj kyYzAiLCJzY29wZSI6Imh0dHBzOi8vaXBzLmRldi5hcGkucmljb2gvdjEiLCJyaWNvaF9tc3Mi OnsibWVkaWEiOnsicXVvdGEiOjEwLCJ0aHJvdHRsZSI6eyJ2YWx1ZSI6MCwid2luZG93IjowfX1 9fQ.jVq_c_cTzgsLipkJKBjAHzm8KDehW4rFA1Yg0EQRmqWmBDlEKtpRpDHZeF6ZSQfNH2OlrBW FBiVDV9Th091QFEYrZETZ1IE1koAO14oj4kf8TCmhiG_CtJagvctvloW1wAdgMB1_Eubz9a8oim cODqL7_uTmA5jKFx3ez9uoqQrEKZ51g665jSI6NlyeLtj4LrxpI9jZ4zTx1yqqjQx0doYQjBPhOB 06Z5bdiVyhJDRpE8ksRCC3kDPS2nsvDAal28sMgyeP8sPvfKvp5sa2UsH78WJmTzeZWcJfX2C2ba3 xwRMB5LaaVrQZlhj9xjum0MfDpIS1hJI6p5CHZ8w&scope=business.api'  |   |   |   |  |   |  |   |  |   |  |   |  |   |  |  After accepting the credentials, the authorization server returns an access token. { "access_token":"eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIiwia2lkIjpudWxsfQ ..lXm332TFi0u2E9YZ.bVVBvsjcavoQbBnQVeDiqEzmUIlaH9zLKY6rl36A_TD8wvgvWxp yBXMQuhs-qWG_dxQ5nfuJEIxOp8bIndfLE_4a3AiYtW0BsppO3vkWxMe0HWnzglkFbKUHU 3PaJbLHpimmnLvQr44wUAeNcv1LmUPaSWT4pfaBzv3dMe3PNHJJCLVLfzNlWTmPxViIivQ t3xyiQ9laBO6qIQiKs9zX7KE3holGpJ-Wvo39U6ZmGs7uK9BoNBPaFtd_q914mb9ChHAKc QaxF3Gadtu_Z5rYFg.vD0iQuRwHGYVnDy27qexCw", "token_type": "Bearer", "expires_in": 3600, "scope": "business.api" }  |  |   |  |   |  |   |  |   |  |  Use this token to access Apple School Manager and Apple Business APIs. The access token has an expiration of 1 hour. Apps need to generate an access token every hour, and also whenever Apple School Manager and Apple Business APIs return a ‘401’ response.
