Documentación de la API
REST · JSON · Bearer auth. Un solo endpoint hace el 90% del trabajo.
Quickstart
Después de registrarte, tenés una API key bb_live_... con 500 créditos gratis. Con eso ya podés hacer verificaciones. Base URL:
https://api.byebouncer.comcurl -X POST https://api.byebouncer.com/api/v1/verify \
-H "Authorization: Bearer bb_live_xxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"email": "someone@example.com"}'Autenticación
Todos los endpoints que consumen créditos requieren el header Authorization: Bearer <api_key>.
- Live keys (
bb_live_*): backend, sin restricción de dominio, todos los endpoints. - Public keys (
bb_pub_*): frontend (widget JS), CORS restringido por dominio y acceso autenticado solo a/verify./suggestes público y no necesita key.
Nunca commitees API keys al repo. Rotalas desde el dashboard si sospechás compromiso.
POST /api/v1/verify
Verifica un email. Corta la respuesta cache-hit (misma dirección en última hora) sin consumir crédito.
La verificación SMTP es una señal, no una garantía de entrega. Gmail y otros proveedores pueden aceptar o rechazar destinatarios según sus políticas anti-abuso; tratá unknown como revisión manual y no como válido.
Request
{
"email": "someone@example.com"
}Response (200)
{
"email": "someone@example.com",
"status": "deliverable",
"action": "allow",
"flagged": false,
"signals": [
"valid_syntax",
"mx_found",
"mailbox_accepts_mail"
],
"domain": {
"name": "example.com",
"type": "business",
"disposable": false,
"free_provider": false,
"has_mx": true
},
"cached": false,
"response_time_ms": 1230,
"credits_remaining": 499,
"verified_at": "2026-08-18T15:30:00Z"
}curl -X POST https://api.byebouncer.com/api/v1/verify \
-H "Authorization: Bearer bb_live_xxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"email": "someone@example.com"}'POST /api/v1/verify-phone
Valida formato, país y tipo de línea con metadata local. Para números nacionales, enviá default_country como código ISO de dos letras. Los resultados invalid, possible, unknown y los cache hits no consumen créditos.
valid confirma reglas del plan de numeración. No confirma que la línea exista, esté activa ni use SMS o WhatsApp. carrier proviene de metadata local y puede no reflejar portabilidad. El estado de la línea en vivo (HLR) es opcional: solo se consulta si enviás live: true (ver «Línea en vivo» más abajo) y tiene su propio costo.
Request
{
"phone": "11 5555-1234",
"default_country": "AR"
}Response (200)
{
"phone_hash": "a1b2c3…",
"normalized_e164": "+5491155551234",
"is_valid": true,
"status": "valid",
"country": "AR",
"country_calling_code": 54,
"line_type": "mobile",
"carrier": "Movistar",
"signals": [
"country_detected",
"country_from_default",
"valid_format",
"e164_normalized",
"mobile_line"
],
"level": "l1",
"cached": false,
"credits_remaining": 499,
"response_time_ms": 1,
"verified_at": "2026-09-13T15:30:00Z"
}curl -X POST https://api.byebouncer.com/api/v1/verify-phone \
-H "Authorization: Bearer bb_live_xxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"phone":"11 5555-1234","default_country":"AR"}'Línea en vivo (HLR)
Consulta a la red del operador si la línea está conectada ahora, para decidir si llamar a un lead de inmediato. El teléfono no suena y el titular no se entera. Tarda unos segundos: llamalo desde tu backend cuando ya tenés el lead, no mientras alguien escribe en un formulario.
Dos formas de pedirlo: agregá "live": true a /api/v1/verify-phone o /api/v1/lead/verify (se suma al resultado normal), o llamá a POST /api/v1/verify-phone/live para recibir solo el estado en vivo. Requiere una API key live y que el servicio lo tenga habilitado.
Request
{
"phone": "+5491163083418",
"live": true
}Campos que se agregan a la respuesta
{
"live": {
"status": "connected",
"connected": true,
"ported": true,
"roaming": false,
"current_network": "Claro Argentina (AMX Argentina S.A.)",
"origin_network": "Movistar (Telefonica Moviles Argentina S.A.)"
},
"contactability": "yes",
"live_credits_charged": 30,
"live_cached": false,
"live_checked_at": "2026-09-29T15:00:00Z",
"credits_remaining": 470
}contactability
yes— conectada ahora: se puede llamar.retry_later— el teléfono está apagado o sin cobertura. Es una línea real: reintentá más tarde.unverifiable— línea fija o VoIP: el estado en vivo solo existe para móviles.no— número inválido, desconocido para la red o en tu lista negra.
«Conectada» significa registrada en la red en este momento. No garantiza que la persona atienda ni que el número sea suyo.
Cobro
Solo se cobra una respuesta concluyente de la red (connected, absent o unknown). No se cobra si el número es inválido, fijo o VoIP, si está en tu lista negra, si el operador no responde, ni si el resultado viene de la caché de unos minutos. Si la parte en vivo falla, el resultado normal se entrega igual con live_error y solo esa parte queda sin cobro.
Errores posibles de live_error: live_key_required, phone_live_unavailable, insufficient_credits, hlr_unavailable, hlr_busy y hlr_daily_limit.
POST /api/v1/suggest
Detecta typos en el dominio y devuelve una sugerencia si la distancia Levenshtein contra un dominio conocido es ≤ 2. No hace lookup de red.
curl -X POST https://api.byebouncer.com/api/v1/suggest \
-H "Content-Type: application/json" \
-d '{"email": "user@gnail.com"}'
# → { "suggestion": "user@gmail.com", ... }GET /api/v1/domain/:domain
Clasifica un dominio (disposable/free/business/education) + MX lookup. Útil para páginas de SEO o quick-check antes de registrar.
curl https://api.byebouncer.com/api/v1/domain/mailinator.com
# → { "domain": "mailinator.com", "type": "disposable", ... }GET /api/v1/credits
Balance actual de la key usada. Se lee siempre desde DB (nunca del cache).
curl https://api.byebouncer.com/api/v1/credits \
-H "Authorization: Bearer bb_live_xxxxxxxxxx"GET /api/v1/status
Estado del servicio. Devuelve ok o degraded según ping a Postgres + Redis. Podés apuntar Better Uptime u otro monitor externo.
Códigos de error
| HTTP | error | Significado |
|---|---|---|
| 400 | invalid_request | Body malformado o vacío |
| 401 | missing_authorization_header | Falta header Bearer |
| 401 | invalid_api_key | Key inexistente o revocada |
| 402 | insufficient_credits | Sin saldo suficiente |
| 403 | origin_not_allowed | Public key: Origin no está en allowed_domains |
| 403 | live_key_required | La operación requiere una key live |
| 429 | rate_limit_exceeded | Rate limit por IP o por api_key alcanzado |
| 500 | verify_failed | Error interno del motor |
| 503 | pack_not_configured | Falta env var de Paddle price_id |
Rate limits
Aplicamos rate limiting con sliding window en Redis. Headers en toda respuesta:
X-RateLimit-Limit: 50
X-RateLimit-Remaining: 47
X-RateLimit-Reset: 1723644800| Endpoint | Límite | Ventana | Identificador |
|---|---|---|---|
| /verify (live key) | 50 | 1 segundo | api_key_id |
| /verify (live key) | 10.000 | 1 hora | api_key_id |
| /verify (public key) | 10 | 1 segundo | api_key_id |
| /verify-phone (live key) | 50 | 1 segundo | api_key_id |
| /verify-phone (live key) | 10.000 | 1 hora | api_key_id |
| /verify-phone (public key) | 10 | 1 segundo | api_key_id |
| /verify-phone/live (live key) | 5 | 1 segundo | api_key_id |
| /verify-phone/live (live key) | 1.000 | 1 hora | api_key_id |
| /suggest | 20 | 1 minuto | IP |
| /domain/:d | 30 | 1 minuto | IP |
| /demo/verify | 5 | 1 hora | IP |