> For the complete documentation index, see [llms.txt](https://docs.mdintegrations.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.mdintegrations.com/partner/troubleshooting/technical-concepts/token-expiration-and-refresh.md).

# Token Expiration & Refresh

Access tokens issued by the MDI auth endpoint expire after **30 minutes**. Because of that, your integration needs a real strategy for regenerating a token before it expires, or immediately after — one that avoids interrupting the request in flight any more than necessary.

## Tokens last 60 minutes

An access token obtained from the `client_credentials` grant is valid for 60 minutes from the moment it's issued. Once that window closes, the token simply stops working, and you regenerate it by calling the same token endpoint again with your `client_id` and `client_secret` — there's no separate "refresh token" grant to learn; you just request a new access token the same way you got the first one.

* Store the `access_token` you receive from `/v1/partner/auth/token` as an opaque string.
* Use the response to know when the token was issued, so you can calculate when its 60-minute window closes.
* Never persist a token past 60 minutes and assume it still works — always regenerate it before then.

{% hint style="info" %}
The token response also includes an `expires_in` value at issuance time, which reflects the same 30-minute lifetime. Use whichever is more convenient for your integration's internal bookkeeping — both point at the same expiration.
{% endhint %}

## Cache and refresh proactively

Requesting a new token on every single API call would technically work, but it's wasteful and adds latency to every request you make. A better approach is to:

{% stepper %}
{% step %}
Request a token once and cache it (in memory, or in a short-lived store if your integration runs across multiple processes).
{% endstep %}

{% step %}
Track when it was issued, and plan to regenerate it before the 30-minute window closes.
{% endstep %}

{% step %}
Before that window closes, request a fresh token and replace the cached one — ahead of your next API call, not in response to a failure.
{% endstep %}
{% endstepper %}

Handled this way, your integration never needs to retry a request just because the token happened to expire mid-flight.

{% hint style="info" %}
Because the window is short, proactive caching matters even more than it would with a longer-lived token. An integration that requests a fresh token on every call will be regenerating tokens constantly — caching and refreshing ahead of expiration, as described above, keeps that overhead out of your request path instead of adding a token request to every single call.
{% endhint %}

## Refresh on 401 as a safety net

Even with proactive refresh in place, it's worth building a fallback: if any request comes back with a `401` status, treat it as "the token is no longer valid" regardless of the underlying reason, request a new token from the same endpoint using your `client_id` and `client_secret`, and retry the original request once with the new token.

```http
POST https://api.mdintegrations.com/v1/partner/auth/token
Content-Type: application/json
```

```json
{
  "grant_type": "client_credentials",
  "client_id": "[your_client_id]",
  "client_secret": "[your_secret]",
  "scope": "*"
}
```

Together, these two habits — caching and refreshing proactively, while always staying ready to refresh reactively on a `401` — cover both routine expiration and edge cases like a credential being rotated or revoked mid-session. See Error Codes & Handling for how `401` fits alongside the platform's other error responses.

{% hint style="warning" %}
Don't retry indefinitely. If a fresh token still results in a `401`, stop and surface the failure — it likely means the credential itself is invalid or has been revoked, not that the token expired.
{% endhint %}


---

# 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, and the optional `goal` query parameter:

```
GET https://docs.mdintegrations.com/partner/troubleshooting/technical-concepts/token-expiration-and-refresh.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
