Send a message

.md

Write a new message or answer one, from a mailbox you can open.

Scopesmail:write
POST/v1/me/mail/messages

Sends immediately and files a copy in Sent. Answering an existing message keeps the reply in the same conversation, on both ends: leave in_reply_to out and the recipient's mail client will file your answer as a new exchange.

Send the same Idempotency-Key on a retry

A phone on a train retries, and a retry without the key sends the same message twice. With it, the second attempt gets the first one's answer back and nothing leaves twice. See Idempotency.

Request

curl -X POST https://api.proppertrading.com/v1/me/mail/messages \
  -H "Authorization: Bearer ptat_9f2c1a44_3b8e7d2f5c9a1b4e6d8f0a2c4e6b8d1f" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 7d8e9f01-2a3b-4c5d-6e7f-8091a2b3c4d5" \
  -d '{
    "address_id": "mbx_w6sy3skvgydh5e3b",
    "to": ["[email protected]"],
    "cc": [],
    "subject": "Re: Payout request",
    "body": "<p>Your payout is on its way.</p>",
    "in_reply_to": "msg_h3k8q2w7n4r9t5vx",
    "quoted": "<blockquote>Hi, I passed the evaluation last week.</blockquote>",
    "draft_id": "msg_q9w3k7x2n8m4t6vb",
    "signature_id": "sig_khuz893vv6fzuusz"
  }'
FieldTypeDescription
address_idstringThe id of the mailbox it goes out from, from list mailboxes. Required, and it has to be one of yours
toarrayOne to fifty addresses. Required
ccarrayUp to fifty. Optional
subjectstringRequired, up to 255 characters
bodystringHTML. Required, up to 100000 characters
in_reply_tostringThe id of the message being answered, so the reply stays in its conversation
quotedstringThe quoted half, kept apart from the body
draft_idstringThe id of the draft this became. It turns into the sent message rather than being left behind
signature_idstringWhich sign-off to append, the id from list signatures. Left out or null, the message goes out without one

to and cc also accept one string with commas or semicolons in it, which is what a paste from somewhere else looks like.

Every id is a string, such as msg_h3k8q2w7n4r9t5vx. A number in any of the four is refused with validation_failed, and an empty string reads as left out.

Keep quoted out of body. They are sent apart so the message can be assembled as body, signature, quote in that order, and so the reader on the other end can fold the quote away.

A signature has to belong to the mailbox you are sending from, or to no mailbox in particular, and to you, or to nobody in particular. Anything else is ignored and the message goes out unsigned: a colleague's own sign-off is theirs, and an id from another mailbox would put a name under a message its owner did not write. List signatures returns exactly the ones that pass, and says which one the mailbox would start you on.

Response

{
    "data": {
        "id": "msg_q9w3k7x2n8m4t6vb",
        "object": "mail_message",
        "thread_id": "thr_c4n8w2k7p5x9m3qd",
        "address_id": "mbx_w6sy3skvgydh5e3b",
        "folder": "sent",
        "subject": "Re: Payout request",
        "to_recipients": [{ "email": "[email protected]", "name": null }],
        "cc_recipients": [],
        "message_at": "2026-08-19T18:22:04.000000Z"
    },
    "meta": { "request_id": "req_01kz4bkr1aj1gv63d8fv3133ey" }
}

Status is 201. Sending also marks the conversation as answered, by you.

Errors

StatusCodeMeaning
400missing_idempotency_keyEvery POST needs one
400not_a_draftdraft_id points at a message that is not a draft
403insufficient_scopeThis device does not hold mail:write
404resource_not_foundThe mailbox, the message being answered or the draft is not one of yours
422validation_failedSomething is missing or malformed, or an id was sent as a number
500send_failedThe provider would not take it. The draft is still there, so offer to try again