# Basic authentication with client credentials The Pismo platform supports server-to-server (S2S) authentication using stored credentials. This is similar to a username/password system, except it uses a `server_key` and a `server_secret` key. The Pismo platform's Passport API allows server-to-server authentication, so a proxy server can execute some operations. For example, in the case of a person using an app on a mobile device or an operator using a CRM system, the authentication process should go through a proxy server. # Initial authentication When first logging in from an external server, you need to send the Pismo platform a request to create an access token. Pismo will return a JSON Web Token (JWT). You must include your `server_key` and `server_secret` in the body of the request. If you intend to make calls on behalf of a specific account, you must also include the corresponding account identifier (`account_id`). If you provide an account identifier, subsequent calls can only access resources that belong to that particular account. You can find a complete list of the endpoints that you can use for requests in the API Reference. For a list of the endpoints that require the account identifier, see [Endpoints that require an account-specific token](https://developers.pismo.io/pismo-docs/reference/endpoints-that-require-an-account-specific-token). To request an access token, use the following endpoint. [Get basic authentication access token](https://developers.pismo.io/pismo-docs/reference/post-passport-v2-s2s-access-token)\ Request body: ```json { "server_key": "", "server_secret": "", "account_id": } ``` The following code shows an example of a response body for this request. It includes an access token (`token`), which you can use as an authorization header in future requests. ```json { "server_key": "", "tenant": "", "program_ids": [], "roles": [ "account-server", "onboarding-server", "crm-server", "crm-operator" ], "token": "eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJQYXNzcG9ydCIsInN1YiI6IkFVVEgtNjQ1ZmEwMjgtMzJiOS00N2Y3LWJiYTgtZWEyMDRlYTllZmI4IiwiZXhwIjoxNjQzODIxMDAzLCJpYXQiOjE2NDM4MjA0MDMsInVpZCI6IlROLTZhZWM2MTNmLTQ0YmEtNDE4NC05NDg4LWJmMDM0M2U3NDczNDo2NzgxOTM3MTY2OGE2MmRjMWIxMjE4YTQ4NGE4YzQ1NTE2NWU0OTkwIiwidGt2ZXIiOiIyIn0.EhofQQDZLzOca90dAqnv5QfX17gLYfE-qXUiADf-1ZlixnwaSsaBU2ombiYRJM0NtGfo2V_UqWbszKmEtTF2VA", "refresh": "eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJQYXNzcG9ydCIsInN1YiI6IkFVVEgtNjQ1ZmEwMjgtMzJiOS00N2Y3LWJiYTgtZWEyMDRlYTllZmI4IiwiZXhwIjoxNjQzODIxMDAzLCJpYXQiOjE2NDM4MjA0MDMsInVpZCI6IlROLTZhZWM2MTNmLTQ0YmEtNDE4NC05NDg4LWJmMDM0M2U3NDczNDo2NzgxOTM3MTY2OGE2MmRjMWIxMjE4YTQ4NGE4YzQ1NTE2NWU0OTkwIiwidGt2ZXIiOiIyIn0.EhofQQDZLzOca90dAqnv5QfX17gLYfE-qXUiADf-1ZlixnwaSsaBU2ombiYRJM0NtGfo2V_UqWbszKmEtTF2VA" } ``` > 📘 Access tokens expire after 10 minutes > > Your application should catch the error generated when this happens. It can then generate another JWT, sign it, and request another access token. # Renewing an expired token The access token has a predefined lifetime. There is an `exp` field in the JWT that contains the date/time of expiration in [Unix Epoch time](https://www.unixtutorial.org/epoch-time/). After the access token expires, the Pismo platform rejects additional requests. If you make a request using an expired token, the request returns `Unauthorized`. You should check for this message in your code and request a new access token when you receive it. > 📘 > > You can use the [JWT Debugger](https://jwt.io/) website to view the fields in a JWT. Holding the mouse pointer over the decoded `exp` value displays it as a human-readable date/time. > > If you need to access the field values in your code, see [Parsing the JWT](https://developers.pismo.io/pismo-docs/docs/verifying-webhook-requests#parsing-the-jwt).