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.com
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"}'

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. /suggest es público y no necesita key.

Nunca commitees API keys al repo. Rotalas desde el dashboard si sospechás compromiso.

POST /api/v1/verify

POSTAuth: Live/Public1 crédito

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

POSTAuth: Live/PublicCosto L1 configurable; solo valid

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)

POSTAuth: Live30 créditos por consulta conclusiva (opcional)

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

POSTAuth: PúblicoGratis (20/min por IP)

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

GETAuth: PúblicoGratis (30/min por IP)

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

GETAuth: LiveGratis

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

GETAuth: PúblicoGratis

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

HTTPerrorSignificado
400invalid_requestBody malformado o vacío
401missing_authorization_headerFalta header Bearer
401invalid_api_keyKey inexistente o revocada
402insufficient_creditsSin saldo suficiente
403origin_not_allowedPublic key: Origin no está en allowed_domains
403live_key_requiredLa operación requiere una key live
429rate_limit_exceededRate limit por IP o por api_key alcanzado
500verify_failedError interno del motor
503pack_not_configuredFalta 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
EndpointLímiteVentanaIdentificador
/verify (live key)501 segundoapi_key_id
/verify (live key)10.0001 horaapi_key_id
/verify (public key)101 segundoapi_key_id
/verify-phone (live key)501 segundoapi_key_id
/verify-phone (live key)10.0001 horaapi_key_id
/verify-phone (public key)101 segundoapi_key_id
/verify-phone/live (live key)51 segundoapi_key_id
/verify-phone/live (live key)1.0001 horaapi_key_id
/suggest201 minutoIP
/domain/:d301 minutoIP
/demo/verify51 horaIP