Topics are the foundation of UbSub. It has many ways it can be invoked, including via a HTTP URL. They receive a payload (usually as JSON), and distribute it to all subscriptions that belong to it.

Topics can validate an incoming payload using templates to check if it matches a schema or pre-defined values. They can also translate the payload to another format, and forward it along to its consumers.

Trigger Protocols

These are the protocols supported in triggering a given topic.


  • Async: When invoked, an async topic won't wait for the subscribers to respond before responding to the trigger


The easiest way to trigger a topic is to invoke it via it's http/https endpoint.

Examples urls:

  • Uri:{userId}/{topicNameOrId}
  • Uri:{topicId}

The topic name or id can be used when the user is included. Otherwise the unique topic id needs to be used.

Authorization / Keys

If a key is present on the topic, it also must be passed at the time of invocation. It can be sent in different ways:

  1. Authorization header. eg Authorization: Bearer <mykey>
  2. key query parameter on the url. eg. /event/example/example?key=mykey

Supported Encodings

The event endpoint supports the following data-encoding:

  • Any query parameter, except key (which is reserved for the topic)
  • JSON Body (application/json)
  • URL Form Encoding (application/x-www-form-urlencoded)
  • Multipart form encoding (Small upload files allowed) (multipart/form-data)
  • Plain-text body (Will be encapsulated in body object) (text/plain)


Uploaded values will be expanded in the following way:

  "img": {
    "mimetype": "application/octet-stream",
    "filename": "<filename>",
    "data": "<base64 encoded string>"


# Invoking the URL with cURL
curl -d key=val -d key2=val2{userId}/{topicNameOrId}?key={key}


This is an example response of invoking a topic with 3 subscriptions, each with its own scenario:

    // Response object will be present if response was received
    "response": {
      // Status response of downstream server
      "statusCode": 200,
      "body": {
        // Response body of the downstream
        // Won't exist if there is no body
      "headers": {
        // set of headers returned by the downstream server
        "server": "Apache",
        "content-length": "0",
        "content-type": "text/plain; charset=UTF-8"
    // Identify which subscription this is in response to
    "subscription": {
      "id": "Skj5FH3HZ",
      "topicId": "Byg2kKB3SZ"
    // An error message if any non-2xx was returned or
    // if there was an underlying issue (connection, timeout, etc)
    "error": "Downstream did not return 200, got 404",
    "response": {
      "statusCode": 404,
      "headers": {
        "content-type": "application/json",
        "content-length": "0",
    "subscription": {
      "id": "B1nHumgIZ",
      "topicId": "Byg2kKB3SZ"
    // No response since there was only an error
    "error": "getaddrinfo ENOTFOUND 123asdf 123asdf:80",
    "subscription": {
      "id": "rJ8qq7lI-",
      "topicId": "Byg2kKB3SZ"
    queued: true, // Will be set to true if the event is queued for retry

SMTP (Email)

You can send an email directly to a smtpd server that will route the email to a topic.

The email address format is: <topicId>+<key>

If your topic is keyless, simply leave it off. The + symbol is used to split the topic from the key.

If the body of the email is parseable JSON, it will be turned into JSON, otherwise it will be plain-text body.

Example email full payload:

  "payload": {... payload ... },
  "subject": "Email subject",
  "from": [{


Pixel is intended to use in a tracking-pixel use-case. Any call to the pixel service returns a 1x1 transparent gif (regardless of whether or not the backend call to the router succeeded).

To use, simply add an img tag to your page to hit


If the topic requires a key, you must provide it via a ?key= query param.

In addition, query-params are parsed and passed to the event, so it's helpful for tracking additional info on the pixel. The key param will be stripped.

<!-- Simple pixel -->
<img src="{topicId}">

<!-- Pixel with topic key -->
<img src="{topicId}?key={key}">

<!-- Pixel with additional data -->
<img src="{topicId}?key={key}&location=create-user&source=facebook">


UDP is added for support for IoT devices, and low-level applications that might not support TCP or HTTPS.

Do not confuse the udp:// protocol, below, with the IoT protocol. The latter is secure and encrypted. More details can be found here.

Version 0 (Keyless)

WARNING: The UDPv0 protocol is not secure. Anyone can watch packets over-the-wire, and you are subject to a man-in-the-middle attack. Please use https for better security.

IMPORTANT: Unlike https, UDP does not wait for the payload to be acknowledged or delivered in any way. This method should be considered lossy, but good when performance or compatibility are important factors.

UDP is added for support for and low-level applications.

You can send a payload to a topic in a http-like datagram to port 4000.


KEY def
USER qhy

{"test": "this is my json"}

Only TOPIC is required. A space separates a header from its value. A \n character designates new lines. Similar to HTTP, a blank new-line precedes the body.

Version 2/3 (For IoT)

The specification and details for UDPv3 can be found here.

It provides in additional functionality such as guaranteed-delivery, encryption/security/validation, NAT negotiation, etc.

C++ Implementation for Embedded Platforms


UbSub supports MQTT by proxying through a Eclipse Mosquitto.

Go to mqtt for more information.

WebSockets & SocketIO

You can also send and receive events via WebSockets or SocketIO