# Métricas de uso y facturación

En esta guía se muestra cómo leer los recuentos de tokens, el uso de ventanas de contexto, el costo de crédito de IA y la cuota de la cuenta desde una aplicación del SDK de Copilot. Se muestran ejemplos para TypeScript, Python, Go, .NET, Java y Rust.

<!-- markdownlint-disable GHD046 GHD005 -->

<!-- Suppressed: GHD046 (outdated release terminology), GHD005 (hardcoded data variable) -->

> \[!TIP]
> Cada ejemplo es funcionalmente equivalente entre idiomas. El fragmento de código de TypeScript aparece expandido de forma predeterminada; selecciona tu idioma en los bloques desplegables para ver la misma lógica en ese SDK correspondiente.

## Información general

El SDK expone los datos de uso a través de dos mecanismos complementarios:

* **Eventos de sesión**: eventos transitorios que el entorno de ejecución emite mientras se ejecuta un turno. Suscríbase a estas para obtener datos en tiempo real de cada llamada a la API.
* **Métodos RPC**: llamadas de petición-respuesta que se realizan bajo demanda. Úselos para obtener una instantánea de los totales acumulados o consultar la cuota de la cuenta.

En la tabla siguiente se asigna cada señal a la API que la expone.

| Señal                                           | API                            | Ámbito   | Tipo |
| ----------------------------------------------- | ------------------------------ | -------- | ---- |
| Recuentos de tokens por llamada                 |                                |          |      |
| `assistant.usage` evento                        | Session                        | Event    |      |
| Uso de la ventana de contexto                   |                                |          |      |
| `session.usage_info` evento                     | Session                        | Event    |      |
| Desglose de la ventana de contexto (a petición) | `session.metadata.contextInfo` | Session  | RPC  |
| Totales acumulados de créditos y tokens de IA   | `session.usage.getMetrics`     | Session  | RPC  |
| Precios de crédito por modelo de IA             | `models.list`                  | Servidor | RPC  |
| Cuota de cuenta e interacciones premium         | `account.getQuota`             | Servidor | RPC  |

> \[!NOTE]
> `session.usage.getMetrics`, `session.metadata.contextInfo`y `session.metadata.recomputeContextTokens` se marcan como experimentales en la superficie RPC generada. En .NET emiten el `GHCP001` diagnóstico experimental, que se suprime con `#pragma warning disable GHCP001` o un `<NoWarn>GHCP001</NoWarn>` en el nivel de proyecto. Ancle tanto el SDK como el entorno de ejecución de la CLI de Copilot si la aplicación depende de ellos.

Las tablas de campos siguientes muestran solo los campos usados en los ejemplos de esta página. La referencia de campos completa y siempre actualizada la componen los tipos generados del SDK y [Eventos de la sesión de transmisión](/es/copilot/how-tos/copilot-sdk/features/streaming-events), que se regenera a partir del esquema de la CLI con cada actualización de dependencias. Trátelos como la fuente de la verdad y esta página como una guía orientada a tareas.

## Recuentos de tokens por llamada

El evento `assistant.usage` se emite una vez por cada llamada a la API del modelo en un turno (incluidas las llamadas realizadas por los subagentes). Incluye los recuentos de tokens y el multiplicador de facturación de esa llamada concreta.

En el ejemplo siguiente se usan estos campos. Consulte [Eventos de la sesión de transmisión](/es/copilot/how-tos/copilot-sdk/features/streaming-events#assistantusage) para obtener la lista completa, incluidos los campos de caché, razonamiento, latencia y seguimiento.

| Campo          | Tipo     | Description                                                  |
| -------------- | -------- | ------------------------------------------------------------ |
| `model`        | `string` | Identificador de modelo para esta llamada                    |
| `inputTokens`  | `number` | Tokens de entrada consumidos                                 |
| `outputTokens` | `number` | Tokens de salida generados                                   |
| `cost`         | `number` | Multiplicador de solicitudes Premium aplicado a esta llamada |

> \[!TIP]
> `assistant.usage` es efímero, por lo que se entrega en vivo pero no se reproduce cuando se reanuda una sesión. Para leer los totales acumulados a posteriori, llame a `session.usage.getMetrics` (consulte [Crédito de IA acumulado y totales de tokens](#accumulated-ai-credit-and-token-totals)).

<div class="ghd-codetabs">
<div class="ghd-codetab" data-lang="typescript" data-label="TypeScript"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">TypeScript</div>

```typescript
session.on("assistant.usage", (event) => {
    const { model, inputTokens, outputTokens, cost } = event.data;
    console.log(
        `${model}: in=${inputTokens ?? 0} out=${outputTokens ?? 0} cost=${cost ?? 0}`,
    );
});
```

</div>

<div class="ghd-codetab" data-lang="python" data-label="Python"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Python</div>

```python
def on_usage(event):
    if event.type == SessionEventType.ASSISTANT_USAGE:
        data = event.data
        print(f"{data.model}: in={data.input_tokens or 0} out={data.output_tokens or 0} cost={data.cost or 0}")

session.on(on_usage)
```

</div>

<div class="ghd-codetab" data-lang="go" data-label="Go"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Go</div>

```golang
session.On(func(event copilot.SessionEvent) {
    d, ok := event.Data.(*copilot.AssistantUsageData)
    if !ok {
        return
    }
    in, out, cost := int64(0), int64(0), float64(0)
    if d.InputTokens != nil {
        in = *d.InputTokens
    }
    if d.OutputTokens != nil {
        out = *d.OutputTokens
    }
    if d.Cost != nil {
        cost = *d.Cost
    }
    fmt.Printf("%s: in=%d out=%d cost=%g\n", d.Model, in, out, cost)
})
```

</div>

<div class="ghd-codetab" data-lang="dotnet" data-label=".NET"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">.NET</div>

```csharp
session.On<AssistantUsageEvent>(evt =>
{
    var data = evt.Data;
    Console.WriteLine(
        $"{data.Model}: in={data.InputTokens ?? 0} out={data.OutputTokens ?? 0} cost={data.Cost ?? 0}");
});
```

</div>

<div class="ghd-codetab" data-lang="java" data-label="Java"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Java</div>

<!-- docs-validate: skip -->

```java
session.on(AssistantUsageEvent.class, event -> {
    var data = event.getData();
    long in = data.inputTokens() != null ? data.inputTokens() : 0;
    long out = data.outputTokens() != null ? data.outputTokens() : 0;
    double cost = data.cost() != null ? data.cost() : 0.0;
    System.out.printf("%s: in=%d out=%d cost=%s%n", data.model(), in, out, cost);
});
```

</div>

<div class="ghd-codetab" data-lang="rust" data-label="Rust"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Rust</div>

```rust
use github_copilot_sdk::session_events::AssistantUsageData;

let mut events = session.subscribe();
while let Ok(event) = events.recv().await {
    if event.event_type == "assistant.usage" {
        if let Some(data) = event.typed_data::<AssistantUsageData>() {
            println!(
                "{}: in={} out={} cost={}",
                data.model,
                data.input_tokens.unwrap_or(0),
                data.output_tokens.unwrap_or(0),
                data.cost.unwrap_or(0.0),
            );
        }
    }
}
```

</div>

</div>

## Uso de la ventana de contexto

Los recuentos de tokens te indican cuántos consumió cada llamada. El uso de la ventana de contexto indica cómo está completa la ventana de solicitud del modelo en este momento, útil para mostrar una barra de progreso o advertir al usuario antes de que se inicie la compactación automática.

### Actualizaciones en directo con `session.usage_info`

El entorno de ejecución emite el evento `session.usage_info` cada vez que cambia el tamaño de la ventana de contexto. En el ejemplo se usa `currentTokens` y `tokenLimit`; vea [Eventos de la sesión de transmisión](/es/copilot/how-tos/copilot-sdk/features/streaming-events#sessionusage_info) para obtener la carga completa.

| Campo           | Tipo     | Description                                                    |
| --------------- | -------- | -------------------------------------------------------------- |
| `currentTokens` | `number` | Tokens actualmente en la ventana de contexto                   |
| `tokenLimit`    | `number` | Número máximo de tokens para la ventana de contexto del modelo |

<div class="ghd-codetabs">
<div class="ghd-codetab" data-lang="typescript" data-label="TypeScript"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">TypeScript</div>

```typescript
session.on("session.usage_info", (event) => {
    const { currentTokens, tokenLimit } = event.data;
    const pct = Math.round((currentTokens / tokenLimit) * 100);
    console.log(`Context: ${currentTokens}/${tokenLimit} (${pct}%)`);
});
```

</div>

<div class="ghd-codetab" data-lang="python" data-label="Python"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Python</div>

```python
def on_usage_info(event):
    if event.type == SessionEventType.SESSION_USAGE_INFO:
        data = event.data
        pct = round(data.current_tokens / data.token_limit * 100)
        print(f"Context: {data.current_tokens}/{data.token_limit} ({pct}%)")

session.on(on_usage_info)
```

</div>

<div class="ghd-codetab" data-lang="go" data-label="Go"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Go</div>

```golang
session.On(func(event copilot.SessionEvent) {
    d, ok := event.Data.(*copilot.SessionUsageInfoData)
    if !ok {
        return
    }
    pct := int(float64(d.CurrentTokens) / float64(d.TokenLimit) * 100)
    fmt.Printf("Context: %d/%d (%d%%)\n", d.CurrentTokens, d.TokenLimit, pct)
})
```

</div>

<div class="ghd-codetab" data-lang="dotnet" data-label=".NET"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">.NET</div>

```csharp
session.On<SessionUsageInfoEvent>(evt =>
{
    var pct = (int)Math.Round((double)evt.Data.CurrentTokens / evt.Data.TokenLimit * 100);
    Console.WriteLine($"Context: {evt.Data.CurrentTokens}/{evt.Data.TokenLimit} ({pct}%)");
});
```

</div>

<div class="ghd-codetab" data-lang="java" data-label="Java"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Java</div>

<!-- docs-validate: skip -->

```java
session.on(SessionUsageInfoEvent.class, event -> {
    var data = event.getData();
    long pct = Math.round((double) data.currentTokens() / data.tokenLimit() * 100);
    System.out.printf("Context: %d/%d (%d%%)%n", data.currentTokens(), data.tokenLimit(), pct);
});
```

</div>

<div class="ghd-codetab" data-lang="rust" data-label="Rust"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Rust</div>

```rust
use github_copilot_sdk::session_events::SessionUsageInfoData;

let mut events = session.subscribe();
while let Ok(event) = events.recv().await {
    if event.event_type == "session.usage_info" {
        if let Some(data) = event.typed_data::<SessionUsageInfoData>() {
            let pct = (data.current_tokens as f64 / data.token_limit as f64 * 100.0) as i64;
            println!("Context: {}/{} ({}%)", data.current_tokens, data.token_limit, pct);
        }
    }
}
```

</div>

</div>

### Desglose a petición con `session.metadata.contextInfo`

Los eventos solo se activan cuando cambia el contexto. Para leer el desglose actual en cualquier momento (por ejemplo, justo después de reanudar una sesión), llame a `session.metadata.contextInfo`. Pase `0` para `promptTokenLimit` que use el valor predeterminado en tiempo de ejecución; pase `0` para `outputTokenLimit` si el valor es desconocido.

El resultado `contextInfo` es `null` hasta que se ha inicializado la sesión (se han almacenado en caché la solicitud del sistema y los metadatos de la herramienta). Divide el total en `systemTokens`, `conversationTokens`y `toolDefinitionsTokens`, junto con `promptTokenLimit`.

<div class="ghd-codetabs">
<div class="ghd-codetab" data-lang="typescript" data-label="TypeScript"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">TypeScript</div>

```typescript
const { contextInfo } = await session.rpc.metadata.contextInfo({
    promptTokenLimit: 0,
    outputTokenLimit: 0,
});

if (contextInfo) {
    console.log(
        `Total ${contextInfo.totalTokens}/${contextInfo.promptTokenLimit} ` +
            `(system=${contextInfo.systemTokens}, conversation=${contextInfo.conversationTokens})`,
    );
}
```

</div>

<div class="ghd-codetab" data-lang="python" data-label="Python"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Python</div>

```python
result = await session.rpc.metadata.context_info(
    MetadataContextInfoRequest(prompt_token_limit=0, output_token_limit=0)
)
info = result.context_info

if info is not None:
    print(
        f"Total {info.total_tokens}/{info.prompt_token_limit} "
        f"(system={info.system_tokens}, conversation={info.conversation_tokens})"
    )
```

</div>

<div class="ghd-codetab" data-lang="go" data-label="Go"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Go</div>

```golang
result, _ := session.RPC.Metadata.ContextInfo(ctx, &rpc.MetadataContextInfoRequest{
    PromptTokenLimit: 0,
    OutputTokenLimit: 0,
})

if info := result.ContextInfo; info != nil {
    fmt.Printf("Total %d/%d (system=%d, conversation=%d)\n",
        info.TotalTokens, info.PromptTokenLimit, info.SystemTokens, info.ConversationTokens)
}
```

</div>

<div class="ghd-codetab" data-lang="dotnet" data-label=".NET"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">.NET</div>

```csharp
var result = await session.Rpc.Metadata.ContextInfoAsync(promptTokenLimit: 0, outputTokenLimit: 0);
var info = result.ContextInfo;

if (info is not null)
{
    Console.WriteLine(
        $"Total {info.TotalTokens}/{info.PromptTokenLimit} " +
        $"(system={info.SystemTokens}, conversation={info.ConversationTokens})");
}
```

</div>

<div class="ghd-codetab" data-lang="java" data-label="Java"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Java</div>

<!-- docs-validate: skip -->

```java
var result = session.getRpc().metadata
    .contextInfo(new SessionMetadataContextInfoParams(null, 0L, 0L, null))
    .join();
var info = result.contextInfo();

if (info != null) {
    System.out.printf("Total %d/%d (system=%d, conversation=%d)%n",
        info.totalTokens(), info.promptTokenLimit(), info.systemTokens(), info.conversationTokens());
}
```

</div>

<div class="ghd-codetab" data-lang="rust" data-label="Rust"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Rust</div>

```rust
use github_copilot_sdk::rpc::MetadataContextInfoRequest;

let result = session
    .rpc()
    .metadata()
    .context_info(MetadataContextInfoRequest {
        prompt_token_limit: 0,
        output_token_limit: 0,
        selected_model: None,
    })
    .await?;

if let Some(info) = result.context_info {
    println!(
        "Total {}/{} (system={}, conversation={})",
        info.total_tokens, info.prompt_token_limit, info.system_tokens, info.conversation_tokens,
    );
}
```

</div>

</div>

## Totales acumulados de créditos y tokens de IA

`session.usage.getMetrics` devuelve los totales acumulados de toda la sesión en una sola llamada. Esta es la forma más clara de consultar el coste de los créditos de IA, porque agrega por ti cada llamada a la API (agente principal y subagentes).

En el ejemplo se usan los campos siguientes. El tipo generado `UsageGetMetricsResult` es la referencia completa.

| Campo                     | Tipo                          | Description                                                                                       |
| ------------------------- | ----------------------------- | ------------------------------------------------------------------------------------------------- |
| `totalNanoAiu`            | `number`                      | Coste de créditos de IA de toda la sesión, en unidades nano-IA                                    |
| `totalPremiumRequestCost` | `number`                      | Coste de la solicitud prémium para todos los modelos, tras aplicar los multiplicadores            |
| `modelMetrics`            | `Record<string, ModelMetric>` | Desglose por modelo; cada entrada tiene `usage.inputTokens`, `usage.outputTokens`y `totalNanoAiu` |

> \[!NOTE]
> El costo se notifica en **unidades de nano-AI** (el campo se denomina `totalNanoAiu`). La conversión exacta a créditos de IA y el significado preciso del cómputo de las solicitudes prémium los define la facturación de GitHub Copilot, no el SDK; considera [la documentación de facturación de Copilot de GitHub](/es/copilot/concepts/billing) como la fuente autorizada y verifícala antes de mostrar a los usuarios valores de tipo monetario. Los ejemplos usan la división por `1e9` por comodidad, siguiendo el prefijo `nano` del SI; confirme que esto coincide con la facturación actual antes de basarse en ello. Los mapas `modelMetrics` y `tokenDetails` se codifican mediante cadenas de tiempo de ejecución (ID de modelos y nombres de tipo de token) que el sistema de tipo de SDK no valida.

<div class="ghd-codetabs">
<div class="ghd-codetab" data-lang="typescript" data-label="TypeScript"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">TypeScript</div>

```typescript
const metrics = await session.rpc.usage.getMetrics();

const aiCredits = (metrics.totalNanoAiu ?? 0) / 1e9;
console.log(`AI credits used: ${aiCredits.toFixed(6)}`);
console.log(`Premium requests: ${metrics.totalPremiumRequestCost}`);

for (const [model, m] of Object.entries(metrics.modelMetrics)) {
    if (!m) continue;
    console.log(
        `${model}: in=${m.usage.inputTokens} out=${m.usage.outputTokens} ` +
            `nanoAiu=${m.totalNanoAiu ?? 0}`,
    );
}
```

</div>

<div class="ghd-codetab" data-lang="python" data-label="Python"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Python</div>

```python
metrics = await session.rpc.usage.get_metrics()

ai_credits = (metrics.total_nano_aiu or 0) / 1e9
print(f"AI credits used: {ai_credits:.6f}")
print(f"Premium requests: {metrics.total_premium_request_cost}")

for model, m in metrics.model_metrics.items():
    print(f"{model}: in={m.usage.input_tokens} out={m.usage.output_tokens} nanoAiu={m.total_nano_aiu or 0}")
```

</div>

<div class="ghd-codetab" data-lang="go" data-label="Go"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Go</div>

```golang
metrics, _ := session.RPC.Usage.GetMetrics(ctx)

aiCredits := float64(0)
if metrics.TotalNanoAiu != nil {
    aiCredits = *metrics.TotalNanoAiu / 1e9
}
fmt.Printf("AI credits used: %.6f\n", aiCredits)
fmt.Printf("Premium requests: %v\n", metrics.TotalPremiumRequestCost)

for model, m := range metrics.ModelMetrics {
    nanoAiu := float64(0)
    if m.TotalNanoAiu != nil {
        nanoAiu = *m.TotalNanoAiu
    }
    fmt.Printf("%s: in=%d out=%d nanoAiu=%v\n", model, m.Usage.InputTokens, m.Usage.OutputTokens, nanoAiu)
}
```

</div>

<div class="ghd-codetab" data-lang="dotnet" data-label=".NET"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">.NET</div>

```csharp
var metrics = await session.Rpc.Usage.GetMetricsAsync();

var aiCredits = (metrics.TotalNanoAiu ?? 0) / 1e9;
Console.WriteLine($"AI credits used: {aiCredits:F6}");
Console.WriteLine($"Premium requests: {metrics.TotalPremiumRequestCost}");

foreach (var (model, m) in metrics.ModelMetrics)
{
    Console.WriteLine(
        $"{model}: in={m.Usage.InputTokens} out={m.Usage.OutputTokens} nanoAiu={m.TotalNanoAiu ?? 0}");
}
```

</div>

<div class="ghd-codetab" data-lang="java" data-label="Java"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Java</div>

<!-- docs-validate: skip -->

```java
var metrics = session.getRpc().usage.getMetrics().join();

double aiCredits = metrics.totalNanoAiu() != null ? metrics.totalNanoAiu() / 1e9 : 0;
System.out.printf("AI credits used: %.6f%n", aiCredits);
System.out.printf("Premium requests: %s%n", metrics.totalPremiumRequestCost());

metrics.modelMetrics().forEach((model, m) -> {
    double nanoAiu = m.totalNanoAiu() != null ? m.totalNanoAiu() : 0;
    System.out.printf("%s: in=%d out=%d nanoAiu=%s%n",
        model, m.usage().inputTokens(), m.usage().outputTokens(), nanoAiu);
});
```

</div>

<div class="ghd-codetab" data-lang="rust" data-label="Rust"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Rust</div>

```rust
let metrics = session.rpc().usage().get_metrics().await?;

let ai_credits = metrics.total_nano_aiu.unwrap_or(0.0) / 1e9;
println!("AI credits used: {ai_credits:.6}");
println!("Premium requests: {}", metrics.total_premium_request_cost);

for (model, m) in &metrics.model_metrics {
    let nano_aiu = m.total_nano_aiu.unwrap_or(0.0);
    println!(
        "{model}: in={} out={} nanoAiu={nano_aiu}",
        m.usage.input_tokens, m.usage.output_tokens,
    );
}
```

</div>

</div>

## Precios de crédito por modelo de IA

Para calcular el coste antes de ejecutar un turno, lea los precios del token de cada modelo de `models.list`. Se trata de una llamada con ámbito de servidor en el cliente, por lo que no requiere una sesión. Los precios se expresan en créditos de IA por cada lote de tokens facturado. El tipo generado `ModelBillingTokenPrices` enumera todos los campos, incluido `cachePrice`.

| Campo                             | Tipo     | Description                                                               |
| --------------------------------- | -------- | ------------------------------------------------------------------------- |
| `billing.multiplier`              | `number` | Multiplicador de costos de solicitud Premium en relación con la tasa base |
| `billing.tokenPrices.inputPrice`  | `number` | Costo de crédito de IA por lote de tokens de entrada                      |
| `billing.tokenPrices.outputPrice` | `number` | Costo de crédito de IA por lote de tokens de salida                       |
| `billing.tokenPrices.batchSize`   | `number` | Número de tokens por lote de facturación                                  |

> \[!NOTE]
> Los valores de precio cambian a medida que evolucionan los planes y los modelos. Léelas en tiempo de ejecución como se muestra a continuación; nunca codifique de forma rígida los números en la aplicación.

<div class="ghd-codetabs">
<div class="ghd-codetab" data-lang="typescript" data-label="TypeScript"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">TypeScript</div>

```typescript
const { models } = await client.rpc.models.list({});

for (const model of models) {
    const prices = model.billing?.tokenPrices;
    if (!prices) continue;
    console.log(
        `${model.id}: input=${prices.inputPrice} output=${prices.outputPrice} ` +
            `per ${prices.batchSize} tokens (x${model.billing?.multiplier ?? 1})`,
    );
}
```

</div>

<div class="ghd-codetab" data-lang="python" data-label="Python"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Python</div>

```python
result = await client.rpc.models.list(ModelsListRequest())

for model in result.models:
    prices = model.billing.token_prices if model.billing else None
    if prices is None:
        continue
    multiplier = model.billing.multiplier if model.billing else 1
    print(
        f"{model.id}: input={prices.input_price} output={prices.output_price} "
        f"per {prices.batch_size} tokens (x{multiplier})"
    )
```

</div>

<div class="ghd-codetab" data-lang="go" data-label="Go"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Go</div>

```golang
list, _ := client.RPC.Models.List(ctx, &rpc.ModelsListRequest{})

for _, model := range list.Models {
    if model.Billing == nil || model.Billing.TokenPrices == nil {
        continue
    }
    prices := model.Billing.TokenPrices
    multiplier := 1.0
    if model.Billing.Multiplier != nil {
        multiplier = *model.Billing.Multiplier
    }
    in, out := 0.0, 0.0
    if prices.InputPrice != nil {
        in = *prices.InputPrice
    }
    if prices.OutputPrice != nil {
        out = *prices.OutputPrice
    }
    batch := int64(0)
    if prices.BatchSize != nil {
        batch = *prices.BatchSize
    }
    fmt.Printf("%s: input=%v output=%v per %d tokens (x%v)\n", model.ID, in, out, batch, multiplier)
}
```

</div>

<div class="ghd-codetab" data-lang="dotnet" data-label=".NET"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">.NET</div>

```csharp
var list = await client.Rpc.Models.ListAsync();

foreach (var model in list.Models)
{
    var prices = model.Billing?.TokenPrices;
    if (prices is null) continue;
    Console.WriteLine(
        $"{model.Id}: input={prices.InputPrice} output={prices.OutputPrice} " +
        $"per {prices.BatchSize} tokens (x{model.Billing?.Multiplier ?? 1})");
}
```

</div>

<div class="ghd-codetab" data-lang="java" data-label="Java"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Java</div>

<!-- docs-validate: skip -->

```java
var list = client.getRpc().models.list().join();

for (var model : list.models()) {
    var billing = model.billing();
    if (billing == null || billing.tokenPrices() == null) {
        continue;
    }
    var prices = billing.tokenPrices();
    double multiplier = billing.multiplier() != null ? billing.multiplier() : 1;
    System.out.printf("%s: input=%s output=%s per %d tokens (x%s)%n",
        model.id(), prices.inputPrice(), prices.outputPrice(), prices.batchSize(), multiplier);
}
```

</div>

<div class="ghd-codetab" data-lang="rust" data-label="Rust"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Rust</div>

```rust
let list = client.rpc().models().list().await?;

for model in &list.models {
    let Some(billing) = &model.billing else { continue };
    let Some(prices) = &billing.token_prices else { continue };
    let multiplier = billing.multiplier.unwrap_or(1.0);
    println!(
        "{}: input={} output={} per {} tokens (x{multiplier})",
        model.id,
        prices.input_price.unwrap_or(0.0),
        prices.output_price.unwrap_or(0.0),
        prices.batch_size.unwrap_or(0),
    );
}
```

</div>

</div>

## Cuota de cuenta e interacciones premium

`account.getQuota` notifica el derecho de Copilot restante del usuario autenticado. El mapa `quotaSnapshots` del resultado se codifica por tipo de cuota, normalmente `premium_interactions`, `chat` y `completions`. Úselo para mostrar a los usuarios cuánto les queda de su cuota mensual o para bloquear el trabajo antes de que alcancen el límite.

En el ejemplo se usan los campos siguientes; el tipo generado `AccountQuotaSnapshot` es la referencia completa. Las claves `quotaSnapshots` son cadenas de tiempo de ejecución que el sistema de tipos de SDK no valida, así que compruebe las búsquedas.

| Campo                 | Tipo     | Description                                                          |
| --------------------- | -------- | -------------------------------------------------------------------- |
| `entitlementRequests` | `number` | Solicitudes incluidas en el plan, o `-1` para solicitudes ilimitadas |
| `usedRequests`        | `number` | Solicitudes usadas hasta ahora en este período                       |
| `remainingPercentage` | `number` | Porcentaje del derecho restante                                      |
| `resetDate`           | `string` | Fecha ISO 8601 cuando se restablece la cuota                         |

> \[!TIP]
> Para leer la cuota de un usuario específico en lugar del contexto de autenticación global de la conexión (por ejemplo, en un back-end multiinquilino), pase el token de GitHub del usuario a `getQuota`. Consulte [Multiinquilino e implementaciones de servidor](/es/copilot/how-tos/copilot-sdk/setup/multi-tenancy).

<div class="ghd-codetabs">
<div class="ghd-codetab" data-lang="typescript" data-label="TypeScript"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">TypeScript</div>

```typescript
const { quotaSnapshots } = await client.rpc.account.getQuota({});
const premium = quotaSnapshots["premium_interactions"];

if (premium) {
    console.log(
        `Premium interactions: ${premium.usedRequests}/${premium.entitlementRequests} ` +
            `(${premium.remainingPercentage.toFixed(1)}% left, resets ${premium.resetDate ?? "n/a"})`,
    );
}
```

</div>

<div class="ghd-codetab" data-lang="python" data-label="Python"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Python</div>

```python
result = await client.rpc.account.get_quota(AccountGetQuotaRequest())
premium = result.quota_snapshots.get("premium_interactions")

if premium is not None:
    print(
        f"Premium interactions: {premium.used_requests}/{premium.entitlement_requests} "
        f"({premium.remaining_percentage:.1f}% left, resets {premium.reset_date or 'n/a'})"
    )
```

</div>

<div class="ghd-codetab" data-lang="go" data-label="Go"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Go</div>

```golang
result, _ := client.RPC.Account.GetQuota(ctx, &rpc.AccountGetQuotaRequest{})

if premium, ok := result.QuotaSnapshots["premium_interactions"]; ok {
    resets := "n/a"
    if premium.ResetDate != nil {
        resets = premium.ResetDate.Format(time.RFC3339)
    }
    fmt.Printf("Premium interactions: %d/%d (%.1f%% left, resets %s)\n",
        premium.UsedRequests, premium.EntitlementRequests, premium.RemainingPercentage, resets)
}
```

</div>

<div class="ghd-codetab" data-lang="dotnet" data-label=".NET"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">.NET</div>

```csharp
var result = await client.Rpc.Account.GetQuotaAsync();

if (result.QuotaSnapshots.TryGetValue("premium_interactions", out var premium))
{
    Console.WriteLine(
        $"Premium interactions: {premium.UsedRequests}/{premium.EntitlementRequests} " +
        $"({premium.RemainingPercentage:F1}% left, resets {premium.ResetDate?.ToString("o") ?? "n/a"})");
}
```

</div>

<div class="ghd-codetab" data-lang="java" data-label="Java"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Java</div>

<!-- docs-validate: skip -->

```java
var result = client.getRpc().account.getQuota().join();
var premium = result.quotaSnapshots().get("premium_interactions");

if (premium != null) {
    System.out.printf("Premium interactions: %d/%d (%.1f%% left, resets %s)%n",
        premium.usedRequests(), premium.entitlementRequests(),
        premium.remainingPercentage(), premium.resetDate());
}
```

</div>

<div class="ghd-codetab" data-lang="rust" data-label="Rust"><div class="ghd-codetab-fallback-label" role="heading" aria-level="3">Rust</div>

```rust
let result = client.rpc().account().get_quota().await?;

if let Some(premium) = result.quota_snapshots.get("premium_interactions") {
    let resets = premium.reset_date.as_deref().unwrap_or("n/a");
    println!(
        "Premium interactions: {}/{} ({:.1}% left, resets {resets})",
        premium.used_requests, premium.entitlement_requests, premium.remaining_percentage,
    );
}
```

</div>

</div>

## Elección de la API correcta

Use este resumen para decidir qué API se ajusta a su caso de uso:

* ```
            **Representar un medidor en directo de costes o tokens mientras se ejecuta un turno**: suscríbase a `assistant.usage` y `session.usage_info`.
  ```
* **Mostrar un resumen final de costes al final de un turno o de una sesión**: llamar a `session.usage.getMetrics`.
* ```
            **Mostrar el uso de la ventana de contexto al reanudar, antes de cualquier nuevo turno**: llame a `session.metadata.contextInfo`.
  ```
* **Calcule el costo antes de ejecutar el trabajo**: leer `models.list` los precios del token.
* **Advertir a los usuarios antes de agotar su plan**: llame a `account.getQuota`.

## Lectura adicional

* [Eventos de la sesión de transmisión](/es/copilot/how-tos/copilot-sdk/features/streaming-events): referencia de nivel de campo completo para `assistant.usage`, `session.usage_info`y todos los demás eventos de sesión
* [Observability](/es/copilot/how-tos/copilot-sdk/observability): exportar datos de uso a OpenTelemetry para la atribución de costos
* [Multiinquilino e implementaciones de servidor](/es/copilot/how-tos/copilot-sdk/setup/multi-tenancy): resolución de la cuota y los modelos por usuario con un token de GitHub