{"openapi":"3.1.0","info":{"title":"Postman","description":"API du bureau de poste télégraphique. Trois points d'accès partagent ce même cœur : le site web, `curl`/HTTP et le client CLI `postman`. Authentification par en-tête `X-API-Key` (voir le manuel sur `/manuel`).","version":"1.0"},"paths":{"/messages":{"post":{"tags":["messages"],"summary":"Send Message","operationId":"send_message_messages_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["messages"],"summary":"List Messages","description":"Trafic en vie ; `freq` restreint à une fréquence de la bande (kHz).","operationId":"list_messages_messages_get","parameters":[{"name":"freq","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Freq"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MessageOut"},"title":"Response List Messages Messages Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/messages/{message_id}":{"get":{"tags":["messages"],"summary":"Get Message","operationId":"get_message_messages__message_id__get","parameters":[{"name":"message_id","in":"path","required":true,"schema":{"type":"string","title":"Message Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/stream/now":{"get":{"tags":["stream"],"summary":"Now","operationId":"now_stream_now_get","parameters":[{"name":"freq","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Freq"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Now Stream Now Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/stream/listen":{"get":{"tags":["stream"],"summary":"Listen","description":"Écoute continue en **SSE**, sur une fenêtre bornée.\n\nChaque message qui passe sur la ligne est poussé au client (dédupliqué), sans\nqu'il ait à sonder `/messages` en boucle. `seconds` est borné à [1, 300]. Deux\nmodes : une **fréquence** (`freq`, défaut = fréquence serveur) ; ou **toute la\nbande** (`all=true`, `freq` alors ignoré) multiplexée en un seul flux, chaque\névénement portant sa `frequency`. Le client se raccorde à la fin de la fenêtre\npour une écoute sans fin (voir `postman listen --follow [--all]`).","operationId":"listen_stream_listen_get","parameters":[{"name":"freq","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Freq"}},{"name":"seconds","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Seconds"}},{"name":"all","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"All"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/podcast.xml":{"get":{"tags":["flux"],"summary":"Rss Feed","description":"Flux complet, ou restreint à une fréquence de la bande via `?freq=`.","operationId":"rss_feed_podcast_xml_get","parameters":[{"name":"freq","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Freq"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/feed":{"get":{"tags":["flux"],"summary":"Rss Feed","description":"Flux complet, ou restreint à une fréquence de la bande via `?freq=`.","operationId":"rss_feed_feed_get","parameters":[{"name":"freq","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Freq"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/rss":{"get":{"tags":["flux"],"summary":"Rss Feed","description":"Flux complet, ou restreint à une fréquence de la bande via `?freq=`.","operationId":"rss_feed_rss_get","parameters":[{"name":"freq","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Freq"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/feed/{message_id}.{ext}":{"get":{"tags":["flux"],"summary":"Enclosure","operationId":"enclosure_feed__message_id___ext__get","parameters":[{"name":"message_id","in":"path","required":true,"schema":{"type":"string","title":"Message Id"}},{"name":"ext","in":"path","required":true,"schema":{"type":"string","title":"Ext"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/directory":{"get":{"tags":["annuaire"],"summary":"List Directory","operationId":"list_directory_directory_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/UserOut"},"type":"array","title":"Response List Directory Directory Get"}}}}}}},"/directory/{username}":{"get":{"tags":["annuaire"],"summary":"Get Entry","operationId":"get_entry_directory__username__get","parameters":[{"name":"username","in":"path","required":true,"schema":{"type":"string","title":"Username"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserOut"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/directory/{username}/key":{"get":{"tags":["annuaire"],"summary":"Get Key","operationId":"get_key_directory__username__key_get","parameters":[{"name":"username","in":"path","required":true,"schema":{"type":"string","title":"Username"}}],"responses":{"200":{"description":"Successful Response","content":{"text/plain":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/register":{"post":{"tags":["auth"],"summary":"Register","operationId":"register_auth_register_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterIn"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Register Auth Register Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/login":{"post":{"tags":["auth"],"summary":"Login","operationId":"login_auth_login_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Login Auth Login Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/logout":{"post":{"tags":["auth"],"summary":"Logout","operationId":"logout_auth_logout_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Logout Auth Logout Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/me":{"get":{"tags":["auth"],"summary":"Me","operationId":"me_auth_me_get","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Me Auth Me Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/keys":{"get":{"tags":["auth"],"summary":"My Keys","operationId":"my_keys_auth_keys_get","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"},"title":"Response My Keys Auth Keys Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["auth"],"summary":"Create My Key","description":"Émet une clé pour soi-même. Quota et validité sont **plafonnés** aux\nréglages admin (demander plus donne le plafond), et le nombre de clés actives\npar compte est borné (409 sinon).","operationId":"create_my_key_auth_keys_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeyCreateIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Create My Key Auth Keys Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/settings":{"get":{"tags":["admin"],"summary":"Get Settings","operationId":"get_settings_admin_settings_get","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get Settings Admin Settings Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["admin"],"summary":"Update Settings","operationId":"update_settings_admin_settings_put","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SettingsIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Update Settings Admin Settings Put"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/messages":{"get":{"tags":["admin"],"summary":"All Messages","operationId":"all_messages_admin_messages_get","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"},"title":"Response All Messages Admin Messages Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/messages/{message_id}":{"delete":{"tags":["admin"],"summary":"Delete Message","operationId":"delete_message_admin_messages__message_id__delete","parameters":[{"name":"message_id","in":"path","required":true,"schema":{"type":"string","title":"Message Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Delete Message Admin Messages  Message Id  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/messages/purge":{"post":{"tags":["admin"],"summary":"Purge","operationId":"purge_admin_messages_purge_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Purge Admin Messages Purge Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/users":{"get":{"tags":["admin"],"summary":"All Users","operationId":"all_users_admin_users_get","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"},"title":"Response All Users Admin Users Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/users/{username}":{"delete":{"tags":["admin"],"summary":"Delete User","operationId":"delete_user_admin_users__username__delete","parameters":[{"name":"username","in":"path","required":true,"schema":{"type":"string","title":"Username"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Delete User Admin Users  Username  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/apikeys":{"get":{"tags":["admin"],"summary":"All Keys","operationId":"all_keys_admin_apikeys_get","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"},"title":"Response All Keys Admin Apikeys Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["admin"],"summary":"Create Key","operationId":"create_key_admin_apikeys_post","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminKeyIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Create Key Admin Apikeys Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/apikeys/{key_id}/revoke":{"post":{"tags":["admin"],"summary":"Revoke Key","operationId":"revoke_key_admin_apikeys__key_id__revoke_post","parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"string","title":"Key Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Revoke Key Admin Apikeys  Key Id  Revoke Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/apikeys/{key_id}/limits":{"put":{"tags":["admin"],"summary":"Set Key Limits","operationId":"set_key_limits_admin_apikeys__key_id__limits_put","parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"string","title":"Key Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LimitsIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Set Key Limits Admin Apikeys  Key Id  Limits Put"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/activity":{"get":{"tags":["admin"],"summary":"Activity Log","description":"Événements récents (plus récent d'abord), filtrables.","operationId":"activity_log_admin_activity_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"action","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Action"}},{"name":"username","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Username"}},{"name":"ip","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ip"}},{"name":"fingerprint","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fingerprint"}},{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Q"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"},"title":"Response Activity Log Admin Activity Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/activity/stats":{"get":{"tags":["admin"],"summary":"Activity Stats","description":"Statistiques agrégées sur la fenêtre `days` (bornée [1, 90]).","operationId":"activity_stats_admin_activity_stats_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":7,"title":"Days"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Activity Stats Admin Activity Stats Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/activity/purge":{"post":{"tags":["admin"],"summary":"Activity Purge","description":"Purge les événements plus vieux que `days` jours (défaut = rétention réglée).","operationId":"activity_purge_admin_activity_purge_post","parameters":[{"name":"days","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Days"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Activity Purge Admin Activity Purge Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/download/postman.py":{"get":{"tags":["téléchargement"],"summary":"Download Cli","description":"Renvoie `postman.py` prêt à l'emploi (401 si non authentifié).","operationId":"download_cli_download_postman_py_get","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/":{"get":{"tags":["web"],"summary":"Listening Room","operationId":"listening_room__get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/annuaire":{"get":{"tags":["web"],"summary":"Directory Page","operationId":"directory_page_annuaire_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/manuel":{"get":{"tags":["web"],"summary":"Manual Page","description":"Manuel de l'opérateur : fonctionnement de l'API et du client CLI.","operationId":"manual_page_manuel_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/histoire":{"get":{"tags":["web"],"summary":"History Page","description":"Musée du bureau : l'invention du morse, le télégraphe, la TSF (histoire + technique).","operationId":"history_page_histoire_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/login":{"get":{"tags":["web"],"summary":"Login Page","operationId":"login_page_login_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/admin":{"get":{"tags":["web"],"summary":"Admin Page","operationId":"admin_page_admin_get","responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}}}}},"/health":{"get":{"summary":"Health","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Health Health Get"}}}}}}},"/api/info":{"get":{"summary":"Api Info","operationId":"api_info_api_info_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Api Info Api Info Get"}}}}}}}},"components":{"schemas":{"AdminKeyIn":{"properties":{"username":{"type":"string","title":"Username"},"quota":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Quota"},"validity_days":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Validity Days"}},"type":"object","required":["username"],"title":"AdminKeyIn"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"KeyCreateIn":{"properties":{"quota":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Quota"},"validity_days":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Validity Days"}},"type":"object","title":"KeyCreateIn"},"LimitsIn":{"properties":{"quota":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Quota"},"validity_days":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Validity Days"}},"type":"object","title":"LimitsIn"},"LoginIn":{"properties":{"username":{"type":"string","title":"Username"},"password":{"type":"string","title":"Password"}},"type":"object","required":["username","password"],"title":"LoginIn"},"MessageCreate":{"properties":{"text":{"anyOf":[{"type":"string","maxLength":4000},{"type":"null"}],"title":"Text","description":"Contenu en clair ; exclusif avec `raw_morse`"},"raw_morse":{"anyOf":[{"type":"string","maxLength":8000},{"type":"null"}],"title":"Raw Morse","description":"Morse brut transmis verbatim (public uniquement, sans Base32)"},"is_public":{"type":"boolean","title":"Is Public","default":true},"sender":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Sender"},"recipient":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Recipient","description":"Destinataire (message privé uniquement)"},"recipient_public_key_pem":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recipient Public Key Pem","description":"Clé publique RSA (PEM) du destinataire, requise si privé"},"ttl_seconds":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Ttl Seconds","description":"TTL explicite ; sinon le défaut serveur s'applique"},"frequency":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Frequency","description":"Fréquence d'émission en kHz (invité : bande fixe ; inscrit : toute la bande étendue) ; défaut serveur sinon"}},"type":"object","title":"MessageCreate"},"MessageOut":{"properties":{"id":{"type":"string","title":"Id"},"sender":{"type":"string","title":"Sender"},"is_public":{"type":"boolean","title":"Is Public"},"raw":{"type":"boolean","title":"Raw"},"recipient":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recipient"},"frequency":{"type":"integer","title":"Frequency"},"morse":{"type":"string","title":"Morse"},"encoded":{"type":"string","title":"Encoded"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"}},"type":"object","required":["id","sender","is_public","raw","recipient","frequency","morse","encoded","created_at","expires_at"],"title":"MessageOut"},"RegisterIn":{"properties":{"username":{"type":"string","maxLength":64,"minLength":3,"title":"Username"},"password":{"type":"string","minLength":12,"title":"Password"},"public_key_pem":{"type":"string","title":"Public Key Pem"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"admin_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Admin Token","description":"Jeton d'amorçage admin (requis pour être promu admin)"}},"type":"object","required":["username","password","public_key_pem"],"title":"RegisterIn"},"SettingsIn":{"properties":{"message_ttl_seconds":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Message Ttl Seconds"},"broadcasts_guest":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Broadcasts Guest"},"broadcasts_user":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Broadcasts User"},"max_chars_guest":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Max Chars Guest"},"max_chars_user":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Max Chars User"},"send_rate_guest":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Send Rate Guest"},"send_rate_user":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Send Rate User"},"apikey_quota":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Apikey Quota"},"apikey_validity_days":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Apikey Validity Days"},"apikey_max_per_user":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Apikey Max Per User"},"activity_retention_days":{"anyOf":[{"type":"integer","exclusiveMinimum":0.0},{"type":"null"}],"title":"Activity Retention Days"}},"type":"object","title":"SettingsIn"},"UserOut":{"properties":{"username":{"type":"string","title":"Username"},"public_key_pem":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Public Key Pem"},"fingerprint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fingerprint"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["username","created_at"],"title":"UserOut","description":"Entrée d'annuaire **publique**, empreinte incluse (calculée dans la route).\n\n⚠️ Pas d'`email` ici : l'annuaire est lisible sans authentification, et une\nadresse donnée à l'inscription n'a pas à être publiée (moissonnage). L'admin la\nvoit dans son propre rendu (`GET /admin/users`), qui n'utilise pas ce schéma.\nCe que l'annuaire doit exposer, c'est un nom et une clé publique (invariant #4)."},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}}}