> ## Documentation Index
> Fetch the complete documentation index at: https://docs.smokeball.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Client Credentials Grant

> Use the Client Credentials Grant to authenticate and authorize server-to-server operations

The **Client Credentials** grant type is typically used for server-to-server API operations. In this scenario, you are not acting as a Smokeball user but a type of "service" that can perform operations on an Account level.

## Request an Access Token

Make a POST request to `https://auth.smokeball.com/oauth2/token` with the following parameters and headers:

<CodeGroup>
  ```bash curl theme={"dark"}
    curl --request POST 'https://auth.smokeball.com/oauth2/token' \
      --header 'Authorization: Basic Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQ=' \
      --header 'Content-Type: application/x-www-form-urlencoded' \
      --data-urlencode 'grant_type=client_credentials' \
      --data-urlencode 'client_id=xxxx'
  ```

  ```json http theme={"dark"}
  {
    "method": "POST",
    "url": "https://auth.smokeball.com/oauth2/token",
    "headers": {
      "Authorization": "Basic Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQ=",
      "Content-Type": "application/x-www-form-urlencoded"
    },
    "body": {
      "grant_type": "client_credentials",
      "client_id": "xxxx"
    }
  }
  ```
</CodeGroup>

<ParamField path="Authorization" type="string" required="true">
  Basic Authentication header containing the `client_id` and `client_secret` (base64-encoded).

  Format: `Basic base64(client_id:client_secret)`.

  Example: `Basic Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQ=`
</ParamField>

<ParamField path="Content-Type" type="string" required="true">
  Must be set to `application/x-www-form-urlencoded`.
  Ensures the request body is properly encoded.
</ParamField>

<ParamField path="grant_type" type="string" required="true">
  Must be set to `client_credentials` for this OAuth 2.0 flow.

  Indicates the request is for client credentials grant.
</ParamField>

<ParamField path="client_id" type="string" required="true">
  The client identifier that has been issued.

  Used to authenticate the client making the request.
</ParamField>

> The **Authorization** header must be the string "Basic" followed by your client\_id and client\_secret with a colon : in between, Base64 Encoded. For example, client\_id:client\_secret is Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQ=

**Sample Response**

```json theme={"dark"}
HTTP/1.1 200 OK
Content-Type: application/json

{
    "access_token": "dmcxd329ujdmkemkd349r...",
    "expires_in": 3600,
    "token_type": "Bearer"
}
```

<ResponseField name="access_token" type="string">
  The token to use in the `Authorization` header when making API requests.
</ResponseField>

<ResponseField name="expires_in" type="number">
  The lifetime of the access token in **seconds**.

  After expiration, a new token must be obtained.
</ResponseField>

<ResponseField name="token_type" type="string">
  The type of token returned. Always `Bearer`.
</ResponseField>

## Caching Access Tokens

We recommend caching your access token and reusing it until it expires, rather than requesting a new token for every API request. Requesting a token on every request adds latency to each call and places unnecessary load on the token endpoint.

When you receive a token, store it along with its expiry time (calculated from `expires_in`, which is the token lifetime in seconds). Reuse the cached token for all API requests until it is close to expiry, then request a new one. A common approach is to refresh the token slightly before it expires (for example, 60 seconds early) to avoid using an expired token on an in-flight request.

> See [Making Requests - Server-to-Server requests](/docs/api-docs/ivmfjbc61tvjs-making-requests#server-to-server-requests) for details on using Client Credentials.
