Skip to navigation

Exchange a refresh token for a new token pair

Returns a new access token and a new refresh token. The refresh token you send is spent by this call.

A spent token still redeems for a short grace window (currently 30 seconds), and returns the same successor the first refresh issued. After the window it is refused with 401. So concurrent refreshes with one token all succeed with the same new refresh token, and a refresh whose response was lost can be retried promptly.

The contract a client must implement:

  1. On a 401 from another endpoint, refresh once and retry the original request once. A 401 from this endpoint, or from the retried request, ends the session.
  2. Store the refresh from the response, replacing the one you sent. Concurrent refreshes return the same one, so the last response stored wins harmlessly.
  3. Single-flighting refreshes is an optimisation, not a requirement.
  4. 429 is a rate limit, not a sign-out: back off and retry.

Refreshing pushes back the idle timeout, never the hard cap. The new refresh token expires one idle period from now, or at the cap counted from sign-in if that is sooner. The sign-in time is carried unchanged in every rotated token, and an access token never outlives its refresh token.

Authentication is by the refresh token in the body, not by the Authorization header, so this endpoint takes no bearer token.

Rate limited per user (not per IP), so colleagues sharing an office egress address do not share a budget.

Request

This endpoint expects an object.
refreshstringRequired

The refresh token last issued to this client — either from login or from the previous refresh.

Response

A fresh token pair. The token you sent is spent; inside the grace window it returns this same refresh token again.

accessstringOptional
A new access token.
refreshstringOptional

The successor refresh token. Replace your stored copy with this one. It expires one idle period from now, or at the session's hard cap from sign-in if that is sooner.

Errors

401
Unauthorized Error
429
Too Many Requests Error