---
title: "mail.agent-reply-request@1 · OpenVibe.Services"
canonical: "https://openvibe.services/docs/contracts/mail.agent-reply-request"
updated: null
---

# mail.agent-reply-request@1 · OpenVibe.Services

HTML: [mail.agent-reply-request@1 · OpenVibe.Services](https://openvibe.services/docs/contracts/mail.agent-reply-request)

# MailAgentReplyRequest `mail.agent-reply-request@1`

Generated at 2026-11-13 06:25:48 UTC from [`openvibe-contracts v0.419.0`](https://github.com/OpenVibers/OpenVibe.Contracts/tree/v0.419.0) and [`openvibe-sdk v0.161.0`](https://github.com/OpenVibers/OpenVibe.SDK/tree/v0.161.0).

- Version: 1.0.0
- Owner: mail
- Visibility: first-party
- Status: active
- Compatibility: backward
- Schema: [`https://openvibe.network/contracts/mail/agent-reply-request.v1.json`](/docs/contracts/mail.agent-reply-request.json)

mail.agent.reply-request@1: the body of mail.agent.reply (POST /internal/mail/agents/:agent\_id/reply), an agent answering a letter to its own address. The reply goes FROM the agent's inbox, never from the person's mailbox: the person's own address is not the agent's to write from. \`body\` is plain text, cut to 10000 characters; \`in\_reply\_to\` and \`references\` are Message-IDs WITHOUT the angle brackets, and Mail wraps each in one, so a thread stays one thread in the reader that receives it. A reply to an address that is not the sender's answers nothing: Mail refuses it rather than write to a stranger the agent's answer was not for. Nothing here says who the person is; the token does.

## Fields

| Field | Type | Required | Description | Constraints |
| --- | --- | --- | --- | --- |
| `message_id` | string |  | The message being answered, as mail.agent.read gave it. Mail takes the sender and the subject from it, so a caller cannot write to someone the message did not come from. | - `minLength 1`<br>- `maxLength 512` |
| `to` | string |  | Who the reply goes to. Optional: without it the reply goes to the sender of message\_id. When both are given they must be the same address. | - `format email`<br>- `maxLength 254` |
| `body` | string | yes | The reply, as plain text. Mail builds the message from it and sends no HTML. | - `minLength 1`<br>- `maxLength 10000` |
| `in_reply_to` | string \| null |  | The Message-ID this reply answers, without angle brackets. Mail wraps it: In-Reply-To: <…>. | - `maxLength 998` |
| `references` | array of string |  | The Message-IDs of the conversation, oldest first, without angle brackets. Mail wraps each: References: <…> <…>. | - `maxItems 100`<br>- `items: maxLength 998` |

## Examples

From the contract's own test fixtures: valid ones validate, rejected ones must fail.

 Valid: threaded

~~~~
{
  "message_id": "m-4711",
  "to": "dana@example.net",
  "body": "Tuesday at 10 is still good. See you then.\n\n— Helper, answering for Alice",
  "in_reply_to": "dana-1@example.net",
  "references": [
    "dana-1@example.net"
  ]
}
~~~~

Valid: to-the-sender

~~~~
{
  "message_id": "m-4711",
  "body": "Thanks, noted."
}
~~~~

Rejected: from-and-html

~~~~
{
  "message_id": "m-4711",
  "body": "An answer sent from the person's own mailbox, which is not the agent's to write from.",
  "from": "alice@openvibe.email",
  "html": "<p>An answer</p>"
}
~~~~

Rejected: no-body

~~~~
{
  "message_id": "m-4711",
  "to": "dana@example.net",
  "body": ""
}
~~~~

Rejected: with-attachments

~~~~
{
  "message_id": "m-4711",
  "body": "At most 10000 characters, said the contract.",
  "attachments": [
    {
      "name": "a.pdf",
      "blob": "AAA"
    }
  ]
}
~~~~

## Validate

~~~~
const contracts = require('openvibe-contracts');
contracts.validate('mail.agent-reply-request@1', value);   // { valid, errors: [{ path, message }] }
~~~~
