Skip to content
OpenTrain AIOpenTrain AIOpenTrain AIDocs

Ask OpenTrain

Answers from the documentation, with sources.

What would you like to do with OpenTrain?

AI answers can be mistaken. Check the linked sources. Don’t include private account information.

Open app

DEVELOPER DOCUMENTATION

Send Message

Send a plain-text message into an existing conversation you participate in.

POST/api/public/v1/messages

Sends a plain-text message into an existing conversation you participate in. The same membership, rate-limit, and content-policy checks as the in-app messaging flow apply. This endpoint never creates conversations — get a conversationId from GET /messages or by starting a proposal thread.

Requirements: messages:write scope + the public_api_messaging_writes feature + a claimed account (unclaimed accounts get 403 with details.reason: "account_claim_required" and a claimUrl).

conversationIdstringbodyrequired

Existing conversation you participate in.

contentstringbodyrequired

Plain-text message, 1–10,000 characters.

Returns 201 on success.

okboolean

true on success.

messageobject

The created message, in the same shape as the message entries on GET /messages: {id, createdAt, updatedAt, conversationId, jobId, senderUserId, isFromViewer, content, messageType, system, hasUnreadFlag, attachmentCount, hasAudio, editedAt, reactionCount}.

StatuscodeMeaning
400BAD_REQUESTEmpty body, invalid JSON, or invalid fields (details.issues carries zod details — e.g. content empty or over 10,000 chars)
401UNAUTHORIZEDMissing or invalid token
403FORBIDDENMissing messages:write scope, feature disabled, account not claimed (details.reason: "account_claim_required", details.claimUrl), not a participant in the conversation, or content blocked by policy (details.reason: "message_policy_blocked" with details.policy)
404NOT_FOUNDNo such conversation
409CONFLICTSend blocked — details.reason is employer_first_message_required (candidate replying before the employer’s first message), read_only_conversation, or message_blocked
429RATE_LIMITEDMessaging rate limit hit — retry after details.retryAfterSeconds