:::note[Fail-open par défaut]
Chaque exemple enveloppe l'appel Syvel dans un `try/catch` avec un timeout de 3 secondes. Si l'API est injoignable (erreur réseau, timeout, quota dépassé), la vérification est **ignorée et l'utilisateur est laissé passer**. Ne laissez jamais un service tiers bloquer une inscription.
:::

Aucun package à installer — l'API `fetch` native fonctionne dans tous les navigateurs modernes et Node.js 18+.

## Vérification basique

```javascript
async function checkEmail(email) {
  try {
    const res = await fetch(
      `https://api.syvel.io/v1/check/${encodeURIComponent(email)}`,
      {
        headers: { Authorization: 'Bearer sv_votre_cle' },
        signal: AbortSignal.timeout(3000),
      }
    );

    if (!res.ok) return null; // quota dépassé ou erreur serveur → fail open

    return await res.json();
  } catch {
    return null; // erreur réseau ou timeout → fail open
  }
}

// Dans un handler de soumission de formulaire :
const result = await checkEmail(email);
if (result?.is_risky) {
  // bloquer l'utilisateur
}
// si result est null → API indisponible, laisser passer l'utilisateur
```

## Formulaire HTML avec validation en temps réel

```html
<form id="signup-form">
  <input type="email" id="email" name="email" placeholder="vous@exemple.com" />
  <p id="email-error" style="color: red; display: none;"></p>
  <button type="submit">S'inscrire</button>
</form>

<script>
  const emailInput = document.getElementById('email');
  const emailError = document.getElementById('email-error');
  let debounce;

  emailInput.addEventListener('input', () => {
    clearTimeout(debounce);
    debounce = setTimeout(async () => {
      const email = emailInput.value;
      if (!email.includes('@')) return;

      try {
        const res = await fetch(
          `https://api.syvel.io/v1/check/${encodeURIComponent(email)}`,
          {
            headers: { Authorization: 'Bearer sv_votre_cle' },
            signal: AbortSignal.timeout(3000),
          }
        );
        const result = res.ok ? await res.json() : null;
        if (result?.is_risky) {
          emailError.textContent = 'Merci d\'utiliser une vraie adresse email.';
          emailError.style.display = 'block';
        } else {
          emailError.style.display = 'none';
        }
      } catch {
        emailError.style.display = 'none'; // fail open
      }
    }, 500);
  });
</script>
```

## React hook

```tsx
import { useState, useCallback } from 'react';

const API_KEY = import.meta.env.VITE_SYVEL_API_KEY;

export function useEmailCheck() {
  const [isRisky, setIsRisky] = useState<boolean | null>(null);
  const [loading, setLoading] = useState(false);

  const check = useCallback(async (email: string) => {
    if (!email.includes('@')) return;
    setLoading(true);
    try {
      const res = await fetch(
        `https://api.syvel.io/v1/check/${encodeURIComponent(email)}`,
        {
          headers: { Authorization: `Bearer ${API_KEY}` },
          signal: AbortSignal.timeout(3000),
        }
      );
      const data = res.ok ? await res.json() : null;
      setIsRisky(data?.is_risky ?? null);
    } catch {
      setIsRisky(null); // fail open
    } finally {
      setLoading(false);
    }
  }, []);

  return { isRisky, loading, check };
}

// Usage dans un composant :
function SignupForm() {
  const { isRisky, loading, check } = useEmailCheck();

  return (
    <div>
      <input
        type="email"
        onChange={(e) => check(e.target.value)}
        placeholder="vous@exemple.com"
      />
      {loading && <span>Vérification…</span>}
      {isRisky && (
        <p style={{ color: 'red' }}>
          Email jetable détecté. Utilisez une adresse professionnelle.
        </p>
      )}
    </div>
  );
}
```

## Node.js 18+ (Express)

```javascript
async function checkEmail(email) {
  try {
    const res = await fetch(
      `https://api.syvel.io/v1/check/${encodeURIComponent(email)}`,
      {
        headers: { Authorization: `Bearer ${process.env.SYVEL_API_KEY}` },
        signal: AbortSignal.timeout(3000),
      }
    );
    if (!res.ok) return null;
    return await res.json();
  } catch {
    return null;
  }
}

app.post('/register', async (req, res) => {
  const result = await checkEmail(req.body.email);
  if (result?.is_risky) {
    return res.status(422).json({ error: 'Veuillez utiliser une adresse email professionnelle.' });
  }
  // continuer l'inscription…
});
```

## Ressources

- [Référence API — Vérification email](/fr/docs/api/check)
- [Authentification](/fr/docs/guides/authentication)
- [Codes d'erreur](/fr/docs/guides/errors)
- [SDK JavaScript / Node.js](/fr/docs/integrations/javascript)