HomeHelp › Messaging

6. Messaging

Messaging is the single largest subsystem on Ditto Up. Everything you'd expect from a modern messenger is in here — direct messages, group chats, voice messages, translation, scheduling, templates, archives, AI screening — plus a few things you wouldn't, like a reputation tier that controls how many strangers you can DM in a day.

In this section


6.1 Inbox basics

Open the inbox at /messages/. Template inbox.html renders a two-pane layout:

  • Left — list of all conversations (1:1 and group), sorted by most-recent-message first. Each row shows the other party's name (or group name), avatar, last-message preview, time, unread badge.
  • Right — the open conversation, or a "Pick a conversation" placeholder if you haven't selected one yet.

Above the list there are filter tabs: All, Unread, Pinned, Starred, Archived, Labels, Scheduled. Each tab is a stable URL so you can bookmark them.

The unread count badge that appears in the site's top-right corner comes from /messages/unread-count/ — polled every 30 seconds (or pushed via WebSocket when WS_ENABLED is on).


6.2 Starting a new conversation

From the inbox top-right, click + New message (or hit the keyboard shortcut shown in the menu). The modal at /messages/compose/ (compose_modal.html) opens.

  1. Type the recipient's name or email in the search field — autocompletion is powered by /search-users/.
  2. Select one or more recipients (selecting more than one creates a group conversation, see 6.9).
  3. Optionally pick a template from the dropdown — see 6.12 Templates and labels.
  4. Type your first message.
  5. Click Send.

The conversation is created and you are dropped into it.

Stranger-DM rules. Whether you can message a person you've never spoken to before depends on (a) their privacy setting and (b) your reputation tier. See 6.13 AI screening & reputation tiers.


6.3 Sending and receiving messages

Inside an open conversation (/messages/<conversation_id>/, template conversation.html):

  • The scrollback loads the last 50 messages on open and lazy-loads older ones as you scroll up.
  • The composer at the bottom supports text, paste-image, attachments (drag-drop), and emoji picker.
  • Each message you receive is auto-marked read after it's been visible on screen for ~1 second; the system POSTs to /messages/<conversation_id>/read/.
  • The Send button uses /messages/<conversation_id>/reply/ under the hood. Optimistic rendering puts the message in the thread immediately; if the server rejects it you see a red banner and a Retry button.
  • An "is typing…" indicator appears for the other party when they're composing (only when WebSockets are enabled).

You can quote-reply to a specific message by hovering it and clicking the speech-bubble icon.


6.4 Voice messages and on-demand transcription

To send a voice message:

  1. In the composer, hold or click the microphone icon.
  2. Speak — the recorder shows a live waveform.
  3. Release / click again to stop. Preview the audio.
  4. Send. The audio is uploaded to S3 (the same multimedia bucket used for video) and posted via /messages/<conversation_id>/voice/.

Voice messages display as a small audio player with a Transcribe button. Clicking transcribe calls /messages/message/<message_id>/transcribe/, runs AWS Transcribe, and shows the text below the player. Transcription is on-demand to keep costs down.

Voice messages count against the same daily message limit (see 6.13) as text messages.


6.5 Editing, deleting, pinning and starring messages

Hover any message you sent to reveal a small action menu:

Action URL Notes
Edit /messages/message/<message_id>/edit/ Available for ~5 minutes after sending. Edited messages show a small (edited) label.
Delete for me /messages/message/<message_id>/delete-for-me/ Hides the message from your view only; everyone else still sees it.
Delete for all /messages/message/<message_id>/delete-for-all/ Removes the message from everyone's view. Sender or admin only.
Pin /messages/message/<message_id>/pin/ Pins to the top of the conversation. Anyone in the conversation sees pinned messages.
Star /messages/message/<message_id>/star/ Personal bookmark. Only you see your starred set.

Two dedicated lookup pages let you find what you've pinned or starred:

  • /messages/<conversation_id>/pinned/ — every pinned message in this conversation.
  • /messages/starred/ — every starred message you've ever made, across all conversations.

For received messages, only Star, React, Forward and Delete for me are available.


6.6 Reactions and forwarding

6.6.1 Reactions

Hover a message → click the smile icon to drop a quick emoji reaction. Available reactions:

  • 👍 like
  • ❤️ love
  • 😂 laugh
  • 😢 cry
  • 😡 angry
  • 🎉 celebrate

Backend: POST to /messages/message/<message_id>/react/ — same endpoint toggles on/off. List who reacted via /messages/message/<message_id>/reactions/.

6.6.2 Forwarding

Click Forward in the message menu. A modal (forward_modal.html) lets you pick one or more conversations and adds an optional comment. Backend: POST to /messages/message/<message_id>/forward/.

The forwarded message is shown in the destination thread with a Forwarded from <name> label so the new recipient knows where it came from.


6.7 Translation (per-conversation and per-message)

Ditto Up is multilingual. You can translate either a whole conversation or one message at a time.

Action URL Notes
Translate this conversation /messages/<conversation_id>/translate/ Adds a translated rendition under each existing message. The translation language is your account's preferred language (Account → Language) or the browser default. Toggle off to revert.
Translate just this message /messages/message/<message_id>/translate-one/ Inline translation under the single message.

Translations are cached server-side, so re-opening the same conversation tomorrow doesn't re-charge for the same content.


6.8 Scheduled messages

To send a message later — useful for time-zone-respect:

  1. Compose your message normally.
  2. Click the clock icon to the right of the Send button.
  3. Pick a date and time.
  4. Click Schedule.
Action URL
Schedule a message /messages/<conversation_id>/schedule/
List scheduled messages in this conversation /messages/<conversation_id>/scheduled/
Cancel a scheduled message /messages/message/<message_id>/cancel-scheduled/

Scheduled messages stay in your Scheduled tab and convert to real messages when their send time arrives. If you delete the conversation before the send time, the schedule is also cancelled.


6.9 Group conversations

You can have any number of people in a single conversation.

Action URL
Create a group /messages/groups/create/ (create_group_modal.html)
Add a member /messages/groups/<conversation_id>/add-member/
Remove a member /messages/groups/<conversation_id>/remove-member/
Leave the group /messages/groups/<conversation_id>/leave/
Rename the group /messages/groups/<conversation_id>/rename/

Group rules:

  • The creator is automatically the admin. Admins can rename the group, add/remove anyone, and delete-for-all.
  • Non-admins can leave at any time and remove themselves.
  • A group with one remaining member is auto-archived.
  • Visibility-toggle is available on individual messages — you can post a message that's visible to admins only via /messages/message/<message_id>/toggle-visibility/.

6.10 Archiving and exporting

Archived conversations move out of the main inbox but remain searchable.

Action URL
Archive a conversation /messages/<conversation_id>/archive/
Unarchive /messages/<conversation_id>/unarchive/
List archived /messages/archived/
Export as PDF / text /messages/<conversation_id>/export/

Export produces a single PDF with the full thread, sender, timestamp and any voice-message transcripts. Useful for HR records, dispute archiving, or feeding into your own ATS.


6.11 Search inside messages

Three search levels exist — each one a separate URL:

URL Scope
/messages/search/?q=<keyword> Across every conversation you have.
/messages/search/<conversation_id>/?q=<keyword> Inside a single conversation.
/messages/search/advanced/ Advanced filters: date range, sender, has-attachment, voice-only, scheduled, screening status.

Results highlight the matched terms and link straight to the message in context.


6.12 Templates and labels

For recruiters or anyone sending the same type of message often, the platform has templates and labels.

6.12.1 Templates (canned replies)

Action URL
List templates /messages/templates/
Create /messages/templates/create/
Update /messages/templates/<template_id>/update/
Delete /messages/templates/<template_id>/delete/
Insert into composer /messages/templates/<template_id>/use/

Templates support placeholders like {{first_name}}, {{job_title}}, {{business_name}}. When you use a template, the placeholders are auto-filled from the recipient's profile and the open job posting (if any).

6.12.2 Labels (conversation tags)

Labels are coloured tags you stick on conversations to organise your inbox.

Action URL
List labels /messages/labels/
Create /messages/labels/create/
Update /messages/labels/<label_id>/update/
Delete /messages/labels/<label_id>/delete/
Get a conversation's labels /messages/<conversation_id>/labels/
Assign a label /messages/<conversation_id>/labels/assign/
Remove a label /messages/<conversation_id>/labels/remove/

Labels show up as small coloured dots in the inbox list, and you can filter by label using the Labels tab at the top of the inbox.


6.13 AI screening & reputation tiers

To stop spam and harassment, every message between users who have never spoken before is run through a lightweight AI screening before delivery.

The screening has four possible outcomes:

Outcome Effect
Pass Message delivered immediately.
Hold for clarification The message is held; the sender sees "Reviewed by Ditto Up — please add context." The recipient sees nothing yet.
Warn for mismatch Message delivered but flagged. Common for "off-topic for the recipient's profile" messages — e.g. a recruiter pitching a role outside the candidate's stated terms.
Block Message rejected (policy violation).

The recipient can override holds by visiting their Moderation queue at /moderation/ (flagged_messages.html) and clicking Approve or Approve all. Endpoints: /moderation/action/, /moderation/approve-all-held/. The sender can also resolve a hold from their side via /messages/message/<message_id>/resolve-screening/ if they've been asked for clarification.

6.13.1 Reputation tiers

In addition to AI screening, the platform tiers users on a reputation scale to gate stranger-DM volume. View your current tier on /reputation/ (reputation_dashboard.html).

Tier Daily new-stranger DM cap How to reach it
New 3 / day Default for new accounts.
Established 10 / day Verified email + complete profile + 7 days on the platform without flags.
Trusted 30 / day 30 days on the platform + at least one worthwhile signal received from a recipient (see 6.14).
Unlimited No cap Manually granted (sales reps, support staff, premium recruiter plan).

Replies inside an existing conversation are unlimited at every tier.


6.14 Worthwhile signals

Recipients can mark a received message as Worthwhile or Not Worthwhile. This is most often used by candidates after a recruiter pitch:

Action URL Effect
Mark worthwhile /messages/message/<message_id>/worthwhile/ Boosts the sender's reputation.
Mark not worthwhile /messages/message/<message_id>/not-worthwhile/ Lowers reputation; repeated flags can demote tier.
One-click via email /messages/message/<message_id>/worthwhile-email/ Used in notification emails so recipients can flag without opening the site.

The signal feeds back into the reputation tier (6.13) and into the AI screening model.


6.15 Commitments (action items)

Ditto Up auto-detects action items mentioned in conversations — for example "I'll send you the contract by Friday" — and surfaces them as commitments.

URL Purpose
/messages/<conversation_id>/commitments/ Every commitment found in this conversation.
/messages/<conversation_id>/commitments/create/ Manually add a commitment (free text + due date).
/messages/commitment/<commitment_id>/complete/ Mark complete (a check appears next to the source message).
/messages/commitment/<commitment_id>/dismiss/ Hide / mark not-actually-a-commitment.

Commitments roll up into the recipient's daily digest if any are coming due in the next 48 hours.


6.16 AI summaries and reply suggestions

For long threads:

  • /messages/<conversation_id>/summary/ — generates a 3–5 bullet summary of the conversation so far. The output is cached until a new message lands.
  • /messages/<conversation_id>/suggest-reply/ — suggests three short replies to the most-recent inbound message.

Both are opt-in and use the same Claude pipeline as VBQ scoring.


6.17 Online status, unread count, mentions and analytics

Endpoint What it returns
/api/online-status/ Online / away / offline status for a list of user IDs.
/messages/unread-count/ Total unread messages across all conversations (used for the top-bar badge).
/mentions/ Every place someone has @-mentioned you in a message or post.
/messages/analytics/ (Recruiter view) Aggregate delivery / open / response / worthwhile rates for messages you've sent.
/messages/message/<message_id>/info/ Deliveries, reads, reactions for a single message.
/messages/message/<message_id>/interaction/ Quick state check — "has the recipient replied? has the message been read?"

6.18 SMS and email reply paths

You can reply to a Ditto Up conversation from outside the site via two paths:

Path How it works
Email reply When the platform emails you about a new message, you can reply to that email. The system has a unique reply-to address per conversation; the body of your reply is parsed (signatures stripped) and posted as your next message. The endpoint that ingests this is /forward-email/.
SMS reply If you have an active Twilio integration enabled (set on your account), each new-message email also fires an SMS. Replying to that SMS goes through the Twilio webhook at /sms/ and posts as your reply.

Both paths are subject to the same screening and reputation rules as in-site messages.


6.19 Moderation queue (held messages)

Every recipient has a moderation queue for held inbound messages.

URL Purpose
/moderation/ List of held messages awaiting your decision (template flagged_messages.html).
/moderation/action/ POST: approve or dismiss a single held message.
/moderation/approve-all-held/ POST: approve everything currently held.

You can also configure auto-approval rules in /settings/: e.g. "auto-approve messages from anyone whose published VBQ score for my main term is Advanced or higher."


6.20 Privacy settings for messaging

In /candidate-settings and /settings/ you can choose:

Setting Options
Who can DM me Anyone / Anyone with a complete profile / Anyone whose reputation is Established+ / Only people I follow / Nobody.
Hold messages from people without a VBQ video On / off.
Auto-block from a specific user See Section 9 — Account & privacy.
Email me when a message lands Per-tier filters.

The setting "Only people I follow" combined with the screener gives the most aggressive filtering: every other DM is held until you explicitly approve.


Next: 7. Community — posts, reactions, comments, follows and notifications.

Help
How can we help?
Pick one — both reach our team.
FeedbackShare a suggestion or idea Raise a ticketReport a bug or problem