¿Programas con IA?
Descarga las instrucciones y dáselas a tu asistente (Claude, ChatGPT, Cursor, Copilot…). Traen todo para integrar Hvatar sin adivinar: reglas, flujo, SDK, API, webhook, errores y una lista de verificación.
Integra "Entrar con Hvatar" en mi app siguiendo estas instrucciones al pie de la letra: https://www.hvatar.com/llms-full.txt
Antes de escribir código, pregúntame mi client_id, el origen de mi app, la URL del webhook y qué capacidades necesito. Nunca guardes correo, teléfono ni contraseña de los usuarios.También publicamos /llms.txt para herramientas que lo buscan solas.
Qué recibe tu app
Sí recibe
- Un
sub: identificador aleatorio, distinto en cada app. - Un pase firmado (EdDSA) que dura 15 minutos y se renueva solo.
- Las capacidades que el usuario aceptó: avisarle, verificar su edad, cifrar su contenido…
- Su nombre a mostrar y su avatar o foto, si los usas.
Nunca recibe
- Su correo ni su teléfono.
- Su contraseña ni sus passkeys.
- Su fecha de nacimiento ni sus documentos.
- Un identificador que permita cruzarlo con otras apps.
Integrar en 4 pasos
Los ejemplos usan PHP y el SDK de un solo archivo. Cualquier lenguaje sirve: la API es HTTP con JSON.
1 Registra tu app
Crea tu cuenta de Hvatar y, en Desarrolladores, registra tu app con su dirección (https://tienda.ejemplo.com), su webhook de bajas y las capacidades que necesitas. Recibes un client_id y un client_secret; el secreto solo vive en tu servidor.
2 Descarga el SDK y crea el callback
Descarga hvatar.php (requiere PHP 8.1 con sodium y openssl) y crea hvatar-callback.php:
<?php
require 'hvatar.php';
$hv = new Hvatar([
'url' => 'https://www.hvatar.com',
'client_id' => 'app_…',
'client_secret' => getenv('HVATAR_SECRET'),
]);
// Canjea el código, guarda la sesión y te da el sub del usuario
$hv->handleCallback('/cuenta', function (string $sub) {
// Busca o crea a tu usuario por su sub. No hay correo ni contraseña que guardar.
return null; // o una URL a donde redirigir
});https://tu-sitio.com/hvatar-callback.php?prueba=1 en el navegador. Revisa sodium, la conexión a Hvatar (cURL), tus credenciales y la caché, y responde "todo_bien": true cuando todo está listo. No muestra secretos.3 Agrega el botón
<button data-hvatar-login data-estilo="color"></button>
<script src="https://www.hvatar.com/c.js" data-key="app_…" data-callback="/hvatar-callback.php"></script>En tus páginas, \$hv->user() te da el sub de quien entró, o null.
4 Borra al usuario cuando se dé de baja
<?php
// hvatar-webhook.php (la dirección que registraste como webhook)
require 'hvatar.php';
$hv = new Hvatar([...]);
$hv->handleWebhook(['usuario.baja' => function (string $sub) use ($db) {
$db->prepare('DELETE FROM usuarios WHERE hvatar_sub = ?')->execute([$sub]);
}]);El SDK verifica la firma y responde con el acuse. Si tu servidor no contesta, Hvatar reintenta.
Botones oficiales
c.js dibuja el botón con el símbolo y el texto correctos. Elige y copia.
| Atributo | Valores |
|---|---|
data-estilo | color, claro, oscuro, icono. Sin este atributo el botón conserva tu propio diseño. |
data-texto | iniciar (por omisión), continuar, acceder, registrarse |
data-tamano | chico (40 px), normal (48 px), grande (56 px) |
data-ancho | Ocupa todo el ancho de su contenedor. |
Si agregas botones después de cargar la página, c.js los detecta solo. También puedes llamar hvatar.boton(elemento). Para abrir el inicio de sesión desde tu propio código: hvatar.login().
Capacidades
Las pides al registrar la app; el usuario las ve y las acepta al entrar. Solo funcionan con las que aceptó.
| Capacidad | Qué permite | SDK |
|---|---|---|
notify | Enviarle correos sin conocer su correo. | notifyEmail($sub, $asunto, $texto) |
notify.sms | SMS o WhatsApp sin conocer su teléfono. | notifySms($sub, $texto, 'sms'|'whatsapp') |
correo.alias | Una dirección propia para tu app que le reenvía los mensajes; sus respuestas salen desde el alias. | alias($sub) |
verify.edad | Saber si es mayor de edad sin ver su fecha de nacimiento. | verify($sub, 'edad.mayor_18') |
verify.identidad | Saber si su identidad está verificada con documento, y si un nombre o CURP coincide. | verify($sub, 'identidad.verificada') |
$hv->notifyEmail($sub, 'Tu pedido va en camino', "Hola, tu pedido #1042 salió hoy.");
$r = $hv->verify($sub, 'edad.mayor_18');
// ['respuesta' => true|false|null, 'nivel' => 'autodeclarado'|'documento', 'firmada' => 'eyJ…']
if ($r['respuesta'] === true) { /* puede comprar */ }firmada es la respuesta firmada por Hvatar: guárdala como comprobante. nivel dice si el dato viene de un documento revisado o lo declaró el usuario.
Cifrar el contenido
Lo que el usuario escribe en tu app (direcciones, notas, mensajes) se cifra con una llave suya que Hvatar te da mientras tiene sesión. Si se da de baja, Hvatar destruye la llave y ese contenido queda ilegible, también en tus respaldos.
$guardado = $hv->encrypt($_POST['direccion']); // "hv1.…" — esto va a tu base
echo htmlspecialchars($hv->decrypt($guardado));Bajas (webhook)
Cuando alguien se da de baja de tu app, Hvatar envía un POST firmado a tu webhook:
X-Hvatar-Event: usuario.baja
X-Hvatar-Timestamp: 1767312000
X-Hvatar-Signature: <firma Ed25519 de "timestamp.cuerpo", base64url>
X-Hvatar-Kid: <llave en /.well-known/keys.json>
{"evento":"usuario.baja","event_id":"ev_…","sub":"hv_…","fecha":1767312000}Responde 200 con {"acuse": base64url(HMAC-SHA256(event_id, SHA256(client_secret)))}. handleWebhook() hace todo esto por ti. Desde ese momento los pases de ese usuario dejan de servir y su llave de contenido ya no existe.
El compañero
El avatar del usuario puede acompañarlo en tu app: aparece en una esquina, se mueve y habla. Agrega data-companero al script:
<script src="https://www.hvatar.com/c.js" data-key="app_…" data-callback="/hvatar-callback.php"
data-companero="<?= $hv->companeroAttr() ?>"></script>
<script>
hvatar.companero.decir('¡Listo, guardé tu nota!');
hvatar.companero.accion('celebrar'); // saludar, pulgar, aplaudir, bailar, pensar, idea…
hvatar.action('nueva-nota', () => abrirEditor(), 'Escribir una nota'); // aparece en su menú
</script>Para mostrar su imagen en listas o comentarios: <img src="<?= $hv->avatarUrl() ?>" alt="">. Es su avatar o la foto que eligió, y cambia en todas las apps cuando la cambia en Hvatar.
Referencia de la API
Base: https://www.hvatar.com. Las llamadas de servidor usan HTTP Basic con client_id:client_secret y cuerpo JSON. Los errores responden {"error": "codigo"} con su estado HTTP.
| Ruta | Para qué | Cuerpo |
|---|---|---|
GET /authorize | Ventana de inicio de sesión (la abre c.js). PKCE obligatorio. | — |
POST /token | Canjear el código o renovar. Devuelve pase, expira_en, refresh, sub. | grant_type: authorization_code + code, code_verifier · o refresh_token + refresh |
GET /.well-known/keys.json | Llaves públicas para verificar pases, respuestas y webhooks. | — |
POST /v1/notify/email | Correo al usuario. | sub, asunto, texto |
POST /v1/notify/sms | SMS o WhatsApp. | sub, texto, canal |
POST /v1/correo/alias | Alias de correo del usuario para tu app. | sub |
POST /v1/verify | Preguntas: edad.mayor_18, identidad.verificada, nombre.coincide, curp.coincide. | sub, pregunta, valor (para coincide) |
POST /v1/keys/content | Llave de contenido del usuario (solo en memoria). | pase |
POST /v1/companero | Avatar, nombre a mostrar e imagen. | pase |
El pase
{ "iss": "https://hvatar.com", "aud": "app_…", "sub": "hv_…", "plan": "gratis",
"caps": ["notify", "verify.edad"], "iat": 1767312000, "exp": 1767312900 }JWS con EdDSA (Ed25519). Verifica firma, iss, aud y exp; el SDK lo hace en verifyPass().
Migrar una app existente
Si tu app ya tiene usuarios con correo y contraseña, conéctalos uno por uno:
- Agrega una columna
hvatar_suba tu tabla de usuarios. - A quien entra con el login viejo, muéstrale "Protege tu cuenta: conéctala con Hvatar".
- En el callback, si hay una sesión vieja, guarda el
suben ese usuario y borra su correo, teléfono, nombre y contraseña. - Cifra con
encrypt()lo que el usuario escribió. - Cambia tus envíos de
mail()pornotifyEmail(). - Cuando la mayoría ya se conectó, desactiva el registro con contraseña y después el login viejo.
$hv->handleCallback('/cuenta', function (string $sub) use ($db) {
$actual = $_SESSION['usuario_id'] ?? null; // login viejo
if ($actual) {
$db->prepare('UPDATE usuarios SET hvatar_sub = ?, correo = NULL, telefono = NULL, nombre = NULL, contrasena = NULL WHERE id = ?')
->execute([$sub, $actual]);
return '/cuenta?conectada=1';
}
return null;
});Logos
Úsalos para indicar que tu app funciona con Hvatar. No cambies sus colores ni sus proporciones y déjales aire alrededor (al menos la mitad de su alto). Tamaño mínimo: 16 px.
¿Listo?
Registra tu app gratis y prueba con tu propia cuenta.