> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lekalao.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Formulaires

> Inscrire depuis un site statique, une application React ou un serveur, sans jeton.

Le formulaire d'une liste accepte un `POST` depuis n'importe quel site, sans jeton. C'est la seule façon d'inscrire quelqu'un directement depuis un navigateur. Le guide [Formulaires d'inscription](/fr/contacts/subscription-forms) explique comment l'activer et le HTML prêt à copier.

## L'adresse

```
POST https://lekalao.example.com/subscribe/{id de la liste}
```

Elle est affichée dans l'onglet **Paramètres** de la liste. Elle répond `404` tant que le formulaire n'est pas activé.

## Les champs

| Champ                     |                                                                             |
| ------------------------- | --------------------------------------------------------------------------- |
| `email`                   | Obligatoire.                                                                |
| `first_name`, `last_name` | Facultatifs.                                                                |
| `locale`                  | Langue de lecture : `fr`, `en`, `pt-BR`…                                    |
| `tags`                    | Tableau, 20 au plus. Seuls les tags **déjà créés** sur la liste sont posés. |
| `website`                 | Piège à robots : doit rester vide.                                          |

En `application/x-www-form-urlencoded`, `multipart/form-data` ou `application/json`.

## Réponse JSON

Avec `Accept: application/json`, la réponse est du JSON au lieu d'une redirection :

| Code  | Corps                                                                                 |
| ----- | ------------------------------------------------------------------------------------- |
| `200` | `{"status": "subscribed"}` ou `{"status": "pending"}` si la confirmation est envoyée. |
| `403` | Le site d'origine n'est pas dans les **domaines autorisés** de la liste.              |
| `404` | Formulaire désactivé.                                                                 |
| `422` | Adresse invalide (`errors.email`), ou liste pleine selon la formule.                  |
| `429` | Plus de 10 envois par minute depuis la même adresse IP.                               |

Une adresse bloquée répond `pending`, comme une inscription normale : le formulaire ne révèle jamais qu'une adresse est dans la liste de suppression.

## React

```tsx theme={null}
import { useState } from 'react';

const ACTION =
    'https://lekalao.example.com/subscribe/9d5c2a1e-8f3b-4c7a-9e21-3b8f0c6d4a12';

export function Newsletter() {
    const [state, setState] = useState<
        'idle' | 'sending' | 'pending' | 'subscribed' | 'error'
    >('idle');

    async function subscribe(event: React.FormEvent<HTMLFormElement>) {
        event.preventDefault();
        setState('sending');

        const form = new FormData(event.currentTarget);
        const response = await fetch(ACTION, {
            method: 'POST',
            headers: { Accept: 'application/json' },
            body: form,
        });

        if (!response.ok) return setState('error');

        const { status } = await response.json();
        setState(status);
    }

    if (state === 'pending')
        return <p>Vérifiez votre boîte mail pour confirmer.</p>;
    if (state === 'subscribed') return <p>Merci, vous êtes inscrit.</p>;

    return (
        <form onSubmit={subscribe}>
            <input
                type="email"
                name="email"
                required
                placeholder="vous@exemple.com"
            />
            <input type="hidden" name="locale" value={navigator.language} />
            <input
                type="text"
                name="website"
                tabIndex={-1}
                autoComplete="off"
                hidden
            />
            <button disabled={state === 'sending'}>S'abonner</button>
            {state === 'error' && (
                <p>Ça n'a pas marché. Réessayez dans un instant.</p>
            )}
        </form>
    );
}
```

## Depuis un serveur

Votre serveur peut appeler le formulaire, mais toutes les inscriptions viendraient alors de la même adresse IP et buteraient sur la limite de 10 par minute. Côté serveur, utilisez l'[API](/fr/developers/subscribers) avec un jeton.

## Domaines autorisés

Quand la liste en déclare, Lekalao compare l'en-tête `Origin` (ou `Referer`) du navigateur. Les sous-domaines sont acceptés : `maboulangerie.fr` couvre `www.maboulangerie.fr`. Un appel sans ces en-têtes, depuis `curl` par exemple, est refusé.
