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

# Registrar un cliente OAuth de MCP

> Registra un cliente público con URL de callback exactas y un conjunto limitado de permisos de producto.

Registra un cliente público con URL de callback exactas y un conjunto limitado de permisos de producto.

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

## Autenticación

Ninguna. El registro no inicia la sesión de un usuario ni autoriza una conexión de cuenta.

## Cuerpo de la solicitud

<ParamField body="redirect_uris" type="array" required>
  Entre 1 y 10 URL de retorno antes de eliminar los duplicados.

  Número mínimo de elementos: 1. Número máximo de elementos: 10.
</ParamField>

<ParamField body="client_name" type="string">
  Etiqueta opcional del cliente; se eliminan los espacios de los extremos antes de guardarla y debe seguir sin estar vacía.

  Longitud mínima: 1. Longitud máxima: 120. Patrón: `^(?=.*\S)[^\u0000-\u001F\u007F]+$`. Valor predeterminado: "MCP client".
</ParamField>

<ParamField body="token_endpoint_auth_method" type="field">
  Solo clientes públicos.

  Valor obligatorio: "none". Valor predeterminado: "none".
</ParamField>

<ParamField body="grant_types" type="union">
  Debe incluir authorization\_code; refresh\_token es opcional. Si se omite o es null, se seleccionan ambos. Se eliminan los valores duplicados.

  Valor predeterminado: \["authorization\_code","refresh\_token"].
</ParamField>

<ParamField body="response_types" type="array">
  Lista de valores. Consulta la estructura de sus elementos en el esquema completo de entrada.

  Número mínimo de elementos: 1. Número máximo de elementos: 1. Valor predeterminado: \["code"].
</ParamField>

<ParamField body="scope" type="string">
  Permisos de scopes\_supported separados por espacios, que pueden incluir offline\_access. Se rechazan los nombres no admitidos y los valores que solo contienen espacios en blanco; se eliminan los duplicados. Si se omite scope o no se indican permisos de producto, por ejemplo solo openid o solo offline\_access, se registran todos los ámbitos de producto admitidos. email requiere openid; email solo se rechaza. Cuando OpenID Connect está disponible, el registro incluye openid y email como capacidades del cliente aunque se omita scope. El registro no concede acceso; los permisos de identidad requieren una solicitud de autorización explícita y el consentimiento del usuario.

  Longitud mínima: 1. Longitud máxima: 2048. Patrón: `^ *(?: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>

<Accordion title="Esquema técnico">
  ```json theme={null}
  {
    "type": "object",
    "properties": {
      "redirect_uris": {
        "type": "array",
        "minItems": 1,
        "maxItems": 10,
        "items": {
          "type": "string",
          "minLength": 1,
          "maxLength": 2048,
          "pattern": "^[^\\s\\u0000-\\u001F\\u007F-\\u009F#\\\\]+$",
          "format": "uri",
          "anyOf": [
            {
              "pattern": "^[Hh][Tt][Tt][Pp][Ss]://"
            },
            {
              "pattern": "^http://(?:localhost|127\\.0\\.0\\.1|\\[::1\\])(?::[0-9]{1,5})?(?:/|\\?|$)"
            },
            {
              "const": "cursor://anysphere.cursor-mcp/oauth/callback"
            }
          ],
          "description": "An absolute HTTPS callback, an HTTP callback using the exact lowercase loopback spelling localhost, 127.0.0.1, or [::1], or exactly cursor://anysphere.cursor-mcp/oauth/callback. Must parse as a URL with no username/password, whitespace, control characters, backslashes, or fragment. A loopback port must be a valid URL port. The exact spelling is retained."
        },
        "description": "Between 1 and 10 callbacks before duplicates are removed."
      },
      "client_name": {
        "type": "string",
        "minLength": 1,
        "maxLength": 120,
        "pattern": "^(?=.*\\S)[^\\u0000-\\u001F\\u007F]+$",
        "default": "MCP client",
        "description": "Optional client label; trimmed before saving and must remain nonempty."
      },
      "token_endpoint_auth_method": {
        "const": "none",
        "default": "none",
        "description": "Public clients only."
      },
      "grant_types": {
        "anyOf": [
          {
            "type": "array",
            "minItems": 1,
            "items": {
              "enum": [
                "authorization_code",
                "refresh_token"
              ]
            },
            "contains": {
              "const": "authorization_code"
            }
          },
          {
            "type": "null"
          }
        ],
        "default": [
          "authorization_code",
          "refresh_token"
        ],
        "description": "Must include authorization_code; refresh_token is optional. Omitted or null selects both. Duplicate values are removed."
      },
      "response_types": {
        "type": "array",
        "minItems": 1,
        "maxItems": 1,
        "items": {
          "const": "code"
        },
        "default": [
          "code"
        ]
      },
      "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 permissions from scopes_supported, optionally including offline_access. Unsupported names and whitespace-only values are rejected; duplicates are removed. Omitting scope or supplying no product scopes, such as openid alone or offline_access alone, registers all supported product scopes. email requires openid; email alone is rejected. When OpenID Connect is available, registration includes openid and email as client capabilities even when scope is omitted. Registration grants no access; identity permissions require an explicit authorization request and user consent.",
        "examples": [
          "account:read projects:read offline_access"
        ]
      }
    },
    "required": [
      "redirect_uris"
    ],
    "additionalProperties": true
  }
  ```
</Accordion>

## Ejemplos de solicitud

Sigue la codificación y la autenticación documentadas para esta ruta. El formato envolvente y las reglas de idempotencia de la API de acciones solo se aplican a las invocaciones de acciones.

<RequestExample>
  ```bash cURL theme={null}
  curl --request POST 'https://api.voicecheap.ai/oauth/register' \
    --header 'Content-Type: application/json' \
    --data '{"client_name":"Acme assistant","redirect_uris":["https://assistant.example.com/oauth/callback"],"token_endpoint_auth_method":"none","grant_types":["authorization_code","refresh_token"],"response_types":["code"],"scope":"account:read projects:read offline_access"}'
  ```

  ```javascript JavaScript theme={null}
  const input = {
    client_name: 'Acme assistant',
    redirect_uris: ['https://assistant.example.com/oauth/callback'],
    token_endpoint_auth_method: 'none',
    grant_types: ['authorization_code', 'refresh_token'],
    response_types: ['code'],
    scope: 'account:read projects:read offline_access',
  };
  const response = await fetch('https://api.voicecheap.ai/oauth/register', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(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/register",
      headers={"Content-Type":"application/json"},
      json={"client_name": "Acme assistant", "redirect_uris": ["https://assistant.example.com/oauth/callback"], "token_endpoint_auth_method": "none", "grant_types": ["authorization_code", "refresh_token"], "response_types": ["code"], "scope": "account:read projects:read offline_access"},
      timeout=120,
      allow_redirects=False,
  )
  print(response.status_code, response.text)
  ```
</RequestExample>

## Respuesta

Metadatos del cliente público registrado. Guarda client\_id y úsalo con el redirect\_uri exacto registrado. No se emite ningún client\_secret.

```json HTTP 201 theme={null}
{
  "client_id": "mcp_client_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
  "client_id_issued_at": 1792152000,
  "client_name": "Acme assistant",
  "redirect_uris": ["https://assistant.example.com/oauth/callback"],
  "token_endpoint_auth_method": "none",
  "grant_types": ["authorization_code", "refresh_token"],
  "response_types": ["code"],
  "scope": "account:read projects:read offline_access"
}
```

## Cabeceras de respuesta

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

## Notas de la operación

* Los parámetros escalares reconocidos deben proporcionarse una sola vez como cadenas no vacías, sin caracteres de control ASCII ni DEL. Los campos repetidos de consulta o formulario se decodifican como arrays y se rechazan al leerse como escalares.
* Usa Content-Type application/json. Un cuerpo de registro codificado como URL se rechaza con la respuesta OAuth invalid\_request; el analizador de la integración puede rechazar antes los tipos de contenido no compatibles.
* Las URI de redirección se conservan y se comparan de forma exacta. Los cambios en mayúsculas y minúsculas, representación del puerto, ruta, consulta o barra final requieren registrar esa URI exacta.
* Los callbacks HTTP solo aceptan los nombres de bucle local literales localhost, 127.0.0.1 y \[::1]. No se admiten hosts de redes privadas, representaciones alternativas de IP, \*.localhost ni LOCALHOST en mayúsculas.
* El único callback aceptado con un esquema de URI personalizado es exactamente cursor://anysphere.cursor-mcp/oauth/callback.
* Cada URL de retorno debe superar la validación; una sola URL de retorno no válida rechaza todo el registro. Se rechazan las credenciales en la URL, los espacios en blanco, los caracteres de control, los fragmentos y las barras invertidas.
* El cliente puede registrar cualquier ámbito de producto compatible, pero el usuario debe aprobar por separado el subconjunto solicitado durante la autorización. El registro por sí solo no concede acceso.
* Solo se admiten los tipos de concesión authorization\_code y, opcionalmente, refresh\_token. Un cliente registrado sin refresh\_token no recibe ningún token de actualización.
* La implementación actual ignora los campos de metadatos de nivel superior desconocidos. Los campos conocidos mantienen las restricciones mostradas en el esquema.
* El límite público de registro es de 10 solicitudes cada 10 minutos por IP de cliente, compartido entre los workers. Los cuerpos JSON están limitados a 1 MiB.
* Un registro correcto devuelve HTTP 201.
* openid y email son permisos de identidad, distintos de los permisos del producto, y solo se aceptan cuando se anuncian. email requiere openid. Durante la autorización inicial, una solicitud que solo contiene permisos de identidad usa los permisos predeterminados del producto mostrados en la pantalla de consentimiento.

## Errores

| Estado HTTP | Código | Significado o solución |
| - | - | - |
| 400 | `invalid_request` | El cuerpo o un parámetro reconocido no es válido, falta, está duplicado o tiene una codificación incorrecta. |
| 400 | `invalid_client_metadata` | Número de URL de retorno no válido, etiqueta de cliente vacía o autenticación de cliente, tipos de concesión o tipos de respuesta no compatibles. |
| 400 | `invalid_redirect_uri` | Una URL de callback usa un formato no compatible o inseguro. |
| 400 | `invalid_scope` | La cadena scope contiene un permiso no admitido o no contiene ningún ámbito solicitado. |
| 413 | `REQUEST_TOO_LARGE` | La solicitud supera el tamaño de cuerpo permitido. JSON está limitado a 1 MiB y los formularios codificados como URL a 32 KiB. |
| 415 | `UNSUPPORTED_CONTENT_TYPE` | El analizador del cuerpo de la integración solo acepta JSON o formularios codificados como URL. La ruta puede exigir específicamente una de esas codificaciones. |
| 429 | `temporarily_unavailable` | Se ha alcanzado el límite público de frecuencia de solicitudes OAuth. Espera a que termine la ventana actual antes de reintentarlo. |
| 500 | `server_error` | La autorización no está disponible temporalmente. Vuelve a intentarlo más tarde. |


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