Documentation API
Créez des pushes par script — provisioning, onboarding, CI — tout en conservant le chiffrement de bout en bout.
Authentification
Générez un token personnel dans Compte → Tokens API (affiché une seule fois), puis passez-le en en-tête :
Authorization: Bearer ppush_xxxxxxxxxxxxxxxxxxxxL'API n'accepte que des contenus déjà chiffrés. Le serveur ne chiffre jamais lui-même — c'est ce qui garantit le zéro-knowledge. Utilisez le CLI fourni (recommandé) ou implémentez le format ci-dessous.
Le CLI (recommandé)
tools/ppush-cli.mjs (dans le dépôt) chiffre localement puis appelle l'API. Node ≥ 20, aucune dépendance.
export PPUSH_URL=http://localhost:3000
export PPUSH_TOKEN=ppush_xxx
# mot de passe, 3 vues max, 7 jours
ppush-cli.mjs --password "S3cret!" --views 3 --days 7
# texte depuis stdin
cat config.yml | ppush-cli.mjs --text -
# fichier avec passphrase et note privée
ppush-cli.mjs --file dump.sql.gz --passphrase "sesame" --note "backup pour Bob"
# → imprime l'URL complète, clé de déchiffrement incluse dans le fragmentOptions : --days N · --views N · --passphrase X · --note "…" · --no-retrieval-step · --no-deletable
Endpoints
/api/pushesBearer ou sessionCrée un push. Corps JSON :
{
"kind": "PASSWORD" | "TEXT" | "FILE" | "URL",
"ciphertext": "<base64>", // payload chiffré (cf. format)
"blobPath": "xxx.bin", // FILE uniquement (cf. POST /api/blobs)
"passphrase": "optionnelle",
"expireAfterDays": 7, // 1..30
"expireAfterViews": 5, // 1..50
"retrievalStep": true,
"deletableByViewer": true,
"note": "référence privée optionnelle"
}Réponse 201 : { "slug", "url", "expiresAt", … }. Le lien à transmettre est url + "#" + clé_base64url— la clé n'est connue que de vous.
/api/blobsBearer ou sessionUpload du blob chiffré d'un fichier (corps brut, max ~100 Mo avec un compte). Réponse : { "blobPath": "xxx.bin", "size": 123 } à passer ensuite à POST /api/pushes.
/api/pushes?page=1&filter=activeBearer ou sessionListe paginée de vos pushes. filter : active | expired | (omis = tous).
/api/pushes/:slugBearer ou sessionDétail d'un push + journal d'audit complet (events : CREATED, VIEW, FAILED_PASSPHRASE, EXPIRED, OWNER_DELETE, VIEWER_DELETE, avec IP et user-agent).
/api/pushes/:slugBearer ou sessionFait expirer le push immédiatement (purge définitive du payload).
/api/p/:slugpublicMétadonnées publiques d'un push (type, expiré ou non, passphrase requise…). Ne consomme pas de vue.
/api/p/:slug/revealpublicRévèle le ciphertext et consomme une vue. Corps : { "passphrase": "…" } si exigée. Pour un FILE, retourne aussi un viewToken à usage unique pour GET /api/p/:slug/blob?vt=….
/api/p/:slug/burnpublicDestruction par le destinataire (si autorisée à la création).
Format de chiffrement (v1)
Si vous n'utilisez pas le CLI, produisez le ciphertext ainsi (AES-256-GCM, WebCrypto ou équivalent) :
Clé : 32 octets aléatoires → base64url → fragment du lien (#…)
Payload : JSON { "t": "PASSWORD|TEXT|URL", "d": "<secret>" }
(FILE : { "t":"FILE", "d":"", "name", "mime", "size" })
ciphertext = 0x01 ‖ IV(12 octets) ‖ AES-256-GCM(payload, AAD="ppush:v1:meta")
→ base64 dans le champ "ciphertext"
Fichiers (blob) : chunks de 8 Mio, chacun encadré :
[longueur u32 BE] [IV 12 octets] [ct+tag]
AAD du chunk i : "ppush:v1:<i>:<1 si dernier, sinon 0>"Limites & erreurs
- Réponses d'erreur :
{ "error": "message" }avec le statut HTTP approprié (400validation,401auth,403interdit,404introuvable,409conflit,410expiré,413trop volumineux,429rate limit). - Rate limiting par IP sur les endpoints sensibles (login, passphrase, reveal). En cas de
429, attendez puis réessayez. - Payload texte chiffré : 1024 Ko max · fichiers : 100 Mo max (compte) · rétention : 30 jours / 50 vues max. Sans compte : 7 jours / 5 vues, fichiers 10 Mo.
- Un token API a les droits de son propriétaire (création, listing, expiration de ses pushes). Révocable à tout moment depuis le compte.
Voir aussi la page À propos et la gestion des tokens.