User-restricted RESTful APIs - NHS login separate authentication and authorisation
Learn how to integrate your software with our user-restricted RESTful APIs - using our NHS login separate authentication and authorisation pattern.
Overview
This page explains how to integrate your software with our user-restricted RESTful APIs.
In particular, it describes the NHS login separate authentication and authorisation pattern, which uses our API OAuth 2.0 authorisation server. This process is made up of two parts:
- Authenticating the user - see NHS login for partners and developers
- Exchanging the NHS login ID Token with our API OAuth server (this page)
For a full list of available API patterns, see Security and authorisation.
When to use this pattern
Use this pattern when:
-
you want to access a user-restricted RESTful API
-
you want to separate authentication from authorisation
-
the end user is registered at a GP practice in England, or is receiving NHS services in England
-
you need the end user's identity information
How this pattern works
In this pattern, authentication and authorisation are done separately. You might authenticate the user when they sign in but only get authorisation to call the API if and when you need it. You do authentication directly with NHS login and then separately do authorisation with our OAuth2.0 authorisation service. You need to register your application separately with NHS login and with the API Platform.
The end user authenticates by entering their NHS login email address and password. The user then needs to provide a mobile phone number to receive a one time password (OTP) via a text message. The user needs to enter this OTP when prompted and press continue.
The end user has now verified the ownership of an email address and mobile phone number. This means they have an NHS login with the lowest level of identity verification. For details, see levels of verification.
The following diagram illustrates the pattern:
The following sequence diagram shows how the various components interact:
In words:
-
The calling application forwards the user's browser to the NHS login authentication endpoint.
-
The user signs in to their NHS login account (using a username and password, or other method).
-
NHS login redirects the user's browser back to the calling application, with an authorisation code.
-
The calling application calls the NHS login token endpoint, with the authorisation code, and receives an access token and an ID token in return.
-
Time passes, until the user needs to access a user-restricted API.
-
The calling application calls our OAuth2.0 token endpoint (/oauth/token), passing the ID token, and receives an access token (a token exchange).
-
The calling application calls the user-restricted API, including the access token.
Tutorials
Detailed integration instructions
The following diagram shows the high level integration stages with the API platform and the sections below it explain in detail how to use this security pattern.
Environments and testing
As well as production, we have a number of test environments. Each environment is paired with a suitable NHS login environment. In the steps below, make sure you use the appropriate URL base path:
| Environment | Sign-in method | Availability | URL base path | Paired NHS login environment |
|---|---|---|---|---|
| Sandbox | Simulated sign-in | Hello World API only (all other sandbox APIs are open access) | sandbox.api.service.nhs.uk/oauth2 | Not applicable |
| Development | Simulated sign-in | Limited to specific APIs - check your API specification | dev.api.service.nhs.uk/oauth2-no-smartcard | Not applicable |
| Development | NHS login username and password | Limited to specific APIs - check your API specification | dev.api.service.nhs.uk/oauth2 | Sandpit |
| Integration test | Simulated sign-in - second generation | All APIs | int.api.service.nhs.uk/oauth2-mock | Not applicable |
| Integration test | Simulated sign-in - first generation - deprecated | All APIs | int.api.service.nhs.uk/oauth2-no-smartcard | Not applicable |
| Integration test | NHS login username and password | All APIs | int.api.service.nhs.uk/oauth2 | Integration |
| Production | NHS login username and password | All APIs | api.service.nhs.uk/oauth2 | Live production |
For more information on testing, see Testing APIs.
Phase 1: Set up your application
This section explains the detailed steps to set up your application before you can initiate authorisation. The steps involved are:
- register your application with NHS login
- register your application on the API platform
- generate a key pair
- register your public key
Step 1: Register your application with NHS login
To use this pattern you need to register your application with NHS login directly. NHS login provides a number of ways for patients to authenticate their identity when accessing national clinical information systems.
-
For information on what NHS login is, see NHS login.
-
For information on how to register your application and integrate with NHS login, see NHS login for partners and developers.
Note: There are a number of distinct stages and this step is the setup stage. In a later stage, this configuration allows you to obtain an ID token. The ID token, in turn, provides an access token for calling the API and retrieve the data.
Step 2: Register your application on the API platform
To use this pattern, you need to register a new application on the API platform. This allows you to select and manage which APIs the application can access.
You need a separate application for your production environment. Best practice is to register one application for each of the test environments you want to access - development, integration test, or (for Hello World API only) sandbox:
-
If you do not already have one, create a developer account.
-
Navigate to my developer account and sign in.
- Select 'Environment access' on my developer account.
-
Select 'Add new application'.
-
Enter the details of your application including application owner and application name to create your new application.
- Select 'View your new application' to check or edit your application details.
- Click the 'Edit' button to make a note of the API key. If you are editing the security details for production applications, follow the online instructions to set up mobile authentication.
- Click the 'Add APIs' button to add the API you want to use.
For the Hello World (Sandbox) example, you need to select the API "Hello World API - User Restricted (Sandbox)".
Step 3: Generate a key pair
You need to generate a private/public key pair, which is used to create a client_assertion later in the process, for each application you created in Step 2 to access testing or production environments. It must be a 4096-bit RSA key pair.
Note that if you generate your own JWKS file, you must use the RS512 algorithm to do this.
Decide on your Key Identifier (KID) - a unique name to identify the key pair in use. The KID will be used to refer to the key pair when constructing and posting the JWT.
We recommend:
- test-1 for testing
- prod-1 for production use
If you create multiple applications to test across multiple test environments, you need a different KID and key pair for each environment.
If you create subsequent key pairs for key rotation, number them sequentially, for example test-2, test-3 and so on.
Do not re-use a KID.
For development and integration test environments only, you might find it easiest to use an external key generator to create a private-public key pair, and a JWKS file. Do not use this for a production environment.
For production environments (or test environments), generating your own public-private key locally is much more trustworthy.
Generate a private/public key pair using an external key generator - for test environments only
There are several external key generators available on the internet, and while we cannot endorse any one in particular, we know people have had success with https://mkjwk.org/.
To use it, enter:
| Key Size: | 4096 |
| Key Use: | Signature |
| Algorithm: | RS512 |
| Key ID: | YOUR_KID |
| Show X.509: | Yes |
This produces:
- "Public Key" - your JWKS file for uploading
- "Private Key (X.509 PEM Format)" - your private key in PEM format
- "Public Key (X.509 PEM Format)" - your public key in PEM format
Important - always keep your private key private. Do not send it to us!
Go to Step 4.
Generate your own private/public key pair - for production or test environments
On Windows, the easiest way to get the BASH shell tools to do this is to install Git For Windows.
On Linux and Mac OS, the BASH shell comes as standard.
Open a BASH shell command prompt and define your KID:
KID=YOUR_KID
Then run both of the following commands:
- openssl genrsa -out $KID.pem 4096
- openssl rsa -in $KID.pem -pubout -outform PEM -out $KID.pem.pub
These commands create the following files:
- YOUR_KID.pem - your private key in PEM format
- YOUR_KID.key.pub - your public key in PEM format
Important - always keep your private key private. Do not send it to us!
If this is a key pair for a production application, and you want us to host your public key, go to Step 4.
If this is a key pair for development or integration testing environments, or a production environment key you want to host yourself, you also need to create a JWKS file to upload.
To do this, first get the "modulus" of your private key, by entering the following BASH shell commands:
MODULUS=$(
openssl rsa -pubin -in $KID.pem.pub -noout -modulus `# Print modulus of public key` \
| cut -d '=' -f2 `# Extract modulus value from output` \
| xxd -r -p `# Convert from string to bytes` \
| openssl base64 -A `# Base64 encode without wrapping lines` \
| sed 's|+|-|g; s|/|_|g; s|=||g' `# URL encode as JWK standard requires`
)
Next, build your JWKS file (using the RS512 algorithm) from your KID and public key modulus by entering the following BASH shell commands:
echo '{
"keys": [
{
"kty": "RSA",
"n": "'"$MODULUS"'",
"e": "AQAB",
"alg": "RS512",
"kid": "'"$KID"'",
"use": "sig"
}
]
}' > $KID.json
This creates the JWKS file YOUR_KID.json for uploading in Step 4.
Step 4: Register your public key
We use your public key to verify your client_assertion later in the process.
There are two ways to do this - either host your own public key, or ask us to host it for you.
Host your own public key
To do this, for applications in development or integration test environments:
- Create a JWKS endpoint to publicly host your public key and note the URL.
- Sign in to your developer account.
- Select 'My applications and teams', 'My applications' and then 'Manage your applications'.
- Select the application you want to add your JWKS endpoint to.
- Edit the public key URL
- Enter the URL of your JWKS endpoint and click Save.
If this public key is for a production application, contact us and tell us:
- your application ID
- the public key URL you want to add, or update
Ask us to host your public key
For applications in development or integration test environments:
- Sign in to your developer account.
- Select 'My applications and teams', 'My applications' and then 'Manage your applications'.
- Select the application you want to add your JWKS public key to.
- Edit the public key URL.
- Choose the JWKS file in JSON format for your public key and click Upload.
- Once it's confirmed as a valid public key, click Save.
We use this public key to create a JWKS endpoint to host your public key and link it to your application in the development or integration environment.
For production applications, contact us and make sure you tell us:
- your application’s App ID, from step 2
- your KID, from step 3
- your public key, from step 3, as an attachment in PEM format
- the APIs you want to use
We use this information to create a JWKS endpoint to host your public key and link it to your application in production.
In the future, we hope to make this process more self-service for production applications. You can track progress or vote for this feature on our interactive product backlog.
Step 5: Authenticate the user with NHS login
You need to authenticate the user with NHS login. Successful authentication results in an ID token being issued to the callback endpoint that you registered with NHS login.
Your software needs to follow a standard OIDC authorisation code flow with NHS login. OIDC clients Initiate the NHS login authorisation sequence from the browser by calling the NHS login authorize endpoint. Once the user authentication is successful, your web server should call the NHS login token end point and receive a number of tokens including the ID token.
The ID token has a lifetime of 1 hours, after 1 hour the user must re-authenticate. We strongly recommend to exchange the ID token for our access and refresh tokens as soon as possible.
You need the ID token in step 7.
Step 6: Generate a client assertion
Before you can call a user-restricted API, you first need to generate a client assertion. This happens at runtime, so you need to code it into your application.
A client assertion is a JSON Web Token (JWT) that consists of three parts: a header, a payload and a signature. The header specifies the authentication method and token type. The payload contains data (detailed below) and the signature is used to verify the token itself.
We strongly recommend that you use a library to generate your JWT, as this can be a complicated process to perform by hand.
Header
The JWT header includes the following fields:
| Field | Description | Type |
|---|---|---|
| alg | The algorithm used to sign the JWT, which must be RS512. | string |
| typ | The token type - JWT. | string |
| kid |
The Key Identifier (KID) used to select the public key to use to verify the signature of the JWT, for example test-1. If you have multiple public/private key pairs, this will be used to select the appropriate public key. |
string |
Example
{
"alg": "RS512",
"typ": "JWT",
"kid": "test-1"
}
Payload
The JWT payload includes the following fields:
| Field | Description | Type |
|---|---|---|
| iss | The issuer of the JWT. Set this to your API Key. | string |
| sub | The subject of the JWT. Also set this to your API Key. | string |
| aud | The audience of the JWT. Set this to the URI of the token endpoint you are calling, for example https://api.service.nhs.uk/oauth2/token for our production environment. | string |
| jti | A unique identifier for the JWT, used to prevent replay attacks. We recommend a randomly-generated GUID. | string |
| exp | Expiry time of the JWT, expressed as a Numeric Time value - the number of seconds since epoch (for example, a UNIX timestamp). Must not be more than 5 minutes after the time of creation of the JWT. | number |
Example
{
"iss": "<test-app-api-key>",
"sub": "<test-app-api-key>",
"aud": "https://api.service.nhs.uk/oauth2/token",
"jti": "<unique-per-request-id>",
"exp": <current-time-plus-5mins-from-jwt-creation>
}
Signature
The JWT signature consists of the contents of the header and payload, signed with your private key. We recommend you use a library to generate this.
Assembling the JWT
The JWT consists of:
- the header, base64 encoded
- a period separator
- the payload, base64 encoded
- a period separator
- the signature, base64 encoded
Examples
The following code snippets show how to generate and sign a JWT in Python and C#.
For the Python example, PyJWT requires the installation of the crypto extra in order to use RSA keys. To install this:
python -m pip install PyJWT[crypto]
import uuid
from time import time
import jwt # https://github.com/jpadilla/pyjwt
with open("jwtRS512.key", "r") as f:
private_key = f.read()
claims = {
"sub": "<API_KEY>",
"iss": "<API_KEY>",
"jti": str(uuid.uuid4()),
"aud": "https://api.service.nhs.uk/oauth2/token",
"exp": int(time()) + 300, # 5mins in the future
}
additional_headers = {"kid": "test-1"}
j = jwt.encode(
claims, private_key, algorithm="RS512", headers=additional_headers
)
using System; using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Security.Cryptography.X509Certificates;
using IdentityModel;
using Microsoft.IdentityModel.Tokens;
public class JwtHandler
{
private readonly X509Certificate2 _cert;
private readonly string _audience;
private readonly string _clientId;
private readonly string _kid;
public JwtHandler(string pfxCertPath, string audience, string clientId, string kid)
{
_audience = audience;
_clientId = clientId;
_kid = kid;
_cert = new X509Certificate2(pfxCertPath);
}
public string generateJWT(int expInMinutes = 1)
{
var now = DateTime.UtcNow;
var token = new JwtSecurityToken(
_clientId,
_audience,
new List<Claim>
{
new ("jti", Guid.NewGuid().ToString()),
new (JwtClaimTypes.Subject, _clientId),
},
now,
now.AddMinutes(expInMinutes),
new SigningCredentials(
new X509SecurityKey(_cert, _kid),
SecurityAlgorithms.RsaSha512
)
);
var tokenHandler = new JwtSecurityTokenHandler();
return tokenHandler.WriteToken(token);
}
}
Step 7: Exchange NHS login ID token for access token
Once you integrate with NHS login and successfully authenticate the user, you receive an ID token. Call our token endpoint to exchange the ID token for an access token. This call is an HTTP POST to the following endpoint:
https://api.service.nhs.uk/oauth2/token
Note: the above URL is for our production environment. For other environments, see Environments and testing above.
You need to include the following form parameters in your call:
| Parameter | Description |
|---|---|
| subject_token | ID token received from NHS login in step 5 |
| client_assertion | A JWT token, which is created to prove that your server is a legitimate consumer and contains the application (client_id) as a claim |
| subject_token_type | urn:ietf:params:oauth:token-type:id_token |
| client_assertion_type | urn:ietf:params:oauth:client-assertion-type:jwt-bearer |
| grant_type | As per Section 4.5 of RFC6749, the grant type to receive an access token should be urn:ietf:params:oauth:grant-type:token-exchange |
Here is a complete example, as a CURL command:
curl --location --request POST 'https://api.service.nhs.uk/oauth2/token'\
--header 'Content-Type: application/x-www-form-urlencoded'\
--data-urlencode 'grant_type=urn:ietf:params:oauth:grant-type:token-exchange'\
--data-urlencode 'subject_token_type=urn:ietf:params:oauth:token-type:id_token'\
--data-urlencode 'client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer'\
--data-urlencode 'subject_token={ID token received from NHS login in step 5}\
--data-urlencode 'client_assertion={jwt token}
If the request is valid, the OAuth 2.0 authorisation server responds with a HTTP status 200 and a normal OAuth 2.0 response from the token endpoint. This response contains the following parameters:
| Parameters | Description |
|---|---|
| access_token | The access token issued by the OAuth 2.0 authorization server which can be used to call our user-restricted endpoints |
| expires_in | The time after which the access token expires, in seconds |
| issued_token_type | urn:ietf:params:oauth:token-type:access_token |
| token_type | Bearer |
| refresh_token | A token for refreshing the access token once it has expired (see step 10 below) |
| refresh_token_expires_in | The time in seconds, after which the refresh token expires |
| refresh_count | The number of times the token has been refreshed so far |
Here’s an example:
{
"access_token":"Sr5PGv19wTEHJdDr2wx2f7IGd0cw",
"expires_in":"599",
"issued_token_type":"urn:ietf:params:oauth:token-type:access_token",
"refresh_count":"0",
"refresh_token":"7qvwCqqUUAmzMjRbQyrhdddwBQUJ9vmt",
"refresh_token_expires_in":"3599",
"token_type":"Bearer"
}
Error scenarios
If there are any issues with your call to our token endpoint, we return an error response, as follows:
| Error Scenario | HTTP status | Error code | Error message |
|---|---|---|---|
| Grant type is missing | 400 (Bad Request) | invalid_request | grant_type is missing |
| Grant type is invalid | 400 (Bad Request) | unsupported_grant_type | grant_type is invalid |
| Grant type is invalid but is supported | 400 (Bad Request) | invalid_grant_type | grant_type is invalid |
| Client assertion type is missing or invalid | 400 (Bad Request) | invalid_request | Missing or invalid client_assertion_type - must be 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer' |
| Subject token type is missing or invalid | 400 (Bad Request) | invalid_request | Missing or invalid subject_token_type - must be 'urn:ietf:params:oauth:token-type:id_token' |
| Client assertion (signed JWT) is missing | 400 (Bad Request) | invalid_request | Missing client_assertion |
| Client assertion (signed JWT) is malformed | 400 (Bad Request) | invalid_request | Malformed JWT in client_assertion |
| Subject token is missing | 400 (Bad Request) | invalid_request | Missing subject_token |
| Subject token is invalid | 400 (Bad Request) | invalid_request | subject_token is invalid |
| kid header is missing in client_assertion | 400 (Bad Request) | invalid_request | Missing 'kid' header in client_assertion JWT |
| kid header is invalid in client_assertion | 401 (Unauthorized) | invalid_request | Invalid 'kid' header in client_assertion JWT - no matching public key |
| kid header is missing in subject_token | 400 (Bad Request) | invalid_request |
Missing 'kid' header in subject_token JWT |
| kid header is invalid in subject_token | 401 (Unauthorized) | invalid_request | Invalid 'kid' header in subject_token JWT - no matching public key |
| typ header is missing or invalid in client_assertion | 400 (Bad Request) | invalid_request | Invalid 'typ' header in client_assertion JWT - must be 'JWT' |
| typ header is missing or invalid in subject_token | 400 (Bad Request) | invalid_request | Invalid 'typ' header in subject_token JWT - must be 'JWT' |
| alg header is missing in client_assertion | 400 (Bad Request) | invalid_request | Missing 'alg' header in client_assertion JWT |
| alg header is invalid in client_assertion | 400 (Bad Request) | invalid_request | Invalid 'alg' header in client_assertion JWT - unsupported JWT algorithm - must be 'RS512' |
| alg header is missing in subject_token | 400 (Bad Request) | invalid_request | Missing 'alg' header in subject_token JWT |
| sub and iss claims match but are not a valid API Key in client_assertion | 401 (Unauthorized) | invalid_request | Invalid 'iss'/'sub' claims in client_assertion JWT |
| sub and iss claims don't match or are missing in client_assertion | 400 (Bad Request) | invalid_request |
Missing or non-matching 'iss'/'sub' claims in client_assertion JWT |
| iss claim is missing in subject token | 400 (Bad Request) | invalid_request |
Missing 'iss' claim in subject_token JWT |
| jti claim is missing in client_assertion | 400 (Bad Request) | invalid_request | Missing 'jti' claim in client_assertion JWT |
| jti claim has been reused in client_assertion | 400 (Bad Request) | invalid_request | Non-unique 'jti' claim in client_assertion JWT |
| jti claim is invalid type in client_assertion | 400 (Bad Request) | invalid_request |
Invalid 'jti' claim in client_assertion JWT - must be a unique string value such as a GUID |
| aud claim is missing or invalid in client_assertion | 401 (Unauthorized) | invalid_request | Missing or invalid 'aud' claim in client_assertion JWT |
| aud claim is missing in subject_token | 400 (Bad Request) | invalid_request |
Missing aud claim in subject_token |
| exp claim is missing in client_assertion | 400 (Bad Request) | invalid_request | Missing 'exp' claim in client_assertion JWT |
| exp claim is in the past in client_assertion | 400 (Bad Request) | invalid_request | Invalid 'exp' claim in client_assertion JWT - JWT has expired |
| exp claim is more than 5 minutes in the future in client_assertion | 400 (Bad Request) | invalid_request | Invalid 'exp' claim in client_assertion JWT - more than 5 minutes in future |
| exp claim is invalid type in client_assertion | 400 (Bad Request) | invalid_request |
Invalid 'exp' claim in client_assertion JWT - must be an integer |
| exp claim missing in subject_token | 400 (Bad Request) | invalid_request | Missing 'exp' claim in subject_token JWT |
| exp claim is in the past in subject_token | 400 (Bad Request) | invalid_request | Invalid 'exp' claim in subject_token JWT - JWT has expired |
| exp claim is invalid type in subject_token | 400 (Bad Request) | invalid_request |
Invalid 'exp' claim in subject_token JWT - must be an integer |
| JWT signature is invalid | 401 (Unauthorised) | public_key error | JWT signature verification failed |
| Public key not set up | 403 (Forbidden) | public_key error |
You need to register a public key to use this authentication method - please contact support to configure |
| Public key misconfigured | 403 (Forbidden) | public_key error | The JWKS endpoint for your client_assertion can not be reached |
Step 8: Store your access token for later use
Your access token lasts for 10 minutes and you can use it multiple times. To more than one API call for this user, store your access token securely for later use.
This reduces the load on our authorisation server and also reduces the chance of your application hitting its rate limit.
For details on what to do when your access token expires, see refresh your access token below.
Phase 3: Interact with our user-restricted APIs
This section explains the detailed activities that you need to perform to call a user-restricted API. The activities involved are:
- call a user-restricted API
- refresh our access token
- request a new access token from us
Step 9: Call a user-restricted API
To call our user-restricted APIs, you need to include the following header in your call:
- Authorization = Bearer <your access token from step 7>
Here's an example, using a CURL command:
curl -X GET https://sandbox.api.service.nhs.uk/hello-world/hello/user\
-H "Authorization: Bearer [your access token from step 7]"\
Note: the URL in the above example is for our sandbox environment. For other environments, see Environments and testing above.
All being well, you receive an appropriate response from the API, for example:
HTTP Status: 200
{
"message": "Hello User!"
}
Error scenarios
If there is an issue with your access token, we return one of the following error responses:
| HTTP status | Code | Description |
|---|---|---|
| 401 (Unauthorized) | invalid_credentials | Access token has expired |
| 401 (Unauthorized) | invalid_credentials | Access token is invalid |
| 401 (Unauthorized) | invalid_credentials | Access token is missing |
For detailed error conditions, see the relevant API specification in our API catalogue.
Step 10: Refresh your access token
Your access token from step 7 above expires after 10 minutes and must be refreshed to avoid user re-authentication (see step 5 above).
If your access token has expired, when you call a user-restricted API, we return the following error:
| HTTP status | Code | Description |
|---|---|---|
| 401 (Unauthorized) | invalid_credentials | Access token has expired |
Each access token has a corresponding refresh token. To refresh the access token, submit the expired token’s corresponding refresh token to our token endpoint using grant_type of refresh_token. We return a new pair of access token and it's corresponding refresh token without re-authenticating the user.
You need to include the following form parameters in your request to the token endpoint:
| Parameters | Description |
|---|---|
| client_id | The API Key (also known as the Client ID) of your application |
| client_secret | The secret assigned to your application’s API Key |
| grant_type | As per the OAuth standard, the grant type to refresh your access token should be refresh_token |
| refresh_token | The refresh token issued by the OAuth 2.0 authorization server which can be used to refresh the access token |
If you refresh an access token before it expires, the new access token invalidates the original access token immediately.
You can continue to refresh access tokens for up to 1 hour. After 1 hour, you must repeat step 5 above.
Example request
curl -X POST -H "content-type: application/x-www-form-urlencoded" --data \
"client_secret=[YOUR-SECRET]\
&client_id=[YOUR-API-KEY]\
&grant_type=refresh_token\
&refresh_token=[REFRESH_TOKEN]" \
https://api.service.nhs.uk/oauth2/token
Note: the above URL is for our production environment. For other environments, see Environments and testing.
Example response
HTTP/1.1 200 OK Content-Type: application/json
{
"access_token":"xjPOKAmxlLXQcHkRkBf37AiaGyEx",
"expires_in":"599",
"refresh_token":"A6dpFV8F1yjsca4zPr5GDO0n7raSB6TQ",
"refresh_token_expires_in":"3599",
"refresh_count":"1",
"token_type":"Bearer"
}
Error scenarios
If there are any issues with your call to our token endpoint, in addition to the errors mentioned in step 7, we return the following refresh token specific errors:
| Error scenario | HTTP status | Error code | Error message |
|---|---|---|---|
| Client secret is missing | 401 (Unauthorized) | invalid_request | client_secret is missing |
| Client secret is invalid | 401 (Unauthorized) | invalid_client | client_id or client_secret is invalid |
| Client ID (API key) is missing | 401 (Unauthorized) | invalid_request | client_id is missing |
| Client ID (API key) is invalid | 401 (Unauthorized) | invalid_client | client_id or client_secret is invalid |
| Refresh token is missing | 400 (Bad Request) | invalid_request | refresh_token is missing |
| Refresh token is invalid | 401 (Unauthorized) | invalid_grant | refresh_token is invalid |
| Refresh token has already been used | 401 (Unauthorized) | invalid_grant | refresh_token is invalid |
| Access token refresh period has expired | 401 (Unauthorized) | invalid_grant | access token refresh period has expired |
Step 11: Request a new access token from us
You can continue to request new access_tokens for up to 1 hour.
After that, calls to our token endpoint returns the following error:
| HTTP status | Code | Description |
|---|---|---|
| 401 (Unauthorized) | invalid_credentials | Access token has expired |
If this happens, you must send the user back through the full authorisation process from step 5 above.
If you have any concerns about the session length regarding your use case then then contact us about about it and we will work with you to make it a smooth as possible user experience.
Last edited: 6 November 2024 4:26 pm