1.10. Mailbox RESTful API#

This is the API documentation for the GNU Taler Mailbox service which allows Taler wallets to securely send push and pull payment requests to other wallets without having to interact with the respective messaging service.

Clients (wallets) are expected to generate mailbox keys that uniquely identify a mailbox as well as encryption keys that can be used to encrypt messages for the mailbox (e.g. HPKE. Mailboxes must be registered along with their public key information. Registration may incur costs depending on the mailbox service provider used.

The API specified here follows the general conventions for all details not specified in the individual requests. The glossary defines all specific terms used in this section.

1.10.1. Terms of service API#

These APIs allow clients to obtain the terms of service and the privacy policy of a service.

GET /terms#

Get the terms of service of the service. The endpoint will consider the “Accept” and “Accept-Language” and “Accept-Encoding” headers when generating a response. Specifically, it will try to find a response with an acceptable mime-type, then pick the version in the most preferred language of the user, and finally apply compression if that is allowed by the client and deemed beneficial.

The endpoint will set an “Etag”, and subsequent requests of the same client should provide the tag in an “If-None-Match” header to detect if the terms of service have changed. If not, a “304 Not Modified” response will be returned. Note that the “304 Not Modified” will also be returned if the client changed the “Accept-Language” or “Accept-Encoding” header. Thus, if the client would like to download the resource in a different language or format, the “If-None-Match” header must be omitted.

If the “Etag” is missing, the client should not cache the response and instead prompt the user again at the next opportunity. This is usually only the case if the terms of service were not configured correctly.

The “Etag” is generated from the first 256 bits of the SHA-512 hash over the terms and encoded in Crockford base-32. However, this behavior is not normative and clients MUST NOT rely on it.

A “Taler-Terms-Version” header is generated to indicate the legal version of the terms. This header will change whenever something legally changed in the terms of service and the user must review and accept the terms of service again. If the “Taler-Terms-Version” is identical to one that the user has already accepted, there is no need for the user to review the terms again.

When returning a full response (not a “304 Not Modified”), the server should also include a “Avail-Languages” header which includes a comma-separated list of the languages in which the terms of service are available in (see availability hints specification). Clients can use this to generate a language switcher for users that may not have expressed a proper language preference.

Response:

200 OK:

The body is the terms of service in the requested encoding and language.

501 Not Implemented:

The exchange lacks a valid terms of service configuration. A human-readable error message is returned. Wallets should not require the human to accept any terms of service (and do not need to show this message).

GET /privacy#

Get the privacy policy of the service. Behaves the same way as The “/terms” endpoint, except that it returns the privacy policy instead of the terms of service.

Response:

200 OK:

The body is the privacy policy in the requested encoding and language.

501 Not Implemented:

The exchange lacks a valid terms of service configuration. A human-readable error message is returned. Wallets should not require the human to accept any terms of service (and do not need to show this message).

1.10.2. Configuration information#

GET /config#

Return the protocol version and currency supported by this service.

Response:

200 OK:

The body is a VersionResponse.

Details:

interface VersionResponse {
  // libtool-style representation of the Merchant protocol version, see
  // https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning
  // The format is "current:revision:age".
  version: string;

  // Name of the protocol.
  name: "taler-mailbox";

  // Fee per message.
  message_fee: Amount;

  // Fixed size of message body.
  message_body_bytes: Integer;

  // Maximum number of messages in a
  // single response.
  message_response_limit: Integer;

  // How long will the service store a message
  // before giving up on delivery?
  delivery_period: RelativeTime;

  // How much is the cost of a single
  // registration (update) of a mailbox
  // May be 0 for a free update/registration.
  registration_update_fee: Amount

  // How much is the cost of a single
  // registration period (30 days) of a mailbox
  // May be 0 for a free registration.
  monthly_fee: Amount

}

1.10.3. Mailbox registration and metadata#

GET /info/$H_MAILBOX#

Endpoint that returns mailbox metadata including signing and encryption keys for $H_MAILBOX.

Response

200 Ok:

Info is returned in a MailboxMetadata response,

404 Not Found:

This mailbox is not registered.

429 Too Many Requests:

The system is currently experiencing a too high request load and is unable to accept the message for delivery. The response format is given by MailboxRateLimitedResponse.

Details:

interface MailboxMetadata {

  // The mailbox signing key.
  // Note that $H_MAILBOX == H(singingKey).
  // Note also how this key cannot be updated
  // as it identifies the mailbox.
  // Base32 crockford-encoded.
  signingKey: string;

  // Type of key.
  // Currently only
  // EdDSA keys are supported.
  signingKeyType: "EdDSA";

  // The mailbox encryption key.
  // This is a HPKE public key
  // Currently, only the X25519 format
  // for use in a X25519-DHKEM (RFC 9180)
  // is supported.
  // Base32 crockford-encoded.
  encryptionKey: string;

  // Type of key.
  // Currently only
  // X25519 keys are supported.
  encryptionKeyType: "X25519";

  // Expiration of this mailbox.
  // Unix epoch (seconds)
  expiration: Timestamp;

}
POST /register#

Requests the registration or update of a mailbox. May be used to update encryption keys. May incur cost. The mailbox identity is given through the keys field in the MailboxMetadata field.

Request

The body of the request must be a MailboxRegistrationRequest.

Details:

interface MailboxRegistrationRequest {

  // Keys to add/update for the mailbox.
  mailbox_metadata: MailboxMetadata;

  // Signature by the mailbox's signing key affirming
  // the update of keys, of purpose
  // TALER_SIGNATURE_MAILBOX_REGISTER.
  // The signature is created over the SHA-512 hash
  // of (encryptionKeyType||encryptionKey||expiration)
  // Base32 crockford-encoded.
  // The signature system is defined through the
  // signingKeyType in the keys field.
  signature: string;

}

Response

204 No Content:

Update/creation complete.

403 Forbidden:

The signature is invalid. This response comes with a standard ErrorDetail response.

402 Payment Required

Client needs to make a Taler payment before proceeding. See standard Taler payment procedure.

1.10.4. Sending messages#

POST /$H_MAILBOX#

Puts a message into $H_MAILBOX. $H_MAILBOX is the SHA512 of an EdDSA public key.

Request

The content of the request must be the message with a size of exactly message_body_bytes (see VersionResponse).

Response

204 No Content

Message was stored and will be delivered.

403 Forbidden

The specified order ID in the Mailbox-Order-Id header does not permit sending of this message. Possible reasons include the order being for a different message, unpaid or malformed. This response comes with a standard ErrorDetail response.

429 Too Many Requests:

The system is currently experiencing a too high request load and is unable to accept the message for delivery. The response format is given by MailboxRateLimitedResponse.

Details:

interface MailboxRateLimitedResponse {

  // Taler error code, TALER_EC_MAILBOX_DELIVERY_RATE_LIMITED.
  code: Integer;

  // When the client should retry.
  retry_delay: RelativeTime;

  // The human readable error message.
  hint: string;

}

1.10.5. Receiving messages#

GET /$H_MAILBOX#

Endpoint that returns unread messages in $H_MAILBOX. The number of messages returned by the service can be limited. If the request is simply repeated, the same messages will be returned again (or possibly more if additional messages arrived and the total number is below the service’s current internal limit). To receive additional messages, the client generally has to first explicitly delete already downloaded messages from the mailbox. If messages are returned, the ETag header will be set containing the ID of the first message for use in any potential delete requests that require the message ID.

Request:

Query Parameters:
  • timeout_ms=NUMBEROptional. If specified, the Mailbox service will wait up to NUMBER milliseconds for the arrival of new messages before sending the HTTP response. Note that if the mailbox is non-empty, the service will always return immediately with the messages in the mailbox, and not wait for additional messages to arrive.

Response

200 Ok:

Messages are returned in binary format, 256 bytes per message, starting with the ephemeral key and followed by the encrypted body. Messages are not encapsulated in JSON!

204 No Content:

The mailbox is empty.

429 Too Many Requests:

The system is currently experiencing a too high request load and is unable to accept the message for delivery. The response format is given by MailboxRateLimitedResponse.

DELETE /$ADDRESS#

Requests the deletion of already received messages from the mailbox. Here, $ADDRESS must be the EdDSA public key of the mailbox (not the hash!). The ETag header returned by a GET request for messages returns the ID for the first message received. This allows the caller to select a range of messages starting from the first message received in the last GET call to delete.

Request

The header Match-If must be set to the ID of the first message to delete. The ETag value is retrieved when receiving messages via a GET request. For example, a Match-If header value of 2 and a count field of 5 will delete messages from ID 2 to N such that up to 5 messages are deleted. The Taler-Mailbox-Delete-Signature header must be set with a Base32-Crockfor encoded signature over four 32 bit values in network byte order: NBO(16)||NBO(TALER_SIGNATURE_MAILBOX_DELETE_MESSAGES)||NBO(Etag)||NBO(count) where TALER_SIGNATURE_MAILBOX_DELETE_MESSAGES is a signature purpose value registered in GANA.

Query Parameters:
  • count=NUMBEROptional. If specified, the Mailbox service will delete up to NUMBER of new messages starting from the ID provided in Match-If. If the parameter is not provided, only a single message will be deleted.

Details:

interface MessageDeletionRequest {

  // Number of messages to delete. (Starting from the beginning
  // of the latest GET response).
  count: Integer;

  // Signature by the mailbox's private key affirming
  // the deletion of the messages, of purpuse
  // TALER_SIGNATURE_MAILBOX_DELETE_MESSAGES.
  signature: string;

}

Response

204 No Content:

Deletion complete.

403 Forbidden:

The signature is invalid. This response comes with a standard ErrorDetail response.

404 Not found:

The checksum does not match the messages currently at the head of the mailbox, or count is larger than the number of messages currently in the mailbox. This response comes with a standard ErrorDetail response.