Message Token

This token represents a direct message sent from one profile to another.

A message token enables private, one-on-one communication between users. Unlike posts (which are broadcast to followers), messages are sent directly to a specific recipient and are not federated to other instances.

The token must contain an audience (aud) field pointing to the recipient of the message. For other constraints see the Action Tokens.

Content-Addressing

This token is content-addressed using SHA-256:

Attachments

The a (attachments) field can contain file references:

  • Each entry is a file_id (f1~...)
  • File IDs are content-addressed (SHA256 of file descriptor)
  • Files contain multiple variants (different resolutions)
  • See File Storage for details

Parent Reference

The optional p (parent) field enables message threading:

  • Contains the parent message’s action_id (a1~...)
  • Creates conversation threads and reply chains
  • Parent must exist and be verified

Database Key

The database key for a message token is [iss, t, id]

Purpose: Each message has a unique ID, allowing multiple messages in a conversation thread. The key includes the action ID itself, so messages are never overridden.

Message Types

Simple Text Message

Basic text communication:

{
  "iss": "alice.example.com",
  "aud": "bob.example.com",
  "iat": 1738483200,
  "k": "20240101",
  "t": "MSG",
  "c": "Hey Bob, want to grab coffee tomorrow?"
}

Message with Attachments

Messages can include files, images, or other attachments:

{
  "iss": "alice.example.com",
  "aud": "bob.example.com",
  "iat": 1738483200,
  "k": "20240101",
  "t": "MSG",
  "c": "Here's the photo from our trip!",
  "a": ["f1~abc123..."]
}

Reply to Message

Threading messages in a conversation:

{
  "iss": "bob.example.com",
  "aud": "alice.example.com",
  "iat": 1738483210,
  "k": "20240101",
  "t": "MSG",
  "p": "a1~xyz789...",
  "c": "Sounds great! How about 10am?"
}

Fields

Field Required Description
iss The identity sending the message
aud The identity receiving the message
iat Timestamp when message was sent
k Key ID used to sign the token
t Token type (always “MSG”)
c Message content (markdown)
p Parent message ID (for threading/replies)
a Attachments (files, images, etc.)
exp Optional expiration (for disappearing messages)

Example

User @alice.example.com sends a message to @bob.example.com:

Field Value
iss alice.example.com
aud bob.example.com
iat 2024-04-13T00:01:10.000Z
k 20240101
t MSG
c Hey Bob! Are you coming to the meetup tonight?

Visibility and Federation

Message tokens are direct actions, meaning they are:

  • Sent only to the specified audience (recipient)
  • NOT broadcast to followers
  • Private between sender and recipient
  • Delivered to POST https://cl-o.{recipient}/api/inbox

Federation Flow

When Alice sends a message to Bob:

  1. Alice’s instance creates a MSG token with aud: bob.example.com
  2. The token is signed by Alice’s private key
  3. The message is sent to https://cl-o.bob.example.com/api/inbox
  4. Bob’s instance verifies the signature
  5. Bob’s instance stores the message for Bob to read
  6. Bob receives a notification (via WebSocket bus or push notification)

Permission Checks

When receiving a message token:

  1. Verify signature: Ensure the token is signed by the claimed issuer
  2. Check audience: Verify aud field matches the local user
  3. Check relationship: Verify sender is connected or followed (configurable)
  4. Spam prevention: Check sender is not blocked
  5. Rate limiting: Enforce message rate limits per sender

Message Delivery

Messages use a different delivery mechanism than broadcast actions:

Aspect Broadcast Actions (POST) Direct Messages (MSG)
Delivery To all followers To specific recipient only
Federation Sent to multiple instances Sent to one instance
Storage Stored publicly (with permissions) Stored privately
Visibility Timeline/feed Message inbox
Retry Best-effort Reliable delivery with retry

Message Threading

Messages can be threaded using the parent (p) field:

Message 1 (no parent)
  ├─ Reply 1 (p: Message 1)
  ├─ Reply 2 (p: Message 1)
  │   └─ Reply 3 (p: Reply 2)
  └─ Reply 4 (p: Message 1)

This allows for:

  • Conversation continuity
  • Quote/reply functionality
  • Context preservation

Read Receipts

Read receipts can be implemented using ACK tokens:

{
  "iss": "bob.example.com",
  "aud": "alice.example.com",
  "iat": 1738483220,
  "k": "20240101",
  "t": "ACK",
  "p": "a1~xyz789...",
  "c": "read"
}

This acknowledges that Bob has read Alice’s message.

Encryption (Future)

While action tokens are already signed for authentication, end-to-end encryption of message content is a planned feature:

  • Message content (c field) encrypted with recipient’s public key
  • Only sender and recipient can decrypt
  • Server cannot read message content
  • Forward secrecy with ephemeral keys

Message Storage

Messages are stored in MetaAdapter with:

  • Sender and recipient identity tags
  • Read/unread status
  • Delivery status
  • Optional expiration timestamp

Privacy considerations:

  • Messages stored locally at sender and recipient instances
  • Not replicated to other instances
  • Can be deleted by either party
  • Retention policies configurable per user

Notifications

New messages trigger notifications via:

  1. WebSocket Bus: Real-time notification if recipient is online
  2. Push Notifications: If configured and recipient is offline
  3. Email: Optional email notification for important messages

Notification payload includes:

  • Sender identity
  • Message preview (first ~100 characters)
  • Timestamp
  • Attachment indicator

Comparison with Conversations

Feature MSG (Message) CONV (Conversation)
Participants 1-to-1 Group (multiple participants)
Status ✅ Implemented ⚠️ Future/Planned
Use Case Direct messaging Group chats
Audience Single recipient Multiple recipients

See Also

  • Action Tokens - Overview of all action token types
  • Acknowledge Token - For read receipts
  • Conversation Token - For group messaging (future)
  • [Access Control](/architecture/data-layer/access-control/access - Permission checking for messages
  • Federation - How messages federate between instances