> ## Documentation Index
> Fetch the complete documentation index at: https://api-docs.voicecheap.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Wissel een autorisatiecode in of roteer een vernieuwingstoken

> Verkrijg kort geldige MCP-toegangstokens met de S256-autorisatiecode of het huidige vernieuwingstoken van een publieke client.

Verkrijg kort geldige MCP-toegangstokens met de S256-autorisatiecode of het huidige vernieuwingstoken van een publieke client.

```http theme={null}
POST https://api.voicecheap.ai/oauth/token
```

## Authenticatie

Geen HTTP-clientauthenticatie. Stuur client\_id in de URL-gecodeerde body. Elke Authorization-header, client\_secret of client\_assertion wordt geweigerd.

## Aanvraagbody

<Expandable title="grant_type: authorization_code">
  <ParamField body="client_id" type="string" required>
    De client\_id uit dynamische registratie of de exacte openbare HTTPS-URL van het clientmetadatadocument.

    Minimale lengte: 1. Maximale lengte: 2048. Patroon: `^[^\u0000-\u001F\u007F]+$`.
  </ParamField>

  <ParamField body="resource" type="string" required>
    Vereiste exacte resource-audience: gebruik de resource-waarde uit de metadata van de beschermde resource van deze omgeving. In productie is dit [https://api.voicecheap.ai/mcp](https://api.voicecheap.ai/mcp). Een andere origin, een ander pad of een afsluitende slash wordt geweigerd.

    Formaat: "uri".
  </ParamField>

  <ParamField body="grant_type" type="field" required>
    Waarde zoals gedefinieerd in het volledige invoerschema.

    Vereiste waarde: "authorization\_code".
  </ParamField>

  <ParamField body="code" type="string" required>
    Eenmalige code die naar de exact geregistreerde callback wordt teruggestuurd.

    Minimale lengte: 1. Maximale lengte: 256. Patroon: `^mcp_code_[A-Za-z0-9_-]{43}$`.
  </ParamField>

  <ParamField body="redirect_uri" type="string" required>
    Moet exact gelijk zijn aan de callback die aan deze code en registratie is gekoppeld.

    Minimale lengte: 1. Maximale lengte: 2048. Patroon: `^[^\u0000-\u001F\u007F]+$`.
  </ParamField>

  <ParamField body="code_verifier" type="string" required>
    Oorspronkelijke PKCE-verifier die is gebruikt om de S256 code\_challenge van de autorisatieaanvraag te berekenen.

    Minimale lengte: 43. Maximale lengte: 128. Patroon: `^[A-Za-z0-9._~-]{43,128}$`.
  </ParamField>
</Expandable>

<Expandable title="grant_type: refresh_token">
  <ParamField body="client_id" type="string" required>
    De client\_id uit dynamische registratie of de exacte openbare HTTPS-URL van het clientmetadatadocument.

    Minimale lengte: 1. Maximale lengte: 2048. Patroon: `^[^\u0000-\u001F\u007F]+$`.
  </ParamField>

  <ParamField body="resource" type="string" required>
    Vereiste exacte resource-audience: gebruik de resource-waarde uit de metadata van de beschermde resource van deze omgeving. In productie is dit [https://api.voicecheap.ai/mcp](https://api.voicecheap.ai/mcp). Een andere origin, een ander pad of een afsluitende slash wordt geweigerd.

    Formaat: "uri".
  </ParamField>

  <ParamField body="grant_type" type="field" required>
    Waarde zoals gedefinieerd in het volledige invoerschema.

    Vereiste waarde: "refresh\_token".
  </ParamField>

  <ParamField body="refresh_token" type="string" required>
    Het huidige, nog niet gebruikte vernieuwingstoken van een client die voor refresh\_token is geregistreerd.

    Minimale lengte: 1. Maximale lengte: 256. Patroon: `^mcp_refresh_[A-Za-z0-9_-]{43}$`.
  </ParamField>

  <ParamField body="scope" type="string">
    Door spaties gescheiden deelverzameling van de oorspronkelijke rechten, eventueel met offline\_access. Niet-ondersteunde namen, lege waarden en extra rechten worden geweigerd; duplicaten worden verwijderd. Een expliciete scope behoudt alleen de genoemde product- en identiteitsrechten en kan alle productrechten verwijderen. Laat scope weg om de huidige autorisatie te behouden, behalve dat identiteitsrechten vervallen als OpenID Connect niet beschikbaar is.

    Minimale lengte: 1. Maximale lengte: 2048. Patroon: `^ *(?:account:read|usage:read|settings:read|settings:write|team:read|team:write|projects:read|projects:write|projects:delete|translations:write|transcription:read|transcription:write|subtitles:read|subtitles:write|tts:read|tts:write|voices:read|voices:write|images:read|images:write|thumbnails:read|thumbnails:write|folders:read|folders:write|glossary:read|glossary:write|webhooks:read|webhooks:write|publishing:read|publishing:write|offline_access|openid|email)(?: +(?:account:read|usage:read|settings:read|settings:write|team:read|team:write|projects:read|projects:write|projects:delete|translations:write|transcription:read|transcription:write|subtitles:read|subtitles:write|tts:read|tts:write|voices:read|voices:write|images:read|images:write|thumbnails:read|thumbnails:write|folders:read|folders:write|glossary:read|glossary:write|webhooks:read|webhooks:write|publishing:read|publishing:write|offline_access|openid|email))* *$`.
  </ParamField>
</Expandable>

<Accordion title="Technisch schema">
  ```json theme={null}
  {
    "oneOf": [
      {
        "type": "object",
        "properties": {
          "client_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2048,
            "pattern": "^[^\\u0000-\\u001F\\u007F]+$",
            "description": "The client_id returned by dynamic registration, or the exact public HTTPS URL of the client metadata document."
          },
          "resource": {
            "type": "string",
            "format": "uri",
            "description": "Required exact resource audience: use the resource value from this environment's protected-resource metadata. In production this is https://api.voicecheap.ai/mcp. A different origin, path, or trailing slash is rejected.",
            "examples": [
              "https://api.voicecheap.ai/mcp"
            ]
          },
          "grant_type": {
            "const": "authorization_code"
          },
          "code": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256,
            "pattern": "^mcp_code_[A-Za-z0-9_-]{43}$",
            "description": "Single-use code returned to the exact registered callback."
          },
          "redirect_uri": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2048,
            "pattern": "^[^\\u0000-\\u001F\\u007F]+$",
            "description": "Must exactly equal the callback bound to this code and registration."
          },
          "code_verifier": {
            "type": "string",
            "minLength": 43,
            "maxLength": 128,
            "pattern": "^[A-Za-z0-9._~-]{43,128}$",
            "description": "Original PKCE verifier used to calculate the authorization request's S256 code_challenge."
          }
        },
        "required": [
          "grant_type",
          "client_id",
          "resource",
          "code",
          "redirect_uri",
          "code_verifier"
        ],
        "not": {
          "anyOf": [
            {
              "required": [
                "client_secret"
              ]
            },
            {
              "required": [
                "client_assertion"
              ]
            }
          ]
        },
        "additionalProperties": true
      },
      {
        "type": "object",
        "properties": {
          "client_id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2048,
            "pattern": "^[^\\u0000-\\u001F\\u007F]+$",
            "description": "The client_id returned by dynamic registration, or the exact public HTTPS URL of the client metadata document."
          },
          "resource": {
            "type": "string",
            "format": "uri",
            "description": "Required exact resource audience: use the resource value from this environment's protected-resource metadata. In production this is https://api.voicecheap.ai/mcp. A different origin, path, or trailing slash is rejected.",
            "examples": [
              "https://api.voicecheap.ai/mcp"
            ]
          },
          "grant_type": {
            "const": "refresh_token"
          },
          "refresh_token": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256,
            "pattern": "^mcp_refresh_[A-Za-z0-9_-]{43}$",
            "description": "The current unconsumed refresh token from a client registered for refresh_token."
          },
          "scope": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2048,
            "pattern": "^ *(?:account:read|usage:read|settings:read|settings:write|team:read|team:write|projects:read|projects:write|projects:delete|translations:write|transcription:read|transcription:write|subtitles:read|subtitles:write|tts:read|tts:write|voices:read|voices:write|images:read|images:write|thumbnails:read|thumbnails:write|folders:read|folders:write|glossary:read|glossary:write|webhooks:read|webhooks:write|publishing:read|publishing:write|offline_access|openid|email)(?: +(?:account:read|usage:read|settings:read|settings:write|team:read|team:write|projects:read|projects:write|projects:delete|translations:write|transcription:read|transcription:write|subtitles:read|subtitles:write|tts:read|tts:write|voices:read|voices:write|images:read|images:write|thumbnails:read|thumbnails:write|folders:read|folders:write|glossary:read|glossary:write|webhooks:read|webhooks:write|publishing:read|publishing:write|offline_access|openid|email))* *$",
            "description": "Space-delimited subset of the original permissions, optionally including offline_access. Unsupported names, empty values, and added permissions are rejected; duplicates are removed. An explicit scope keeps only the listed product and identity permissions and may remove every product permission. Omit scope to retain the current grant, except identity permissions are dropped if OpenID Connect is unavailable.",
            "examples": [
              "account:read projects:read offline_access"
            ]
          }
        },
        "required": [
          "grant_type",
          "client_id",
          "resource",
          "refresh_token"
        ],
        "not": {
          "anyOf": [
            {
              "required": [
                "client_secret"
              ]
            },
            {
              "required": [
                "client_assertion"
              ]
            }
          ]
        },
        "additionalProperties": true
      }
    ]
  }
  ```
</Accordion>

## Voorbeeldaanvragen

Volg de gedocumenteerde codering en authenticatie voor deze route. De antwoordstructuur en idempotentieregels van de actie-API gelden alleen voor actieaanroepen.

<RequestExample>
  ```bash cURL theme={null}
  curl --request POST 'https://api.voicecheap.ai/oauth/token' \
    --header 'Content-Type: application/x-www-form-urlencoded' \
    --data-urlencode 'grant_type=authorization_code' \
    --data-urlencode 'client_id=mcp_client_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' \
    --data-urlencode 'code=mcp_code_CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC' \
    --data-urlencode 'redirect_uri=https://assistant.example.com/oauth/callback' \
    --data-urlencode 'code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk' \
    --data-urlencode 'resource=https://api.voicecheap.ai/mcp'
  ```

  ```javascript JavaScript theme={null}
  const input = {
    grant_type: 'authorization_code',
    client_id: 'mcp_client_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
    code: 'mcp_code_CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC',
    redirect_uri: 'https://assistant.example.com/oauth/callback',
    code_verifier: 'dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk',
    resource: 'https://api.voicecheap.ai/mcp',
  };
  const response = await fetch('https://api.voicecheap.ai/oauth/token', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded',
    },
    body: new URLSearchParams(input),
    redirect: 'manual',
  });
  console.log(response.status, await response.text());
  ```

  ```python Python theme={null}
  import os
  import requests

  response = requests.request(
      "POST",
      "https://api.voicecheap.ai/oauth/token",
      headers={"Content-Type":"application/x-www-form-urlencoded"},
      data={"grant_type": "authorization_code", "client_id": "mcp_client_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", "code": "mcp_code_CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC", "redirect_uri": "https://assistant.example.com/oauth/callback", "code_verifier": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk", "resource": "https://api.voicecheap.ai/mcp"},
      timeout=120,
      allow_redirects=False,
  )
  print(response.status_code, response.text)
  ```
</RequestExample>

## Antwoord

Een ondoorzichtig Bearer-toegangstoken, de resterende geldigheidsduur in seconden, toegekende machtigingen en een vernieuwingstoken wanneer de client refresh\_token heeft geregistreerd. expires\_in is maximaal 900 en kan lager zijn wanneer de autorisatie bijna verloopt.

```json HTTP 200 theme={null}
{
  "access_token": "mcp_access_DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD",
  "token_type": "Bearer",
  "expires_in": 900,
  "refresh_token": "mcp_refresh_EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE",
  "scope": "account:read projects:read offline_access"
}
```

## Antwoordheaders

```json theme={null}
{
  "Cache-Control": "no-store",
  "Pragma": "no-cache"
}
```

## Opmerkingen bij de bewerking

* Herkende scalaire parameters moeten eenmaal worden opgegeven als niet-lege strings zonder ASCII-besturingstekens of DEL. Herhaalde query-/formuliervelden worden gedecodeerd als arrays en geweigerd wanneer ze als scalaire waarden worden gelezen.
* Gebruik URL-gecodeerde formuliergegevens, zoals curl --data-urlencode per veld. Een JSON-tokenbody wordt geweigerd met invalid\_request.
* De resource-audience is vereist voor beide granttypen en moet exact overeenkomen met de MCP-URL van de omgeving die de code of het vernieuwingstoken heeft uitgegeven.
* Voor het inwisselen van een autorisatiecode zijn de oorspronkelijke client\_id, exacte redirect\_uri en overeenkomende S256 code\_verifier vereist. Codes verlopen na 2 minuten en zijn eenmalig te gebruiken.
* Het tokeneindpunt weigert elke opgegeven Authorization-header, inclusief Basic en Bearer, evenals elk bodyveld client\_secret of client\_assertion.
* Toegangstokens zijn maximaal 15 minuten geldig. Wanneer refresh\_token is geregistreerd, verlopen de verbinding en de vernieuwingstokenfamilie 30 dagen nadat de gebruiker toestemming heeft gegeven; rotatie verlengt die termijn niet.
* Of refresh\_token wordt geretourneerd, hangt af van de geregistreerde granttypen. Het hangt niet af van het opnemen van offline\_access in de autorisatieaanvraag. De geretourneerde scope voegt offline\_access toe wanneer een vernieuwingstoken wordt geretourneerd.
* Stuur voor vernieuwing grant\_type=refresh\_token met client\_id, de huidige refresh\_token, resource en optioneel een beperktere scope. Vervang het opgeslagen vernieuwingstoken atomair door de nieuwe waarde.
* Hergebruik van een verbruikte autorisatiecode of geroteerd vernieuwingstoken trekt de volledige verbinding in, inclusief alle bijbehorende toegangstokens. Wissel dezelfde code of hetzelfde vernieuwingstoken niet gelijktijdig in.
* Vernieuwingsverzoeken voegen nooit rechten toe. Met een expliciete scope blijven alleen de gevraagde product- en identiteitsrechten behouden; offline\_access behoudt geen weggelaten productrechten.
* Tokens zijn gebonden aan de gebruiker die toestemming verleent, de client, de resource-audience, het huidige teameigendom en actieve betaalde toegang. Bij ingetrokken toestemming of gewijzigd eigendom moet opnieuw verbinding worden gemaakt.
* De openbare tokenlimiet is 60 aanvragen per minuut per client-IP, gedeeld door alle workers. URL-gecodeerde body's zijn beperkt tot 32 KiB.
* OAuth-fouten retourneren error en error\_description. Fouten bij het parsen van de body kunnen eerder worden geretourneerd in de foutvorm van de integratieparser.
* openid en email zijn identiteitsrechten, los van productrechten, en worden alleen geaccepteerd als ze worden vermeld. email vereist openid. Bij de eerste autorisatie gebruikt een verzoek met alleen identiteitsscopes de standaardproductrechten die op het toestemmingsscherm staan.
* De client\_id uit dynamische registratie of de exacte openbare HTTPS-URL van het clientmetadatadocument.
* Wanneer openid is verleend, geeft het uitwisselen van de autorisatiecode ook een met RS256 ondertekend id\_token terug. Controleer de handtekening, uitgever, doelgroep, vervaltijd en nonce indien opgegeven. Verleende identiteitsscopes staan in scope van het tokenantwoord; vernieuwingsantwoorden geven geen nieuw id\_token uit.
* Als OpenID Connect niet meer beschikbaar is, behoudt vernieuwen zonder scope de productrechten en verwijdert het de identiteitsrechten. Expliciet om niet-beschikbare identiteitsscopes vragen geeft invalid\_scope terug.
* Als het account is verwijderd of uitgeschakeld, geeft het tokenendpoint invalid\_grant met HTTP 400 terug.

## Fouten

| HTTP-status | Code | Betekenis of herstel |
| - | - | - |
| 400 | `invalid_request` | De body of een herkende parameter is ongeldig, ontbreekt, is dubbel opgegeven of heeft de verkeerde codering. |
| 400 | `invalid_client` | De client\_id is onbekend, er is HTTP-clientauthenticatie opgegeven, of er is een client\_secret/client\_assertion opgegeven. |
| 400 | `invalid_target` | De resourcedoelgroep ontbreekt of komt niet exact overeen met de MCP-resource. |
| 400 | `unsupported_grant_type` | De grant wordt niet ondersteund, of refresh\_token is niet voor deze client geregistreerd. |
| 400 | `invalid_grant` | De code of het token is ongeldig, verlopen, ingetrokken, opnieuw gebruikt, komt niet overeen of is niet langer geautoriseerd voor het huidige account/team. |
| 400 | `invalid_scope` | Een vernieuwingsaanvraag probeert machtigingen toe te voegen of bevat niet-ondersteunde scopes. |
| 413 | `REQUEST_TOO_LARGE` | De aanvraag overschrijdt de toegestane bodygrootte. JSON is beperkt tot 1 MiB en URL-gecodeerde formulieren tot 32 KiB. |
| 415 | `UNSUPPORTED_CONTENT_TYPE` | De bodyparser van de integratie accepteert alleen JSON of URL-gecodeerde formulieren. De route kan specifiek een van deze coderingen vereisen. |
| 429 | `temporarily_unavailable` | De openbare frequentielimiet voor OAuth-aanvragen is bereikt. Wacht tot het huidige tijdvenster voorbij is voordat je het opnieuw probeert. |
| 500 | `server_error` | Autorisatie is tijdelijk niet beschikbaar. Probeer het later opnieuw. |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.