---
title: Autenticar con vaults
url: https://platform.claude.com/docs/es/managed-agents/vaults
description: Registra credenciales por usuario al crear sesiones.
featureMetadata:
  topic:
    title: Managed Agents
    url: https://platform.claude.com/docs/en/managed-agents/overview
  status: beta
  betaHeader: managed-agents-2026-04-01
---

Los vaults y las credenciales son primitivas de autenticación que te permiten registrar credenciales para servicios de terceros una sola vez y referenciarlas por ID al crear una sesión. Esto significa que no necesitas ejecutar tu propio almacén de secretos, transmitir tokens en cada llamada, ni perder el rastro de en nombre de qué usuario final actuó un agente.

La referencia al vault es un parámetro por sesión, por lo que puedes gestionar tu producto con la granularidad del recurso `agent` y tus usuarios con la granularidad del recurso `session`.

## Crear un vault

<Warning>
  Los vaults y las credenciales tienen alcance de espacio de trabajo, lo que significa que cualquier clave de API con acceso al espacio de trabajo puede referenciarlos al crear una sesión. Para revocar el acceso, elimina el vault o la credencial.
</Warning>

Un vault es la colección de `credentials` asociadas a un usuario final. Asígnale un `display_name` (java, php: `displayName`; csharp, go: `DisplayName`) y, opcionalmente, etiquétalo con `metadata` (csharp, go: `Metadata`) para poder asociarlo con tus propios registros de usuario.

<CodeGroup>
  ```bash cURL
  curl --fail-with-body -sS https://api.anthropic.com/v1/vaults \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: managed-agents-2026-04-01" \
    -H "content-type: application/json" \
    --data '{
      "display_name": "Alice",
      "metadata": {"external_user_id": "usr_abc123"}
    }'
  ```

  <CodeGroupItem>
    ```bash CLI
    ant apply vaults/service_accounts.yaml
    ```

    <File filename="vaults/service_accounts.yaml">
      ```yaml
      # yaml-language-server: $schema=https://platform.claude.com/schemas/ant/beta/vault.json
      display_name: Service accounts
      ```
    </File>

    [`ant apply`](https://platform.claude.com/docs/es/cli-sdks-libraries/cli/apply) crea el vault a partir de `vaults/service_accounts.yaml`, imprime su ID y lo registra en `claude-lock.json`. Para ver el registro del vault, ejecuta `ant beta:vaults retrieve`.
  </CodeGroupItem>

  ```python Python
  vault = client.beta.vaults.create(
      display_name="Alice",
      metadata={"external_user_id": "usr_abc123"},
  )
  print(vault.id)  # "vlt_01ABC..."
  ```

  ```typescript TypeScript
  const vault = await client.beta.vaults.create({
    display_name: "Alice",
    metadata: { external_user_id: "usr_abc123" }
  });
  console.log(vault.id); // "vlt_01ABC..."
  ```

  ```csharp C#
  var vault = await client.Beta.Vaults.Create(new()
  {
      DisplayName = "Alice",
      Metadata = new Dictionary<string, string> { ["external_user_id"] = "usr_abc123" },
  });
  Console.WriteLine(vault.ID); // "vlt_01ABC..."
  ```

  ```go Go
  vault, err := client.Beta.Vaults.New(ctx, anthropic.BetaVaultNewParams{
  	DisplayName: "Alice",
  	Metadata:    map[string]string{"external_user_id": "usr_abc123"},
  })
  if err != nil {
  	panic(err)
  }
  fmt.Println(vault.ID) // "vlt_01ABC..."
  ```

  ```java Java
  var vault = client.beta().vaults().create(VaultCreateParams.builder()
      .displayName("Alice")
      .metadata(VaultCreateParams.Metadata.builder()
          .putAdditionalProperty("external_user_id", JsonValue.from("usr_abc123"))
          .build())
      .build());
  IO.println(vault.id()); // "vlt_01ABC..."
  ```

  ```php PHP
  $vault = $client->beta->vaults->create(
      displayName: 'Alice',
      metadata: ['external_user_id' => 'usr_abc123'],
  );
  echo $vault->id . "\n"; // "vlt_01ABC..."
  ```

  ```ruby Ruby
  vault = client.beta.vaults.create(
    display_name: "Alice",
    metadata: {external_user_id: "usr_abc123"}
  )
  puts vault.id # "vlt_01ABC..."
  ```
</CodeGroup>

La respuesta es el registro completo del vault:

```json
{
  "type": "vault",
  "id": "vlt_01ABC...",
  "display_name": "Alice",
  "metadata": { "external_user_id": "usr_abc123" },
  "created_at": "2026-03-18T10:00:00Z",
  "updated_at": "2026-03-18T10:00:00Z",
  "archived_at": null
}
```

## Agregar una credencial

Se admiten dos categorías de credenciales:

* **Credenciales de MCP** (`mcp_oauth`, `static_bearer`): cada credencial se identifica mediante un `mcp_server_url` (java: `mcpServerUrl`; php: `mcpServerURL`; csharp: `McpServerUrl`; go: `MCPServerURL`). Cuando el agente se conecta a un servidor en esa URL durante la ejecución de la sesión, el token se inyecta automáticamente.
* **Variables de entorno** (`environment_variable`): cada credencial se identifica mediante un `secret_name` (java, php: `secretName`; csharp, go: `SecretName`) (el nombre de la variable de entorno) y se almacena en el sandbox como un marcador de posición opaco. Cuando el agente inicia una solicitud saliente, el marcador de posición opaco se sustituye por el secreto real en la salida ("egress"). El agente nunca ve el valor del secreto. Usa esto para cualquier servicio que se autentique mediante una variable de entorno, como CLIs, SDKs o llamadas directas a la API.

Los valores reales de las credenciales que proporcionas (`token` (csharp, go: `Token`), `access_token` (java, php: `accessToken`; csharp, go: `AccessToken`), `refresh_token` (java, php: `refreshToken`; csharp, go: `RefreshToken`), `client_secret` (java, php: `clientSecret`; csharp, go: `ClientSecret`), `secret_value` (java, php: `secretValue`; csharp, go: `SecretValue`)) se tratan como campos sensibles de solo escritura y nunca se devuelven en las respuestas de la API.

<Note>
  Las credenciales de variables de entorno (`environment_variable`) aún no son compatibles con los [sandboxes autoalojados](https://platform.claude.com/docs/es/managed-agents/self-hosted-sandboxes).
</Note>

Para obtener el mismo comportamiento con un sandbox autoalojado, puedes ejecutar tu propio proxy que reemplace los valores de marcador de posición por los secretos reales en la salida.

<Tabs>
  <Tab title="MCP OAuth">
    Usa `mcp_oauth` cuando el servidor MCP use OAuth 2.0. Si proporcionas un bloque `refresh` (csharp, go: `Refresh`), Anthropic actualiza el token de acceso en tu nombre cuando expira.

    El campo `refresh.token_endpoint_auth.type` indica cómo autenticar la llamada de actualización:

    * `none`: cliente público
    * `client_secret_basic`: autenticación HTTP Basic con el secreto del cliente
    * `client_secret_post`: secreto del cliente en el cuerpo del POST

    <CodeGroup>
      ```bash cURL
      curl --fail-with-body -sS "https://api.anthropic.com/v1/vaults/$VAULT_ID/credentials" \
        -H "x-api-key: $ANTHROPIC_API_KEY" \
        -H "anthropic-version: 2023-06-01" \
        -H "anthropic-beta: managed-agents-2026-04-01" \
        -H "content-type: application/json" \
        --data @- <<'EOF'
      {
        "display_name": "Alice's Slack",
        "auth": {
          "type": "mcp_oauth",
          "mcp_server_url": "https://mcp.slack.com/mcp",
          "access_token": "xoxp-...",
          "expires_at": "2099-12-31T23:59:59Z",
          "refresh": {
            "token_endpoint": "https://slack.com/api/oauth.v2.user.access",
            "client_id": "1234567890.0987654321",
            "scope": "channels:read chat:write",
            "refresh_token": "xoxe-1-...",
            "token_endpoint_auth": {"type": "client_secret_post", "client_secret": "abc123..."}
          }
        }
      }
      EOF
      ```

      ```bash CLI
      ant beta:vaults:credentials create \
        --vault-id "$VAULT_ID" \
        --display-name "Slack" <<'YAML'
      auth:
        type: mcp_oauth
        mcp_server_url: https://mcp.slack.com/mcp
        access_token: xoxp-...
        expires_at: "2099-12-31T23:59:59Z"
        refresh:
          token_endpoint: https://slack.com/api/oauth.v2.user.access
          client_id: "1234567890.0987654321"
          scope: channels:read chat:write
          refresh_token: xoxe-1-...
          token_endpoint_auth:
            type: client_secret_post
            client_secret: abc123...
      YAML
      ```

      ```python Python
      credential = client.beta.vaults.credentials.create(
          vault_id=vault.id,
          display_name="Alice's Slack",
          auth={
              "type": "mcp_oauth",
              "mcp_server_url": "https://mcp.slack.com/mcp",
              "access_token": "xoxp-...",
              "expires_at": "2099-12-31T23:59:59Z",
              "refresh": {
                  "token_endpoint": "https://slack.com/api/oauth.v2.user.access",
                  "client_id": "1234567890.0987654321",
                  "scope": "channels:read chat:write",
                  "refresh_token": "xoxe-1-...",
                  "token_endpoint_auth": {
                      "type": "client_secret_post",
                      "client_secret": "abc123...",
                  },
              },
          },
      )
      ```

      ```typescript TypeScript
      const credential = await client.beta.vaults.credentials.create(vault.id, {
        display_name: "Alice's Slack",
        auth: {
          type: "mcp_oauth",
          mcp_server_url: "https://mcp.slack.com/mcp",
          access_token: "xoxp-...",
          expires_at: "2099-12-31T23:59:59Z",
          refresh: {
            token_endpoint: "https://slack.com/api/oauth.v2.user.access",
            client_id: "1234567890.0987654321",
            scope: "channels:read chat:write",
            refresh_token: "xoxe-1-...",
            token_endpoint_auth: {
              type: "client_secret_post",
              client_secret: "abc123..."
            }
          }
        }
      });
      ```

      ```csharp C#
      var credential = await client.Beta.Vaults.Credentials.Create(vault.ID, new()
      {
          DisplayName = "Alice's Slack",
          Auth = new BetaManagedAgentsMcpOAuthCreateParams
          {
              Type = BetaManagedAgentsMcpOAuthCreateParamsType.McpOAuth,
              McpServerUrl = "https://mcp.slack.com/mcp",
              AccessToken = "xoxp-...",
              ExpiresAt = DateTimeOffset.Parse("2099-12-31T23:59:59Z"),
              Refresh = new()
              {
                  TokenEndpoint = "https://slack.com/api/oauth.v2.user.access",
                  ClientID = "1234567890.0987654321",
                  Scope = "channels:read chat:write",
                  RefreshToken = "xoxe-1-...",
                  TokenEndpointAuth = new BetaManagedAgentsTokenEndpointAuthPostParam
                  {
                      Type = BetaManagedAgentsTokenEndpointAuthPostParamType.ClientSecretPost,
                      ClientSecret = "abc123...",
                  },
              },
          },
      });
      ```

      ```go Go
      credential, err := client.Beta.Vaults.Credentials.New(ctx, vault.ID, anthropic.BetaVaultCredentialNewParams{
      	DisplayName: anthropic.String("Alice's Slack"),
      	Auth: anthropic.BetaVaultCredentialNewParamsAuthUnion{
      		OfMCPOAuth: &anthropic.BetaManagedAgentsMCPOAuthCreateParams{
      			Type:         anthropic.BetaManagedAgentsMCPOAuthCreateParamsTypeMCPOAuth,
      			MCPServerURL: "https://mcp.slack.com/mcp",
      			AccessToken:  "xoxp-...",
      			ExpiresAt:    anthropic.Time(time.Date(2099, time.December, 31, 23, 59, 59, 0, time.UTC)),
      			Refresh: anthropic.BetaManagedAgentsMCPOAuthRefreshParams{
      				TokenEndpoint: "https://slack.com/api/oauth.v2.user.access",
      				ClientID:      "1234567890.0987654321",
      				Scope:         anthropic.String("channels:read chat:write"),
      				RefreshToken:  "xoxe-1-...",
      				TokenEndpointAuth: anthropic.BetaManagedAgentsMCPOAuthRefreshParamsTokenEndpointAuthUnion{
      					OfClientSecretPost: &anthropic.BetaManagedAgentsTokenEndpointAuthPostParam{
      						Type:         anthropic.BetaManagedAgentsTokenEndpointAuthPostParamTypeClientSecretPost,
      						ClientSecret: "abc123...",
      					},
      				},
      			},
      		},
      	},
      })
      if err != nil {
      	panic(err)
      }
      ```

      ```java Java
      var credential = client.beta().vaults().credentials().create(vault.id(),
          CredentialCreateParams.builder()
              .displayName("Alice's Slack")
              .auth(BetaManagedAgentsMcpOAuthCreateParams.builder()
                  .type(BetaManagedAgentsMcpOAuthCreateParams.Type.MCP_OAUTH)
                  .mcpServerUrl("https://mcp.slack.com/mcp")
                  .accessToken("xoxp-...")
                  .expiresAt(OffsetDateTime.parse("2099-12-31T23:59:59Z"))
                  .refresh(BetaManagedAgentsMcpOAuthRefreshParams.builder()
                      .tokenEndpoint("https://slack.com/api/oauth.v2.user.access")
                      .clientId("1234567890.0987654321")
                      .scope("channels:read chat:write")
                      .refreshToken("xoxe-1-...")
                      .clientSecretPostTokenEndpointAuth("abc123...")
                      .build())
                  .build())
              .build());
      ```

      ```php PHP
      $credential = $client->beta->vaults->credentials->create(
          vaultID: $vault->id,
          displayName: "Alice's Slack",
          auth: ManagedAgentsMCPOAuthCreateParams::with(
              type: 'mcp_oauth',
              mcpServerURL: 'https://mcp.slack.com/mcp',
              accessToken: 'xoxp-...',
              expiresAt: new \DateTimeImmutable('2099-12-31T23:59:59Z'),
              refresh: ManagedAgentsMCPOAuthRefreshParams::with(
                  tokenEndpoint: 'https://slack.com/api/oauth.v2.user.access',
                  clientID: '1234567890.0987654321',
                  scope: 'channels:read chat:write',
                  refreshToken: 'xoxe-1-...',
                  tokenEndpointAuth: ManagedAgentsTokenEndpointAuthPostParam::with(
                      type: 'client_secret_post',
                      clientSecret: 'abc123...',
                  ),
              ),
          ),
      );
      ```

      ```ruby Ruby
      credential = client.beta.vaults.credentials.create(
        vault.id,
        display_name: "Alice's Slack",
        auth: {
          type: "mcp_oauth",
          mcp_server_url: "https://mcp.slack.com/mcp",
          access_token: "xoxp-...",
          expires_at: "2099-12-31T23:59:59Z",
          refresh: {
            token_endpoint: "https://slack.com/api/oauth.v2.user.access",
            client_id: "1234567890.0987654321",
            scope: "channels:read chat:write",
            refresh_token: "xoxe-1-...",
            token_endpoint_auth: {
              type: "client_secret_post",
              client_secret: "abc123..."
            }
          }
        }
      )
      ```
    </CodeGroup>

    Establece `refresh.token_endpoint` (java, php: `refresh.tokenEndpoint`; csharp, go: `Refresh.TokenEndpoint`) en el endpoint de token del flujo OAuth que emitió el token de actualización, porque Anthropic envía cada solicitud de actualización a esa URL y el campo no se puede cambiar después de crear la credencial.
  </Tab>

  <Tab title="MCP static bearer">
    Usa `static_bearer` cuando el servidor MCP acepta un token bearer fijo (clave de API, token de acceso personal o similar). No se necesita flujo de actualización.

    <CodeGroup>
      ```bash cURL
      curl --fail-with-body -sS "https://api.anthropic.com/v1/vaults/$VAULT_ID/credentials" \
        -H "x-api-key: $ANTHROPIC_API_KEY" \
        -H "anthropic-version: 2023-06-01" \
        -H "anthropic-beta: managed-agents-2026-04-01" \
        -H "content-type: application/json" \
        --data @- <<'EOF'
      {
        "display_name": "Linear API key",
        "auth": {
          "type": "static_bearer",
          "mcp_server_url": "https://mcp.linear.app/mcp",
          "token": "lin_api_your_linear_key"
        }
      }
      EOF
      ```

      ```bash CLI
      ant beta:vaults:credentials create --vault-id "$VAULT_ID" <<'YAML'
      display_name: Linear API key
      auth:
        type: static_bearer
        mcp_server_url: https://mcp.linear.app/mcp
        token: lin_api_your_linear_key
      YAML
      ```

      ```python Python
      bearer_credential = client.beta.vaults.credentials.create(
          vault_id=vault.id,
          display_name="Linear API key",
          auth={
              "type": "static_bearer",
              "mcp_server_url": "https://mcp.linear.app/mcp",
              "token": "lin_api_your_linear_key",
          },
      )
      ```

      ```typescript TypeScript
      const bearerCredential = await client.beta.vaults.credentials.create(vault.id, {
        display_name: "Linear API key",
        auth: {
          type: "static_bearer",
          mcp_server_url: "https://mcp.linear.app/mcp",
          token: "lin_api_your_linear_key"
        }
      });
      ```

      ```csharp C#
      var bearerCredential = await client.Beta.Vaults.Credentials.Create(vault.ID, new()
      {
          DisplayName = "Linear API key",
          Auth = new BetaManagedAgentsStaticBearerCreateParams
          {
              Type = BetaManagedAgentsStaticBearerCreateParamsType.StaticBearer,
              McpServerUrl = "https://mcp.linear.app/mcp",
              Token = "lin_api_your_linear_key",
          },
      });
      ```

      ```go Go
      bearerCredential, err := client.Beta.Vaults.Credentials.New(ctx, vault.ID, anthropic.BetaVaultCredentialNewParams{
      	DisplayName: anthropic.String("Linear API key"),
      	Auth: anthropic.BetaVaultCredentialNewParamsAuthUnion{
      		OfStaticBearer: &anthropic.BetaManagedAgentsStaticBearerCreateParams{
      			Type:         anthropic.BetaManagedAgentsStaticBearerCreateParamsTypeStaticBearer,
      			MCPServerURL: "https://mcp.linear.app/mcp",
      			Token:        "lin_api_your_linear_key",
      		},
      	},
      })
      if err != nil {
      	panic(err)
      }
      _ = bearerCredential
      ```

      ```java Java
      var bearerCredential = client.beta().vaults().credentials().create(vault.id(),
          CredentialCreateParams.builder()
              .displayName("Linear API key")
              .auth(BetaManagedAgentsStaticBearerCreateParams.builder()
                  .type(BetaManagedAgentsStaticBearerCreateParams.Type.STATIC_BEARER)
                  .mcpServerUrl("https://mcp.linear.app/mcp")
                  .token("lin_api_your_linear_key")
                  .build())
              .build());
      ```

      ```php PHP
      $bearerCredential = $client->beta->vaults->credentials->create(
          vaultID: $vault->id,
          displayName: 'Linear API key',
          auth: ManagedAgentsStaticBearerCreateParams::with(
              type: 'static_bearer',
              mcpServerURL: 'https://mcp.linear.app/mcp',
              token: 'lin_api_your_linear_key',
          ),
      );
      ```

      ```ruby Ruby
      bearer_credential = client.beta.vaults.credentials.create(
        vault.id,
        display_name: "Linear API key",
        auth: {
          type: "static_bearer",
          mcp_server_url: "https://mcp.linear.app/mcp",
          token: "lin_api_your_linear_key"
        }
      )
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Environment variable">
    Usa `environment_variable` para autenticarte en servicios externos a través de una variable de entorno, como CLIs, SDKs o llamadas directas a la API. Las credenciales de variables de entorno funcionan para clientes que envían el valor del secreto textualmente en una solicitud saliente, así que verifica los criterios de elegibilidad del cliente en esta pestaña antes de configurar una.

    El arreglo `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`) en `networking` (csharp, go: `Networking`) controla para qué hosts salientes se puede sustituir el secreto. Usa `"type": "limited"` con una lista específica, o `"type": "unrestricted"` si el llamador accede a dominios que no puedes enumerar de antemano.

    Se recomienda encarecidamente limitar los dominios por motivos de seguridad, y evita que tu clave se comparta alguna vez con hosts no autorizados.

    <Note>
      `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`) en `networking` (csharp, go: `Networking`) en una credencial de vault controla qué solicitudes usan el secreto, no qué solicitudes están permitidas. Para que el agente pueda acceder realmente a un dominio, este también debe estar permitido a [nivel de entorno](https://platform.claude.com/docs/es/managed-agents/environments). Ambos niveles deben incluir el dominio (ya sea mediante redes `unrestricted` o enumerando explícitamente el dominio en `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`)) para que una solicitud con el secreto sustituido tenga éxito.
    </Note>

    El campo opcional `injection_location` (java, php: `injectionLocation`; csharp, go: `InjectionLocation`) delimita dónde se sustituye el secreto; la semántica completa se describe después del ejemplo.

    <CodeGroup>
      ```bash cURL
      curl --fail-with-body -sS "https://api.anthropic.com/v1/vaults/$VAULT_ID/credentials" \
        -H "x-api-key: $ANTHROPIC_API_KEY" \
        -H "anthropic-version: 2023-06-01" \
        -H "anthropic-beta: managed-agents-2026-04-01" \
        -H "content-type: application/json" \
        --data @- <<'EOF'
      {
        "auth": {
          "type": "environment_variable",
          "secret_name": "NOTION_API_KEY",
          "secret_value": "ntn_your-secret-here",
          "networking": {
            "type": "limited",
            "allowed_hosts": ["api.notion.com"]
          },
          "injection_location": {"header": true}
        },
        "display_name": "Notion API key for sandbox"
      }
      EOF
      ```

      ```bash CLI
      ant beta:vaults:credentials create --vault-id "$VAULT_ID" <<'YAML'
      display_name: Notion API key for sandbox
      auth:
        type: environment_variable
        secret_name: NOTION_API_KEY
        secret_value: ntn_your-secret-here
        injection_location:
          header: true
        networking:
          type: limited
          allowed_hosts: [api.notion.com]
      YAML
      ```

      ```python Python
      env_credential = client.beta.vaults.credentials.create(
          vault_id=vault.id,
          display_name="Notion API key for sandbox",
          auth={
              "type": "environment_variable",
              "secret_name": "NOTION_API_KEY",
              "secret_value": "ntn_your-secret-here",
              "networking": {
                  "type": "limited",
                  "allowed_hosts": ["api.notion.com"],
              },
              "injection_location": {"header": True},
          },
      )
      if env_credential.auth.type == "environment_variable":
          location = env_credential.auth.injection_location
          print(
              f"header: {location.header}, body: {location.body}"
          )  # header: True, body: False
      ```

      ```typescript TypeScript
      const envVarCredential = await client.beta.vaults.credentials.create(vault.id, {
        display_name: "Notion API key for sandbox",
        auth: {
          type: "environment_variable",
          secret_name: "NOTION_API_KEY",
          secret_value: "ntn_your-secret-here",
          networking: {
            type: "limited",
            allowed_hosts: ["api.notion.com"]
          },
          injection_location: { header: true }
        }
      });
      if (envVarCredential.auth.type === "environment_variable") {
        console.log(envVarCredential.auth.injection_location); // { header: true, body: false }
      }
      ```

      ```csharp C#
      var envVarCredential = await client.Beta.Vaults.Credentials.Create(vault.ID, new()
      {
          DisplayName = "Notion API key for sandbox",
          Auth = new BetaManagedAgentsEnvironmentVariableCreateParams
          {
              Type = BetaManagedAgentsEnvironmentVariableCreateParamsType.EnvironmentVariable,
              SecretName = "NOTION_API_KEY",
              SecretValue = "ntn_your-secret-here",
              Networking = new BetaManagedAgentsLimitedCredentialNetworkingParams
              {
                  Type = BetaManagedAgentsLimitedCredentialNetworkingParamsType.Limited,
                  AllowedHosts = ["api.notion.com"],
              },
              InjectionLocation = new() { Header = true },
          },
      });
      if (envVarCredential.Auth.TryPickBetaManagedAgentsEnvironmentVariableAuthResponse(out var envVarAuth))
      {
          var injectionLocation = envVarAuth.InjectionLocation;
          Console.WriteLine($"Header: {injectionLocation.Header}, Body: {injectionLocation.Body}"); // "Header: True, Body: False"
      }
      ```

      ```go Go
      envVarCredential, err := client.Beta.Vaults.Credentials.New(ctx, vault.ID, anthropic.BetaVaultCredentialNewParams{
      	DisplayName: anthropic.String("Notion API key for sandbox"),
      	Auth: anthropic.BetaVaultCredentialNewParamsAuthUnion{
      		OfEnvironmentVariable: &anthropic.BetaManagedAgentsEnvironmentVariableCreateParams{
      			Type:        anthropic.BetaManagedAgentsEnvironmentVariableCreateParamsTypeEnvironmentVariable,
      			SecretName:  "NOTION_API_KEY",
      			SecretValue: "ntn_your-secret-here",
      			Networking: anthropic.BetaManagedAgentsCredentialNetworkingParamsUnion{
      				OfLimited: &anthropic.BetaManagedAgentsLimitedCredentialNetworkingParams{
      					Type:         anthropic.BetaManagedAgentsLimitedCredentialNetworkingParamsTypeLimited,
      					AllowedHosts: []string{"api.notion.com"},
      				},
      			},
      			InjectionLocation: anthropic.BetaManagedAgentsInjectionLocationParams{
      				Header: anthropic.Bool(true),
      			},
      		},
      	},
      })
      if err != nil {
      	panic(err)
      }
      if envVarAuth, ok := envVarCredential.Auth.AsAny().(anthropic.BetaManagedAgentsEnvironmentVariableAuthResponse); ok {
      	injectionLocation := envVarAuth.InjectionLocation
      	fmt.Printf("Header:%t Body:%t\n", injectionLocation.Header, injectionLocation.Body) // "Header:true Body:false"
      }
      ```

      ```java Java
      var envVarCredential = client.beta().vaults().credentials().create(vault.id(),
          CredentialCreateParams.builder()
              .displayName("Notion API key for sandbox")
              .auth(BetaManagedAgentsEnvironmentVariableCreateParams.builder()
                  .type(BetaManagedAgentsEnvironmentVariableCreateParams.Type.ENVIRONMENT_VARIABLE)
                  .secretName("NOTION_API_KEY")
                  .secretValue("ntn_your-secret-here")
                  .limitedNetworking(List.of("api.notion.com"))
                  .injectionLocation(BetaManagedAgentsInjectionLocationParams.builder()
                      .header(true)
                      .build())
                  .build())
              .build());
      envVarCredential.auth().environmentVariable().ifPresent(envVarAuth -> {
          var injectionLocation = envVarAuth.injectionLocation();
          IO.println("header=" + injectionLocation.header() + " body=" + injectionLocation.body()); // header=true body=false
      });
      ```

      ```php PHP
      $envVarCredential = $client->beta->vaults->credentials->create(
          vaultID: $vault->id,
          displayName: 'Notion API key for sandbox',
          auth: ManagedAgentsEnvironmentVariableCreateParams::with(
              type: ManagedAgentsEnvironmentVariableCreateParams\Type::ENVIRONMENT_VARIABLE,
              secretName: 'NOTION_API_KEY',
              secretValue: 'ntn_your-secret-here',
              networking: ManagedAgentsLimitedCredentialNetworkingParams::with(
                  type: ManagedAgentsLimitedCredentialNetworkingParams\Type::LIMITED,
                  allowedHosts: ['api.notion.com'],
              ),
              injectionLocation: ManagedAgentsInjectionLocationParams::with(header: true),
          ),
      );
      if ($envVarCredential->auth instanceof \Anthropic\Beta\Vaults\Credentials\ManagedAgentsEnvironmentVariableAuthResponse) {
          $injectionLocation = $envVarCredential->auth->injectionLocation;
          echo 'header: ' . json_encode($injectionLocation->header) . "\n"; // header: true
          echo 'body: ' . json_encode($injectionLocation->body) . "\n"; // body: false
      }
      ```

      ```ruby Ruby
      env_credential = client.beta.vaults.credentials.create(
        vault.id,
        display_name: "Notion API key for sandbox",
        auth: {
          type: "environment_variable",
          secret_name: "NOTION_API_KEY",
          secret_value: "ntn_your-secret-here",
          networking: {
            type: "limited",
            allowed_hosts: ["api.notion.com"]
          },
          injection_location: {header: true}
        }
      )
      if env_credential.auth.type == :environment_variable
        env_credential.auth.injection_location => {header:, body:}
        puts "header: #{header}, body: #{body}" # header: true, body: false
      end
      ```
    </CodeGroup>

    Las cargas útiles de las solicitudes a menudo se construyen a partir del contenido con el que trabaja el agente, por lo que el cuerpo de la solicitud es la superficie de exposición más amplia. La mayoría de los servicios leen una clave de API desde un encabezado de la solicitud, por lo que habilitar solo `header` (csharp, go: `Header`) es la configuración más restringida. Limita la sustitución a los valores de los encabezados de la solicitud para esa credencial.

    El `injection_location` (java, php: `injectionLocation`; csharp, go: `InjectionLocation`) de la credencial controla en qué partes de una solicitud saliente se sustituye el secreto. Es un objeto opcional, hermano de `networking` (csharp, go: `Networking`), con dos campos booleanos: `header` (csharp, go: `Header`) (encabezados de la solicitud) y `body` (csharp, go: `Body`) (cuerpo de la solicitud). `injection_location` (java, php: `injectionLocation`; csharp, go: `InjectionLocation`) es independiente de `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`) en `networking` (csharp, go: `Networking`): `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`) delimita para qué hosts se sustituye el secreto, y `injection_location` (java, php: `injectionLocation`; csharp, go: `InjectionLocation`) delimita en qué partes de la solicitud se sustituye.

    `injection_location` se comporta de manera diferente al crear y al actualizar:

    | Operación             | Comportamiento de `injection_location`                                                                                                                                                                                                   |
    | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | Crear credencial      | Si proporcionas el objeto, cualquier campo que omitas dentro de él toma el valor predeterminado `false`: `{"header": true}` crea una credencial solo de encabezado. Omite el objeto por completo y ambas ubicaciones quedan habilitadas. |
    | Actualizar credencial | Los campos se fusionan individualmente: `{"body": false}` deshabilita la sustitución en el cuerpo y deja `header` sin cambios.                                                                                                           |

    Una credencial debe tener al menos una ubicación habilitada, por lo que una creación o actualización que deshabilitaría ambas ubicaciones devuelve un error 400. Pasar un `null` explícito para el objeto `injection_location` (java, php: `injectionLocation`; csharp, go: `InjectionLocation`) o para cualquiera de sus campos también devuelve un error 400 ("omit the field instead"). La respuesta siempre devuelve ambos campos con sus valores resueltos.

    Un marcador de posición en una ubicación deshabilitada no se sustituye ni se elimina. La solicitud se envía al tercero con la cadena literal del marcador de posición opaco en esa ubicación. Si llega al tercero una solicitud que contiene la cadena literal del marcador de posición, o bien esa ubicación está deshabilitada para la credencial, o bien el host de destino no está cubierto por el `allowed_hosts` (java, php: `allowedHosts`; csharp, go: `AllowedHosts`) en el `networking` (csharp, go: `Networking`) de la credencial.

    <Note>
      Las credenciales creadas en la Console habilitan solo la inyección de encabezado. Si tu cliente envía el secreto en el cuerpo de la solicitud, como una solicitud de token codificada en formulario, el marcador de posición pasa literalmente y el servicio lo rechaza con su propio error de autenticación. Habilita la inyección en el cuerpo en el formulario de la Console cuando crees la credencial, o actualiza la credencial con `{"injection_location": {"body": true}}`.
    </Note>

    La sustitución ocurre en la salida, no dentro del sandbox. Cualquier cosa que procese la credencial localmente ve el marcador de posición opaco, no el valor real: los clientes que validan el formato de la credencial al iniciarse pueden rechazarla, y los clientes que calculan una firma de solicitud a partir del secreto (por ejemplo, AWS SigV4) producen una firma no válida. Las credenciales de variables de entorno funcionan con clientes que envían el valor del secreto textualmente en una solicitud saliente, en una ubicación que el `injection_location` (java, php: `injectionLocation`; csharp, go: `InjectionLocation`) de la credencial habilita.

    La sustitución es solo saliente. Si un cliente usa el secreto almacenado para obtener un token de sesión (por ejemplo, una concesión de credenciales de cliente OAuth), el token devuelto llega al sandbox sin redactar. Para flujos basados en intercambio, realiza el intercambio tú mismo y almacena el token resultante en el vault en su lugar.

    <Tip>
      Delimita la clave de API solo a los permisos que el agente necesita. El agente puede hacer cualquier cosa que la clave permita, por lo que una clave con permisos más amplios de lo necesario aumenta el radio de impacto si el agente se comporta de manera inesperada.
    </Tip>
  </Tab>
</Tabs>

Las credenciales se almacenan tal como se proporcionan y no se validan hasta el tiempo de ejecución de la sesión. Una credencial inválida aparece como un error de autenticación o de flujo descendente durante la sesión, que se emite pero no impide que la sesión continúe.

Restricciones:

* **Clave única por vault.** `mcp_server_url` (java: `mcpServerUrl`; php: `mcpServerURL`; csharp: `McpServerUrl`; go: `MCPServerURL`) (credenciales de MCP) y `secret_name` (java, php: `secretName`; csharp, go: `SecretName`) (credenciales de variables de entorno) deben ser únicos entre las credenciales activas de un vault. Crear un duplicado devuelve un 409.
* **Las claves son inmutables.** Para cambiar `mcp_server_url` (java: `mcpServerUrl`; php: `mcpServerURL`; csharp: `McpServerUrl`; go: `MCPServerURL`) o `secret_name` (java, php: `secretName`; csharp, go: `SecretName`), archiva la credencial y crea una nueva.
* **Máximo 20 credenciales por vault.**

## Referenciar el vault al crear la sesión

Pasa `vault_ids` (java: `vaultIds`; php: `vaultIDs`; csharp: `VaultIds`; go: `VaultIDs`) al crear una sesión:

<CodeGroup>
  ```bash cURL
  curl --fail-with-body -sS https://api.anthropic.com/v1/sessions \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: managed-agents-2026-04-01" \
    -H "content-type: application/json" \
    --data '{
      "agent": "'"$AGENT_ID"'",
      "environment_id": "'"$ENVIRONMENT_ID"'",
      "vault_ids": ["'"$VAULT_ID"'"],
      "title": "Slack digest for Alice"
    }'
  ```

  ```bash CLI
  ant beta:sessions create \
    --agent "$AGENT_ID" \
    --environment-id "$ENVIRONMENT_ID" \
    --vault-id "$VAULT_ID" \
    --title "Slack digest"
  ```

  ```python Python
  session = client.beta.sessions.create(
      agent=agent.id,
      environment_id=environment.id,
      vault_ids=[vault.id],
      title="Alice's Slack digest",
  )
  ```

  ```typescript TypeScript
  const session = await client.beta.sessions.create({
    agent: agent.id,
    environment_id: environment.id,
    vault_ids: [vault.id],
    title: "Alice's Slack digest"
  });
  ```

  ```csharp C#
  var session = await client.Beta.Sessions.Create(new()
  {
      Agent = agent.ID,
      EnvironmentID = environment.ID,
      VaultIds = [vault.ID],
      Title = "Alice's Slack digest",
  });
  ```

  ```go Go
  session, err := client.Beta.Sessions.New(ctx, anthropic.BetaSessionNewParams{
  	Agent: anthropic.BetaSessionNewParamsAgentUnion{
  		OfString: anthropic.String(agent.ID),
  	},
  	EnvironmentID: environment.ID,
  	VaultIDs:      []string{vault.ID},
  	Title:         anthropic.String("Alice's Slack digest"),
  })
  if err != nil {
  	panic(err)
  }
  ```

  ```java Java
  var session = client.beta().sessions().create(SessionCreateParams.builder()
      .agent(agent.id())
      .environmentId(environment.id())
      .vaultIds(List.of(vault.id()))
      .title("Alice's Slack digest")
      .build());
  ```

  ```php PHP
  $session = $client->beta->sessions->create(
      agent: $agent->id,
      environmentID: $environment->id,
      vaultIDs: [$vault->id],
      title: "Alice's Slack digest",
  );
  ```

  ```ruby Ruby
  session = client.beta.sessions.create(
    agent: agent.id,
    environment_id: environment.id,
    vault_ids: [vault.id],
    title: "Alice's Slack digest"
  )
  ```
</CodeGroup>

Comportamiento en tiempo de ejecución:

* Cuando ninguna credencial de MCP coincide por `mcp_server_url` (java: `mcpServerUrl`; php: `mcpServerURL`; csharp: `McpServerUrl`; go: `MCPServerURL`), se intenta la conexión sin autenticación y fallará si el servidor requiere autenticación.
* Cuando múltiples vaults contienen una credencial coincidente, gana el primer vault con una coincidencia.
* En [sesiones multiagente](https://platform.claude.com/docs/es/managed-agents/multiagent-orchestration), las credenciales del vault se aplican a cada hilo. Un agente cuya propia definición declara el servidor MCP coincidente se autentica con estas credenciales. Consulta [Conectar agentes a servidores MCP](https://platform.claude.com/docs/es/managed-agents/multiagent-orchestration#connect-agents-to-mcp-servers).

## Rotar una credencial

Se pueden actualizar los valores de los secretos, `display_name` (java, php: `displayName`; csharp, go: `DisplayName`) y (en las credenciales de variables de entorno) `injection_location` (java, php: `injectionLocation`; csharp, go: `InjectionLocation`). Las actualizaciones de `injection_location` (java, php: `injectionLocation`; csharp, go: `InjectionLocation`) se fusionan por campo, como se describe en la pestaña Environment variable de [Agregar una credencial](https://platform.claude.com/docs/es/managed-agents/vaults#add-a-credential). Para una sesión en ejecución, una actualización de `injection_location` (java, php: `injectionLocation`; csharp, go: `InjectionLocation`) se propaga de la misma manera que una rotación de secreto: las credenciales de la sesión se vuelven a resolver sin reiniciar, como se describe en [Ciclo de vida de las credenciales](https://platform.claude.com/docs/es/managed-agents/vaults#credential-lifecycle), y las ubicaciones actualizadas se aplican a las solicitudes salientes posteriores de la sesión. Los campos estructurales (`mcp_server_url` (java: `mcpServerUrl`; php: `mcpServerURL`; csharp: `McpServerUrl`; go: `MCPServerURL`), `secret_name` (java, php: `secretName`; csharp, go: `SecretName`), `token_endpoint` (java, php: `tokenEndpoint`; csharp, go: `TokenEndpoint`), `client_id` (java: `clientId`; php: `clientID`; csharp, go: `ClientID`)) quedan bloqueados después de la creación. Para cambiarlos, archiva la credencial y crea una nueva.

<CodeGroup>
  ```bash cURL
  curl --fail-with-body -sS \
    "https://api.anthropic.com/v1/vaults/$VAULT_ID/credentials/$CREDENTIAL_ID" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: managed-agents-2026-04-01" \
    -H "content-type: application/json" \
    -d @- <<'EOF'
  {
    "auth": {
      "type": "mcp_oauth",
      "access_token": "xoxp-new-...",
      "expires_at": "2099-12-31T23:59:59Z",
      "refresh": {"refresh_token": "xoxe-1-new-..."}
    }
  }
  EOF
  ```

  ```bash CLI
  ant beta:vaults:credentials update \
    --vault-id "$VAULT_ID" \
    --credential-id "$CREDENTIAL_ID" <<'YAML'
  auth:
    type: mcp_oauth
    access_token: xoxp-new-...
    expires_at: "2099-12-31T23:59:59Z"
    refresh:
      refresh_token: xoxe-1-new-...
  YAML
  ```

  ```python Python
  client.beta.vaults.credentials.update(
      credential.id,
      vault_id=vault.id,
      auth={
          "type": "mcp_oauth",
          "access_token": "xoxp-new-...",
          "expires_at": "2099-12-31T23:59:59Z",
          "refresh": {"refresh_token": "xoxe-1-new-..."},
      },
  )
  ```

  ```typescript TypeScript
  await client.beta.vaults.credentials.update(credential.id, {
    vault_id: vault.id,
    auth: {
      type: "mcp_oauth",
      access_token: "xoxp-new-...",
      expires_at: "2099-12-31T23:59:59Z",
      refresh: {
        refresh_token: "xoxe-1-new-..."
      }
    }
  });
  ```

  ```csharp C#
  await client.Beta.Vaults.Credentials.Update(credential.ID, new()
  {
      VaultID = vault.ID,
      Auth = new BetaManagedAgentsMcpOAuthUpdateParams
      {
          Type = BetaManagedAgentsMcpOAuthUpdateParamsType.McpOAuth,
          AccessToken = "xoxp-new-...",
          ExpiresAt = DateTimeOffset.Parse("2099-12-31T23:59:59Z"),
          Refresh = new() { RefreshToken = "xoxe-1-new-..." },
      },
  });
  ```

  ```go Go
  _, err = client.Beta.Vaults.Credentials.Update(ctx, credential.ID, anthropic.BetaVaultCredentialUpdateParams{
  	VaultID: vault.ID,
  	Auth: anthropic.BetaVaultCredentialUpdateParamsAuthUnion{
  		OfMCPOAuth: &anthropic.BetaManagedAgentsMCPOAuthUpdateParams{
  			Type:        anthropic.BetaManagedAgentsMCPOAuthUpdateParamsTypeMCPOAuth,
  			AccessToken: anthropic.String("xoxp-new-..."),
  			ExpiresAt:   anthropic.Time(time.Date(2099, time.December, 31, 23, 59, 59, 0, time.UTC)),
  			Refresh: anthropic.BetaManagedAgentsMCPOAuthRefreshUpdateParams{
  				RefreshToken: anthropic.String("xoxe-1-new-..."),
  			},
  		},
  	},
  })
  if err != nil {
  	panic(err)
  }
  ```

  ```java Java
  client.beta().vaults().credentials().update(credential.id(),
      CredentialUpdateParams.builder()
          .vaultId(vault.id())
          .auth(BetaManagedAgentsMcpOAuthUpdateParams.builder()
              .type(BetaManagedAgentsMcpOAuthUpdateParams.Type.MCP_OAUTH)
              .accessToken("xoxp-new-...")
              .expiresAt(OffsetDateTime.parse("2099-12-31T23:59:59Z"))
              .refresh(BetaManagedAgentsMcpOAuthRefreshUpdateParams.builder()
                  .refreshToken("xoxe-1-new-...")
                  .build())
              .build())
          .build());
  ```

  ```php PHP
  $client->beta->vaults->credentials->update(
      $credential->id,
      vaultID: $vault->id,
      auth: ManagedAgentsMCPOAuthUpdateParams::with(
          type: 'mcp_oauth',
          accessToken: 'xoxp-new-...',
          expiresAt: new \DateTimeImmutable('2099-12-31T23:59:59Z'),
          refresh: ManagedAgentsMCPOAuthRefreshUpdateParams::with(refreshToken: 'xoxe-1-new-...'),
      ),
  );
  ```

  ```ruby Ruby
  client.beta.vaults.credentials.update(
    credential.id,
    vault_id: vault.id,
    auth: {
      type: "mcp_oauth",
      access_token: "xoxp-new-...",
      expires_at: "2099-12-31T23:59:59Z",
      refresh: {refresh_token: "xoxe-1-new-..."}
    }
  )
  ```
</CodeGroup>

## Ciclo de vida de las credenciales

Las credenciales se vuelven a resolver periódicamente, tanto durante una sesión como durante el ciclo de vida del vault. Esto garantiza que la rotación, el archivado o la eliminación de credenciales se propaguen a las sesiones en ejecución sin un reinicio.

Para recibir notificaciones si una credencial se archiva, se elimina o no se puede actualizar, puedes suscribirte a los [webhooks](https://platform.claude.com/docs/es/managed-agents/webhooks) de vault y credencial asociados con esos cambios de ciclo de vida.

| Evento                            | Disparador                                                                                                                     |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `vault.archived`                  | Vault archivado. También se emite un evento `vault_credential.archived` para cada credencial subyacente.                       |
| `vault.deleted`                   | Vault eliminado. También se emite un evento `vault_credential.deleted` para cada credencial subyacente.                        |
| `vault_credential.archived`       | Credencial archivada, ya sea directamente o como resultado del archivado del vault.                                            |
| `vault_credential.deleted`        | Credencial eliminada, ya sea directamente o como resultado de la eliminación del vault.                                        |
| `vault_credential.refresh_failed` | Una credencial `mcp_oauth` no se puede actualizar (token de actualización inválido, o error irrecuperable del servidor OAuth). |

<Note>
  Esta es una lista no exhaustiva de webhooks; consulta [Suscribirse a webhooks](https://platform.claude.com/docs/es/managed-agents/webhooks) para ver la lista completa.
</Note>

Para las credenciales `mcp_oauth`, la re-resolución también actualiza el token de acceso si ha expirado. Si la actualización falla, se emite un evento `vault_credential.refresh_failed`.

### Diagnosticar un fallo de actualización de OAuth

Para diagnosticar por qué falló una actualización, llama a `POST /v1/vaults/{vault_id}/credentials/{credential_id}/mcp_oauth_validate` (o `client.beta.vaults.credentials.mcp_oauth_validate(...)` (typescript: `client.beta.vaults.credentials.mcpOAuthValidate(...)`; csharp: `client.Beta.Vaults.Credentials.McpOAuthValidate(...)`; go: `client.Beta.Vaults.Credentials.MCPOAuthValidate(...)`; java: `client.beta().vaults().credentials().mcpOAuthValidate(...)`; php: `$client->beta->vaults->credentials->mcpOAuthValidate(...)`) en el SDK). Esto te permite decidir cómo manejar el fallo; la acción adecuada depende del tipo de error.

El `status` (csharp, go: `Status`) de nivel superior te indica qué hacer a continuación:

* `valid`: el token funciona; no se necesita ninguna acción.
* `invalid`: la concesión ya no existe o el servidor OAuth rechazó la actualización con un 4xx. Solicita al usuario final que vuelva a autorizar.
* `unknown`: un error transitorio (5xx, 429 o fallo de red). Espera y reintenta.

<CodeGroup>
  ```bash cURL
  curl --fail-with-body -sS -X POST \
    "https://api.anthropic.com/v1/vaults/$VAULT_ID/credentials/$CREDENTIAL_ID/mcp_oauth_validate?beta=true" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: managed-agents-2026-04-01"
  ```

  ```bash CLI
  ant beta:vaults:credentials mcp-oauth-validate \
    --vault-id "$VAULT_ID" \
    --credential-id "$CREDENTIAL_ID"
  ```

  ```python Python
  validation = client.beta.vaults.credentials.mcp_oauth_validate(
      credential.id,
      vault_id=vault.id,
  )
  print(validation.status)  # "valid", "invalid", or "unknown"
  ```

  ```typescript TypeScript
  const validation = await client.beta.vaults.credentials.mcpOAuthValidate(credential.id, {
    vault_id: vault.id
  });
  console.log(validation.status); // "valid", "invalid", or "unknown"
  ```

  ```csharp C#
  var validation = await client.Beta.Vaults.Credentials.McpOAuthValidate(credential.ID, new()
  {
      VaultID = vault.ID,
  });
  Console.WriteLine(validation.Status.Raw()); // "valid", "invalid", or "unknown"
  ```

  ```go Go
  validation, err := client.Beta.Vaults.Credentials.MCPOAuthValidate(ctx, credential.ID, anthropic.BetaVaultCredentialMCPOAuthValidateParams{
  	VaultID: vault.ID,
  })
  if err != nil {
  	panic(err)
  }
  fmt.Println(validation.Status) // "valid", "invalid", or "unknown"
  ```

  ```java Java
  var validation = client.beta().vaults().credentials().mcpOAuthValidate(credential.id(),
      CredentialMcpOAuthValidateParams.builder()
          .vaultId(vault.id())
          .build());
  IO.println(validation.status()); // valid, invalid, or unknown
  ```

  ```php PHP
  $validation = $client->beta->vaults->credentials->mcpOAuthValidate(
      $credential->id,
      vaultID: $vault->id,
  );
  echo $validation->status . "\n"; // "valid", "invalid", or "unknown"
  ```

  ```ruby Ruby
  validation = client.beta.vaults.credentials.mcp_oauth_validate(
    credential.id,
    vault_id: vault.id
  )
  puts validation.status # :valid, :invalid, or :unknown
  ```
</CodeGroup>

La respuesta es un objeto `vault_credential_validation`. `mcp_probe` incluye el paso fallido del handshake MCP; `refresh` incluye el resultado de la actualización intentada.

```json
{
  "type": "vault_credential_validation",
  "credential_id": "vcrd_01ABC...",
  "vault_id": "vlt_01XYZ...",
  "validated_at": "2026-04-29T17:12:00Z",
  "has_refresh_token": false,
  "status": "invalid",
  "mcp_probe": {
    "method": "initialize",
    "http_response": {
      "status_code": 401,
      "content_type": "application/json",
      "body": "{\"error\":\"invalid_token\"}",
      "body_truncated": false
    }
  },
  "refresh": {
    "status": "no_refresh_token",
    "http_response": null
  }
}
```

## Otras operaciones

* **Listar vaults o credenciales:** Paginado, los más recientes primero. Los registros archivados se excluyen de forma predeterminada (pasa `include_archived=true` para incluirlos).
* **Archivar un vault:** `POST /v1/vaults/{id}/archive`. Se propaga en cascada a todas las credenciales. Los secretos se purgan; los registros se conservan para auditoría. Las sesiones futuras que referencien este vault fallan; las sesiones en ejecución continúan.
* **Archivar una credencial:** `POST /v1/vaults/{id}/credentials/{cred_id}/archive`. Purga la carga útil del secreto; la clave de la credencial (`mcp_server_url` o `secret_name`) permanece visible y queda liberada para una credencial de reemplazo.
* **Eliminar un vault o credencial:** Eliminación permanente. El registro no se conserva. Usa el archivado si necesitas un rastro de auditoría.
