OPT-OAU-006Bank's choiceinconsistencyOAuth2 and tokens

Refresh token and rotation

Does the bank issue a refresh token, and does it rotate it?

The options

  • No refresh token

    refresh_token is optional in authorization code, OpenID Connect and CIBA responses. It never exists with client credentials or for the PISP confirmation.

  • Without rotation

    The same refresh token works until it is revoked.

  • With rotation

    The refresh response can contain a new refresh token, which replaces the old one.

Bank side
A revoked refresh token returns 400. The scope can be specified on refresh (aisp or cbpii), without extended_transaction_history.
TPP side
Keep the new refresh token if there is one, otherwise keep the old one. Without a refresh token, start a new SCA when the access token expires.
Spec inconsistency
The spec writes the error as invalid grant, with a space, where RFC 6749 says invalid_grant.

Entry checked on October 19, 2026.

Based on the STET PSD2 API 1.6.3 specification, licensed CC BY 3.0 FR.

The entry as stored
{
  "id": "OPT-OAU-006",
  "edition": "1.6.3",
  "chooser": "aspsp",
  "title": {
    "fr": "Refresh token et rotation",
    "en": "Refresh token and rotation",
    "es": "Refresh token y rotación",
    "pt-br": "Refresh token e rotação"
  },
  "question": {
    "fr": "La banque émet-elle un refresh token, et le fait-elle tourner ?",
    "en": "Does the bank issue a refresh token, and does it rotate it?",
    "es": "¿Emite el banco un refresh token, y lo rota?",
    "pt-br": "O banco emite um refresh token e faz a rotação dele?"
  },
  "options": [
    {
      "label": {
        "fr": "Pas de refresh token",
        "en": "No refresh token",
        "es": "Sin refresh token",
        "pt-br": "Sem refresh token"
      },
      "text": {
        "fr": "`refresh_token` est optionnel dans les réponses authorization code, OpenID Connect et CIBA. Il n'existe jamais en client credentials ni pour la confirmation PISP.",
        "en": "`refresh_token` is optional in authorization code, OpenID Connect and CIBA responses. It never exists with client credentials or for the PISP confirmation.",
        "es": "`refresh_token` es opcional en las respuestas authorization code, OpenID Connect y CIBA. Nunca existe en client credentials ni para la confirmación PISP.",
        "pt-br": "`refresh_token` é opcional nas respostas de authorization code, OpenID Connect e CIBA. Ele nunca existe em client credentials nem na confirmação PISP."
      }
    },
    {
      "label": {
        "fr": "Sans rotation",
        "en": "Without rotation",
        "es": "Sin rotación",
        "pt-br": "Sem rotação"
      },
      "text": {
        "fr": "Le même refresh token sert jusqu'à sa révocation.",
        "en": "The same refresh token works until it is revoked.",
        "es": "El mismo refresh token sirve hasta que se revoca.",
        "pt-br": "O mesmo refresh token vale até ser revogado."
      }
    },
    {
      "label": {
        "fr": "Avec rotation",
        "en": "With rotation",
        "es": "Con rotación",
        "pt-br": "Com rotação"
      },
      "text": {
        "fr": "La réponse au refresh peut contenir un nouveau refresh token, qui remplace l'ancien.",
        "en": "The refresh response can contain a new refresh token, which replaces the old one.",
        "es": "La respuesta al refresh puede contener un nuevo refresh token, que sustituye al anterior.",
        "pt-br": "A resposta ao refresh pode conter um novo refresh token, que substitui o anterior."
      }
    }
  ],
  "stet": {
    "sections": [
      {
        "part": "framework",
        "section": "3.4.2.9",
        "page": 41
      }
    ],
    "openapi": [],
    "flows": [],
    "changes": [],
    "remark": null
  },
  "aspsp": {
    "fr": "Un refresh token révoqué renvoie 400. Le scope peut être précisé au refresh (`aisp` ou `cbpii`), sans `extended_transaction_history`.",
    "en": "A revoked refresh token returns 400. The scope can be specified on refresh (`aisp` or `cbpii`), without `extended_transaction_history`.",
    "es": "Un refresh token revocado devuelve 400. El scope puede indicarse en el refresh (`aisp` o `cbpii`), sin `extended_transaction_history`.",
    "pt-br": "Um refresh token revogado retorna 400. O scope pode ser especificado no refresh (`aisp` ou `cbpii`), sem `extended_transaction_history`."
  },
  "tpp": {
    "fr": "Garder le nouveau refresh token s'il y en a un, sinon conserver l'ancien. Sans refresh token, relancer une SCA à l'expiration de l'access token.",
    "en": "Keep the new refresh token if there is one, otherwise keep the old one. Without a refresh token, start a new SCA when the access token expires.",
    "es": "Guardar el nuevo refresh token si lo hay; si no, conservar el anterior. Sin refresh token, lanzar una nueva SCA cuando expire el access token.",
    "pt-br": "Guardar o novo refresh token, se houver, ou então manter o anterior. Sem refresh token, refazer uma SCA quando o access token expirar."
  },
  "regulation": null,
  "note": {
    "fr": "La spec écrit l'erreur `invalid grant`, avec une espace, là où la RFC 6749 dit `invalid_grant`.",
    "en": "The spec writes the error as `invalid grant`, with a space, where RFC 6749 says `invalid_grant`.",
    "es": "La especificación escribe el error `invalid grant`, con un espacio, donde la RFC 6749 dice `invalid_grant`.",
    "pt-br": "A especificação escreve o erro `invalid grant`, com espaço, onde a RFC 6749 diz `invalid_grant`."
  },
  "production": null,
  "verifiedAt": "2026-10-19"
}