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=https://ppush.online
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",
"expireAfterMinutes": 10080, // 5..43200 (min 5 ; "expireAfterDays" en jours encore accepté)
"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 ~90 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, à passer en en-tête X-View-Token sur GET /api/p/:slug/blob (jamais dans l’URL). Si le transfert est interrompu, rappeler reveal ré-émet un token sans consommer de vue supplémentaire, tant que le fichier n’a pas été livré en entier.
/api/p/:slug/burnpublicDestruction par le destinataire (si autorisée à la création).
/api/storagepublicFair-use transparent du stockage fichiers : { "availableBytes", "upcoming": [{ "bytes", "at" }] } — upcomingliste les libérations d'espace à venir (cumulées, par date d'expiration au plus tard). Authentifié, ajoute "user": { "usedBytes", "availableBytes", "quotaBytes" } (quota personnel de fichiers actifs). Un upload refusé faute d'espace renvoie 507avec l'estimation de la prochaine fenêtre.
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 : 90 Mo max (compte) · rétention : 30 jours / 50 vues max. Sans compte : 7 jours / 5 vues, fichiers 10 Mo.
- Stockage fichiers fair-use : espace global partagé (voir
GET /api/storage) + quota personnel de 3 Go de fichiers actifs par compte. Saturation →507avec l'estimation des prochaines libérations d'espace. - 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.