Documentação da API

Uma API REST para criar, ver e gerir segredos. Todos os pedidos e respostas utilizam JSON, e toda a encriptação e desencriptação acontece do seu lado, pelo que o texto em claro nunca chega aos nossos servidores.

Visão geral

O URL base para todos os endpoints da API é:

URL
https://password.link/api

Pode utilizar a API para tratar a encriptação e a desencriptação do segredo fora do nosso serviço, sem precisar de carregar quaisquer activos nossos. Também lhe permite utilizar qualquer tipo de método de entrega para a parte da palavra-passe pública (metade da palavra-passe que é utilizada para derivar a chave de encriptação do segredo) e, basicamente, criar qualquer tipo de configuração personalizada para visualizar o segredo.

Para código completo e funcional, consulte os Exemplos de API.

Autenticação

Cada pedido deve ser autenticado com uma chave de API, enviada no cabeçalho Authorization:

HTTP
Authorization: ApiKey public_key_abcd...

Existem dois tipos de chaves de API:

Tipo de chave Descrição
Chave de API pública Destinada à criação de uma página personalizada e autoalojada para ver segredos. Pode ser utilizada em scripts públicos. Apenas permite ver e confirmar segredos.
Chave de API privada Necessária para todas as outras ações da API. Deve ser sempre mantida privada.

Ambas as chaves API contêm o tipo da chave na própria chave para que possam ser facilmente distinguidas.

Cada endpoint abaixo mostra o tipo de chave que requer.

Erros

Quando um pedido falha, a resposta contém um objeto de erro:

JSON
{
  "data": null,
  "metadata": null,
  "error": {
    "message": "Ciphertext can't be blank",
    "field": "ciphertext"
  }
}
Campo Descrição
message A mensagem de erro completa.
field O campo a que o erro se refere, quando se trata de um erro de validação.

O código de estado HTTP da resposta também indica o tipo de erro:

Código de estado Descrição
403 Forbidden O pedido não foi permitido, por exemplo devido a uma chave de API inválida.
404 Not Found O recurso solicitado não foi encontrado.
422 Unprocessable Content O pedido foi compreendido mas falhou a validação, por exemplo devido a um parâmetro em falta ou inválido.

Encriptação de segredos

Os segredos são encriptados no lado do cliente antes de serem enviados para a API. Esta secção descreve os formatos de palavra-passe e de texto cifrado que o serviço espera.

As partes da palavra-passe

A palavra-passe que é utilizada para encriptar o segredo no AES deve consistir em duas cadeias de 18 caracteres. A chave de encriptação real será a concatenação destas duas cadeias ("parte privada" + "parte pública") e é derivada da palavra-passe utilizando o PBKDF2.

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

A parte privada é enviada para a API (codificada em Base64) e armazenada com o segredo. A parte pública nunca é enviada para a API e normalmente é entregue no próprio link, pelo que nós nunca podemos desencriptar o segredo.

Se utilizar a página de visualização do segredo fornecida por nós, também deve codificar a parte pública em Base64. Se utilizar uma página de visualização autoalojada, pode usar o mesmo método ou criar o seu próprio. Consulte os Exemplos de API para implementações de referência.

Formato do texto cifrado

O texto cifrado é um objeto JSON, codificado em Base64:

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

Deve utilizar as seguintes definições para o AES ao encriptar o segredo:

Definição Valor
Modo AES-GCM com uma etiqueta de autenticação de 128 bits anexada ao texto cifrado (predefinição do Web Crypto)
Tamanho da chave 256 bits
Derivação da chave PBKDF2 com SHA-256
Iterações PBKDF2 O valor do campo iter. Intervalo permitido 1000-1000000, recomendamos 10000.
Vetor de inicialização 12 bytes aleatórios
Salt 16 bytes aleatórios

Formato SJCL legado (obsoleto)

Os textos cifrados criados com a Stanford Javascript Crypto Library (SJCL) continuam a ser aceites: uma cadeia JSON de texto cifrado compatível com SJCL codificada em Base64, utilizando AES-GCM ("mode:gcm"), uma chave de 256 bits ("ks:256") e 10000 iterações PBKDF2 ("iter:10000"). Este formato está obsoleto e o seu suporte será removido no futuro.

Desencriptação de segredos

A API Ver segredo devolve o texto cifrado exatamente como foi armazenado. Os segredos criados na aplicação web utilizam o formato Web Crypto descrito acima. Os segredos criados por clientes da API mais antigos, pela extensão do Chrome ou por ligações ainda não abertas podem utilizar o formato SJCL legado.

Uma página de visualização autoalojada tem de suportar ambos os formatos. Depois de descodificar o texto cifrado de Base64 para JSON, verifique se existe uma chave ct: se estiver presente, desencripte com SJCL; caso contrário, desencripte com Web Crypto. Consulte o exemplo Ver segredo.

Os clientes da API que apenas criam segredos não precisam de alterações: os textos cifrados SJCL continuam a ser aceites na criação. Os clientes que desencriptam segredos obtidos da API têm de adicionar suporte para Web Crypto, caso contrário falharão nos segredos criados na aplicação web.

Criar segredo

POST /api/secrets Chave de API privada

Cria um segredo encriptado e devolve o seu ID. O texto cifrado deve ser criado conforme descrito em Encriptação de segredos. Devolve 201 Created em caso de sucesso.

Parâmetros do pedido

Parâmetro Tipo Descrição
ciphertextobrigatório string Uma cadeia JSON de texto cifrado do segredo compatível com Web Crypto, codificada em Base64. Também são aceites textos cifrados antigos compatíveis com SJCL (obsoleto).
password_part_privateobrigatório string A parte privada da palavra-passe que foi utilizada para encriptar o segredo, codificada em Base64.
password_part_public string A parte pública da palavra-passe, codificada em Base64. Necessária apenas quando se utiliza email_to para que a API possa enviar por email o link alojado do segredo.
description string Uma descrição para o segredo. Não pode ser vista ao visualizar o segredo.
message string Uma mensagem para o segredo. Será mostrada juntamente com o segredo.
expiration integer Um tempo de expiração para o segredo, em horas. Valores possíveis: 1-500.
view_button boolean Mostrar um botão para ver o segredo em vez de mostrar o segredo imediatamente após abrir o link.
captcha boolean Mostrar um CAPTCHA simples antes de mostrar o segredo, principalmente para bloquear scanners automatizados.
password string Uma palavra-passe para o segredo.
max_views integer Quantas vezes o segredo pode ser visto. Valores possíveis: 1-100.
email_to string Destinatários de email separados por vírgulas que devem receber o link do segredo criado. Requer password_part_public.
otp_email_recipient string Endereço de e-mail que recebe uma palavra-passe de utilização única. Quando definido, o destinatário deve introduzir o código enviado por e-mail antes de poder ver o Secret.
otp_recipient string Aceite como alias de otp_email_recipient. Prefira otp_email_recipient para novas integrações.
otp_sms_recipient string Número de telefone que recebe uma palavra-passe de utilização única por SMS, em formato internacional começando com + e sem espaços.
allowed_ips string Endereços IP ou intervalos CIDR separados por vírgulas autorizados a ver o Secret.
allowed_locations array Array de códigos de país ISO 3166-1 alfa-2 autorizados a ver o Secret.
available_after datetime Data e hora antes das quais o Secret não pode ser visualizado.
secret_folder_id string ID de uma pasta de Secrets existente pertencente ao utilizador da chave API.
reply_enabled boolean Ativar uma resposta de utilização única do destinatário depois de o Secret ter sido visualizado.
ack_required boolean Exigir confirmação do destinatário antes de o Secret poder ser visualizado.
ack_mode string Modo de confirmação. Use checkbox ou phrase.
ack_phrase string Frase que o destinatário deve escrever. Obrigatória quando ack_required é true e ack_mode é phrase.
ack_disclosure_text string Texto de divulgação mostrado ao destinatário, até 500 caracteres.
ack_collect_name boolean recolher o nome do destinatário com a confirmação.
ack_name_required boolean Exigir o nome do destinatário. Isto também ativa ack_collect_name.
ack_collect_org boolean recolher a organização do destinatário com a confirmação.
attachment object Metadados para um anexo de ficheiro encriptado, consulte Anexos. Requer um plano ativo.
attachment.file_name string O nome original do arquivo mostrado ao destinatário. Obrigatório quando é fornecido um anexo.
attachment.file_type string O tipo MIME original, por exemplo text/plain ou application/pdf. Obrigatório quando é fornecido um anexo.
attachment.file_size integer O tamanho original não criptografado do arquivo em bytes. Obrigatório quando é fornecido um anexo.

As Definições de Secrets da Equipa podem desativar, exigir ou impor predefinições para opções de Secret suportadas. A API aplica essas regras da equipa ao criar um Secret.

Exemplo de pedido

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

Exemplo de resposta

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

O link para o segredo é formado combinando o URL da página de visualização alojada, o ID do segredo e a parte pública da palavra-passe codificada em Base64:

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

Anexos

O carregamento de um anexo é um processo de dois passos: primeiro crie o segredo com os metadados do anexo (consulte Criar segredo), depois encripte e carregue o payload encriptado do anexo para o URL de carregamento devolvido.

O conteúdo do segredo e o conteúdo do anexo são criptografados separadamente. Ambos utilizam dados AES-GCM compatíveis com Web Crypto, codificados em Base64, mas os campos do payload são codificados de forma diferente: o payload do segredo contém campos codificados em Base64 e um campo iter, enquanto o payload do anexo contém campos de cadeias binárias em bruto.

Encriptação do anexo

Antes da criptografia, represente o arquivo como uma URL de dados:

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

A palavra-passe de encriptação do anexo é a parte privada em bruto da palavra-passe concatenada com a parte pública em bruto (sem codificação Base64).

Encripte essa cadeia data URL com AES-GCM usando PBKDF2-SHA256, 10000 iterações, uma chave derivada de 256 bits, um salt aleatório de 16 bytes e um IV aleatório de 12 bytes. Guarde o payload encriptado do anexo como um objeto JSON e depois codifique a cadeia JSON em Base64:

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

Carregamento do ficheiro encriptado

Quando é incluído um anexo, a resposta de criação do segredo contém um destino de carregamento em data.attachment.upload:

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

Carregue o JSON encriptado codificado em Base64 como text/plain usando multipart/form-data para o upload.url devolvido. Adicione todos os pares chave/valor devolvidos em upload.metadata ou upload.fields aos dados do formulário antes de adicionar o ficheiro encriptado. O campo do ficheiro encriptado deve chamar-se file.

Para URLs de upload da Password.link, inclua a mesma chave de API privada no cabeçalho Authorization: ApiKey <key>. URLs de upload direto para armazenamento, como URLs S3 pré-assinadas, devem receber apenas os campos de formulário retornados e o campo file criptografado.

URLs de upload hospedadas no Password.link incluem um objeto fields vazio. URLs de upload direto para armazenamento, como URLs S3 pré-assinadas, retornam os campos de assinatura em metadata.

Os limites de tamanho dos anexos dependem da quota da conta ou da equipa, e o carregamento encriptado é maior do que o ficheiro original porque o ficheiro é convertido em Base64 e encriptado.

Ver segredo

GET /api/secrets/<id> Chave de API pública

Obtém o texto cifrado, a parte privada da palavra-passe e outros detalhes de um segredo. Este endpoint pode ser utilizado para criar uma página personalizada e autoalojada para ver o segredo que não carrega scripts nem outros recursos do nosso serviço. Devolve 200 OK em caso de sucesso.

A obtenção bem sucedida de um segredo marca-o automaticamente como visualizado e, assim, elimina o texto cifrado e a parte da palavra-passe privada da nossa base de dados, tornando impossível visualizar novamente o segredo.

O texto cifrado pode estar no formato Web Crypto ou no formato SJCL legado. Detete os payloads SJCL pela presença de uma chave ct no JSON descodificado. Consulte Desencriptação de segredos.

Exemplo de pedido

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

Exemplo de resposta

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 Chave de API pública

Envia a confirmação do destinatário para um segredo criado com ack_required e devolve os mesmos dados do segredo que View Secret quando a confirmação é válida. Devolve 200 OK em caso de sucesso.

Se for necessária confirmação, GET /api/secrets/<id> devolve 403 Forbidden com secret_status definido como ack_required até que este endpoint seja utilizado.

Os payloads de confirmação inválidos ou incompletos também devolvem 403 Forbidden. Não são devolvidos como erros de validação.

Parâmetros do pedido

Parâmetro Tipo Descrição
ack_confirmed boolean Definir como true para a confirmação por caixa de seleção.
ack_phrase string Necessário para confirmação por frase, e deve corresponder à frase configurada para o Secret.
ack_signer_name string Nome do destinatário, necessário quando a recolha de nome está ativada e marcada como obrigatória.
ack_signer_org string Organização do destinatário, guardada quando a recolha de organização está ativada.

Exemplo de pedido

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

Segredos da lista

GET /api/secrets Chave de API privada

Obtém uma lista de segredos. Não contém os textos cifrados nem as partes privadas das palavras-passe, apenas IDs, descrições e semelhantes. Devolve 200 OK em caso de sucesso.

A quantidade máxima de resultados devolvidos por cada consulta está limitada a 50. Pode controlar o offset com o parâmetro de consulta opcional offset, por exemplo: /api/secrets?offset=50

Exemplo de pedido

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

Exemplo de resposta

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

Atualizar Secret

PATCH /api/secrets/<id> Chave de API privada

Atualiza as definições e os metadados suportados de um segredo existente. Devolve 204 No Content em caso de sucesso.

PATCH não substitui o conteúdo encriptado do segredo, não reenvia emails de entrega nem cria metadados de carregamento de anexos. Use Create Secret para o texto cifrado, as partes da palavra-passe, a entrega do link e os anexos.

Os seguintes parâmetros podem ser atualizados, com o mesmo significado que em 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 e os metadados de anexos só podem ser definidos na criação. São ignorados pelo PATCH.

Exemplo de pedido

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

Eliminar segredo

DELETE /api/secrets/<id> Chave de API privada

Elimina um segredo. Devolve 200 OK em caso de sucesso.

Exemplo de pedido

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

Exemplo de resposta

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

Criar pasta de Secrets

POST /api/secret_folders Chave de API privada

Cria uma pasta de segredos. Devolve 201 Created em caso de sucesso.

Parâmetros do pedido

Parâmetro Tipo Descrição
nameobrigatório string Nome da pasta.
description string Descrição da pasta.

Exemplo de resposta

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 pastas de Secrets

GET /api/secret_folders Chave de API privada

Obtém uma lista de pastas de segredos. Devolve 200 OK em caso de sucesso.

Exemplo de resposta

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

Atualizar pasta de Secrets

PATCH /api/secret_folders/<id> Chave de API privada

Atualiza o nome e a descrição de uma pasta de segredos. Aceita os mesmos parâmetros que Create Secret Folder e devolve 204 No Content em caso de sucesso.

Eliminar a pasta secreta

DELETE /api/secret_folders/<id> Chave de API privada

Elimina uma pasta de segredos. Devolve 200 OK em caso de sucesso.

Criar pedido secreto

POST /api/secret_requests Chave de API privada

Cria um novo pedido de segredo. Devolve 201 Created em caso de sucesso.

Parâmetros do pedido

Parâmetro Tipo Descrição
description string Descrição do pedido secreto.
message string Mensagem para o visualizador do Pedido Secreto.
expiration integer Tempo de expiração do Pedido Secreto, em horas.
limit integer Limite de utilização do pedido secreto.
send_request_to_email string Envia a ligação do Pedido Secreto criada para o endereço de correio eletrónico indicado.
send_request_to_sms string Enviar a ligação do Secret Request criado para o número de telefone indicado.
send_to_email string Envia a ligação secreta criada utilizando o Pedido de Segredo para o endereço de correio eletrónico indicado.
secret_description string Descrição para o Segredo criado utilizando o Pedido de Segredo.
secret_message string Mensagem para o Segredo criado utilizando o Pedido de Segredo.
secret_expiration integer Tempo de expiração para o Segredo criado utilizando o Pedido de Segredo, em horas.
secret_password string Palavra-passe para o Secret criado usando o Secret Request.
secret_max_views integer Limite de visualização para o Segredo criado utilizando o Pedido de Segredo.
template_id string ID do modelo de pedido a usar.
secret_allowed_emails string Endereços de e-mail ou domínios separados por vírgulas autorizados a abrir Secrets criados com este Secret Request.
secret_allowed_ips string Endereços IP ou intervalos CIDR separados por vírgulas autorizados a abrir Secrets criados com este Secret Request.

Exemplo de pedido

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

Exemplo de resposta

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 Pedidos secretos

GET /api/secret_requests Chave de API privada

Obtém uma lista de pedidos de segredo. Devolve 200 OK em caso de sucesso.

A quantidade máxima de resultados devolvidos por cada consulta está limitada a 50. Pode controlar o offset com o parâmetro de consulta opcional offset, por exemplo: /api/secret_requests?offset=50

A resposta da lista não inclui secret_allowed_emails nem secret_allowed_ips.

Exemplo de pedido

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

Exemplo de resposta

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

Pedido de eliminação de segredo

DELETE /api/secret_requests/<id> Chave de API privada

Elimina um pedido de segredo. Devolve 200 OK em caso de sucesso.

Exemplo de pedido

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