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

# Rescate

> De la solicitud al USDC en la billetera de la empresa, con un ejemplo completo en TypeScript

> [!WARNING]
>
> Borrador: especificación en curso. Los endpoints y campos pueden cambiar.

Un rescate devuelve USDC a una billetera vinculada de propiedad de la empresa. Tras la firma del custodio, el saldo llega en segundos.

## Estados

| Estado | Significado |
| - | - |
| `pendente` | Creado, a la espera de aprobación |
| `aprovado` | Aprobado, transacciones en preparación |
| `aguardando_assinatura` | Transacciones sin firmar disponibles para el custodio |
| `concluido` | USDC confirmado on-chain en la billetera de destino |
| `falhou` | La transacción falló o expiró. Se puede crear un nuevo rescate |

## Ejemplo completo

Valores ilustrativos. El envío al custodio depende de la API de cada custodio y aparece aquí como una función de su propia integración.

```typescript TypeScript theme={null}
const BASE = "https://api.t3sa.com/v1"; // URL propuesta
const auth = { Authorization: `Bearer ${process.env.TESA_API_KEY}` };

async function tesa(path: string, init: RequestInit = {}) {
  const res = await fetch(`${BASE}${path}`, {
    ...init,
    headers: { ...auth, "Content-Type": "application/json", ...init.headers },
  });
  const body = await res.json();
  if (!res.ok) throw new Error(`${body.erro.codigo}: ${body.erro.mensagem}`);
  return body;
}

// 1. Solicitud (alcance propose)
const resgate = await tesa("/resgates", {
  method: "POST",
  headers: { "Idempotency-Key": crypto.randomUUID() },
  body: JSON.stringify({
    valor: "150000.00",
    carteira_destino_id: "cart_3k9d",
    referencia_interna: "folha-2026-09",
  }),
});

// 2. Aprobación (alcance admin, en un entorno restringido)
const aprovado = await tesa(`/resgates/${resgate.id}/aprovar`, {
  method: "POST",
  headers: { "Idempotency-Key": crypto.randomUUID() },
  body: JSON.stringify({ comentario: "Folha de setembro" }),
});

// 3. Enviar cada transacción sin firmar al custodio
for (const tx of aprovado.transacoes) {
  await enviarAoCustodiante(tx.rede, tx.payload_nao_assinado);
}

// 4. Esperar el webhook resgate.concluido, o consultar GET /resgates/{id}
```

## Errores comunes

| HTTP | Código | Qué hacer |
| - | - | - |
| `422` | `saldo_insuficiente` | El monto supera el saldo disponible para rescate. Revise `GET /posicoes` |
| `422` | `carteira_nao_vinculada` | El destino no es una billetera vinculada de la empresa |
| `409` | `conflito_idempotencia` | Se usó la misma `Idempotency-Key` con un cuerpo distinto |
| `503` | `servico_indisponivel` | Una dependencia externa no está disponible, como una pausa del CCTP. Reintente con la misma `Idempotency-Key` |

Lista completa en [Errores y límites](https://t3sa.com/docs/es/api/erros-e-limites.md).


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