# IP de salida de webhooks

GET /v1/meta/egress-ips

Direcciones desde las que FITAL envía webhooks, para tu firewall. Pública, con un minuto de caché. La firma HMAC sigue siendo la protección principal.

| Dato | Valor |
|---|---|
| Método y ruta | `GET /v1/meta/egress-ips` |
| Servidor | `https://widget.fital.xyz` |
| `operationId` | `getEgressIps` |
| Acceso | Público, sin llave |
| Firma de petición | No aplica |
| Idempotencia | No aplica |

## Encabezados de la petición

| Encabezado | Obligatorio | Descripción |
|---|---|---|

Sin llave ni otros encabezados obligatorios.

## Respuestas correctas

### 200 Correcto

| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
| `addresses` | lista de objeto | Sí | Direcciones vigentes o anunciadas. |
| `addresses[].active_from` | texto o `null` | Sí | Desde cuándo se usa. |
| `addresses[].ip` | texto | Sí | Dirección IP de salida. |
| `addresses[].retiring_at` | texto o `null` | Sí | Cuándo deja de usarse. null si no tiene fecha de retiro. |
| `note` | texto | Sí | Recordatorio: autoriza por firma, no sólo por IP. |

```json
{
  "addresses": [
    {
      "active_from": "2026-11-01T00:00:00.000Z",
      "ip": "198.51.100.10",
      "retiring_at": null
    }
  ],
  "note": "La firma HMAC es la protección principal"
}
```

## Encabezados de la respuesta

| Encabezado | Contenido |
|---|---|
| `X-Request-Id` | Identificador de la petición. Cítalo con soporte. |

## Errores

Todos usan la forma de [Errores](/docs/errores/): `error.code`, `message`, `request_id`, `details`, `retryable` y `docs_url`. Decide por `code`.

| HTTP | Código | Cuándo sale | `retryable` |
|---|---|---|---|
| 429 | [`rate_limited`](/docs/errores/#rate_limited) | Superaste el límite por IP. Llega con `Retry-After`. | `true` |
| 500 | [`internal_error`](/docs/errores/#internal_error) | Fallo nuestro. | `true` |

### Ejemplos de error

`429 rate_limited`:

```json
{
  "error": {
    "code": "rate_limited",
    "message": "Demasiadas peticiones",
    "request_id": "0123456789abcdef0123456789abcdef",
    "details": {},
    "retryable": true,
    "docs_url": "https://merchants.fital.xyz/docs/errores/#rate_limited"
  }
}
```

`500 internal_error`:

```json
{
  "error": {
    "code": "internal_error",
    "message": "Error interno",
    "request_id": "0123456789abcdef0123456789abcdef",
    "details": {},
    "retryable": true,
    "docs_url": "https://merchants.fital.xyz/docs/errores/#internal_error"
  }
}
```

## Reintentos

Es una lectura: repetirla no tiene efecto.

- `429 rate_limited`: Espera lo que indique `Retry-After` y repite.
- `500 internal_error`: Repite con espera exponencial.

Ver [Reintentos](/docs/recetas/reintentos/) y [Límites](/docs/limites/).

## Muestras

**Variables de estas muestras: simulador público, sin cuenta**

Define esto en tu terminal. Con estos valores las muestras corren tal cual contra el simulador público:

```bash
export FITAL_API="https://widget.fital.xyz/explorar/v1"
export FITAL_KEY="sk_test_sandbox_publica"
```

En la cuenta de prueba o en producción cambia la base, la llave y el secreto, y sustituye los `id` de ejemplo por los tuyos. Ver [Ambientes](/docs/ambientes/).

```bash
curl -sS "$FITAL_API/meta/egress-ips"
```

```js
const r = await fetch(`${process.env.FITAL_API}/meta/egress-ips`);
console.log(r.status, await r.json());
```

```python
import json, os, urllib.error, urllib.request
pet = urllib.request.Request(os.environ["FITAL_API"] + "/meta/egress-ips", method="GET",
    headers={})
try:
    with urllib.request.urlopen(pet) as r:
        print(r.status, json.load(r))
except urllib.error.HTTPError as e:
    print(e.code, e.read().decode())
```

```php
<?php
$c = curl_init(getenv('FITAL_API') . '/meta/egress-ips');
curl_setopt_array($c, [
  CURLOPT_RETURNTRANSFER => true,
]);
echo curl_exec($c), "\n";
```

## Guías

- [IP de webhooks](/docs/seguridad/ip-webhooks/)
- [Autenticación](/docs/autenticacion/)
- [Cuenta de prueba](/docs/sandbox/cuenta-de-prueba/)
