Send a direct message to a user
const url = 'https://chat.work.optidata.cloud/api/users/3f1c9a52-4d7e-4b31-9c02-77a1b6e5d840/chats/messages';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"content":"Can you review the draft today?"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://chat.work.optidata.cloud/api/users/3f1c9a52-4d7e-4b31-9c02-77a1b6e5d840/chats/messages \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "content": "Can you review the draft today?" }'The shortest way to reach a person: send text to a user and let the server find — or create — the private conversation between the two of you. No conversation id needed.
Use POST /chats/{chat}/messages when you need files, mentions, replies
or polls; this operation only carries text.
Authorizations
Section titled “Authorizations”Parameters
Section titled “ Parameters ”Path Parameters
Section titled “Path Parameters”UUID of the user. Read your own from GET /me.
Request Bodyrequired
Section titled “Request Bodyrequired”object
The message text.
Responses
Section titled “ Responses ”The created message, in the send-time serialization
(CreatedMessage): the conversation is embedded under chat, user
is the full user record, and the read-side enrichment fields are absent.
object
The message shape returned by the send endpoints
(POST /chats/{chat}/messages and POST /users/{userUuid}/chats/messages).
It is a different serialization from the Message returned by the read
endpoints: it embeds the whole conversation under chat, serializes user
as the full user record, and omits the read-side enrichment fields
(reactions, meta, is_seen, is_forwarded, is_important,
is_favorite, message_link_id, poll).
object
Author of the message.
The message this one replies to, or null.
Stable identifier of the message.
The client-supplied value that made the send idempotent.
The message text.
The author, serialized as the full user record.
object
Numeric id, used on the conversation and participant routes.
Stable identifier of the user across the Optiwork suite.
Identifier of the company the user belongs to.
null for a person. 0 marks the Optiwork AI assistant, 1 a bot and
2 a contact reached over an external messaging integration.
The colour used for this user’s name in the interface.
Set when the user has been removed from the company.
Details of the linked external-messaging contact, present when the user
is reached over an external messaging integration (type 2); null
for an ordinary person. Its keys depend on the integration, so treat it
as an open object.
A file attached to a message.
object
Alternative identifier accepted by the attachment content endpoints.
Size in bytes.
true for a voice message.
Playback length in seconds, for audio and video.
Thumbnail, when one was generated.
Storage metadata. Its keys depend on where the file is stored, so treat it as an open object.
The conversation the message belongs to, embedded — the conversation’s
own columns plus its participants under users. This embed is unique
to the send responses.
object
Identifier of the company the conversation belongs to.
External identifier, set when the conversation mirrors one in another Optiwork module.
The group or channel name. null on a private conversation, whose
name is the other person.
true for a one-to-one conversation.
What kind of conversation this is: 1 group, 2 private, 3 the
user’s own saved-messages space, 4 a conversation created by another
Optiwork module, 5 channel, 6 a conversation bridged to an
external messaging integration. A freshly created conversation may
report null here until it is classified.
Set on channels; null elsewhere.
How many messages the caller has not seen.
false once the caller has left or been removed.
The caller’s unsent text for this conversation.
The call currently running in the conversation, or null.
One user’s membership of one conversation. It appears as pivot on the
conversation payload and carries everything that is personal to that user:
their role, their read marker and their pin, mute, archive and draft state.
object
One message. type separates what a person wrote (USER) from what the
service recorded about the conversation (SYSTEM) — a rename, a join, a
departure. Render SYSTEM messages as notices, not as chat bubbles; their
data holds the details of what happened.
object
Author of the message.
The message this one replies to, or null.
Stable identifier of the message. This is what
POST /chats/messages/forward takes.
The client-supplied value that made the send idempotent.
The message text.
Structured payload. On a SYSTEM message it describes the event; on a
USER message it carries the mentioned user ids, when there are any.
Where the message came in from — chat for Talk itself, or the name of
the external messaging integration that relayed it.
true when the message was copied here from another conversation.
1 when the caller has favourited this message, 0 otherwise.
How many participants have seen the message.
Position of the message within the conversation.
The trimmed user record embedded in message payloads and search results.
object
Details of the linked external-messaging contact, present when the
embedded user is one (type 2); null otherwise. Open object.
A file attached to a message.
object
Alternative identifier accepted by the attachment content endpoints.
Size in bytes.
true for a voice message.
Playback length in seconds, for audio and video.
Thumbnail, when one was generated.
Storage metadata. Its keys depend on where the file is stored, so treat it as an open object.
Preview of the first link found in the text, when there is one.
Reactions on the message: the ids of the users who left each emoji, keyed by the emoji. Empty when nobody has reacted.
object
A poll carried by a message. total_votes and the per-option
votes_count / voter_ids are computed for every message payload, so a
client can render the result without a second call.
object
Whether a voter may pick more than one option.
object
Display order, starting at 0.
When the user pinned the conversation, or null.
When the mute expires. null on an indefinite mute, and on an
unmuted conversation. Unlike the other timestamps, the value inside
pivot is a plain YYYY-MM-DD HH:MM:SS UTC string, not ISO-8601.
Whether an unread message mentions this user.
Set when the user has left or been removed.
Settings that apply to a conversation as a whole.
object
Participant ceiling, or null when unlimited.
When true, nobody may post.
When true, only administrators may post.
How many unread messages trigger an automatic summary, or null when
the feature is off for this conversation.
The participants, each with their own pivot and status.
object
Numeric id, used on the conversation and participant routes.
Stable identifier of the user across the Optiwork suite.
Identifier of the company the user belongs to.
null for a person. 0 marks the Optiwork AI assistant, 1 a bot and
2 a contact reached over an external messaging integration.
The colour used for this user’s name in the interface.
Set when the user has been removed from the company.
Details of the linked external-messaging contact, present when the user
is reached over an external messaging integration (type 2); null
for an ordinary person. Its keys depend on the integration, so treat it
as an open object.
One user’s membership of one conversation. It appears as pivot on the
conversation payload and carries everything that is personal to that user:
their role, their read marker and their pin, mute, archive and draft state.
object
One message. type separates what a person wrote (USER) from what the
service recorded about the conversation (SYSTEM) — a rename, a join, a
departure. Render SYSTEM messages as notices, not as chat bubbles; their
data holds the details of what happened.
object
Author of the message.
The message this one replies to, or null.
Stable identifier of the message. This is what
POST /chats/messages/forward takes.
The client-supplied value that made the send idempotent.
The message text.
Structured payload. On a SYSTEM message it describes the event; on a
USER message it carries the mentioned user ids, when there are any.
Where the message came in from — chat for Talk itself, or the name of
the external messaging integration that relayed it.
true when the message was copied here from another conversation.
1 when the caller has favourited this message, 0 otherwise.
How many participants have seen the message.
Position of the message within the conversation.
The trimmed user record embedded in message payloads and search results.
object
Details of the linked external-messaging contact, present when the
embedded user is one (type 2); null otherwise. Open object.
A file attached to a message.
object
Alternative identifier accepted by the attachment content endpoints.
Size in bytes.
true for a voice message.
Playback length in seconds, for audio and video.
Thumbnail, when one was generated.
Storage metadata. Its keys depend on where the file is stored, so treat it as an open object.
Preview of the first link found in the text, when there is one.
Reactions on the message: the ids of the users who left each emoji, keyed by the emoji. Empty when nobody has reacted.
object
A poll carried by a message. total_votes and the per-option
votes_count / voter_ids are computed for every message payload, so a
client can render the result without a second call.
object
Whether a voter may pick more than one option.
object
Display order, starting at 0.
When the user pinned the conversation, or null.
When the mute expires. null on an indefinite mute, and on an
unmuted conversation. Unlike the other timestamps, the value inside
pivot is a plain YYYY-MM-DD HH:MM:SS UTC string, not ISO-8601.
Whether an unread message mentions this user.
Set when the user has left or been removed.
Presence information for a user.
object
When the user was last active.
One message. type separates what a person wrote (USER) from what the
service recorded about the conversation (SYSTEM) — a rename, a join, a
departure. Render SYSTEM messages as notices, not as chat bubbles; their
data holds the details of what happened.
object
Author of the message.
The message this one replies to, or null.
Stable identifier of the message. This is what
POST /chats/messages/forward takes.
The client-supplied value that made the send idempotent.
The message text.
Structured payload. On a SYSTEM message it describes the event; on a
USER message it carries the mentioned user ids, when there are any.
Where the message came in from — chat for Talk itself, or the name of
the external messaging integration that relayed it.
true when the message was copied here from another conversation.
1 when the caller has favourited this message, 0 otherwise.
How many participants have seen the message.
Position of the message within the conversation.
The trimmed user record embedded in message payloads and search results.
object
Details of the linked external-messaging contact, present when the
embedded user is one (type 2); null otherwise. Open object.
A file attached to a message.
object
Alternative identifier accepted by the attachment content endpoints.
Size in bytes.
true for a voice message.
Playback length in seconds, for audio and video.
Thumbnail, when one was generated.
Storage metadata. Its keys depend on where the file is stored, so treat it as an open object.
Preview of the first link found in the text, when there is one.
Reactions on the message: the ids of the users who left each emoji, keyed by the emoji. Empty when nobody has reacted.
object
A poll carried by a message. total_votes and the per-option
votes_count / voter_ids are computed for every message payload, so a
client can render the result without a second call.
object
Whether a voter may pick more than one option.
object
Display order, starting at 0.
One message. type separates what a person wrote (USER) from what the
service recorded about the conversation (SYSTEM) — a rename, a join, a
departure. Render SYSTEM messages as notices, not as chat bubbles; their
data holds the details of what happened.
object
Author of the message.
The message this one replies to, or null.
Stable identifier of the message. This is what
POST /chats/messages/forward takes.
The client-supplied value that made the send idempotent.
The message text.
Structured payload. On a SYSTEM message it describes the event; on a
USER message it carries the mentioned user ids, when there are any.
Where the message came in from — chat for Talk itself, or the name of
the external messaging integration that relayed it.
true when the message was copied here from another conversation.
1 when the caller has favourited this message, 0 otherwise.
How many participants have seen the message.
Position of the message within the conversation.
The trimmed user record embedded in message payloads and search results.
object
Details of the linked external-messaging contact, present when the
embedded user is one (type 2); null otherwise. Open object.
A file attached to a message.
object
Alternative identifier accepted by the attachment content endpoints.
Size in bytes.
true for a voice message.
Playback length in seconds, for audio and video.
Thumbnail, when one was generated.
Storage metadata. Its keys depend on where the file is stored, so treat it as an open object.
Preview of the first link found in the text, when there is one.
Reactions on the message: the ids of the users who left each emoji, keyed by the emoji. Empty when nobody has reacted.
object
A poll carried by a message. total_votes and the per-option
votes_count / voter_ids are computed for every message payload, so a
client can render the result without a second call.
object
Whether a voter may pick more than one option.
object
Display order, starting at 0.
Example
{ "message": { "type": "USER", "origin": "chat", "user": { "messenger_color": "#2180f3" }, "chat": { "type": 1, "visibility": "public", "pivot": { "role": "OWNER", "last_message_seen": { "type": "USER", "origin": "chat" } }, "users": [ { "messenger_color": "#2180f3", "pivot": { "role": "OWNER", "last_message_seen": { "type": "USER", "origin": "chat" } } } ], "last_message": { "type": "USER", "origin": "chat" }, "last_message_seen": { "type": "USER", "origin": "chat" } } }}Missing, malformed or expired authentication key.
Authentication failures — and a few permission denials — use an error
key rather than message.
object
Examples
No bearer token sent
{ "error": "JWT passport exception: Missing bearer token in request"}The resource does not exist, or does not belong to the given conversation.
Generic error envelope used by policy, binding and framework failures.
object
Human-readable description of the failure.
Examples
{ "message": "No query results for model [App\\Models\\Chat\\Chat] 99999999"}Validation failed, or the target user is the caller — you cannot send a direct message to yourself.
Generic error envelope used by policy, binding and framework failures.
object
Human-readable description of the failure.
Examples
{ "message": "You cannot send a message to yourself."}Rate limit exceeded. Retry after the window resets.
Generic error envelope used by policy, binding and framework failures.
object
Human-readable description of the failure.
Examples
{ "message": "Too Many Attempts."}