Docs - API

Une API REST pour créer, consulter et gérer des secrets. Toutes les requêtes et réponses utilisent JSON, et tout le chiffrement et le déchiffrement se font de votre côté, de sorte que le texte en clair n'atteint jamais nos serveurs.

Aperçu

L'URL de base pour tous les points de terminaison de l'API est :

URL
https://password.link/api

Vous pouvez utiliser l'API pour gérer à la fois le cryptage et le décryptage du secret en dehors de notre service, sans avoir besoin de charger des ressources de notre part. Cela vous permet également d'utiliser n'importe quelle méthode de livraison pour la partie mot de passe public (la moitié du mot de passe qui est utilisée pour dériver la clé de cryptage du secret) et de créer fondamentalement n'importe quelle configuration personnalisée pour visualiser le secret.

Pour du code complet et fonctionnel, consultez les Exemples d'API.

Authentification

Chaque requête doit être authentifiée avec une clé API, envoyée dans l'en-tête Authorization :

HTTP
Authorization: ApiKey public_key_abcd...

Il existe deux types de clés API :

Type de clé Description
Clé API publique Destinée à la création d'une page personnalisée d'affichage du secret auto-hébergée. Peut être utilisée dans des scripts publics. Permet uniquement de consulter et de confirmer les secrets.
Clé API privée Requise pour toutes les autres actions de l'API. Doit toujours rester privée.

Les deux clés API contiennent le type de la clé dans la clé elle-même, ce qui permet de les distinguer facilement.

Chaque point de terminaison ci-dessous indique le type de clé requis.

Erreurs

Lorsqu'une requête échoue, la réponse contient un objet d'erreur :

JSON
{
  "data": null,
  "metadata": null,
  "error": {
    "message": "Ciphertext can't be blank",
    "field": "ciphertext"
  }
}
Champ Description
message Le message d'erreur complet.
field Le champ concerné par l'erreur, lorsqu'il s'agit d'une erreur de validation.

Le code de statut HTTP de la réponse indique également le type d'erreur :

Code de statut Description
403 Forbidden La requête n'a pas été autorisée, par exemple à cause d'une clé API invalide.
404 Not Found La ressource demandée est introuvable.
422 Unprocessable Content La requête a été comprise mais n'a pas passé la validation, par exemple à cause d'un paramètre manquant ou invalide.

Chiffrement des secrets

Les secrets sont chiffrés côté client avant d'être envoyés à l'API. Cette section décrit les formats de mot de passe et de texte chiffré attendus par le service.

Les parties du mot de passe

Le mot de passe utilisé pour crypter le secret dans AES doit consister en deux chaînes de 18 caractères. La clé de chiffrement proprement dite sera la concaténation de ces deux chaînes ("partie privée" + "partie publique") et sera dérivée du mot de passe à l'aide de PBKDF2.

Exemple
Password: fkgjbnvlakwiejgutnFIGKEOTIRUBNAKQJRL
  => Private part: fkgjbnvlakwiejgutn
  => Public part:  FIGKEOTIRUBNAKQJRL

La partie privée est envoyée à l'API (encodée en Base64) et stockée avec le secret. La partie publique n'est jamais envoyée à l'API et est généralement transmise dans le lien lui-même, de sorte que nous ne pouvons jamais déchiffrer le secret nous-mêmes.

Si vous utilisez la page d'affichage du secret fournie par nous, vous devez également encoder la partie publique en Base64. Si vous utilisez une page d'affichage du secret auto-hébergée, vous pouvez utiliser la même méthode ou créer la vôtre. Veuillez consulter les Exemples d'API pour des implémentations de référence.

Format du texte chiffré

Le texte chiffré est un objet JSON, encodé en Base64 :

JSON
{
  "cipher": "<Base64 encoded AES-GCM ciphertext>",
  "iv": "<Base64 encoded 12-byte initialization vector>",
  "salt": "<Base64 encoded 16-byte PBKDF2 salt>",
  "iter": 10000
}

Vous devez utiliser les paramètres suivants pour AES lors du cryptage du secret :

Réglage Valeur
Mode AES-GCM avec une balise d'authentification de 128 bits ajoutée à la fin du texte chiffré (valeur par défaut de Web Crypto)
Taille de la clé 256 bits
Dérivation de la clé PBKDF2 avec SHA-256
Itérations PBKDF2 La valeur du champ iter. Plage autorisée 1000-1000000, nous recommandons 10000.
Vecteur d'initialisation 12 octets aléatoires
Sel 16 octets aléatoires

Ancien format SJCL (obsolète)

Les textes chiffrés créés avec la Stanford Javascript Crypto Library (SJCL) sont toujours acceptés : une chaîne JSON de texte chiffré compatible SJCL encodée en Base64, utilisant AES-GCM ("mode:gcm"), une clé de 256 bits ("ks:256") et 10000 itérations PBKDF2 ("iter:10000"). Ce format est obsolète et sa prise en charge sera supprimée à l'avenir.

Déchiffrement des secrets

L'API Voir le secret renvoie le texte chiffré exactement tel qu'il a été stocké. Les secrets créés dans l'application web utilisent le format Web Crypto décrit ci-dessus. Les secrets créés par d'anciens clients de l'API, par l'extension Chrome ou par des liens encore non ouverts peuvent utiliser l'ancien format SJCL.

Une page d'affichage auto-hébergée doit prendre en charge les deux formats. Après avoir décodé le texte chiffré du Base64 vers JSON, vérifiez la présence d'une clé ct : si elle est présente, déchiffrez avec SJCL, sinon déchiffrez avec Web Crypto. Consultez l'exemple Voir le secret.

Les clients de l'API qui ne font que créer des secrets n'ont pas besoin d'être modifiés : les textes chiffrés SJCL sont toujours acceptés à la création. Les clients qui déchiffrent des secrets récupérés via l'API doivent prendre en charge Web Crypto, sinon ils échoueront sur les secrets créés dans l'application web.

Créer un secret

POST /api/secrets Clé API privée

Crée un secret chiffré et renvoie son ID. Le texte chiffré doit être créé comme décrit dans Chiffrement des secrets. Renvoie 201 Created en cas de succès.

Paramètres de la demande

Paramètre Type Description
ciphertextrequis string Une chaîne JSON de texte chiffré du secret compatible Web Crypto, encodée en Base64. Les textes chiffrés hérités compatibles SJCL sont également acceptés (obsolète).
password_part_privaterequis string La partie privée du mot de passe qui a été utilisée pour chiffrer le secret, encodée en Base64.
password_part_public string La partie publique du mot de passe, encodée en Base64. Requise uniquement lors de l'utilisation de email_to afin que l'API puisse envoyer par e-mail le lien hébergé du secret.
description string Une description pour le secret. Non visible lors de la consultation du secret.
message string Un message pour le secret. Sera affiché avec le secret.
expiration integer Un délai d'expiration pour le secret, en heures. Valeurs possibles : 1-500.
view_button boolean Afficher un bouton de consultation du secret au lieu d'afficher le secret immédiatement après l'ouverture du lien.
captcha boolean Afficher un simple CAPTCHA avant d'afficher le secret, principalement pour bloquer les scanners automatisés.
password string Un mot de passe pour le secret.
max_views integer Combien de fois le secret peut être consulté. Valeurs possibles : 1-100.
email_to string Destinataires e-mail séparés par des virgules qui doivent recevoir le lien du secret créé. Nécessite password_part_public.
otp_email_recipient string Adresse e-mail qui reçoit un mot de passe à usage unique. Lorsqu'elle est définie, le destinataire doit saisir le code envoyé par e-mail avant de pouvoir voir le Secret.
otp_recipient string Accepté comme alias de otp_email_recipient. Préférez otp_email_recipient pour les nouvelles intégrations.
otp_sms_recipient string Numéro de téléphone qui reçoit un mot de passe à usage unique par SMS, au format international commençant par + et sans espaces.
allowed_ips string Adresses IP ou plages CIDR séparées par des virgules autorisées à voir le Secret.
allowed_locations array Tableau de codes pays ISO 3166-1 alpha-2 autorisés à voir le Secret.
available_after datetime Date et heure avant lesquelles le Secret ne peut pas être affiché.
secret_folder_id string ID d'un dossier de Secrets existant appartenant à l'utilisateur de la clé API.
reply_enabled boolean Activer une réponse à usage unique du destinataire après l'affichage du Secret.
ack_required boolean Exiger la confirmation du destinataire avant que le Secret puisse être affiché.
ack_mode string Mode de confirmation. Utilisez checkbox ou phrase.
ack_phrase string Phrase que le destinataire doit saisir. Requise lorsque ack_required est true et que ack_mode est phrase.
ack_disclosure_text string Texte de divulgation affiché au destinataire, jusqu'à 500 caractères.
ack_collect_name boolean recueillir le nom du destinataire avec la confirmation.
ack_name_required boolean Exiger le nom du destinataire. Active également ack_collect_name.
ack_collect_org boolean recueillir l'organisation du destinataire avec la confirmation.
attachment object Métadonnées pour une pièce jointe chiffrée, voir Pièces jointes. Nécessite un abonnement actif.
attachment.file_name string Le nom de fichier d'origine affiché au destinataire. Requis lorsqu'une pièce jointe est fournie.
attachment.file_type string Le type MIME d'origine, par exemple text/plain ou application/pdf. Requis lorsqu'une pièce jointe est fournie.
attachment.file_size integer La taille d'origine non chiffrée du fichier en octets. Requis lorsqu'une pièce jointe est fournie.

Les paramètres de Secrets d'équipe peuvent désactiver, rendre obligatoires ou imposer des valeurs par défaut pour les options de Secret prises en charge. L'API applique ces règles d'équipe lors de la création d'un Secret.

Exemple de requête

cURL
curl -H "Authorization: ApiKey private_key_abcd" \
     -H "Content-Type: application/json" \
     -X POST https://password.link/api/secrets \
     -d '{
       "ciphertext": "eyJjaXBoZXIiOiJRc3hxsN3...aXRlciI6MTAwMDB9",
       "password_part_private": "ZmtnamJudmxha3dpZWpndXRu",
       "description": "Database credentials",
       "expiration": 24,
       "view_button": true,
       "max_views": 1
     }'

Exemple de réponse

JSON
{
  "data": {
    "id": "dT5g"
  },
  "metadata": {
    "secrets_total": 70,
    "secrets_usage": 25,
    "secrets_allowance": 100,
    "secret_requests_total": 10,
    "secret_requests_allowance": 100
  }
}

Le lien vers le secret est formé en combinant l'URL de la page d'affichage hébergée, l'ID du secret et la partie publique du mot de passe encodée en Base64 :

URL
https://password.link/<id>/#<public password part, Base64>

Pièces jointes

Le téléversement d'une pièce jointe se fait en deux étapes : créez d'abord le secret avec les métadonnées de la pièce jointe (voir Créer un secret), puis chiffrez et téléversez la charge utile chiffrée de la pièce jointe vers l'URL de téléversement renvoyée.

Le contenu du secret et le contenu de la pièce jointe sont chiffrés séparément. Les deux utilisent des données AES-GCM compatibles Web Crypto, encodées en Base64, mais les champs de la charge utile sont encodés différemment : la charge utile du secret contient des champs encodés en Base64 et un champ iter, tandis que la charge utile de la pièce jointe contient des champs de chaînes binaires brutes.

Chiffrement de la pièce jointe

Avant le chiffrement, représentez le fichier sous forme d'URL de données :

URL
data:<mime-type>;base64,<base64 file bytes>

Le mot de passe de chiffrement de la pièce jointe est la partie privée brute du mot de passe concaténée avec la partie publique brute (sans encodage Base64).

Chiffrez cette chaîne data URL avec AES-GCM en utilisant PBKDF2-SHA256, 10000 itérations, une clé dérivée de 256 bits, un sel aléatoire de 16 octets et un IV aléatoire de 12 octets. Stockez la charge utile chiffrée de la pièce jointe sous forme d'objet JSON, puis encodez la chaîne JSON en Base64 :

JSON
{
  "cipher": "<binary string>",
  "iv": "<binary string>",
  "salt": "<binary string>"
}

Téléversement du fichier chiffré

Lorsqu'une pièce jointe est incluse, la réponse de création du secret contient une cible de téléversement dans data.attachment.upload :

JSON
{
  "data": {
    "id": "dT5g",
    "attachment": {
      "file_name": "example.txt",
      "upload": {
        "url": "/api/secrets/dT5g/attachment",
        "fields": {},
        "metadata": {}
      }
    }
  },
  "metadata": {}
}

Téléversez le JSON chiffré encodé en Base64 en tant que text/plain via multipart/form-data vers le upload.url renvoyé. Ajoutez toutes les paires clé/valeur renvoyées dans upload.metadata ou upload.fields aux données du formulaire avant d'ajouter le fichier chiffré. Le champ du fichier chiffré doit être nommé file.

Pour les URL de téléversement Password.link, incluez la même clé API privée dans l'en-tête Authorization: ApiKey <key>. Les URL de téléversement direct vers le stockage, comme les URL S3 présignées, ne doivent recevoir que les champs de formulaire renvoyés et le champ file chiffré.

Les URL de téléversement hébergées sur Password.link incluent un objet fields vide. Les URL de téléversement vers un stockage direct, comme les URL S3 pré-signées, renvoient les champs de signature dans metadata.

Les limites de taille des pièces jointes dépendent du quota du compte ou de l'équipe, et le téléversement chiffré est plus volumineux que le fichier d'origine, car le fichier est converti en Base64 puis chiffré.

Voir le secret

GET /api/secrets/<id> Clé API publique

Récupère le texte chiffré, la partie privée du mot de passe et d'autres détails d'un secret. Ce point de terminaison peut être utilisé pour créer une page personnalisée d'affichage du secret auto-hébergée qui ne charge aucun script ni autre ressource depuis notre service. Renvoie 200 OK en cas de succès.

L'obtention d'un secret marque automatiquement sa consultation et supprime donc le texte chiffré et le mot de passe privé de notre base de données, ce qui rend impossible une nouvelle consultation du secret.

Le texte chiffré peut être au format Web Crypto ou à l'ancien format SJCL. Repérez les charges utiles SJCL grâce à une clé ct dans le JSON décodé. Consultez Déchiffrement des secrets.

Exemple de requête

cURL
curl -H "Authorization: ApiKey public_key_abcd" \
     https://password.link/api/secrets/dT5g

Exemple de réponse

JSON
{
  "data": {
    "id": "dT5g",
    "ciphertext": "eyJjaXBoZXIiOiJRc3hxsN3...aXRlciI6MTAwMDB9",
    "password_part_private": "ZmtnamJudmxha3dpZWpndXRu",
    "message": "Here are the credentials we talked about"
  },
  "metadata": null
}

Confirmer le Secret

POST /api/secrets/<id>/acknowledge Clé API publique

Envoie la confirmation du destinataire pour un secret créé avec ack_required, et renvoie les mêmes données du secret que View Secret lorsque la confirmation est valide. Renvoie 200 OK en cas de succès.

Si une confirmation est requise, GET /api/secrets/<id> renvoie 403 Forbidden avec secret_status défini sur ack_required jusqu'à ce que ce point de terminaison soit utilisé.

Les données de confirmation invalides ou incomplètes renvoient également 403 Forbidden. Elles ne sont pas renvoyées comme des erreurs de validation.

Paramètres de la demande

Paramètre Type Description
ack_confirmed boolean Définir sur true pour la confirmation par case à cocher.
ack_phrase string Requis pour la confirmation par phrase, et doit correspondre à la phrase configurée pour le Secret.
ack_signer_name string Nom du destinataire, requis lorsque la collecte du nom est activée et marquée comme obligatoire.
ack_signer_org string Organisation du destinataire, enregistrée lorsque la collecte de l'organisation est activée.

Exemple de requête

cURL
curl -H "Authorization: ApiKey public_key_abcd" \
     -H "Content-Type: application/json" \
     -X POST https://password.link/api/secrets/dT5g/acknowledge \
     -d '{"ack_confirmed": true, "ack_signer_name": "Jane Doe"}'

Secrets de liste

GET /api/secrets Clé API privée

Récupère une liste de secrets. Ne contient pas les textes chiffrés ni les parties privées des mots de passe, seulement les ID, les descriptions et autres informations similaires. Renvoie 200 OK en cas de succès.

Le nombre maximal de résultats renvoyés pour chaque requête est limité à 50. Vous pouvez contrôler le décalage avec le paramètre de requête facultatif offset, par exemple : /api/secrets?offset=50

Exemple de requête

cURL
curl -H "Authorization: ApiKey private_key_abcd" \
     https://password.link/api/secrets

Exemple de réponse

JSON
{
  "data": [
    {
      "id": "dT5g",
      "created_at": "2026-07-02T10:00:00.000Z",
      "message": "Here are the credentials we talked about",
      "description": "Database credentials",
      "view_button": true,
      "captcha": false,
      "password": false,
      "expiration": 24,
      "expired": false,
      "view_times": 1,
      "max_views": 1,
      "secret_folder_id": "5e976e6e-d205-4f58-8df9-5ac0048bc702",
      "views": [
        {
          "viewed_at": "2026-07-02T12:34:56.000Z",
          "viewed_by_ip": "192.0.2.10",
          "viewed_by_user_agent": "Mozilla/5.0 ..."
        }
      ]
    }
  ],
  "metadata": {
    "secrets_total": 70,
    "secrets_usage": 25,
    "secrets_allowance": 100,
    "secret_requests_total": 10,
    "secret_requests_allowance": 100
  }
}

Mettre à jour le Secret

PATCH /api/secrets/<id> Clé API privée

Met à jour les paramètres pris en charge et les métadonnées d'un secret existant. Renvoie 204 No Content en cas de succès.

PATCH ne remplace pas le contenu chiffré du secret, ne renvoie pas les e-mails de livraison et ne crée pas de métadonnées de téléversement de pièce jointe. Utilisez Create Secret pour le texte chiffré, les parties du mot de passe, l'envoi du lien et les pièces jointes.

Les paramètres suivants peuvent être mis à jour, avec la même signification que dans Create Secret :

description, message, expiration, max_views, view_button, captcha, password, otp_email_recipient, otp_recipient, otp_sms_recipient, allowed_ips, allowed_locations, available_after, secret_folder_id, reply_enabled, ack_required, ack_mode, ack_phrase, ack_disclosure_text, ack_collect_name, ack_name_required, ack_collect_org

ciphertext, password_part_private, password_part_public, email_to et les métadonnées de pièce jointe ne peuvent être définis qu'à la création. Ils sont ignorés par PATCH.

Exemple de requête

cURL
curl -H "Authorization: ApiKey private_key_abcd" \
     -H "Content-Type: application/json" \
     -X PATCH https://password.link/api/secrets/dT5g \
     -d '{"description": "Updated description", "otp_email_recipient": "recipient@example.com"}'

Supprimer le secret

DELETE /api/secrets/<id> Clé API privée

Supprime un secret. Renvoie 200 OK en cas de succès.

Exemple de requête

cURL
curl -H "Authorization: ApiKey private_key_abcd" \
     -X DELETE https://password.link/api/secrets/dT5g

Exemple de réponse

JSON
{
  "data": null,
  "metadata": {
    "secrets_total": 69,
    "secrets_usage": 24,
    "secrets_allowance": 100,
    "secret_requests_total": 10,
    "secret_requests_allowance": 100
  }
}

Créer un dossier de Secrets

POST /api/secret_folders Clé API privée

Crée un dossier de secrets. Renvoie 201 Created en cas de succès.

Paramètres de la demande

Paramètre Type Description
namerequis string Nom du dossier.
description string Description du dossier.

Exemple de réponse

JSON
{
  "data": {
    "id": "5e976e6e-d205-4f58-8df9-5ac0048bc702"
  },
  "metadata": {
    "secrets_total": 70,
    "secrets_usage": 25,
    "secrets_allowance": 100,
    "secret_requests_total": 10,
    "secret_requests_allowance": 100
  }
}

Lister les dossiers de Secrets

GET /api/secret_folders Clé API privée

Récupère une liste de dossiers de secrets. Renvoie 200 OK en cas de succès.

Exemple de réponse

JSON
{
  "data": [
    {
      "id": "5e976e6e-d205-4f58-8df9-5ac0048bc702",
      "name": "Clients",
      "description": "Client credentials",
      "created_at": "2026-07-02T10:00:00.000Z",
      "updated_at": "2026-07-02T10:00:00.000Z"
    }
  ],
  "metadata": {
    "secrets_total": 70,
    "secrets_usage": 25,
    "secrets_allowance": 100,
    "secret_requests_total": 10,
    "secret_requests_allowance": 100
  }
}

Mettre à jour le dossier de Secrets

PATCH /api/secret_folders/<id> Clé API privée

Met à jour le nom et la description d'un dossier de secrets. Accepte les mêmes paramètres que Create Secret Folder et renvoie 204 No Content en cas de succès.

Supprimer le dossier secret

DELETE /api/secret_folders/<id> Clé API privée

Supprime un dossier de secrets. Renvoie 200 OK en cas de succès.

Créer une demande de secret

POST /api/secret_requests Clé API privée

Crée une nouvelle demande de secret. Renvoie 201 Created en cas de succès.

Paramètres de la demande

Paramètre Type Description
description string Description de la demande secrète.
message string Pour le visualisateur de demandes secrètes.
expiration integer Le délai d'expiration de la demande secrète, en heures.
limit integer La limite d'utilisation de la demande secrète.
send_request_to_email string Envoie le lien de demande de secret créé à l'adresse électronique indiquée.
send_request_to_sms string Envoyer le lien de Secret Request créé au numéro de téléphone indiqué.
send_to_email string Envoie le lien secret créé à l'aide de la demande de secret à l'adresse électronique indiquée.
secret_description string Description du secret créé à l'aide de la demande de secret.
secret_message string Pour le secret créé à l'aide de la demande de secret.
secret_expiration integer Le délai d'expiration du secret créé à l'aide de la demande de secret, en heures.
secret_password string Mot de passe pour le Secret créé avec la Secret Request.
secret_max_views integer Limite de visualisation pour le secret créé à l'aide de la demande de secret.
template_id string ID du modèle de demande à utiliser.
secret_allowed_emails string Adresses e-mail ou domaines séparés par des virgules autorisés à ouvrir les Secrets créés avec cette Secret Request.
secret_allowed_ips string Adresses IP ou plages CIDR séparées par des virgules autorisées à ouvrir les Secrets créés avec cette Secret Request.

Exemple de requête

cURL
curl -H "Authorization: ApiKey private_key_abcd" \
     -H "Content-Type: application/json" \
     -X POST https://password.link/api/secret_requests \
     -d '{"description": "Request for VPN credentials", "expiration": 48}'

Exemple de réponse

JSON
{
  "data": {
    "id": "5e976e6e-d205-4f58-8df9-5ac0048bc702"
  },
  "metadata": {
    "secrets_total": 70,
    "secrets_usage": 25,
    "secrets_allowance": 100,
    "secret_requests_total": 10,
    "secret_requests_allowance": 100
  }
}

Liste des demandes secrètes

GET /api/secret_requests Clé API privée

Récupère une liste de demandes de secret. Renvoie 200 OK en cas de succès.

Le nombre maximal de résultats renvoyés pour chaque requête est limité à 50. Vous pouvez contrôler le décalage avec le paramètre de requête facultatif offset, par exemple : /api/secret_requests?offset=50

La réponse de liste n'inclut pas secret_allowed_emails ni secret_allowed_ips.

Exemple de requête

cURL
curl -H "Authorization: ApiKey private_key_abcd" \
     https://password.link/api/secret_requests

Exemple de réponse

JSON
{
  "data": [
    {
      "id": "5e976e6e-d205-4f58-8df9-5ac0048bc702",
      "description": "Request for VPN credentials",
      "message": "Please send me the VPN credentials",
      "expiration": 48,
      "limit": 1,
      "send_request_to_email": "request-recipient@example.com",
      "send_request_to_sms": "+358401234567",
      "send_to_email": "example@example.com",
      "secret_description": "VPN credentials",
      "secret_message": null,
      "secret_expiration": 24,
      "secret_max_views": 1,
      "secret_password": false,
      "template_id": null
    }
  ],
  "metadata": {
    "secrets_total": 70,
    "secrets_usage": 25,
    "secrets_allowance": 100,
    "secret_requests_total": 10,
    "secret_requests_allowance": 100
  }
}

Demande de suppression du secret

DELETE /api/secret_requests/<id> Clé API privée

Supprime une demande de secret. Renvoie 200 OK en cas de succès.

Exemple de requête

cURL
curl -H "Authorization: ApiKey private_key_abcd" \
     -X DELETE https://password.link/api/secret_requests/5e976e6e-d205-4f58-8df9-5ac0048bc702