> For the complete documentation index, see [llms.txt](https://devdocs.brightpay.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://devdocs.brightpay.com/authentication/retrieving-a-refresh-and-access-token.md).

# Retrieving a Refresh and Access Token

The authentication process works by retrieving a Refresh and Access Token from the Bright Identity Provider (using OAuth 2). These tokens will allow your server side application to get and post data to the BrightPay API on behalf of the logged on user. This means your application will only be able to interact with data that the user has access to within BrightPay.

The scheme will work as below:

* Your application will publish a link pointing to the Bright Identity Provider (the link will include your Client Id)
* Your users will click on the link and their browser will be directed to the Bright Identity Provider
* The user will authenticate using their Bright ID username and password
* The Bright Identity Provider will redirect the user's browser back to your server-side application
* Your server-side application will catch the redirect and extract an authorisation code from the url
* Your server-side application will then pass the authorisation code along with your Client Secret to the Bright Identity Provider which will return a Refresh and Access Token
* Your server-side application will extract the Refresh and Access Token and store them server side
* The Access Token can be added to requests in order to authorise them (on behalf of the user).&#x20;
* The Access Token will work for 5 minutes, shortly before the 5 minutes is complete you can use the Refresh token to request a new Access Token.

### Creating the Initial Login UrI

Prerequisites - this step assumes you have a Bright Client Id and Secret for your application - please see [<mark style="color:blue;">Authentication</mark>](/authentication.md) for how to get these.

The first step in the process is to create a link (to be presented on your application) pointing to the Bright Identity Provider with the correct Scopes and Client Id.

<https://login.brightsg.com/login.brightsg.com/B2C\\_1A\\_BPOL\\_SIGNIN\\_PROD/oauth2/v2.0/authorize>? response\_type=code\&client\_id=YOURCLIENTID\&redirect\_uri=YOURREDIRECTURL\&state=YOURSTATE\&scope=offline\_access%20https%3A%2F%2Flogin.brightsg.com%2F456b7587-bc0e-4a1e-824e-756b078a2ade%2Fbrightpay.online.external.api

[<br>](<https://login.brightsg.com/login.brightsg.com/B2C_1A_BPOL_SIGNIN_DEV/oauth2/v2.0/authorize?response_type=code\&client_id=2033200c-25be-4ca7-be38-3a523dfa2687\&redirect_uri=https%3A%2F%2Flocalhost%3A7467%2FLogin\&state=7f4b7d0949c1457d8f108ad66c5b9fad_Home\&scope=offline_access%20https%3A%2F%2Fbrightsoftwaregroup.onmicrosoft.com%2F5ed99d55-656d-405a-99e9-36001d3f245d%2Fbrightpay.online.external.api&#xA;>)

<table><thead><tr><th width="165">Item</th><th>Description</th></tr></thead><tbody><tr><td>base URL</td><td>https://login.brightsg.com/login.brightsg.com/B2C_1A_BPOL_SIGNIN_PROD/oauth2/v2.0/authorize</td></tr><tr><td>response_type</td><td>Set to the value "code"</td></tr><tr><td>client_id</td><td>Set to your Client Id</td></tr><tr><td>redirect_uri</td><td><p>https%3A%2F%2Flocalhost%3A7467%2FLogin</p><p></p><p>The redirect_uri is the end point that the Bright Identity Provider should redirect the browser to after generating an Authorization Code. Your application will listen at this specified end point and catch the request for further processing (as the request will include the Authorization Code). In this case the value has been set to "https://localhost:7467/Login" for testing purposes. In production this should be set to a production URL.</p><p>Note the value specified for the redirect_uri must match one of the expected redirect_uri stored in the Bright Identity Provider. The redirect_uri(s) supported will be agreed when requesting the Client Id and Secret.</p></td></tr><tr><td>state</td><td><p>For example "7f4b7d0949c1457d8f108ad66c5b9fad_Home"</p><p></p><p>The state represents the state of your application at the time of the request. The state will be passed back to your application when the Bright Identity Provider, after successful authentication, redirects the browser to the redirect uri with an Authorization Code. For example, the state could be used to track the page the login request was initially made from. Then when the browser arrives at the redirect uri (and the Authorisation Code has been extracted) your server-side application can redirect the browser back to the original page.</p></td></tr><tr><td>scope</td><td><p>offline_access%20https%3A%2F%2Flogin.brightsg.com%2F456b7587-bc0e-4a1e-824e-756b078a2ade%2Fbrightpay.online.external.api</p><p></p><p>The scopes are the "permissions" or "abilities" your application is requesting to be added to the token. The scope has been set to <strong>offline_access https://login.brightsg.com/456b7587-bc0e-4a1e-824e-756b078a2ade/brightpay.online.external.api</strong> which are the scopes that are required to interact with the API.</p></td></tr></tbody></table>

Therefore, once the user has Authenticated with the Bright Identity Provider, the Bright Identity Provider will redirect the user’s browser to your applications redirect\_uri, where your server-side application should listen for requests. Again, note the redirect\_uri supplied must match a redirect\_uri stored in the Bright Identity Provider.

### &#x20;**Catching the response and extracting an Authorisation Code**

The identity provider will redirect the user's browser to the redirect\_uri with a response similar to below[https://localhost:7467/Login?state=7f4b7d0949c1457d8f108ad66c5b9fad\_Home\&code=eyJraWQiOiIwV1ZMal9IVDRtOH......48IUjfpxmypgpqjHMrOenoh0oQULSwtNfIlCDvt4MdOVnNQX1FUIVmeVVBM5LpxW0FKwRnB1HnVprvYhQqjWHDM4OV00rieHw.LzvGCz4XJMiVkvJJ1rBlC](https://localhost:7467/Login?state=7f4b7d0949c1457d8f108ad66c5b9fad_Home\&code=eyJraWQiOiIwV1ZMal9IVDRtOH......48IUjfpxmypgpqjHMrOenoh0oQULSwtNfIlCDvt4MdOVnNQX1FUIVmeVVBM5LpxW0FKwRnB1HnVprvYhQqjWHDM4OV00rieHw.LzvGCz4XJMiVkvJJ1rBlCQ)

This URI is constructed as below

<table><thead><tr><th width="167">Item</th><th>Description</th></tr></thead><tbody><tr><td>base URL</td><td><p><a href="https://localhost:7467/Login?state=5f5b08e1ad1945b48d0085e930596750_ExampleTimeSheet&#x26;code=eyJraWQiOiIwV1ZMal9IVDRtOHk1QmZrOXVnUjduSUYyOHNRQ05HOW0zd0JJYU9XNnhVIiwidmVyIjoiMS4wIiwiemlwIjoiRGVmbGF0ZSIsInNlciI6IjEuMCJ9.DrVc1TOP14zXsIYi_6wy-y21kM91BfNTzOvfmSp5T88DV8HukXp5uqRwz85AxHQPfPNG7YcNr2VVEmxl6DLlxfbvh1-Nugx64ZBV3ShN5k5MgP5W33AVyUYPpcmMykqp2mD4OfiuWSkKi3yq5o2MqGXX9RDWL_e1s89TueLdou7_h16f_fYTcbRRdmWMup6bVOuPTKOYYzuGNqIsX7HoH48JsCyaX7mNDMkT0GMmzjNUqBNovMOO1YEN4mvPdjM1fDrEZMOYajh7pNDZoADleI49Kbp4XR1QL3497AOXvr_qEyuRlz-pWLyXYfT6LAMqo--wgLj10WwfSKd-ORW_Vg.WBbHiFan9T8MmPar.6PHg9CmA0xqouCKz4Npn7U1nH7pmqAYDNYrQ8QioB4XKwFvl94Cj2jbHxhy6FJiLtjXTVTCku9aqkM3MjKnEblF4KWqqNa2xv5zZIE9VR2URvjN-RcpHHhLILBjingBfqr1AAOGOMvoy-6KeooyMcAezK7szh-dE-bD2mln-h8x2ZUshnqthXlbjf8Mw5tQCJwz8QXrNFlPWqgKS9QBkChsU4JutlEmxMl7BjSxURITEpVgXnzGv9fSep4yUawqXD_jIjFp09NZ2OF2Sbhe-T6gAv-1MIKPWwFBgwJis06Bj71FaTP_mY5jK_DrvnSHQN0qS5SMFdBBWEQ2A-1eP6b4x4WsefCkt3KZUQcIyMuUWLupxnxSwzyeKJIyNp8IgXcb-vuHXuAQiYs2CxjYNQxujxETEf-ogMv8fS3tRZ01BJsw0YnYkf6RMxaj5MbA658XfDqemTF32a-soZZOfFSjQbw62rJK1ZlPv1L33X6m5ZBvGrX2Mj3el8yILiA7gO-ps4Erloeqd13Ad5h75tufo8lIZPgvkbwycU_3jd9pFz9PCXUpjuGzJse-4MYNvB7q8VYzXK3BVscLpSpoEz3R-IYp4FA0frnhKcd7pcfcaNf9-aVMhb0bmY-dYzmzf8pe2CJ0ShFN1qcZEFLNy9KARPM-HZi8nVGli3GAmrvdWwRWaHT9ewhIX73s1l2OsASzZ4qgRjOU3_j3LXH_FdaaGXPN4ovtI-NqybCsgHOacV9D_taXRf0S9dreLvTLF2PD46XQaqZ2vWMgfbegneGNCi293E6kxjZaDsm9rV-I1Y7IW7GD2-48IUjfpxmypgpqjHMrOenoh0oQULSwtNfIlCDvt4MdOVnNQX1FUIVmeVVBM5LpxW0FKwRnB1HnVprvYhQqjWHDM4OV00rieHw.LzvGCz4XJMiVkvJJ1rBlCQ">https://localhost:7467/Login</a> </p><p></p><p>This is going to be a url to an endpoint on your application. Currently the site has been set to localhost for testing (with “Login” as the path). There will be some functionality at the "Login" end point to catch the request and process it. In production this should be set to a production URL. e.g. https://myproductionsite.com/Login.</p></td></tr><tr><td>state</td><td><p>7f4b7d0949c1457d8f108ad66c5b9fad_Home </p><p></p><p>This is the state you provided in the Initial URI and will allow your application to navigate back to the calling page etc.</p></td></tr><tr><td>code</td><td><p>eyJraWQiOiIwV1ZMal9IVDRtOH......48IUjfpxmypgpqjHMrOenoh0oQULSwtNfIlCDvt4MdOVnNQX1FUIVmeVVBM5LpxW0FKwRnB1HnVprvYhQqjWHDM4OV00rieHw.LzvGCz4XJMiVkvJJ1rBlCQ </p><p></p><p>This is the Authorisation Code that can be used to get a Refresh and Access Token.</p></td></tr></tbody></table>

Once your server-side application receives a request at the Redirect URI it should extract the "code" parameter which can later be exchanged for an Access Token.

### Using the Authorisation Code to get a Refresh and Access Token

The next stage is to take the supplied Authorisation Code and ask the Bright Identity Provider to exchange it for an Access Token. To do this we need to POST data to the token end point below:

<https://login.brightsg.com/login.brightsg.com/B2C_1A_BPOL_SIGNIN_PROD/oauth2/v2.0/token>

with the following settings:

<table><thead><tr><th width="235">Setting</th><th>Value</th></tr></thead><tbody><tr><td>Request Method</td><td>POST</td></tr><tr><td>Request Accept</td><td>application/json</td></tr><tr><td>Content Type</td><td>application/x-www-form-urlencoded</td></tr></tbody></table>

The request should include a body similar to below:

grant\_type=authorization\_code\&code= eyJraWQiOiIwV1ZMal9IVDRtOH......48IUjfpxmypgpqjHMrOenoh0oQULSwtNfIlCDvt4MdOVnNQX1FUIVmeVVBM5LpxW0FKwRnB1HnVprvYhQqjWHDM4OV00rieHw\.LzvGCz4XJMiVkvJJ1rBlCQ\&client\_id= 20ed300c-425be-4ca7-be38-3a523dfa2687\&client\_secret=45RtnwFe40Kgr...6edaaWgge334gHR\&scope=offline\_access%20https%3A%2F%2Flogin.brightsg.com%2F456b7587-bc0e-4a1e-824e-756b078a2ade%2Fbrightpay.online.external.api\&redirect\_uri=https%3A%2F%2Flocalhost%3A7467%2FLogin

Which is broken down as

<table><thead><tr><th width="176">Item</th><th>Description</th></tr></thead><tbody><tr><td>grant_type</td><td><p>authorization_code </p><p></p><p>Set the grant_type to the value above.</p></td></tr><tr><td>code</td><td><p>eyJraWQiOiIwV1ZMal9IVDRtOH......48IUjfpxmypgpqjHMrOenoh0oQULSwtNfIlCDvt4MdOVnNQX1FUIVmeVVBM5LpxW0FKwRnB1HnVprvYhQqjWHDM4OV00rieHw.LzvGCz4XJMiVkvJJ1rBlCQ </p><p></p><p>This is the "Code" retrieved in the previous step.</p></td></tr><tr><td>client_id</td><td><p>20ed300c-45be-4ca7-be38-3a523dfa2687 </p><p></p><p>This is your application's Client Id which has been supplied by Bright.</p></td></tr><tr><td>client_secret</td><td><p>45RtnwFe40Kgr...6edaaWgge334gHR</p><p></p><p>This is your application's Client Secret which has been supplied by Bright.</p></td></tr><tr><td>scope</td><td><p>offline_access%20https%3A%2F%2Flogin.brightsg.com%2F456b7587-bc0e-4a1e-824e-756b078a2ade%2Fbrightpay.online.external.api </p><p></p><p>Set the scopes to the value above.</p></td></tr><tr><td>redirect_uri</td><td><p>https%3A%2F%2Flocalhost%3A7467%2FLogin</p><p></p><p>This is your redirect uri (in this case Localhost port 7476 for testing)</p></td></tr></tbody></table>

The provider will respond with the JSON similar to

<pre data-overflow="wrap"><code><strong>{
</strong>"access_token":"reEseTEreseE…WRsHT5srtrtrsfd",
"token_type":"Bearer",
"not_before":1719399215,
"expires_in":300,
"expires_on":1719435215,
"resource":"456b7587-bc0e-4a1e-824e-756b078a2ade",
"profile_info":"ere12…wew33223221",
"scope":"https://login.brightsg.com/456b7587-bc0e-4a1e-824e-756b078a2ade/brightpay.online.external.api offline_access",
"refresh_token":"EyWEWA…RT_QEuttttW",
"refresh_token_expires_in":7776000
}
</code></pre>

Breaking this down the fields you are interested in are:

<table><thead><tr><th width="232">Item</th><th>Description</th></tr></thead><tbody><tr><td>access_token</td><td>This string is an access token that can be added as a "bearer" http request header, in order to interact with the BrightPay API on behalf of the user.</td></tr><tr><td>expires_in</td><td>How long in seconds before the access token expires (300 seconds = 5 minutes).</td></tr><tr><td>refresh_token</td><td>This string is a refresh token that can be used to retrieve another Access Token (just before the current Access Token has timed out).</td></tr><tr><td>refresh_token_expires_in</td><td>How long before the Refresh Token expires (7776000 seconds = 90 days).</td></tr></tbody></table>

### Using the Access Token to request user information

To test the Access Token, request data from this end point (no parameters required)

<https://external.brightpay.com/api/v1/Payroll/GetCurrentUserSummary>

<table><thead><tr><th width="233">Setting</th><th>Value</th></tr></thead><tbody><tr><td>Request Method</td><td>GET</td></tr><tr><td>Request Accept</td><td>application/json</td></tr></tbody></table>

With an HTTP Header as follows (the value is the Bearer plus the Access Token you received earlier):

<table><thead><tr><th width="234">Header Name</th><th>Value</th></tr></thead><tbody><tr><td>Authorization</td><td>Bearer reEseTEreseE…WRsHT5srtrtrsfd</td></tr></tbody></table>

If successful, this end point should respond with JSON containing the logged on user's name and email similar to:

```
{
  "name": "John Doe",
  "emailAddress": "john.doe@brightsg.com",
  "isSuccess": true,
  "apiErrors": []
}
```

### Using the Refresh Token to request a new Access Token

The Access Token will expire after 5 minutes. Your application can use the stored Refresh Token to request a new Access Token (perhaps 15 seconds before the original Access Token expires). To retrieve a new Access Token you need to POST data to the token end point below:

<https://login.brightsg.com/login.brightsg.com/B2C\\_1A\\_BPOL\\_SIGNIN\\_PROD/oauth2/v2.0/token>

with the following settings:

|                | Value                             |
| -------------- | --------------------------------- |
| Request Method | POST                              |
| Request Accept | application/json                  |
| Content Type   | application/x-www-form-urlencoded |

The request should include a body similar to below:

grant\_type=refresh\_token\&refresh\_token=EyWEWA…RT\_QEuttttW\&client\_id=2033200c-45be-4ca7-be38-3a523efd2687\&client\_secret=45RtnwFe40Kgr...6edaaWgge334gHR \&scope=offline\_access%20https%3A%2F%2Flogin.brightsg.com%2F456b7587-bc0e-4a1e-824e-756b078a2ade%2Fbrightpay.online.external.api

Which is broken down as

| Item           | Description                                                                                                                                                              |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| grant\_type    | <p>refresh\_token</p><p>Set this value to "refresh\_token".</p>                                                                                                          |
| refresh\_token | <p>e.g. EyWEWA…RT\_QEuttttW</p><p>This is your Refresh token retrieved earlier.</p>                                                                                      |
| client\_id     | <p>e.g. 2033200c-45be-4ca7-be38-3a523dfa2687</p><p>This is your Client Id which has been supplied by Bright.</p>                                                         |
| client\_secret | <p>e.g. 45RtnwFe40Kgr...6edaaWgge334gHR</p><p>This is your Client Secret which has been supplied by Bright.</p>                                                          |
| scope          | <p>offline\_access%20https%3A%2F%2Flogin.brightsg.com%2F456b7587-bc0e-4a1e-824e-756b078a2ade%2Fbrightpay.online.external.api</p><p>Set the scope to the value above.</p> |

The Bright Identity Provider will respond with JSON similar to below:

{% code overflow="wrap" %}

```
{
"access_token":"tyT34Tethrhe…R4ereRErrbj4w",
"token_type":"Bearer",
"not_before":1719402949,
"expires_in":300,
"expires_on":1719438949,
"resource":"456b7587-bc0e-4a1e-824e-756b078a2ade",
"profile_info":" ere12…wew33223221",
"scope":"https://login.brightsg.com/456b7587-bc0e-4a1e-824e-756b078a2ade/brightpay.online.external.api offline_access",
"refresh_token":" EyWEWA…QwdfGIed2 ",
"refresh_token_expires_in":7776000
}
```

{% endcode %}

Which is broken down as

<table><thead><tr><th width="185">Item</th><th>Description</th></tr></thead><tbody><tr><td>access_token</td><td>The Access token, this can be added as a http request header to interact with Bright APIs.</td></tr><tr><td>expires_in</td><td>How long in seconds before the access token expires (300 seconds = 5 minutes).</td></tr><tr><td>refresh_token</td><td>The Refresh token, this can be used to retrieve another Access token. Note this is a new value and should be stored as a replacement of the current Refresh token.</td></tr><tr><td>refresh_token_expires_in</td><td>How long before the Refresh token expires (7776000 seconds = 90 days)</td></tr></tbody></table>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://devdocs.brightpay.com/authentication/retrieving-a-refresh-and-access-token.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
