# Validación y formateo del teléfono con API v2

> Validar y formatear números telefónicos nacionales o internacionales con GenderAPI v2. Consulte el contexto obligatorio del país, los campos JSON y el cargo de un crédito.

Canonical HTML: https://www.genderapi.io/es/docs/v2/phone-validation

Last reviewed: 2026-09-25

## Validar y formatear un número de teléfono

POST /phone/validate acepta number y el campo opcional country. Utilice un número de teléfono internacional que comience con +. Para un número de teléfono nacional, proporcione un código de país ISO en mayúsculas. La respuesta tiene valid, possible, e164, country y country_calling_code dentro de data, además del objeto compartido meta. Esto verifica la estructura del número de teléfono, no si el suscriptor existe. Cada validación completa cuesta 1 crédito, incluidos los resultados no válidos. La respuesta ilustrativa a continuación muestra un número no válido y es independiente del ejemplo de solicitud.

Ejecute estos ejemplos en su servidor. Configure GENDERAPI_API_KEY en el entorno de proceso con su clave API existente. Confirme que meta.access.mode es api_key: una clave no reconocida puede recurrir a la prueba IP.

Cada solicitud de predicción es una nueva operación facturable, incluidos los reintentos. Estos ejemplos no se reintentan automáticamente. Verifique el estado de facturación antes de enviar otra solicitud.

Las respuestas HTTP 4xx y 5xx JSON conservan el cuerpo del error y devuelven un estado de salida distinto de cero. Verifique code, action y meta.usage.billing_status antes de volver a intentarlo.

| Campo JSON | Tipo | Regla |
| --- | --- | --- |
| number | string | Obligatorio, entre 3 y 32 caracteres. ASCII dígitos, espacios, paréntesis y guiones, con un + inicial opcional. No se aceptan extensiones ni caracteres alfabéticos. |
| country | string | Código ISO 3166-1 alfa-2 en mayúsculas. Requerido para un número de teléfono nacional. Opcional cuando el valor number comienza con +. Omita este campo cuando no sea necesario. |

**cURL**

cURL 7.76+ en un shell POSIX. Ejecuta en tu terminal.

```bash
curl --silent --show-error --fail-with-body --max-time 30 \
  --request POST 'https://api.genderapi.io/api/v2/phone/validate' \
  --header "Authorization: Bearer ${GENDERAPI_API_KEY:?Set GENDERAPI_API_KEY}" \
  --header 'Content-Type: application/json' \
  --data '{
  "number": "+905321234567"
}'
```

**JavaScript / Node.js**

Node.js 22+; búsqueda incorporada. Guarde como example.mjs y ejecute node example.mjs.

```javascript
// Server-side Node.js. Save as example.mjs.
const apiKey = process.env.GENDERAPI_API_KEY;
if (!apiKey) throw new Error("Set GENDERAPI_API_KEY");
const body = {
  "number": "+905321234567"
};

const response = await fetch("https://api.genderapi.io/api/v2/phone/validate", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${apiKey}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify(body),
  signal: AbortSignal.timeout(30_000),
  redirect: "error",
});
const raw = await response.text();
if (!(response.headers.get("content-type") ?? "").includes("json")) {
  throw new Error(`HTTP ${response.status}: expected JSON; request ID ${response.headers.get("x-request-id")}`);
}
const result = JSON.parse(raw); // Also accepts application/problem+json.
if (!response.ok) {
  console.error(`HTTP ${response.status}`, result);
  process.exitCode = 1; // A retry is a new operation; inspect billing first.
} else {
  console.log(JSON.stringify(result, null, 2));
  // For batches, inspect every item: HTTP 200 may contain item errors.
}
```

**Python**

Python 3.10+; biblioteca estándar. Guarde como example.py y ejecute python3 example.py.

```python
import json
import os
import sys
import urllib.error
import urllib.request

api_key = os.environ.get("GENDERAPI_API_KEY")
if not api_key:
    raise RuntimeError("Set GENDERAPI_API_KEY")
body = json.loads("{\"number\":\"+905321234567\"}")

class NoRedirect(urllib.request.HTTPRedirectHandler):
    def redirect_request(self, req, fp, code, msg, headers, newurl):
        return None

request = urllib.request.Request(
    "https://api.genderapi.io/api/v2/phone/validate",
    method="POST",
    data=json.dumps(body).encode("utf-8"),
    headers={
        "Authorization": "Bearer " + api_key,
        "Content-Type": "application/json",
    },
)
opener = urllib.request.build_opener(NoRedirect())
try:
    response = opener.open(request, timeout=30)
except urllib.error.HTTPError as error:
    response = error  # Keep the Problem Details body on non-2xx responses.
with response:
    status = response.status
    raw = response.read().decode("utf-8")
    if "json" not in response.headers.get("Content-Type", ""):
        raise RuntimeError(f"HTTP {status}: expected a JSON response")
    result = json.loads(raw)
print(json.dumps(result, indent=2), file=sys.stderr if status >= 300 else sys.stdout)
if not 200 <= status < 300:
    sys.exit(1)  # Inspect code, action and billing before retrying.
# For batches, inspect every item even when HTTP status is 200.
```

**PHP**

PHP 8+ con la extensión cURL. Guarde como example.php y ejecute php example.php.

```php
<?php
$apiKey = getenv('GENDERAPI_API_KEY');
if (!$apiKey) {
    throw new RuntimeException('Set GENDERAPI_API_KEY');
}
$body = json_decode('{"number":"+905321234567"}', true, 512, JSON_THROW_ON_ERROR);

$ch = curl_init('https://api.genderapi.io/api/v2/phone/validate');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_FOLLOWLOCATION => false,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $apiKey,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode($body, JSON_THROW_ON_ERROR),
]);
$raw = curl_exec($ch);
if ($raw === false) {
    throw new RuntimeException(curl_error($ch));
}
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE) ?: '';
curl_close($ch);
if (strpos($contentType, 'json') === false) {
    throw new RuntimeException("HTTP $status: expected a JSON response");
}
$result = json_decode($raw, true, 512, JSON_THROW_ON_ERROR);
$output = json_encode($result, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR) . PHP_EOL;
if ($status < 200 || $status >= 300) {
    fwrite(STDERR, $output); // Preserve the Problem Details body.
    exit(1);
}
echo $output;
// For batches, inspect every item; HTTP 200 can contain item errors.
```

**Java**

Java 17+; cliente estándar HTTP. Guarde como GenderApiExample.java y ejecute java GenderApiExample.java.

```java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;

public class GenderApiExample {
    private static String requiredEnv(String name) {
        String value = System.getenv(name);
        if (value == null || value.isBlank()) throw new IllegalStateException("Set " + name);
        return value;
    }

    public static void main(String[] args) throws Exception {
        String apiKey = requiredEnv("GENDERAPI_API_KEY");
        String body = "{\"number\":\"+905321234567\"}";
        HttpClient client = HttpClient.newBuilder()
            .connectTimeout(Duration.ofSeconds(10))
            .followRedirects(HttpClient.Redirect.NEVER)
            .build();
        HttpRequest request = HttpRequest.newBuilder(URI.create("https://api.genderapi.io/api/v2/phone/validate"))
            .timeout(Duration.ofSeconds(30))
            .header("Authorization", "Bearer " + apiKey)
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(body, StandardCharsets.UTF_8))
            .build();
        HttpResponse<String> response = client.send(request,
            HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
        if (!response.headers().firstValue("content-type").orElse("").contains("json")) {
            throw new IllegalStateException("HTTP " + response.statusCode() + ": expected JSON");
        }
        // JSON text; parse with your application's JSON library when integrating.
        if (response.statusCode() < 200 || response.statusCode() >= 300) {
            System.err.println(response.body()); // Includes Problem Details.
            System.exit(1);
        }
        System.out.println(response.body());
        // For batches, inspect each item's data or error, including on HTTP 200.
    }
}
```

**C# / .NET**

Aplicación de consola .NET 8+. Úselo como Program.cs en un proyecto de consola, luego ejecute dotnet run.

```csharp
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;

string RequiredEnv(string name) =>
    !string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable(name))
        ? Environment.GetEnvironmentVariable(name)!
        : throw new InvalidOperationException($"Set {name}");

var apiKey = RequiredEnv("GENDERAPI_API_KEY");
using var handler = new HttpClientHandler { AllowAutoRedirect = false };
using var client = new HttpClient(handler) { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(HttpMethod.Post, "https://api.genderapi.io/api/v2/phone/validate");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);
request.Content = new StringContent("{\"number\":\"+905321234567\"}", Encoding.UTF8, "application/json");

using var response = await client.SendAsync(request);
var raw = await response.Content.ReadAsStringAsync();
if (!(response.Content.Headers.ContentType?.MediaType?.Contains("json") ?? false))
    throw new InvalidOperationException($"HTTP {(int)response.StatusCode}: expected JSON");
using var result = JsonDocument.Parse(raw);
if (!response.IsSuccessStatusCode)
{
    Console.Error.WriteLine(result.RootElement); // Preserve Problem Details.
    Environment.ExitCode = 1;
}
else
{
    Console.WriteLine(result.RootElement);
    // For batches, inspect every item even on HTTP 200.
}
```

**Go**

Go 1.22+; biblioteca estándar. Guarde como main.go y ejecute go run main.go.

```go
package main

import (
    "encoding/json"
    "fmt"
    "io"
    "net/http"
    "os"
    "strings"
    "time"
)

func requiredEnv(name string) string {
    value := os.Getenv(name)
    if value == "" { panic("Set " + name) }
    return value
}

func run() error {
    apiKey := requiredEnv("GENDERAPI_API_KEY")
    body := "{\"number\":\"+905321234567\"}"
    request, err := http.NewRequest("POST", "https://api.genderapi.io/api/v2/phone/validate", strings.NewReader(body))
    if err != nil { return err }
    request.Header.Set("Authorization", "Bearer " + apiKey)
    request.Header.Set("Content-Type", "application/json")
    client := &http.Client{
        Timeout: 30 * time.Second,
        CheckRedirect: func(req *http.Request, via []*http.Request) error {
            return http.ErrUseLastResponse
        },
    }
    response, err := client.Do(request)
    if err != nil { return err }
    defer response.Body.Close()
    raw, err := io.ReadAll(response.Body)
    if err != nil { return err }
    if !strings.Contains(response.Header.Get("Content-Type"), "json") || !json.Valid(raw) {
        return fmt.Errorf("HTTP %d: expected a JSON response", response.StatusCode)
    }
    if response.StatusCode < 200 || response.StatusCode >= 300 {
        return fmt.Errorf("HTTP %d: %s", response.StatusCode, raw)
    }
    fmt.Println(string(raw))
    // For batches, inspect every item even on HTTP 200.
    return nil
}

func main() {
    if err := run(); err != nil {
        fmt.Fprintln(os.Stderr, err) // Keep Problem Details for error handling.
        os.Exit(1)
    }
}
```

```json
{
  "data": {
    "valid": false,
    "possible": false,
    "e164": null,
    "country": null,
    "country_calling_code": null
  },
  "meta": {
    "request_id": "11111111-1111-4111-8111-111111111111",
    "duration_ms": 12,
    "access": {
      "mode": "ip_trial",
      "reason": "api_key_missing"
    },
    "usage": {
      "charged_credits": 1,
      "remaining_credits": 7,
      "billing_status": "confirmed",
      "resets_at": "2026-09-26T12:00:00.000Z",
      "limit": 10,
      "period_seconds": 86400
    }
  }
}
```

## Leer campos de validación del teléfono

La entrada con formato incorrecto se rechaza con HTTP 422 antes de la facturación. Si el formato de la solicitud es correcto pero el número de teléfono no se puede analizar, la operación puede devolver HTTP 200 con los campos de formato valid: false y null. Esta validación completa cuesta 1 crédito. Un número que se puede analizar pero que no es válido aún puede tener un valor e164. Verifique valid; un número formateado por sí solo no es prueba de validez.

| Campo dentro de data | Significado |
| --- | --- |
| valid | Si el número coincide con las reglas de validación del plan de numeración. |
| possible | Si el número tiene una longitud plausible para su plan de numeración; más débil que válido. |
| e164 | Número internacional formateado cuando el análisis se realiza correctamente; de lo contrario, null. |
| country | Región derivada del número, o null cuando no esté disponible; no localiza al suscriptor. |
| country_calling_code | Código numérico de llamada internacional, o null cuando no esté disponible. |

## Autenticación y reintentos

Envíe su clave API existente usando autenticación de portador y tipo de contenido: aplicación/json. Los ejemplos leen GENDERAPI_API_KEY del entorno. El campo country es obligatorio para números de teléfono nacionales y opcional cuando el valor number comienza con +.

- [Autenticación](https://www.genderapi.io/es/docs/v2/authentication)
- [Errores y reintentos](https://www.genderapi.io/es/docs/v2/errors-and-retries)
- [Créditos y uso](https://www.genderapi.io/es/docs/v2/credits-and-usage)
