From 91886eb2385499b9a2e25bd3ee8881cea8328876 Mon Sep 17 00:00:00 2001 From: Dmitry Studynsky Date: Thu, 16 Jul 2026 10:48:22 -0400 Subject: [PATCH 1/2] AUT-1473 Document session-capped token TTLs in Authentication API Explain that access/refresh token pairs are capped to a 12-hour session lifespan, so expiresIn/refreshExpiresIn shrink near the end of a session, and guide developers to re-authenticate rather than keep refreshing. Co-Authored-By: Claude Sonnet 5 --- spec/openapi.yaml | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/spec/openapi.yaml b/spec/openapi.yaml index 92df2af7..3f4acebd 100644 --- a/spec/openapi.yaml +++ b/spec/openapi.yaml @@ -79,6 +79,20 @@ tags: } ``` + **A note on session lifetime:** + + Every access/refresh token pair is tied to a single underlying session, + which has a fixed maximum lifespan of 12 hours, regardless of + how many times you refresh. As a session approaches that limit, + refreshing will return an access/refresh token pair capped to whatever + time remains in the session rather than the usual TTLs, and if you keep + refreshing right up to the end, requests will eventually fail with a + 401 even though you never technically ran out of refreshes. If you + notice `refreshExpiresIn` shrinking across successive refresh calls, + treat it as a sign the session is ending soon, and call + `/auth-api/v2/authenticate` again with your `userIdentifier` and + `userSecret` to start a new session. + - name: Account & Projects description: |- Each client within Smartling is given their own account with a designated @@ -435,6 +449,16 @@ paths: description: >- A [renewed access token](https://help.smartling.com/hc/en-us/articles/1260805176849) that can be attached to the header of any API request. + + + Refreshing does not reset your session - it only issues a new token + pair within the current session's remaining lifetime, which is capped + to 12 hours. As that session nears its maximum lifespan, the `expiresIn` + and `refreshExpiresIn` values in the response will shrink to whatever + time is left, and will eventually expire outright even though the + refresh token hasn't been used up. If `refreshExpiresIn` keeps getting + shorter across refreshes, don't just refresh faster - call + `/auth-api/v2/authenticate` again to start a fresh session. summary: Refresh access token operationId: refreshAccessToken requestBody: @@ -9800,10 +9824,24 @@ components: the user. type: string expiresIn: - description: TTL (time-to-live) in seconds for the access token. + description: >- + TTL (time-to-live) in seconds for the access token. This value can be + smaller than usual as the underlying session approaches its maximum + lifespan; see `refreshExpiresIn` below. type: integer refreshExpiresIn: - description: TTL (time-to-live) in seconds for the refresh token. + description: >- + TTL (time-to-live) in seconds for the refresh token. Every + access/refresh token pair belongs to an underlying session that has a + fixed maximum lifespan of 12 hours, regardless of how many + times you refresh. As a session nears that limit, this value is + capped to whatever time is left in the session, so it will shrink on + each successive refresh instead of resetting to its usual value, and + can eventually reach zero even though the refresh token itself has + not expired. Treat a shrinking `refreshExpiresIn` as a signal that + the session is ending soon, and call `/auth-api/v2/authenticate` + again with your `userIdentifier` and `userSecret` to start a new + session, rather than continuing to refresh. type: integer refreshToken: description: A kind of token that can be used to obtain a renewed access token. From 6866b2c74dfe0f23dfa92df5f578f1771d3d79bc Mon Sep 17 00:00:00 2001 From: Dmitry Studynsky Date: Fri, 17 Jul 2026 08:48:27 -0400 Subject: [PATCH 2/2] AUT-1473 Apply wording review feedback to session-lifetime docs Fix self-contradiction in tag description, replace dash-as-separator with colon and drop stray blank line in refresh endpoint description, and trim the third redundant copy of the session-cap explanation in the refreshExpiresIn schema description. Co-Authored-By: Claude Sonnet 5 --- spec/openapi.yaml | 57 +++++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 31 deletions(-) diff --git a/spec/openapi.yaml b/spec/openapi.yaml index 3f4acebd..5f8c73db 100644 --- a/spec/openapi.yaml +++ b/spec/openapi.yaml @@ -81,17 +81,15 @@ tags: **A note on session lifetime:** - Every access/refresh token pair is tied to a single underlying session, - which has a fixed maximum lifespan of 12 hours, regardless of - how many times you refresh. As a session approaches that limit, - refreshing will return an access/refresh token pair capped to whatever - time remains in the session rather than the usual TTLs, and if you keep - refreshing right up to the end, requests will eventually fail with a - 401 even though you never technically ran out of refreshes. If you - notice `refreshExpiresIn` shrinking across successive refresh calls, - treat it as a sign the session is ending soon, and call - `/auth-api/v2/authenticate` again with your `userIdentifier` and - `userSecret` to start a new session. + Every access/refresh token pair belongs to a single underlying session, + which has a fixed maximum lifespan of 12 hours no matter how many times + the pair is refreshed. As a session nears that limit, refreshing returns + a token pair capped to whatever time is left in the session rather than + the usual TTLs. Refreshing past that point eventually returns a 401, + even though the refresh token itself hasn't expired. A shrinking + `refreshExpiresIn` across successive refreshes is a sign the session is + ending soon: call `/auth-api/v2/authenticate` again with the same + `userIdentifier` and `userSecret` to start a new session. - name: Account & Projects description: |- @@ -450,15 +448,14 @@ paths: A [renewed access token](https://help.smartling.com/hc/en-us/articles/1260805176849) that can be attached to the header of any API request. - - Refreshing does not reset your session - it only issues a new token - pair within the current session's remaining lifetime, which is capped - to 12 hours. As that session nears its maximum lifespan, the `expiresIn` - and `refreshExpiresIn` values in the response will shrink to whatever - time is left, and will eventually expire outright even though the - refresh token hasn't been used up. If `refreshExpiresIn` keeps getting - shorter across refreshes, don't just refresh faster - call - `/auth-api/v2/authenticate` again to start a fresh session. + Refreshing does not reset the session: it only issues a new token + pair within the session's remaining lifetime, which is capped to + 12 hours. As the session nears that limit, `expiresIn` and + `refreshExpiresIn` shrink to whatever time is left, and can + eventually reach zero even though the refresh token hasn't expired. + A shrinking `refreshExpiresIn` across repeated refreshes is a sign + the session is ending: call `/auth-api/v2/authenticate` again to + start a new session, rather than refreshing more often. summary: Refresh access token operationId: refreshAccessToken requestBody: @@ -9831,17 +9828,15 @@ components: type: integer refreshExpiresIn: description: >- - TTL (time-to-live) in seconds for the refresh token. Every - access/refresh token pair belongs to an underlying session that has a - fixed maximum lifespan of 12 hours, regardless of how many - times you refresh. As a session nears that limit, this value is - capped to whatever time is left in the session, so it will shrink on - each successive refresh instead of resetting to its usual value, and - can eventually reach zero even though the refresh token itself has - not expired. Treat a shrinking `refreshExpiresIn` as a signal that - the session is ending soon, and call `/auth-api/v2/authenticate` - again with your `userIdentifier` and `userSecret` to start a new - session, rather than continuing to refresh. + TTL (time-to-live) in seconds for the refresh token. This value + is tied to the token pair's underlying session, which has a + fixed maximum lifespan of 12 hours regardless of how many times + the pair is refreshed. As the session nears that limit, + `refreshExpiresIn` shrinks toward zero rather than resetting to + its usual value, even though the refresh token itself hasn't + expired. A shrinking value is a signal to call + `/auth-api/v2/authenticate` again and start a new session, + rather than continue refreshing. type: integer refreshToken: description: A kind of token that can be used to obtain a renewed access token.