> ## 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.

# Einen Autorisierungscode eintauschen oder ein Refresh-Token rotieren

> Rufen Sie kurzlebige MCP-Zugriffstokens mithilfe des S256-Autorisierungscodes eines öffentlichen Clients oder seines aktuellen Aktualisierungstokens ab.

Rufen Sie kurzlebige MCP-Zugriffstokens mithilfe des S256-Autorisierungscodes eines öffentlichen Clients oder seines aktuellen Aktualisierungstokens ab.

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

## Authentifizierung

Keine HTTP-Clientauthentifizierung. Senden Sie client\_id im URL-kodierten Anfragetext. Jeder Authorization-Header sowie client\_secret oder client\_assertion werden abgelehnt.

## Anfragetext

<Expandable title="grant_type: authorization_code">
  <ParamField body="client_id" type="string" required>
    Die von der dynamischen Registrierung zurückgegebene client\_id oder die exakte öffentliche HTTPS-URL des Client-Metadatendokuments.

    Mindestlänge: 1. Höchstlänge: 2048. Muster: `^[^\u0000-\u001F\u007F]+$`.
  </ParamField>

  <ParamField body="resource" type="string" required>
    Erforderliche exakte Ressourcen-Audience: Verwenden Sie den Wert resource aus den Metadaten der geschützten Ressource dieser Umgebung. In der Produktion ist dies [https://api.voicecheap.ai/mcp](https://api.voicecheap.ai/mcp). Ein anderer Origin, Pfad oder ein abschließender Schrägstrich wird abgelehnt.

    Format: "uri".
  </ParamField>

  <ParamField body="grant_type" type="field" required>
    Wert gemäß dem vollständigen Eingabeschema.

    Erforderlicher Wert: "authorization\_code".
  </ParamField>

  <ParamField body="code" type="string" required>
    Einmalcode, der an den exakt registrierten Callback zurückgegeben wird.

    Mindestlänge: 1. Höchstlänge: 256. Muster: `^mcp_code_[A-Za-z0-9_-]{43}$`.
  </ParamField>

  <ParamField body="redirect_uri" type="string" required>
    Muss genau dem Callback entsprechen, der an diesen Code und diese Registrierung gebunden ist.

    Mindestlänge: 1. Höchstlänge: 2048. Muster: `^[^\u0000-\u001F\u007F]+$`.
  </ParamField>

  <ParamField body="code_verifier" type="string" required>
    Ursprünglicher PKCE-Verifier, mit dem die S256 code\_challenge der Autorisierungsanfrage berechnet wurde.

    Mindestlänge: 43. Höchstlänge: 128. Muster: `^[A-Za-z0-9._~-]{43,128}$`.
  </ParamField>
</Expandable>

<Expandable title="grant_type: refresh_token">
  <ParamField body="client_id" type="string" required>
    Die von der dynamischen Registrierung zurückgegebene client\_id oder die exakte öffentliche HTTPS-URL des Client-Metadatendokuments.

    Mindestlänge: 1. Höchstlänge: 2048. Muster: `^[^\u0000-\u001F\u007F]+$`.
  </ParamField>

  <ParamField body="resource" type="string" required>
    Erforderliche exakte Ressourcen-Audience: Verwenden Sie den Wert resource aus den Metadaten der geschützten Ressource dieser Umgebung. In der Produktion ist dies [https://api.voicecheap.ai/mcp](https://api.voicecheap.ai/mcp). Ein anderer Origin, Pfad oder ein abschließender Schrägstrich wird abgelehnt.

    Format: "uri".
  </ParamField>

  <ParamField body="grant_type" type="field" required>
    Wert gemäß dem vollständigen Eingabeschema.

    Erforderlicher Wert: "refresh\_token".
  </ParamField>

  <ParamField body="refresh_token" type="string" required>
    Das aktuelle, noch nicht verbrauchte Refresh-Token eines für refresh\_token registrierten Clients.

    Mindestlänge: 1. Höchstlänge: 256. Muster: `^mcp_refresh_[A-Za-z0-9_-]{43}$`.
  </ParamField>

  <ParamField body="scope" type="string">
    Durch Leerzeichen getrennte Teilmenge der ursprünglichen Berechtigungen, optional einschließlich offline\_access. Nicht unterstützte Namen, leere Werte und zusätzliche Berechtigungen werden abgelehnt; Duplikate werden entfernt. Ein expliziter scope behält nur die aufgeführten Produkt- und Identitätsberechtigungen bei und kann alle Produktberechtigungen entfernen. Ohne scope bleibt die aktuelle Autorisierung bestehen; ist OpenID Connect nicht verfügbar, werden jedoch Identitätsberechtigungen entfernt.

    Mindestlänge: 1. Höchstlänge: 2048. Muster: `^ *(?: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="Technisches 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>

## Anfragebeispiele

Beachten Sie die für diese Route dokumentierte Kodierung und Authentifizierung. Die Antwortstruktur und Idempotenzregeln der Aktions-API gelten nur für Aktionsaufrufe.

<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>

## Antwort

Ein opakes Bearer-Zugriffstoken, seine verbleibende Gültigkeitsdauer in Sekunden, die gewährten Berechtigungen und ein Refresh-Token, wenn der Client refresh\_token registriert hat. expires\_in beträgt höchstens 900 und kann kurz vor Ablauf der Autorisierung kleiner sein.

```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"
}
```

## Antwortheader

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

## Hinweise zur Operation

* Erkannte skalare Parameter müssen genau einmal als nicht leere Zeichenfolgen ohne ASCII-Steuerzeichen oder DEL übergeben werden. Wiederholte Abfrage- oder Formularfelder werden als Arrays dekodiert und beim Lesen als Skalare abgelehnt.
* Verwenden Sie URL-codierte Formulardaten, beispielsweise curl --data-urlencode für jedes Feld. Ein JSON-Token-Body wird mit invalid\_request abgelehnt.
* Die resource-Zielgruppe ist für beide Grant-Typen erforderlich und muss exakt mit der MCP-URL der Umgebung übereinstimmen, die den Code oder das Aktualisierungstoken ausgestellt hat.
* Der Austausch eines Autorisierungscodes erfordert die ursprüngliche client\_id, die exakte redirect\_uri und den passenden S256 code\_verifier. Codes laufen nach 2 Minuten ab und sind nur einmal verwendbar.
* Der Token-Endpunkt lehnt jeden übergebenen Authorization-Header ab, einschließlich Basic und Bearer, sowie jedes client\_secret- oder client\_assertion-Feld im Anfragetext.
* Zugriffstoken sind höchstens 15 Minuten gültig. Wenn refresh\_token registriert ist, laufen die Verbindung und die Refresh-Token-Familie 30 Tage nach der Zustimmung des Benutzers ab; eine Rotation verlängert diese Frist nicht.
* Ob refresh\_token zurückgegeben wird, hängt von den registrierten Grant-Typen ab. Es hängt nicht davon ab, ob offline\_access in der Autorisierungsanfrage enthalten ist. Der zurückgegebene scope ergänzt offline\_access immer dann, wenn ein Refresh-Token zurückgegeben wird.
* Senden Sie zur Erneuerung grant\_type=refresh\_token mit client\_id, dem aktuellen refresh\_token, resource und optional einem eingeschränkten scope. Ersetzen Sie das gespeicherte Refresh-Token atomar durch den neuen Wert.
* Die Wiederverwendung eines verbrauchten Autorisierungscodes oder eines rotierten Refresh-Tokens widerruft die gesamte Verbindung einschließlich aller ihrer Zugriffstoken. Lösen Sie denselben Code oder dasselbe Refresh-Token nicht gleichzeitig mehrfach ein.
* Erneuerungsanfragen fügen niemals Berechtigungen hinzu. Bei einem expliziten scope bleiben nur die angeforderten Produkt- und Identitätsberechtigungen erhalten; offline\_access bewahrt ausgelassene Produktberechtigungen nicht.
* Tokens sind an den gewährenden Nutzer, den Client, die Ressourcen-Audience, die aktuelle Teameigentümerschaft und den aktiven kostenpflichtigen Zugriff gebunden. Eine widerrufene Berechtigung oder geänderte Eigentümerschaft erfordert eine erneute Verbindung.
* Das öffentliche Token-Limit beträgt 60 Anfragen pro Minute und Client-IP und gilt gemeinsam für alle Worker. URL-codierte Bodys sind auf 32 KiB begrenzt.
* Bei OAuth-Fehlern werden error und error\_description zurückgegeben. Fehler des Body-Parsers können bereits zuvor im Fehlerformat des Integrationsparsers zurückgegeben werden.
* openid und email sind Identitätsberechtigungen, getrennt von Produktberechtigungen, und werden nur akzeptiert, wenn sie angekündigt werden. email erfordert openid. Bei der ersten Autorisierung verwendet eine Anfrage nur mit Identitäts-Scopes die auf dem Zustimmungsbildschirm angezeigten Standard-Produktberechtigungen.
* Die von der dynamischen Registrierung zurückgegebene client\_id oder die exakte öffentliche HTTPS-URL des Client-Metadatendokuments.
* Wenn openid gewährt wurde, gibt der Austausch des Autorisierungscodes zusätzlich ein mit RS256 signiertes id\_token zurück. Prüfen Sie Signatur, Aussteller, Zielgruppe, Ablaufzeit und gegebenenfalls nonce. Gewährte Identitäts-Scopes erscheinen in scope der Tokenantwort; Erneuerungsantworten geben kein neues id\_token aus.
* Wenn OpenID Connect nicht mehr verfügbar ist, behält eine Erneuerung ohne scope die Produktberechtigungen bei und entfernt Identitätsberechtigungen. Eine ausdrückliche Anfrage nicht verfügbarer Identitäts-Scopes gibt invalid\_scope zurück.
* Wenn das Konto gelöscht oder deaktiviert wurde, gibt der Token-Endpunkt invalid\_grant mit HTTP 400 zurück.

## Fehler

| HTTP-Status | Code | Bedeutung oder Behebung |
| - | - | - |
| 400 | `invalid_request` | Der Anfragetext oder ein erkannter Parameter ist ungültig, fehlt, ist doppelt vorhanden oder hat die falsche Kodierung. |
| 400 | `invalid_client` | Die client\_id ist unbekannt, es wurde eine HTTP-Clientauthentifizierung übergeben oder es wurde client\_secret/client\_assertion übergeben. |
| 400 | `invalid_target` | Die Ressourcen-Audience fehlt oder stimmt nicht genau mit der MCP-Ressource überein. |
| 400 | `unsupported_grant_type` | Der Grant wird nicht unterstützt, oder refresh\_token wurde für diesen Client nicht registriert. |
| 400 | `invalid_grant` | Der Code oder das Token ist ungültig, abgelaufen, widerrufen, erneut verwendet, nicht passend oder für das aktuelle Konto/Team nicht mehr autorisiert. |
| 400 | `invalid_scope` | Eine Refresh-Anfrage versucht, Berechtigungen hinzuzufügen, oder enthält nicht unterstützte Berechtigungsbereiche. |
| 413 | `REQUEST_TOO_LARGE` | Die Anfrage überschreitet die zulässige Größe des Anfragetexts. JSON ist auf 1 MiB und URL-kodierte Formulare sind auf 32 KiB begrenzt. |
| 415 | `UNSUPPORTED_CONTENT_TYPE` | Der Body-Parser der Integration akzeptiert nur JSON oder URL-codierte Formulardaten. Die Route kann ausdrücklich eine dieser Codierungen erfordern. |
| 429 | `temporarily_unavailable` | Das öffentliche Anfrageratenlimit für OAuth wurde erreicht. Warten Sie vor einem erneuten Versuch das aktuelle Zeitfenster ab. |
| 500 | `server_error` | Die Autorisierung ist vorübergehend nicht verfügbar. Versuchen Sie es später erneut. |


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