Référence CLI
Toutes les fonctions passent par le binaire unique difuzio. Les commandes qui
agissent sur un objet suivent la forme difuzio <groupe> <action> [options], par
exemple difuzio member add ou difuzio list set. Les daemons, les migrations et
les commandes de diagnostic gardent une forme simple : difuzio serve-web,
difuzio migrate up, difuzio doctor.
difuzio help # liste les groupes et les commandes
difuzio help <groupe> # actions d'un groupe (ou : difuzio <groupe>)
difuzio version # version du binaire et backend de base compilé
Les commandes daemon prennent --config <chemin> (et chargent les keyrings). Les
commandes d'administration prennent soit --dsn <dsn>, soit --config <chemin>
pour la connexion à la base ; --dsn l'emporte sur --config.
Le DSN (Data Source Name) est la chaîne de connexion à la base. Sa forme dépend du
backend compilé dans le binaire : chaîne go-sql-driver pour MariaDB, chemin de
fichier pour SQLite (voir Base de données).
difuzio version indique le backend lié.
Toute commande qui lit --config charge aussi les trois keyrings. Si la
configuration référence ${CREDENTIALS_DIRECTORY} (le cas par défaut, cf
Configuration), poser la variable sur la commande,
qui échoue sinon en nommant la variable manquante :
CREDENTIALS_DIRECTORY=/etc/difuzio/secrets difuzio <commande> --config /etc/difuzio/config.yaml
Avec --dsn, les keyrings ne sont pas chargés. Quatre commandes exigent donc
--config et refusent --dsn seul, en l'expliquant : erase, send submit et
archive backfill-attachments (le corps des messages vit hors de la base), et
digest compile (la compilation met du courrier en file). member add sur une
liste en politique confirm a besoin du keyring de tokens et le signale de la
même façon.
Codes de sortie
0: succès.1: échec d'exécution (base injoignable, objet introuvable, refus du service).2: erreur d'invocation (option manquante, valeur inconnue, action inconnue).
difuzio <commande> --help sort en 0. Deux exceptions conservées :
domain check-dns sort en 1 tant que le domaine n'est pas prêt pour l'envoi en
masse (c'est un résultat, pas une erreur), et migrate status en 1 quand le
schéma est marqué "dirty".
Daemons
serve-web
difuzio serve-web --config /etc/difuzio/config.yaml [--insecure]
Lance l'interface web et l'API REST. --insecure envoie les cookies sans le
drapeau Secure (développement local uniquement, jamais derrière TLS public).
serve-lmtp
difuzio serve-lmtp --config /etc/difuzio/config.yaml
Lance le serveur de réception LMTP (posts, commandes par email, bounces, plaintes).
worker
difuzio worker --config /etc/difuzio/config.yaml
Lance le pipeline de traitement, l'envoi sortant, les tâches périodiques, et (si
metrics.bind est défini) le serveur /metrics. On en lance plusieurs pour le
débit. Rien ne part vers le relais tant qu'aucun worker ne tourne.
Configuration et diagnostic
config check
difuzio config check --config /etc/difuzio/config.yaml
Charge et valide la configuration (keyrings, invariants), puis quitte.
doctor
difuzio doctor [--dsn <dsn> | --config /etc/difuzio/config.yaml]
Vérifie que la base répond, que le schéma est à jour et propre, et, avec
--config, recoupe la configuration avec la base : domaines déclarés, stockage
des corps, boîtes d'ingestion.
stats show
difuzio stats show [--dsn <dsn> | --config <chemin>]
Compteurs de l'instance : domaines, listes, listes dont l'envoi est suspendu, listes sans VERP, éléments retenus en modération, copies en file.
queue stats
difuzio queue stats [--state queued|sending|sent|deferred|failed|cancelled]
Profondeur de la file outgoing_queue par état, avec le total. --state
restreint le compte à un seul état.
queue requeue
difuzio queue requeue [--domain lists.example.org [--list announce]]
Ramène les copies deferred en queued avec une prochaine tentative immédiate,
pour que le worker les reprenne sans attendre la fin du backoff. Les compteurs de
tentatives restent intacts : la limite de tentatives continue de s'appliquer.
digest compile
difuzio digest compile --config /etc/difuzio/config.yaml
Compile une fois les digests en attente, sous le même verrou d'avis que la tâche
périodique du worker. Si un worker compile au même moment, la commande ne fait
rien et le dit (code 1) plutôt que d'envoyer un digest en double.
archive backfill-attachments
difuzio archive backfill-attachments --config /etc/difuzio/config.yaml
Recalcule l'indicateur "pièces jointes" (messages.has_attachments) des messages
archivés avant que difuzio ne l'enregistre à la réception. La commande ne lit que
les lignes qui valent encore "non" et dont le corps brut est toujours là : elle
corrige un "non" en "oui", jamais l'inverse.
Ce rattrapage n'est pas fait par une migration : décider si un message porte une pièce jointe demande de parcourir son arborescence MIME, ce qu'aucun moteur SQL ne sait faire, et réécrire toute une archive pendant une migration bloquerait la mise à jour aussi longtemps que dure le parcours. C'est donc une passe de maintenance, à lancer quand l'instance est calme.
Elle est reprenable et interruptible : elle avance par lots validés au fur et à mesure, dans l'ordre des identifiants. Un Ctrl-C ne perd que le lot en cours, et relancer la commande reprend le travail. Un message dont le corps a été purgé par la rétention est compté comme illisible et laissé tel quel : il n'y a plus rien à inspecter. Sortie : nombre de messages examinés, corrigés, illisibles, et mal formés (arborescence MIME partiellement analysable, dont la raison est journalisée).
Migrations
Les migrations s'appliquent avec le compte DDL (Data Definition Language : le
compte autorisé à faire des CREATE / ALTER / DROP), passé via --dsn, ou
via --config en repli. Sous SQLite il n'y a pas de comptes : ce sont les droits
POSIX sur le fichier qui font foi.
difuzio migrate up [--dsn|--config] # applique toutes les migrations
difuzio migrate down [N|all] [--dsn|--config] # annule 1, N, ou toutes (all)
difuzio migrate to <version> [--dsn|--config] # va à une version précise
difuzio migrate status [--dsn|--config] # version courante + drapeau dirty
difuzio migrate force <ver> [--dsn|--config] # force la version, efface dirty
migrate down all est destructeur (mot-clé all requis explicitement). En cas de
schéma "dirty" après un échec, corriger puis migrate force <version>.
bootstrap-admin
difuzio bootstrap-admin --email vous@example.org --password-stdin [--force]
Crée le premier super_admin. Le mot de passe vient de --password ou, mieux, de
--password-stdin (lu sur l'entrée standard). --force permet d'en créer un
autre si un super_admin existe déjà.
Groupe domain
domain add
difuzio domain add --name lists.example.org --base-url https://lists.example.org \
[--display-name "..."] [--robot difuzio] [--locale fr|en]
Provisionne un domaine (en état pending_mta). Voir Domaines.
--locale fixe la langue des courriers transactionnels du domaine (fr par
défaut) : voir Mails transactionnels.
domain ls
difuzio domain ls
Affiche les domaines : id, nom, statut, robot, URL publique.
domain set-status
difuzio domain set-status --domain lists.example.org --status active|suspended|pending_mta
Change l'état d'un domaine. Voir Domaines.
domain set-command-addresses
difuzio domain set-command-addresses --domain lists.example.org --routed=false
difuzio domain set-command-addresses --domain lists.example.org --routed=true
Déclare si les adresses de service des listes du domaine (liste-subscribe@,
liste-unsubscribe@, liste-owner@, liste-request@) sont bien remises à
difuzio. Ce n'est pas une préférence : cela décrit le serveur de messagerie placé
devant.
--routed=true (défaut, cas historique) suppose un MTA qui route tout le domaine
vers difuzio. --routed=false correspond au profil boîte externe, où seule la
boîte de chaque liste est relevée : difuzio cesse alors d'annoncer ces adresses
dans les en-têtes List-Help, List-Subscribe, List-Owner et
List-Unsubscribe, et de les afficher sur les pages publiques. Sans ce réglage,
un abonné qui suit l'un de ces en-têtes écrit à une adresse que l'hébergeur
rejette. Voir Comptes de messagerie externes.
domain add-admin
difuzio domain add-admin --email admin@example.org --domain lists.example.org \
[--display-name "..."] [--password-stdin]
Crée l'utilisateur s'il n'existe pas et lui octroie domain_admin sur le domaine.
Sans mot de passe, le compte reste unverified : il ne peut ni se connecter, ni
devenir propriétaire d'une liste.
domain check-dns
difuzio domain check-dns --domain lists.example.org [--dkim-selector default]
Vérifie SPF, _dmarc et, si un sélecteur est fourni, la clé DKIM publiée. Sort en
1 tant que le domaine n'est pas prêt pour l'envoi en masse.
La console expose la même vérification par POST /api/v1/domains/{domaine}/dns-check
(voir API REST) : c'est le même code, donc les deux
donnent toujours le même verdict. La commande ne touche pas la base ; l'appel API,
lui, enregistre le résultat sur le domaine (dns_ok, dns_checked_at).
domain mta-config
difuzio domain mta-config --domain lists.example.org [--socket /run/difuzio/lmtp.sock]
Imprime les lignes Postfix qui routent le domaine vers difuzio.
Groupe list
list create
difuzio list create --domain lists.example.org --name announce \
(--owner proprio@example.org | --owner-id 12) \
[--display-name "..."] [--description "..."] [--type discussion|newsletter]
Crée une liste et octroie list_owner au propriétaire, qui doit être un compte
actif existant. Exactement une des deux désignations de propriétaire est requise :
en préférer une silencieusement confierait la liste à quelqu'un d'autre que celui
qui a été nommé.
list ls
difuzio list ls [--domain lists.example.org]
Tableau des listes : id, nom, domaine, type, statut, suspension d'envoi éventuelle avec sa raison. Voir Listes.
list show
difuzio list show --domain lists.example.org --list announce
Affiche une liste en détail : identité, état d'envoi, et les 27 réglages avec leur valeur courante.
list set
difuzio list set --domain lists.example.org --list announce [<réglages>]
Met à jour les réglages fournis ; ceux qui ne sont pas passés restent inchangés.
Une chaîne vide efface un réglage textuel (--subject-tag ""), et 0 rétablit
"conserver indéfiniment" pour --archive-retention-days.
--subject-tag, --relay-pool et --consent-text-ver finissent tels quels dans
un en-tête de message : un saut de ligne y est refusé, comme un dépassement de la
longueur de colonne (64, 64 et 32 caractères).
Réglages disponibles :
--post-policy open|members|moderated|owner
--subscribe-policy open|confirm|moderated|closed
--archive-access public|members|owners
--who-can-see-members public|members|owners
--reply-to sender|list|both
--from-munging auto|always|never
--attachment-policy allow|strip|reject
--subject-tag "[annonces]" --subject-tag-enabled=true|false
--footer-text "..." --footer-html "..."
--footer-enabled=true|false --echo-to-author=true|false
--max-message-size 10485760 --relay-pool bulk
--reject-empty-body=true|false --require-dkim-or-spf=true|false
--verp-enabled=true|false --moderation-ttl-hours 168
--moderate-first-post=true|false --welcome-text "..."
--goodbye-text "..." --privacy-notice "..."
--consent-text-ver v3 --archive-retention-days 365
--require-tls-in=true|false --anonymize-sender=true|false
Voir Listes.
list set-policy
difuzio list set-policy --domain lists.example.org --list announce \
[--post-policy ...] [--subscribe-policy ...] [--archive-access ...] \
[--reply-to ...] [--from-munging ...]
Raccourci historique sur les cinq politiques principales. list set couvre tous
les réglages.
list set-status
difuzio list set-status --domain lists.example.org --list announce \
--status active|closed|suspended
Change le cycle de vie de la liste. Une liste non active refuse la réception, les posts et les envois en masse : c'est la suppression douce du produit. À ne pas confondre avec le kill-switch d'envoi ci-dessous, qui laisse la liste recevoir.
list suspend / list resume
difuzio list suspend --domain lists.example.org --list announce [--note "..."]
difuzio list resume --domain lists.example.org --list announce
Suspend ou réactive l'émission d'une liste (kill-switch). Voir Modération.
Groupe member
member add
difuzio member add --domain lists.example.org --list announce --email abonne@example.org \
[--name "..."] [--mode regular|nomail|digest] [--channel web|email|api] \
[--force --consent-evidence "bulletin papier du 2026-08-10"] \
[--consent-source web_form|email_confirm|admin_import|api] \
[--show-confirm-token <fichier>|-]
Abonne une adresse. Le résultat dépend de la politique d'abonnement de la liste :
activation immédiate (open), confirmation par mail (confirm, le défaut),
attente de modération (moderated), ou refus (closed).
--force crée l'abonnement actif quelle que soit la politique : c'est le chemin
d'import administratif, et il exige --consent-evidence, la preuve de
consentement conservée au dossier RGPD. --show-confirm-token écrit le jeton de
confirmation dans un fichier créé en mode 0600 (la commande refuse d'écraser un
fichier existant), ou sur la sortie standard avec - ; il n'est jamais affiché
sans avoir été demandé.
Quand l'abonnement n'est pas activé immédiatement (politiques confirm et
moderated), --mode et --name ne sont pas conservés pendant l'attente : la
demande en instance ne porte pas ces champs, et la confirmation active l'abonné
en regular sans nom. La commande le signale. Pour poser un mode, utiliser
member set-mode après confirmation, ou abonner directement avec --force.
member ls
difuzio member ls --domain lists.example.org --list announce \
[--status pending|active|disabled|unsubscribed|removed] \
[--mode regular|nomail|digest] [--limit 200] [--offset 0]
Tableau des abonnés : id, adresse, statut, mode, score de bounce, date d'abonnement, suivi du nombre affiché et du total filtré.
member rm
difuzio member rm --domain lists.example.org --list announce --email abonne@example.org \
[--purge --confirm]
Retire un abonné (statut removed, historique de bounces conservé). --purge
supprime la ligne définitivement et exige --confirm.
member unsubscribe
difuzio member unsubscribe --domain lists.example.org --list announce --email abonne@example.org
Enregistre que la personne a demandé à partir (statut unsubscribed). C'est un
acte différent de member rm, qui est un retrait administratif.
member disable / enable
difuzio member disable --domain lists.example.org --list announce --email abonne@example.org
difuzio member enable --domain lists.example.org --list announce --email abonne@example.org
Désactive ou réactive la livraison pour un abonné. La réactivation remet aussi le score de bounce à zéro et repose le plancher de la fenêtre de scoring.
member set-mode
difuzio member set-mode --domain lists.example.org --list announce \
--email abonne@example.org --mode regular|nomail|digest
Change le mode de livraison d'un abonné.
member import
difuzio member import --domain lists.example.org --list announce \
--file abonnes.csv --consent-evidence "formulaires signés, lot 12"
Importe des abonnés depuis un CSV (- lit l'entrée standard). La première ligne
est un en-tête : la colonne email est obligatoire, display_name (ou name) et
delivery_mode (ou mode) sont facultatives, l'ordre des colonnes est libre et
les autres colonnes sont ignorées.
--consent-evidence est obligatoire : un import administratif affirme un
consentement que personne n'a confirmé par mail. Le compte rendu donne les lignes
traitées, ajoutées, ignorées et en erreur ; la commande sort en 1 si au moins
une ligne a échoué, les autres restant importées.
member export
difuzio member export --domain lists.example.org --list announce \
[--status ...] [--mode ...] [--file abonnes.csv]
Exporte les abonnés en CSV (-, le défaut, écrit sur la sortie standard). Les
colonnes sont email,display_name,delivery_mode,status,subscribed_at : c'est
l'aller-retour exact de member import. Un fichier est créé en mode 0600. Chaque
export est tracé dans le journal d'audit.
Groupe send
send submit
difuzio send submit --config /etc/difuzio/config.yaml \
--domain lists.example.org --list announce \
--from redaction@lists.example.org [--from-name "La rédaction"] \
--subject "Numéro 1" (--text-file corps.txt | --html-file corps.html | --raw-file message.eml)
Soumet un message à une liste : il suit exactement le même pipeline qu'un post
reçu en LMTP. --raw-file porte un message RFC 5322 complet et exclut alors
--subject, --text-file et --html-file. Un seul de ces fichiers peut valoir
- (entrée standard). --config est obligatoire : le corps est écrit via le
backend de stockage configuré.
Le message est mis en file ; rien ne part tant qu'un worker ne l'a pas traité. La commande imprime l'identifiant d'envoi et le nombre estimé de destinataires, et prévient si l'émission de la liste est suspendue.
send ls
difuzio send ls --domain lists.example.org --list announce [--limit 50]
Envois récents de la liste : id, date, expéditeur, distribué ou non, copies encore en file, sujet. C'est ainsi qu'on retrouve un identifiant d'envoi égaré. La colonne KEPT ne compte que les copies encore présentes dans la file : les copies remises sont purgées après leur fenêtre de rétention, donc un envoi ancien et entièrement distribué affiche légitimement 0.
send status
difuzio send status --domain lists.example.org --list announce --id 42
Compte des copies par état, dans l'ordre du cycle de vie et zéros compris.
send cancel
difuzio send cancel --domain lists.example.org --list announce --id 42
Annule les copies encore en queued. Les copies déjà réclamées par un worker
(sending) ou différées par le relais (deferred) partiront quand même : pour
tout arrêter, suspendre d'abord la liste avec list suspend.
Groupe moderation
difuzio moderation ls --domain lists.example.org --list announce
difuzio moderation approve --domain lists.example.org --list announce --id <id> [--note "..."]
difuzio moderation reject --domain lists.example.org --list announce --id <id> [--note "..."]
Liste, approuve ou rejette les éléments retenus (posts et abonnements).
moderation list reste accepté comme synonyme de moderation ls. Voir
Modération.
Groupe credential
Comptes de messagerie du fournisseur attachés à une liste (profil boîte externe, voir Listes). La saisie se fait dans la console : un mot de passe passé en argument finirait dans l'historique du shell. Ces commandes servent au diagnostic et à la reprise d'une configuration existante.
credential ls
difuzio credential ls --domain lists.example.org --list membres
Comptes enregistrés pour la liste : type, serveur, identifiant, activation, état. L'état distingue "jamais testé", "ok" avec la date du dernier succès, "failing" avec le message de l'hébergeur, et "unreadable" quand la clé de chiffrement qui protégeait le mot de passe n'est plus disponible. Le mot de passe n'est jamais affiché.
credential test
difuzio credential test --domain lists.example.org --list membres \
--kind ingest --config /etc/difuzio/config.yaml
Ouvre une vraie session avec le compte enregistré : connexion, TLS,
authentification, et ouverture du dossier pour l'IMAP. Aucun message n'est envoyé
ni relevé. --kind vaut ingest (boîte IMAP) ou submission (compte SMTP).
--config est requis : le mot de passe est déchiffré avec le keyring. Le
résultat est enregistré sur la liste, donc visible ensuite dans la console.
credential rm
difuzio credential rm --domain lists.example.org --list membres --kind ingest
Supprime un compte enregistré. --kind vaut ingest (boîte IMAP) ou
submission (compte SMTP). C'est la seule écriture disponible en ligne de
commande : ajouter un compte demande un mot de passe, qui n'a rien à faire dans
l'historique du shell, mais le retirer n'expose aucun secret.
Cette commande reste utilisable quand policy.external_mailboxes vaut deny.
C'est même la sortie prévue dans ce cas : sous cette politique, serve-web et
worker refusent de démarrer tant qu'un compte subsiste, en nommant les listes
concernées (voir Configuration, section
policy).
credential import
difuzio credential import --config /etc/difuzio/config.yaml
difuzio credential import --config /etc/difuzio/config.yaml --apply
Verse les entrées relay.auths et ingest.mailboxes du fichier de configuration
dans la base, pour passer à des comptes gérés depuis la console sans ressaisir un
seul mot de passe. Sans --apply, la commande affiche ce qu'elle ferait et
n'écrit rien. Une liste qui a déjà un compte du même type est laissée telle
quelle, sauf --overwrite. Le keyring security.credential_keyring est requis.
Une fois l'import fait et vérifié, retirer relay.auths et ingest.mailboxes du
fichier : la base prime, et une entrée YAML devenue inutile n'apparaît plus que
dans un avertissement du journal. relay.auth (identité de repli du robot) reste
nécessaire.
Groupe webhook
webhook create
difuzio webhook create [--domain lists.example.org [--list announce]] \
--url https://exemple.org/hook --events member.added,member.removed
Enregistre un point de terminaison. --events all souscrit aux dix événements :
member.added, member.removed, member.bounced, subscription.pending,
subscription.confirmed, send.submitted, send.completed, send.failed,
message.held, list.suspended.
L'URL doit être en HTTPS et se résoudre vers une adresse publique : une cible en loopback, en RFC1918 ou sur une adresse de métadonnées est refusée. Le secret de signature n'est affiché qu'une seule fois, à la création.
webhook ls
difuzio webhook ls
Webhooks visibles : id, portée, actif, URL, événements. Le secret n'est jamais réaffiché.
webhook rm
difuzio webhook rm --id 3
Supprime un webhook.
webhook test
difuzio webhook test --id 3
Met en file un ping signé. La requête est émise par un worker en fonctionnement,
et son résultat apparaît dans le journal du worker (component=webhook).
Groupe user
user create
difuzio user create --email u@example.org [--display-name "..."] [--locale fr_FR] \
[--password-stdin]
Crée un compte, sans aucun rôle. Sans mot de passe, le compte reste unverified
et ne peut pas être propriétaire d'une liste.
user ls
difuzio user ls [--email fragment] [--status unverified|active|disabled] \
[--limit 200] [--offset 0]
--offset exige un --limit non nul (SQL n'a pas d'OFFSET seul). Comptes visibles : id, adresse, statut, super_admin, mot de passe posé ou non,
dernière connexion.
user disable
difuzio user disable --email u@example.org [--enable]
Désactive un compte, ou le réactive avec --enable. Le service refuse de laisser
un domaine sans administrateur.
user set-password
difuzio user set-password --email u@example.org --password-stdin
Pose un nouveau mot de passe (haché en argon2id) pour un compte existant.
user roles
difuzio user roles --email u@example.org
Rôles détenus par le compte, avec le domaine et la liste concernés.
Groupe role
difuzio role grant --email u@example.org --role moderator --domain lists.example.org --list announce
difuzio role revoke --email u@example.org --role moderator --domain lists.example.org --list announce
Octroie ou révoque un rôle (super_admin, domain_admin, list_owner,
moderator). --domain et --list selon la portée du rôle. Voir
Utilisateurs et rôles.
Groupe apikey
apikey create
difuzio apikey create --email u@example.org --scope user|domain|list \
[--domain ...] [--list ...] --perms read,members:write,send,moderate,manage [--name ...]
Frappe une clé d'API ; le secret n'est affiché qu'une fois. Voir API REST.
apikey ls
difuzio apikey ls [--all]
Clés administrables : id, propriétaire, nom, portée, permissions, état. Les clés
révoquées ne sont affichées qu'avec --all. Le secret n'est jamais réaffiché.
apikey revoke
difuzio apikey revoke --id 7
Révoque une clé. L'opération est idempotente : une clé déjà révoquée est signalée comme telle, sans erreur.
Groupe audit
difuzio audit ls [--domain lists.example.org [--list announce]] \
[--action member.export] [--result ok|denied|error] [--actor "difuzio erase"] \
[--since 2026-08-01] [--until 2026-09-01] [--limit 100] [--offset 0] [--detail]
Lit le journal d'audit, du plus récent au plus ancien. --since et --until
acceptent une date 2006-01-02 ou un horodatage RFC3339, en UTC. --detail
imprime la charge JSON de chaque entrée.
erase
difuzio erase --email personne@example.org --confirm --config /etc/difuzio/config.yaml
Effacement RGPD d'une personne sur toutes les tables. --confirm est obligatoire.
--config l'est aussi, et --dsn seul est refusé : le corps des messages vit hors
de la base (storage.blob_dir) et seul le fichier de configuration en donne le
chemin. Sans lui, l'effacement viderait les lignes en laissant les corps sur
disque, en annonçant un succès. Le compte rendu indique le nombre d'objets déliés.
Voir RGPD.
Anciennes orthographes
Les commandes plates d'avant le passage aux groupes restent acceptées et font exactement la même chose que leur forme groupée : les scripts existants n'ont pas besoin d'être réécrits.
| Ancienne forme | Forme groupée |
|---|---|
add-domain |
domain add |
set-domain-status |
domain set-status |
add-admin |
domain add-admin |
check-dns |
domain check-dns |
mta-config |
domain mta-config |
create-list |
list create |
lists |
list ls |
set-policy |
list set-policy |
list-suspend |
list suspend |
list-resume |
list resume |
set-delivery-mode |
member set-mode |
reset-password |
user set-password |
grant-role |
role grant |
revoke-role |
role revoke |
create-api-key |
apikey create |