Documentación API

Una API REST para crear, ver y gestionar secretos. Todas las solicitudes y respuestas utilizan JSON, y todo el cifrado y descifrado se realiza en su lado, por lo que el texto sin cifrar nunca llega a nuestros servidores.

Visión general

La URL base para todos los puntos de conexión de la API es:

URL
https://password.link/api

Puedes utilizar la API para manejar tanto el cifrado como el descifrado del secreto fuera de nuestro servicio, sin necesidad de cargar ningún activo nuestro. También le permite utilizar cualquier tipo de método de entrega para la parte de la contraseña pública (la mitad de la contraseña que se utiliza para derivar la clave de cifrado para el secreto de) y, básicamente, crear cualquier tipo de configuración personalizada para ver el secreto.

Para ver código completo y funcional, consulte los Ejemplos de API.

Autenticación

Cada solicitud debe autenticarse con una clave API, enviada en la cabecera Authorization:

HTTP
Authorization: ApiKey public_key_abcd...

Existen dos tipos de claves API:

Tipo de clave Descripción
Clave API pública Pensada para crear una página personalizada y autoalojada para ver secretos. Puede usarse en scripts públicos. Solo permite ver y confirmar secretos.
Clave API privada Necesaria para todas las demás acciones de la API. Debe mantenerse siempre en privado.

Ambas claves API contienen el tipo de clave en la propia clave para que puedan distinguirse fácilmente.

Cada punto de conexión a continuación muestra qué tipo de clave requiere.

Errores

Cuando una solicitud falla, la respuesta contiene un objeto de error:

JSON
{
  "data": null,
  "metadata": null,
  "error": {
    "message": "Ciphertext can't be blank",
    "field": "ciphertext"
  }
}
Campo Descripción
message El mensaje de error completo.
field El campo al que se refiere el error, cuando se trata de un error de validación.

El código de estado HTTP de la respuesta también indica el tipo de error:

Código de estado Descripción
403 Forbidden La solicitud no fue permitida, por ejemplo debido a una clave API no válida.
404 Not Found No se encontró el recurso solicitado.
422 Unprocessable Content La solicitud se entendió pero no superó la validación, por ejemplo debido a un parámetro que falta o no es válido.

Cifrado de secretos

Los secretos se cifran en el lado del cliente antes de enviarse a la API. Esta sección describe los formatos de contraseña y de texto cifrado que espera el servicio.

Las partes de la contraseña

La contraseña que se utiliza para cifrar el secreto en AES debe constar de dos cadenas de 18 caracteres. La clave de cifrado real será la concatenación de estas dos cadenas ("parte privada" + "parte pública") y se obtiene a partir de la contraseña utilizando PBKDF2.

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

La parte privada se envía a la API (codificada en Base64) y se almacena con el secreto. La parte pública nunca se envía a la API y normalmente se entrega en el propio enlace, por lo que nosotros nunca podemos descifrar el secreto.

Si utiliza la página para ver el secreto proporcionada por nosotros, también debe codificar la parte pública en Base64. Si utiliza una página autoalojada para ver el secreto, puede usar el mismo método o crear el suyo propio. Consulte los Ejemplos de API para ver implementaciones de referencia.

Formato del texto cifrado

El texto cifrado es un objeto JSON, codificado 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
}

Debe utilizar la siguiente configuración para AES al cifrar el secreto:

Ajuste Valor
Modo AES-GCM con una etiqueta de autenticación de 128 bits añadida al final del texto cifrado (valor predeterminado de Web Crypto)
Tamaño de la clave 256 bits
Derivación de la clave PBKDF2 con SHA-256
Iteraciones PBKDF2 El valor del campo iter. Rango permitido 1000-1000000, recomendamos 10000.
Vector de inicialización 12 bytes aleatorios
Sal 16 bytes aleatorios

Formato SJCL heredado (obsoleto)

Los textos cifrados creados con la Stanford Javascript Crypto Library (SJCL) siguen aceptándose: una cadena JSON de texto cifrado compatible con SJCL codificada en Base64, que utiliza AES-GCM ("mode:gcm"), una clave de 256 bits ("ks:256") y 10000 iteraciones PBKDF2 ("iter:10000"). Este formato está obsoleto y su compatibilidad se eliminará en el futuro.

Descifrado de secretos

La API Ver Secreto devuelve el texto cifrado exactamente como se almacenó. Los secretos creados en la aplicación web utilizan el formato Web Crypto descrito arriba. Los secretos creados por clientes de la API antiguos, por la extensión de Chrome o por enlaces aún sin abrir pueden utilizar el formato SJCL heredado.

Una página de visualización autoalojada debe gestionar ambos formatos. Tras descodificar el texto cifrado de Base64 a JSON, compruebe si existe una clave ct: si está presente, descifre con SJCL; en caso contrario, descifre con Web Crypto. Consulte el ejemplo de Ver Secreto.

Los clientes de la API que solo crean secretos no necesitan cambios: los textos cifrados con SJCL siguen aceptándose al crear. Los clientes que descifran secretos obtenidos de la API deben añadir compatibilidad con Web Crypto o fallarán con los secretos creados en la aplicación web.

Crear secreto

POST /api/secrets Clave API privada

Crea un secreto cifrado y devuelve su ID. El texto cifrado debe crearse como se describe en Cifrado de secretos. Devuelve 201 Created si tiene éxito.

Parámetros de la solicitud

Parámetro Tipo Descripción
ciphertextobligatorio string Una cadena JSON de texto cifrado del secreto compatible con Web Crypto, codificada en Base64. También se aceptan textos cifrados heredados compatibles con SJCL (obsoleto).
password_part_privateobligatorio string La parte privada de la contraseña que se utilizó para cifrar el secreto, codificada en Base64.
password_part_public string La parte pública de la contraseña, codificada en Base64. Solo es necesaria cuando se usa email_to para que la API pueda enviar por correo electrónico el enlace alojado del secreto.
description string Una descripción para el secreto. No se puede ver al visualizar el secreto.
message string Un mensaje para el secreto. Se mostrará junto con el secreto.
expiration integer Un tiempo de expiración para el secreto, en horas. Valores posibles: 1-500.
view_button boolean Mostrar un botón para ver el secreto en lugar de mostrar el secreto inmediatamente después de abrir el enlace.
captcha boolean Mostrar un CAPTCHA simple antes de mostrar el secreto, principalmente para bloquear escáneres automatizados.
password string Una contraseña para el secreto.
max_views integer Cuántas veces se puede ver el secreto. Valores posibles: 1-100.
email_to string Destinatarios de correo electrónico separados por comas que deben recibir el enlace del secreto creado. Requiere password_part_public.
otp_email_recipient string Dirección de correo que recibe una contraseña de un solo uso. Cuando se establece, el destinatario debe introducir el código enviado por correo antes de poder ver el Secret.
otp_recipient string Se acepta como alias de otp_email_recipient. Prefiera otp_email_recipient para nuevas integraciones.
otp_sms_recipient string Número de teléfono que recibe una contraseña de un solo uso por SMS, en formato internacional comenzando con + y sin espacios.
allowed_ips string Direcciones IP o rangos CIDR separados por comas con permiso para ver el Secret.
allowed_locations array Array de códigos de país ISO 3166-1 alfa-2 con permiso para ver el Secret.
available_after datetime Fecha y hora antes de las cuales no se puede ver el Secret.
secret_folder_id string ID de una carpeta de Secrets existente propiedad del usuario de la clave API.
reply_enabled boolean Habilitar una respuesta de un solo uso del destinatario después de que se haya visto el Secret.
ack_required boolean Requerir confirmación del destinatario antes de que se pueda ver el Secret.
ack_mode string Modo de confirmación. Use checkbox o phrase.
ack_phrase string Frase que el destinatario debe escribir. Obligatoria cuando ack_required es true y ack_mode es phrase.
ack_disclosure_text string Texto de divulgación mostrado al destinatario, hasta 500 caracteres.
ack_collect_name boolean recopilar el nombre del destinatario con la confirmación.
ack_name_required boolean Requerir el nombre del destinatario. Esto también activa ack_collect_name.
ack_collect_org boolean recopilar la organización del destinatario con la confirmación.
attachment object Metadatos para un archivo adjunto cifrado, consulte Archivos adjuntos. Requiere un plan activo.
attachment.file_name string El nombre de archivo original que se muestra al destinatario. Obligatorio cuando se proporciona un archivo adjunto.
attachment.file_type string El tipo MIME original, por ejemplo text/plain o application/pdf. Obligatorio cuando se proporciona un archivo adjunto.
attachment.file_size integer El tamaño original sin cifrar del archivo en bytes. Obligatorio cuando se proporciona un archivo adjunto.

La Configuración de Secrets del equipo puede deshabilitar, requerir o imponer valores predeterminados para las opciones de Secret compatibles. La API aplica esas reglas del equipo al crear un Secret.

Ejemplo de solicitud

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
     }'

Ejemplo de respuesta

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

El enlace al secreto se forma combinando la URL de la página de visualización alojada, el ID del secreto y la parte pública de la contraseña codificada en Base64:

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

Archivos adjuntos

Subir un archivo adjunto es un proceso de dos pasos: primero cree el secreto con los metadatos del adjunto (consulte Crear secreto) y luego cifre y suba la carga cifrada del adjunto a la URL de subida devuelta.

El contenido del secreto y el contenido del adjunto se cifran por separado. Ambos utilizan datos AES-GCM compatibles con Web Crypto, codificados en Base64, pero los campos de la carga útil se codifican de forma diferente: la carga útil del secreto contiene campos codificados en Base64 y un campo iter, mientras que la carga útil del adjunto contiene campos de cadenas binarias sin procesar.

Cifrado del archivo adjunto

Antes de cifrar, represente el archivo como una URL de datos:

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

La contraseña de cifrado del adjunto es la parte privada sin procesar de la contraseña concatenada con la parte pública sin procesar (sin codificación Base64).

Cifre esa cadena data URL con AES-GCM usando PBKDF2-SHA256, 10000 iteraciones, una clave derivada de 256 bits, una sal aleatoria de 16 bytes y un IV aleatorio de 12 bytes. Guarde la carga cifrada del adjunto como un objeto JSON y luego codifique la cadena JSON en Base64:

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

Subida del archivo cifrado

Cuando se incluye un archivo adjunto, la respuesta de creación del secreto contiene un destino de subida en data.attachment.upload:

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

Suba el JSON cifrado codificado en Base64 como text/plain usando multipart/form-data a la upload.url devuelta. Añada todos los pares clave/valor devueltos en upload.metadata o upload.fields a los datos del formulario antes de añadir el archivo cifrado. El campo del archivo cifrado debe llamarse file.

Para las URL de carga de Password.link, incluya la misma clave API privada en el encabezado Authorization: ApiKey <key>. Las URL de carga directa al almacenamiento, como las URL S3 prefirmadas, solo deben recibir los campos de formulario devueltos y el campo file cifrado.

Las URL de carga alojadas en Password.link incluyen un objeto fields vacío. Las URL de carga directa a almacenamiento, como las URL prefirmadas de S3, devuelven los campos de firma en metadata.

Los límites de tamaño de los adjuntos dependen de la asignación de la cuenta o del equipo, y la subida cifrada es más grande que el archivo original porque el archivo se convierte a Base64 y se cifra.

Ver Secreto

GET /api/secrets/<id> Clave API pública

Obtiene el texto cifrado, la parte privada de la contraseña y otros detalles de un secreto. Este punto de conexión puede usarse para crear una página personalizada y autoalojada para ver el secreto que no cargue scripts ni otros recursos de nuestro servicio. Devuelve 200 OK si tiene éxito.

Cuando se obtiene un secreto con éxito, se marca automáticamente como visto y, por lo tanto, se borra el texto cifrado y la contraseña privada de nuestra base de datos, lo que hace imposible volver a ver el secreto.

El texto cifrado puede tener el formato Web Crypto o el formato SJCL heredado. Detecte las cargas SJCL por la presencia de una clave ct en el JSON descodificado. Consulte Descifrado de secretos.

Ejemplo de solicitud

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

Ejemplo de respuesta

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

Confirmar Secret

POST /api/secrets/<id>/acknowledge Clave API pública

Envía la confirmación del destinatario para un secreto creado con ack_required y devuelve los mismos datos del secreto que View Secret cuando la confirmación es válida. Devuelve 200 OK si tiene éxito.

Si se requiere confirmación, GET /api/secrets/<id> devuelve 403 Forbidden con secret_status establecido en ack_required hasta que se use este punto de conexión.

Las cargas de confirmación no válidas o incompletas también devuelven 403 Forbidden. No se devuelven como errores de validación.

Parámetros de la solicitud

Parámetro Tipo Descripción
ack_confirmed boolean Establecer en true para la confirmación mediante casilla de verificación.
ack_phrase string Requerido para la confirmación con frase, y debe coincidir con la frase configurada para el Secret.
ack_signer_name string Nombre del destinatario, requerido cuando la recopilación de nombre está habilitada y marcada como obligatoria.
ack_signer_org string Organización del destinatario, almacenada cuando la recopilación de organización está habilitada.

Ejemplo de solicitud

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"}'

Lista Secretos

GET /api/secrets Clave API privada

Obtiene una lista de secretos. No contiene los textos cifrados ni las partes privadas de las contraseñas, solo IDs, descripciones y similares. Devuelve 200 OK si tiene éxito.

La cantidad máxima de resultados devueltos por cada consulta está limitada a 50. Puede controlar el desplazamiento con el parámetro de consulta opcional offset, por ejemplo: /api/secrets?offset=50

Ejemplo de solicitud

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

Ejemplo de respuesta

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
  }
}

Actualizar Secret

PATCH /api/secrets/<id> Clave API privada

Actualiza los ajustes y metadatos compatibles de un secreto existente. Devuelve 204 No Content si tiene éxito.

PATCH no reemplaza el contenido cifrado del secreto, no reenvía los correos de entrega ni crea metadatos de subida de adjuntos. Use Create Secret para el texto cifrado, las partes de la contraseña, la entrega del enlace y los adjuntos.

Los siguientes parámetros pueden actualizarse, con el mismo significado que en 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 y los metadatos de adjuntos solo pueden establecerse al crear. PATCH los ignora.

Ejemplo de solicitud

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"}'

Borrar secreto

DELETE /api/secrets/<id> Clave API privada

Elimina un secreto. Devuelve 200 OK si tiene éxito.

Ejemplo de solicitud

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

Ejemplo de respuesta

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

Crear carpeta de Secrets

POST /api/secret_folders Clave API privada

Crea una carpeta de secretos. Devuelve 201 Created si tiene éxito.

Parámetros de la solicitud

Parámetro Tipo Descripción
nameobligatorio string Nombre de la carpeta.
description string Descripción de la carpeta.

Ejemplo de respuesta

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
  }
}

Listar carpetas de Secrets

GET /api/secret_folders Clave API privada

Obtiene una lista de carpetas de secretos. Devuelve 200 OK si tiene éxito.

Ejemplo de respuesta

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
  }
}

Actualizar carpeta de Secrets

PATCH /api/secret_folders/<id> Clave API privada

Actualiza el nombre y la descripción de una carpeta de secretos. Acepta los mismos parámetros que Create Secret Folder y devuelve 204 No Content si tiene éxito.

Eliminar carpeta secreta

DELETE /api/secret_folders/<id> Clave API privada

Elimina una carpeta de secretos. Devuelve 200 OK si tiene éxito.

Crear solicitud secreta

POST /api/secret_requests Clave API privada

Crea una nueva solicitud de secreto. Devuelve 201 Created si tiene éxito.

Parámetros de la solicitud

Parámetro Tipo Descripción
description string Descripción de la solicitud secreta.
message string Para el visor de Peticiones Secretas.
expiration integer Tiempo de expiración de la Petición Secreta, en horas.
limit integer Límite de uso de la Solicitud Secreta.
send_request_to_email string Envía el enlace de solicitud secreta creado a la dirección de correo electrónico indicada.
send_request_to_sms string Enviar el enlace de Secret Request creado al número de teléfono indicado.
send_to_email string Envía el enlace secreto creado mediante la solicitud de secreto a la dirección de correo electrónico indicada.
secret_description string Descripción del secreto creado mediante la solicitud de secreto.
secret_message string Para el Secreto creado mediante la Solicitud de Secreto.
secret_expiration integer Tiempo de expiración para el Secreto creado usando la Solicitud de Secreto, en horas.
secret_password string Contraseña para el Secret creado usando el Secret Request.
secret_max_views integer Límite de vistas para el Secreto creado mediante la Solicitud de Secreto.
template_id string ID de la plantilla de solicitud que se usará.
secret_allowed_emails string Direcciones de correo o dominios separados por comas con permiso para abrir Secrets creados con este Secret Request.
secret_allowed_ips string Direcciones IP o rangos CIDR separados por comas con permiso para abrir Secrets creados con este Secret Request.

Ejemplo de solicitud

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}'

Ejemplo de respuesta

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
  }
}

Lista de peticiones secretas

GET /api/secret_requests Clave API privada

Obtiene una lista de solicitudes de secreto. Devuelve 200 OK si tiene éxito.

La cantidad máxima de resultados devueltos por cada consulta está limitada a 50. Puede controlar el desplazamiento con el parámetro de consulta opcional offset, por ejemplo: /api/secret_requests?offset=50

La respuesta de la lista no incluye secret_allowed_emails ni secret_allowed_ips.

Ejemplo de solicitud

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

Ejemplo de respuesta

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
  }
}

Borrar solicitud secreta

DELETE /api/secret_requests/<id> Clave API privada

Elimina una solicitud de secreto. Devuelve 200 OK si tiene éxito.

Ejemplo de solicitud

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