Docs: API

Your API key: n/a (you will see your API key after logging in)

API URL: https://api.password.link/v1

The API works over the HTTPS protocol, using the POST request type. All responses are in JSON.

Each API action costs one API unit.

Sections:
List all stored passwords | View details of a password | Storing a Password: encrypt server-side | Storing a Password: encrypt client-side | Errors

List all stored passwords

HTTPS POST parameters:

ParameterDescription
api_keyYour API key. Required.
api_commandSet to "list_all". Required.

Usage example

A simple usage example using the command line tool curl.

curl -X POST -F 'api_key=YOUR_API_KEY' \
-F 'api_command=list_all' https://api.password.link/v1
			

Response example

{"result":"success","password_list":[
{"password_id":"id1","created_at":"2017-01-01 00:00:00"},
{"password_id":"id2","created_at":"2017-01-01 00:00:00"}]}
			

View details of a password

HTTPS POST parameters:

ParameterDescription
api_keyYour API key. Required.
api_commandSet to "get_details". Required.
password_idThe ID of the password in question. Required.

Usage example

A simple usage example using the command line tool curl.

curl -X POST -F 'api_key=YOUR_API_KEY' \
-F 'api_command=get_details' -F 'password_id=ejbV' https://api.password.link/v1
			

Response example

{"result":"success","details":{"password_id":"ejbV",
"created_at":"2017-01-01 00:00:00",
"viewed_at":"2017-01-01 00:00:00","description":description_if_set,
"message":message_if_set,"notify_email":notify_email_if_set,
"callback_url":callback_url_if_set}}
			

Storing a Password: encrypt server-side

HTTPS POST parameters:

ParameterDescription
api_keyYour API key. Required.
api_commandSet to "store". Required.
password_base64The password encoded in Base64. Required.
descriptionDescription for the password. Optional.
notify_emailSend an email notification to this address when the password has been viewed. Optional.
messageA message to be shown along with the password. Optional.
callback_urlSend an HTTPS POST callback to this URL when the password has been viewed. Optional. Please see the Callback URL documentation.

Simply encode the password in Base64 before sending it over to our API. Our servers will properly encrypt it and create the required SJCL compatible ciphertext JSON string. Rest assured that we never store any plaintext passwords on our servers.

Usage example

A simple usage example using the command line tool curl.

curl -X POST -F 'api_key=YOUR_API_KEY' \
-F 'api_command=store' -F 'password_base64=dGVzdA==' https://api.password.link/v1
			

Response example

{"result":"success","password_id":"p0dy","password_part_public":"L0gobkleMFptQCo3V0wwUFNE"}
			

Create a password link using the returned values: https://password.link/p0dy/#L0gobkleMFptQCo3V0wwUFNE

Storing a Password: encrypt client-side

HTTPS POST parameters:

ParameterDescription
api_keyYour API key. Required.
api_commandSet to "store". Required.
ciphertextAn SJCL compatible ciphertext JSON string of the password, encoded in Base64. Required.
password_part_privateThe "private part" of the password used to encrypt the password, encoded in Base64. Required.
descriptionDescription for the password. Optional.
notify_emailSend an email notification to this address when the password has been viewed. Optional.
messageA message to be shown along with the password. Optional.
callback_urlSend an HTTPS POST callback to this URL when the password has been viewed. Optional. Please see the Callback URL documentation.

Encrypting the password client-side before sending it to our API requires creating an SJCL compatible ciphertext JSON string. Please refer to the SJCL documentation for proper format of the JSON string.

Creating the encryption password

The password which is used to encrypt the actual password in AES must consist of two 18 character long strings. The first string, called "private part", is Base64-encoded and sent over to our API and stored into our database, and the second string, called "public part", is Base64-encoded and added into the password link. Use the concatenation of these two strings ("private part"+"public part") as the password for encrypting the password in AES.

EXAMPLE
Password used in AES encryption: fkgjbnvlakwiejgutnFIGKEOTIRUBNAKQJRL
=> Private part: fkgjbnvlakwiejgutn
=> Public part: FIGKEOTIRUBNAKQJRL
			

Required AES settings

You must use the following settings for AES when encrypting the password:

  • Mode: AES-GCM (SJCL setting: "mode:gcm")
  • Key size: 256 bits (SJCL setting: "ks:256")
  • Key derivation function: PBKDF2 (SJCL default)
  • PBKDF2 iterations: min. 1000 (SJCL setting: "iter:1000")

Responses

All responses are in JSON format.

KeyDescription
resultAPI command result. On successful query: "success", on error: "error".
errorOn error, contains an error message. Example: "invalid_query".
password_idOn successful query, the ID of the password. Example: "h3Kq"

Response example

{"result":"success","password_id":"p0dy"}
			

Example in Ruby

Below is an example written in the Ruby language using the Gibberish encryption library:

require "gibberish"
require "net/http"
require "uri"
require "base64"
require "json"
require "securerandom"

# A function to generate a random string with default length of 18 chars
def generate_string(l=18)
	chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
	str = ""
	l.times { str << chars[rand(chars.size)] }
	str
end

# Create the private password part and also it's Base64 encoded version
password_part_private = generate_string(18)
password_part_private_base64 = Base64.strict_encode64(password_part_private)

# Create the public password part and also it's Base64 encoded version
password_part_public = generate_string(18)
password_part_public_base64 = Base64.strict_encode64(password_part_public)

# The full password used for encryption
full_password = password_part_private + password_part_public

# Create the SJCL compatible ciphertext using Gibberish, encode it in Base64
cipher = Gibberish::AES.new(full_password, { "mode": "gcm", "ks": 256, "iter": 1000 })
ciphertext = cipher.encrypt("the_secret_password_to_be_delivered_securely")
ciphertext_base64 = Base64.strict_encode64(ciphertext)

# Send the data over to password.link API
uri = URI.parse("https://api.password.link/v1")
response = Net::HTTP.post_form(uri,
{
	"api_key" => "API_KEY",
	"api_command" => "store",
	"password_part_private" => password_part_private_base64,
	"ciphertext" => ciphertext_base64
})

# Parse the JSON result: print error if it exists,
# otherwise print the full password link
json = JSON.parse(response.body)
if json["result"] == "error"
	print "Error: " + json["error"]
else
	print "Password link: https://password.link/" +
	json["password_id"] +
	"/#" +
	password_part_public_base64
end
			

Errors

All error responses use the following format:

{"result":"error","error":"error_message"}