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 :
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 :
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 :
{
"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.
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 :
{
"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
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 -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
{
"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 :
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 :
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 :
{
"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 :
{
"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
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 -H "Authorization: ApiKey public_key_abcd" \
https://password.link/api/secrets/dT5g
Exemple de réponse
{
"data": {
"id": "dT5g",
"ciphertext": "eyJjaXBoZXIiOiJRc3hxsN3...aXRlciI6MTAwMDB9",
"password_part_private": "ZmtnamJudmxha3dpZWpndXRu",
"message": "Here are the credentials we talked about"
},
"metadata": null
}
Confirmer le Secret
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 -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
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 -H "Authorization: ApiKey private_key_abcd" \
https://password.link/api/secrets
Exemple de réponse
{
"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
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 -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
Supprime un secret. Renvoie 200 OK en cas de succès.
Exemple de requête
curl -H "Authorization: ApiKey private_key_abcd" \
-X DELETE https://password.link/api/secrets/dT5g
Exemple de réponse
{
"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
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
{
"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
Récupère une liste de dossiers de secrets. Renvoie 200 OK en cas de succès.
Exemple de réponse
{
"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
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
Supprime un dossier de secrets. Renvoie 200 OK en cas de succès.
Créer une demande de secret
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 -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
{
"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
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 -H "Authorization: ApiKey private_key_abcd" \
https://password.link/api/secret_requests
Exemple de réponse
{
"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
Supprime une demande de secret. Renvoie 200 OK en cas de succès.
Exemple de requête
curl -H "Authorization: ApiKey private_key_abcd" \
-X DELETE https://password.link/api/secret_requests/5e976e6e-d205-4f58-8df9-5ac0048bc702