Terminology

Sender

The client that is performing the sending of an event.

Receiver

The server that is the event being sent to.

Event Group

A group of events.

Message (m)

An event which sends or changes something directly visible in the chat history.

State (s)

A event which changes some metadata.

Schema

A type of data.
The character before the period identifies the event group.
Examples are:
File (m.file)
Text (m.text)

Event Type

The type of an event.
Examples are:
Chat (chat, m group)
Reply (reply, m group)
Nickname Change (nick, s group)
Offline/Online (offline, s group)

Architecture

This protocol supports only direct communication between two users.
Each receiver has to host their own domain, which identifies & authenticates them.
Both people in a conversation are both a sender and a receiver.
The sender shall try to send an event first to the main domain, then to all domains in the fallback list, in the order they were added, oldest to newest. If all fail, assume client is offline until an event is received.

Endpoints

POST /send/{channel}

Send an event.
Replies with the event ID & the sender ID the receiver will use to reply.
JSON.
Template:

{
	"event_id": $EVENT_ID/STRING,
	"sender_id": $EVENT_ID/STRING
}

URL Path Parameters

channel

The channel to send to.
Each user's server can have multiple channels, to allow categorizing communications with a single person.
A channel name is shared between two users.
User A: /send/#main "hi"
User B: /send/#main "hello"
Result on both User A and User B:

#main:
  foo: hi
  bar: hello

Required Headers

Chat-Nickname

The nickname to display for this event.

Chat-Identification

The sender ID specific for this receiver.
Identifies & Authenticates the sender.
RECOMMENDED to use a long randomly generated string.
RECOMMENDED to have a unique one per receiver.

Chat-Reply

The domain of the sender, when the receiver wishes to send an event back.

Chat-Version

The version of this protocol. "v1"

Optional Headers

Chat-Profile-Picture

URL to the profile picture

Chat-Reply-Method

Default is replace
Method to use when a new Chat-Reply arrives.

replace

Replace the old domain

fallback

Append to the fallback list

POST /upload

Upload a file
Replies with the file ID in an url used in a m.file schema.
It is RECOMMENDED to use the sha256sum of the file in this format:
sha256://2eacf675c9154110b34a1e1ed0af64422a50e555cfff9485b25fb6e1eb7f0677

Event Format

JSON.
Template:

{
	"type": $EVENT_TYPE/STRING,
	"schema": $SCHEMA/STRING,
	"content": $CONTENT/STRING
}

content is as-defined in the schema. Different types might introduce additional keys.

Schemas

m.text

{
	"format": $FORMAT/STRING,
	"text": $TEXT/ANY
}

Formats

plain

String. Just plain unicode text.

html

String. HTML code.

m.file

{
	"file_type": $FILE_TYPE/STRING,
	"url": $FILE_URL/STRING
}

Event Types

chat

A classic chat message.
Accepted schemas: m.text, m.file

reply

A chat message replying to an event, quoting it.
Accepted schemas: m.text, m.file

{
	"target": $TARGET/STRING
}

react

A reaction to an event.
UX: Should be a single Unicode character (Usually emoji) that shows under the event it is targetting.
Accepted schemas: m.text

{
	"target": $TARGET/STRING
}

edit

An edit of a previous event.
Accepted schemas: m.text, m.file
If referenced event does not exist, a warning is RECOMMENDED to be logged, and it is RECOMMENDED to display to the user.

{
	"target": $TARGET/STRING
}

nick

A notification that the sender's nickname changed.
RECOMMENDED to send if possible directly on the nickname change.

{
	"target": $TARGET/STRING
}

connection

RECOMMENDED to send if possible directly on the nickname change.

{
	"state": $CON_STATE/STRING
}

States

offline

The user is going offline.
Hold onto sending events until user is online.

online

The user is back online.
Any event marks the user as online, however sending this one is RECOMMENDED.

away

The user's client is online, but the user is not present.

quiet

The user's client is online, but the user wishes to not be disturbed.