HTTP API Reference

Common rules

Example: To get the messages of jane.doe#example.net, access https://kullo.example.net/v1/jane.doe%23example.net/messages.

Sending a Message

Authentication

No authentication required. If you authenticate, you can also post meta and you will get a non-empty response (see below for details).

Post a new message to someone's inbox (without attachments)

This uses a JSON request body just like almost all other API endpoints. If you want to send attachments, you need to use the multipart variant (see below).

Method
POST
Path
/$ADDRESS/messages
Body (reference)
  • keySafe (string, base64-encoded binary)
  • content (string, base64-encoded binary)
Additional body data (only with authentication)
meta (string, base64-encoded binary, optional)

Response (without authentication)

Response (with authentication)

id, lastModified, dateReceived

Post a new message to someone's inbox (with or without attachments)

The body must not contain JSON but be of type multipart/form-data.

Method
POST
Path
/$ADDRESS/messages
Body (reference)
  • keySafe (application/octet-stream)
  • content (application/octet-stream)
  • attachments (application/octet-stream, optional)
Additional body data (only with authentication)
meta (application/octet-stream, optional)

Response: see above

Example

Content-Type: multipart/form-data; boundary=boundary

--boundary
Content-Disposition: form-data; name="keySafe"
Content-Type: application/octet-stream

...binary keySafe...
--boundary
Content-Disposition: form-data; name="content"
Content-Type: application/octet-stream

...binary content...
--boundary
Content-Disposition: form-data; name="meta"
Content-Type: application/octet-stream

...binary meta (optional, only when authenticated)...
--boundary
Content-Disposition: form-data; name="attachments"
Content-Type: application/octet-stream

...binary attachment data (optional)...
--boundary--

Downloading public keys

Authentication

No authentication required.

Get a list of public keys

Method
GET
Path
/$ADDRESS/keys/public
Query parameters
  • date (datetime, optional)
  • type (string, optional)

Response

for each key [with (validFrom <= date + 1d) and (validUntil >= date - 1d)]:
    id, type, pubkey, validFrom, validUntil, revocation

type is one of "enc" or "sig" for encryption or signature; revocation holds a revocation certificate if the key was revoked

Get a public key

Method
GET
Path
/$ADDRESS/keys/public/$ID

Response

id, type, pubkey, validFrom, validUntil, revocation

$ID can be set to latest-enc to retrieve the latest public encryption key

Managing the inbox

Authentication

Method
HTTP Basic Auth
Username
Kullo address
Password
Server Login Key: loginKey

The loginKey must be hex-encoded and lowercase.

Messages

Get a list of messages

Method
GET
Path
/$ADDRESS/messages
Query parameters
  • modifiedAfter (uint64, optional)
  • includeData (bool, optional)

Response (message format reference)

resultsTotal (uint32)
resultsReturned (uint32)
data (array)
    id, lastModified, [deleted, dateReceived, meta, keySafe, content, hasAttachments]

The results are sorted by lastModified in ascending order.

A Kullo server assigns ids in ascending order, so that ids are in the same order as dateReceived. IDs need not be continuous.

Get a message

Method
GET
Path
/$ADDRESS/messages/$ID

Response (message format reference)

id, lastModified, deleted, dateReceived, meta, keySafe, content, hasAttachments

dateReceived is the date and time at which the message was received; meta contains message meta data such as read or done (encrypted symmetrically);

Get attachments for a message

Method
GET
Path
/$ADDRESS/messages/$ID/attachments

Response

200 OK if the message exists and has non-empty attachments. Body:

attachments

In this case, the attachments are not base64 encoded or wrapped in JSON. All of the body is just plain binary data.

404 Not Found if either the message doesn't exist or has no non-empty attachments.

Modify message meta

Method
PATCH
Path
/$ADDRESS/messages/$ID
Query parameters
  • lastModified (uint64)
Body
  • meta (string)

Response

id, lastModified

Delete a message

Method
DELETE
Path
/$ADDRESS/messages/$ID
Query parameters
  • lastModified (uint64)

Response

id, lastModified

Keys

These APIs are currently read-only. This is work in progress.

Get privateDataKey

Method
GET
Path
/$ADDRESS/keys/symm

Response

privateDataKey

Note that the key is encrypted with the master key with algorithm and IV as described in Cryptography.

Get a list of asymmetric key pairs

Method
GET
Path
/$ADDRESS/keys/private
Query parameters
  • date (datetime, optional)
  • type (string, optional)

Response

for each key [with (validFrom <= date + 1d) and (validUntil >= date - 1d)]:
    id, type, pubkey, privkey, validFrom, validUntil, revocation

type is one of "enc" or "sig" for encryption or signature; revocation holds a revocation certificate if the key was revoked

Note that the private keys are encrypted with the master key with algorithm and IV as described in Cryptography.

Get an asymmetric key pair

Method
GET
Path
/$ADDRESS/keys/private/$ID

Response

id, type, pubkey, privkey, validFrom, validUntil, revocation

Note that the private key is encrypted with the master key with algorithm and IV as described in Cryptography.

Account management

Account info

Lets the user access information related to his account.

Method
GET
Path
/$ADDRESS/account/info

Response

settingsLocation, planName, storageQuota, storageUsed

settingsLocation is an (optional) URL of a website where the user can edit server-specific settings. This might be used for notification settings or billing.

planName is the (optional) user-facing name of the plan the user is on.

storageQuota and storageUsed are (optional) integer values that show the amount of storage that is available on the user's plan and the amount that is used by the user's data, measured in bytes.

Example

GET https://kullo.example.com/v1/someuser%23example.com/account/info

{
    "settingsLocation": "https://accounts.example.com/QamMYWfeoEobhyuVDIPOppRHzrQPzsfi",
    "planName": "Free",
    "storageQuota": 1073741824,
    "storageUsed": 42424242
}

User profile data

Get a list of profile entries

Method
GET
Path
/$ADDRESS/profile
Query parameters
  • modifiedAfter (uint64, optional)

Response (reference)

data (array)
    key, value, lastModified

The results are sorted by lastModified in ascending order.

Get a profile entry

Method
GET
Path
/$ADDRESS/profile/$KEY

Response (reference)

key, value, lastModified

key is the unencrypted key as given in the request URL; value is the base64-encoded encrypted value corresponding to the key.

Create or modify a profile entry

Method
PUT
Path
/$ADDRESS/profile/$KEY
Query parameters
  • lastModified (uint64, 0 if the client wants to create the entry)
Body (reference)
  • value (string, base64-encoded encrypted value)

Response

key, lastModified

Registration

See Registration for more information on the registration process.

Authentication

No authentication required.

Registering a user account

Method
POST
Path
/accounts
Body
  • address (string)
  • loginKey (string)
  • privateDataKey (string)
  • keypairEncryption (object with string keys pubkey and privkey)
  • keypairSigning (object with string keys pubkey and privkey)
  • acceptedTerms (string, optional)
  • challenge (object with the following keys, optional): type (string), user (string), timestamp (uint64), text (string), optional: can have more fields, depending on type
  • challengeAuth (string, optional)
  • challengeAnswer (string, optional)

acceptedTerms is the URL of the Terms and Conditions that the user accepted. Only set this if the user actively consented to the given terms. If the field is not present and set to a value accepted by the server, the registration might be denied, according to server policy.

When challenge is set, challengeAuth and challengeAnswer must be set as well.

Response

If no challenge is required or the challenge has been answered correctly:

Response 200 (Ok):

-

If the address is already taken:

Response 409 (Conflict):

-

If challenge is required or challenge answer was not correct:

Response 403 (Forbidden):

challenge, challengeAuth

Push notifications

Please be aware that push notifications in the official Kullo apps are only available to users that use our Kullo server kullo.kullo.net. This is a technical necessity, because the app and server are tightly coupled when implementing Google Cloud Messaging or Apple Push Notifications. You can only implement this in your own apps when combined with your own server. Thus, this section is for informational purposes only.

Authentication

See Managing the inbox.

Adding a new Google Cloud Messaging registration

Method
POST
Path
/$ADDRESS/push/gcm
Body
  • registrationToken (string)
  • environment (string)

environment must be one of "android" or "ios".

Response

Response 200 (Ok):

-

Removing a Google Cloud Messaging registration

Method
DELETE
Path
/$ADDRESS/push/gcm/$REGISTRATION_TOKEN

Response

If the registration token could be found and deleted:

Response 200 (Ok):

-

If the token could not be found:

Response 404 (Not Found):

-