# Admin API Authentication

The Admin API uses the OAuth 2.0 **Client Credentials** grant — a server-to-server flow that does not require user interaction. It is intended for backend automation, CI/CD pipelines, and programmatic management of connections and tokens across your Makini account.

> **When to use this vs Makini Link**
> Use the Admin API when *your own backend* needs to act on your Makini account — generating tokens, listing connections, or managing resources programmatically. Use [Makini Link](./authentication) when *your end users* need to authorize their own systems.

## Prerequisites

Before making Admin API requests, retrieve your credentials from the Makini dashboard:

1. Navigate to **Settings > Application Settings**.
2. Copy your **Client ID** and **Client Secret**.

> Keep your Client Secret confidential. Never expose it in client-side code, public repositories, or frontend applications.

## Obtaining an Access Token

Send a `POST` request to the token endpoint with your credentials:

```http
POST https://api.makini.io/link/token
Content-Type: application/json
Accept: application/json

{
  "grant_type": "client_credentials",
  "client_id": "YOUR_CLIENT_ID",
  "client_secret": "YOUR_CLIENT_SECRET"
}
```

A successful response returns an access token and a refresh token:

```json
{
  "access_token": "eyJ0eXAiOiJKV1Qi...",
  "refresh_token": "eyJ0eXAiOiJSZWZy...",
  "token_type": "bearer",
  "expires_in": 1715674414
}
```

| Field | Description |
| --- | --- |
| `access_token` | Bearer token used to authenticate Admin API requests. Valid for **30 days**. |
| `refresh_token` | Used to obtain a new token pair before expiry. Valid for **31 days**. |
| `token_type` | Always `bearer`. |
| `expires_in` | Token expiry as a Unix timestamp. |

## Making Authenticated Requests

Include the access token in the `Authorization` header of every Admin API request:

```http
GET https://api.makini.io/v4/connections
Accept: application/json
Authorization: Bearer YOUR_ACCESS_TOKEN
```

Requests without a valid token, or with an expired token, return `401 Unauthorized`.

## Refreshing a Token

When the access token is near expiry, use the refresh token to obtain a new pair without repeating the full credentials flow:

```http
POST https://api.makini.io/link/token
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token
&refresh_token=YOUR_REFRESH_TOKEN
&client_id=YOUR_CLIENT_ID
&client_secret=YOUR_CLIENT_SECRET
```

The response contains a new `access_token` and `refresh_token`. The previous tokens are invalidated.

> It is recommended to set up a scheduled job that refreshes the token at an interval shorter than 30 days to avoid service interruption.

If the refresh token has also expired, repeat the full [token request](#obtaining-an-access-token) using your Client ID and Client Secret.

## Token Expiration Reference

| Token | Lifetime |
| --- | --- |
| Access token | 30 days |
| Refresh token | 31 days |

## Example: Listing Connections

With a valid access token, the following request returns all connections associated with your account:

```bash
curl https://api.makini.io/v4/connections \
  -H "Accept: application/json" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

See the [Connections](./connections) page for details on connection properties and statuses.

## Troubleshooting

| Symptom | Likely cause |
| --- | --- |
| `401 Unauthorized` | Access token expired or malformed. Refresh or re-issue the token. |
| `400 Bad Request` on token endpoint | Incorrect `grant_type`, or malformed JSON/form body. |
| `403 Forbidden` | `client_id` or `client_secret` is invalid. Verify credentials in Application Settings. |
| Refresh returns `401` | Refresh token has expired. Re-authenticate using client credentials. |
