room:read

Description: Mark a room as read up to a specific timestamp.

This endpoint marks comments in a room as read for the authenticated person. Comments created after the provided timestamp remain unread, enabling precise control over read state without losing track of genuinely new messages.

If no timestamp is provided, all comments up to the current time are marked as read.


Request Schema

{
  "payload": {
    "type": "room:read",
    "room_id": 9415,
    "read_at": "2026-04-15T15:38:28Z"
  },
  "signature": "payload_ed25519_hex_signature",
  "source_public_key": "your_client_public_key"
}

Request Attributes

Field Type Required Default Description
room_id Integer Yes - The unique identifier of the room to mark as read
read_at String No Current time ISO 8601 timestamp up to which comments are marked as read. Comments after this time remain unread.

Authentication Behavior

This endpoint follows Pattern A: Full Account Access.

All authentication methods can mark rooms as read, but only rooms where the authenticated person is a participant or creator can be accessed.

Error Handling

The read operation is processed asynchronously. Check the message status for errors:

  • Record not found: Room does not exist or is not accessible to the authenticated person
  • Validation failed: Invalid room_id or read_at format
  • Authorization failed: Person is not a participant in the room
  • General error: Unexpected processing error

Message status will be set to failed with error details in these cases.

Response Schema

{
  "source_public_key": "community_public_key",
  "source_site": {
    "protocol": "https",
    "fqdn": "arkipel.localhost:3000"
  },
  "created_at": "2025-04-15T15:38:30Z",
  "signature": "8b6392d5550605bd6ccddf9c21ebec470de4b44e4b4deb746076e37ab61c5346e07e7c7c7cebb5bbee41cdd92a476bcd3f02373d146ec165b31c31fc31c9ce0d",
  "payload": {
    "message_id": "6916452112f746b2b4cf48c1",
    "type": "room:read",
    "room_id": 9415,
    "read_at": "2026-04-15T15:38:28Z",
    "unread_count_before": 3,
    "unread_count_after": 0,
    "comments_marked_as_read": 3
  }
}

Response Attributes

  • payload.message_id - String - The unique identifier for the async processing message. Use this to check the processing status.
  • payload.type - String - Always “room:read”
  • payload.room_id - Integer - The ID of the room that was marked as read
  • payload.read_at - String - The timestamp up to which comments were marked as read
  • payload.unread_count_before - Integer - The number of unread comments before this operation
  • payload.unread_count_after - Integer - The number of unread comments remaining after this operation
  • payload.comments_marked_as_read - Integer - The number of comments actually marked as read

Processing Status

After receiving the response, poll the message status using the message_id to determine if the read operation succeeded:

  • queued - Message is waiting to be processed
  • processing - Message is currently being processed
  • persisted - Room was successfully marked as read
  • failed - An error occurred (check error details)

Real Life Examples

Mark all comments as read (up to current time)

{
  "type": "room:read",
  "room_id": 9415
}

Mark comments as read up to specific timestamp

{
  "type": "room:read",
  "room_id": 9415,
  "read_at": "2026-04-15T15:38:28Z"
}

This marks all comments posted at or before 2026-04-15T15:38:28Z as read. Any comments posted after that timestamp remain unread.

Error Responses

Room Not Found

{
  "source_public_key": "community_public_key",
  "source_site": {
    "protocol": "https",
    "fqdn": "arkipel.localhost:3000"
  },
  "created_at": "2025-04-15T15:38:30Z",
  "signature": "...",
  "payload": {
    "type": "room:read",
    "room_id": 99999
  },
  "error": "Room not found with id: 99999",
  "status": "not_found"
}

Not a Participant (Forbidden)

{
  "source_public_key": "community_public_key",
  "source_site": {
    "protocol": "https",
    "fqdn": "arkipel.localhost:3000"
  },
  "created_at": "2025-04-15T15:38:30Z",
  "signature": "...",
  "payload": {
    "type": "room:read",
    "room_id": 123
  },
  "error": "Forbidden: You are not a participant in this room",
  "status": "forbidden"
}

Missing Room ID

{
  "source_public_key": "community_public_key",
  "source_site": {
    "protocol": "https",
    "fqdn": "arkipel.localhost:3000"
  },
  "created_at": "2025-04-15T15:38:30Z",
  "signature": "...",
  "payload": {
    "type": "room:read"
  },
  "error": "Missing required field: room_id",
  "status": "bad_request"
}

Invalid Timestamp Format

{
  "source_public_key": "community_public_key",
  "source_site": {
    "protocol": "https",
    "fqdn": "arkipel.localhost:3000"
  },
  "created_at": "2025-04-15T15:38:30Z",
  "signature": "...",
  "payload": {
    "type": "room:read",
    "room_id": 123,
    "read_at": "invalid-timestamp"
  },
  "error": "Invalid timestamp format for 'read_at'. Use ISO 8601 format (e.g., 2026-04-15T15:38:28Z)",
  "status": "bad_request"
}

Usage Notes

  • This is a persistent mutation - a message is created and processed asynchronously
  • The read_at timestamp enables partial read scenarios (e.g., “I read up to this point, but anything after is new”)
  • If read_at is not provided, all existing comments in the room are marked as read
  • You must be a participant in the room to mark it as read
  • Marking a room as read also marks all notifications for that room as read
  • The comments_marked_as_read count in the response reflects how many comments were actually affected
  • Use this endpoint in combination with inbox:query to build a complete inbox workflow:
    1. Query inbox to get unread rooms and comments
    2. Display comments to the user
    3. Call room:read when user has “read” the comments
    4. Re-query inbox to refresh the view

Back to top

Welcome to the Arkipel DevKit! This documentation will guide you through everything you need to build clients for Arkipel communities.

Contact: devkit@arkipel.co | Page URLs

Copyright © 2026 Arkipel. Distributed under an MIT license.