SendEmailRequest
subject is required unless template supplies one, and one of html, text or template must be given; both are checked after validation and answer 422 invalid_request. A field not listed here is refused with 422 invalid_request naming it, and nothing is sent: a guessed name such as in_reply_to is not ignored.
Properties
| Name | Type | Description |
|---|---|---|
| from | object | Sender on a verified domain: billing@mail.example.com or 'Acme |
| to | object | One mailbox, or an array of at least one. Each is an address, or 'Ana Lima |
| cc | array | Mailboxes, in the same forms as to. The name, if any, appears in the Cc header. Counts toward the 50 recipients a message may have across to, cc and bcc. |
| bcc | array | Mailboxes. A name is accepted and discarded, since Bcc never appears in a header. Counts toward the 50 recipients a message may have across to, cc and bcc. |
| reply_to | string | One mailbox: an address, or 'Name '. The name is kept in the Reply-To header. |
| subject | string | Required unless a template supplies one. No line breaks. With template, this replaces the template's subject verbatim: variables are not substituted into it. |
| html | string | The HTML body. Ignored when template is given. |
| text | string | The plain-text body. Ignored when template is given. When only html is sent, a plain-text part is derived from it at send time. |
| template | string | Slug of a stored template (GET /v1/templates). Preferred over composing HTML: variable values are HTML-escaped, so user-supplied text is safe to interpolate. Its rendered html and text replace html an |
| variables | object | Values for the template's placeholders, all strings. A declared placeholder with no value is 422 missing_variables with a missing array naming them. |
| risk_class | string | Selects which verified domain and reputation pool the message uses. marketing requires a domain verified for marketing and a workspace postal address, goes to exactly one address across to, cc and bcc |
| scheduled_at | string | Send later: an ISO 8601 timestamp (include Z or an offset), or 'in' plus a number and one of min, mins, minute, minutes, hour, hours, day, days, week, weeks (e.g. 'in 3 days'). A past time sends on th |
| sequence_key | string | Stored on the schedule entry of a scheduled send; ignored for an immediate or held send. No public endpoint reads it at present. |
| tags | array | Passed to the provider as message tags: characters outside A-Z, a-z, 0-9, _ and - become _, each is cut to 256 characters, and an empty result becomes unset. Stored as passed: GET /v1/emails and GET / |
| attachments | array | |
| reply_to_message_id | string | Reply to this message: one you sent, or one you received (an inbound entry's id in a thread transcript, or an inbound webhook's id). Sets In-Reply-To and References so the recipient sees one conversat |
| thread_id | string | Put the message on this thread without replying to a particular message. Must be a thread in this workspace or the send is 422 invalid_request. When reply_to_message_id is also given and that message |
| topic | string | A topic key in this workspace. Recipients opted out of the topic are dropped, and a marketing send's unsubscribe link opts out of this topic only. A transactional send with a topic and exactly one rec |
JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://artifacts.apis.io/sendraven-ai/json-schema/sendraven-ai-send-email-request-schema.json",
"title": "SendEmailRequest",
"description": "subject is required unless template supplies one, and one of html, text or template must be given; both are checked after validation and answer 422 invalid_request. A field not listed here is refused with 422 invalid_request naming it, and nothing is sent: a guessed name such as in_reply_to is not ignored.",
"x-generated": "2026-10-31",
"x-method": "derived",
"x-generator": "derive-json-schema.py",
"x-source": "openapi/sendraven-ai-api-openapi.json#/components/schemas/SendEmailRequest",
"type": "object",
"required": [
"from",
"to"
],
"additionalProperties": false,
"properties": {
"from": {
"anyOf": [
{
"type": "string",
"format": "email"
},
{
"type": "string",
"pattern": "^.+<[^@]+@[^>]+>$"
}
],
"description": "Sender on a verified domain: billing@mail.example.com or 'Acme <billing@mail.example.com>'. The domain must match (ignoring case) a sending domain verified for this message's risk_class, or the send is 422 no_verified_identity."
},
"to": {
"oneOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
},
"minItems": 1
}
],
"description": "One mailbox, or an array of at least one. Each is an address, or 'Ana Lima <ana@example.com>' to show the recipient's name in the To line (name at most 100 characters, no line breaks, < or >). Suppression, topic opt-outs, key allowlists and the message log all match on the address alone, so a name never changes who is reached. A message has at most 50 recipients across to, cc and bcc together; more is 422 invalid_request with the limit and the count, the same message whichever fields hold the addresses."
},
"cc": {
"type": "array",
"items": {
"type": "string"
},
"description": "Mailboxes, in the same forms as to. The name, if any, appears in the Cc header. Counts toward the 50 recipients a message may have across to, cc and bcc."
},
"bcc": {
"type": "array",
"items": {
"type": "string"
},
"description": "Mailboxes. A name is accepted and discarded, since Bcc never appears in a header. Counts toward the 50 recipients a message may have across to, cc and bcc."
},
"reply_to": {
"type": "string",
"description": "One mailbox: an address, or 'Name <address>'. The name is kept in the Reply-To header."
},
"subject": {
"type": "string",
"minLength": 1,
"maxLength": 998,
"pattern": "^[^\\r\\n]*$",
"description": "Required unless a template supplies one. No line breaks. With template, this replaces the template's subject verbatim: variables are not substituted into it."
},
"html": {
"type": "string",
"description": "The HTML body. Ignored when template is given."
},
"text": {
"type": "string",
"description": "The plain-text body. Ignored when template is given. When only html is sent, a plain-text part is derived from it at send time."
},
"template": {
"type": "string",
"description": "Slug of a stored template (GET /v1/templates). Preferred over composing HTML: variable values are HTML-escaped, so user-supplied text is safe to interpolate. Its rendered html and text replace html and text. An unknown slug is 422 invalid_request."
},
"variables": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"default": {},
"description": "Values for the template's placeholders, all strings. A declared placeholder with no value is 422 missing_variables with a missing array naming them."
},
"risk_class": {
"type": "string",
"enum": [
"transactional",
"marketing"
],
"default": "transactional",
"description": "Selects which verified domain and reputation pool the message uses. marketing requires a domain verified for marketing and a workspace postal address, goes to exactly one address across to, cc and bcc (more is 422 invalid_request, because the unsubscribe footer and List-Unsubscribe headers are that one person's; use POST /v1/emails/batch or a campaign for several), is never threaded, and is subject to the sending domain's daily warm-up allowance."
},
"scheduled_at": {
"type": "string",
"description": "Send later: an ISO 8601 timestamp (include Z or an offset), or 'in' plus a number and one of min, mins, minute, minutes, hour, hours, day, days, week, weeks (e.g. 'in 3 days'). A past time sends on the scheduler's next pass. An unparseable value, including an empty string, is 422 invalid_schedule. Omit to send now."
},
"sequence_key": {
"type": "string",
"maxLength": 200,
"description": "Stored on the schedule entry of a scheduled send; ignored for an immediate or held send. No public endpoint reads it at present."
},
"tags": {
"type": "array",
"maxItems": 10,
"items": {
"type": "object",
"required": [
"name",
"value"
],
"properties": {
"name": {
"type": "string"
},
"value": {
"type": "string"
}
}
},
"description": "Passed to the provider as message tags: characters outside A-Z, a-z, 0-9, _ and - become _, each is cut to 256 characters, and an empty result becomes unset. Stored as passed: GET /v1/emails and GET /v1/threads filter on them with tag=name:value, and a thread returns the tags of every message sent on it."
},
"attachments": {
"type": "array",
"maxItems": 20,
"items": {
"$ref": "#/$defs/Attachment"
}
},
"reply_to_message_id": {
"type": "string",
"description": "Reply to this message: one you sent, or one you received (an inbound entry's id in a thread transcript, or an inbound webhook's id). Sets In-Reply-To and References so the recipient sees one conversation, and puts the new message on that message's thread. Prefer this over a fresh send whenever you are answering something. An id that matches no message in the workspace is 422 invalid_request."
},
"thread_id": {
"type": "string",
"description": "Put the message on this thread without replying to a particular message. Must be a thread in this workspace or the send is 422 invalid_request. When reply_to_message_id is also given and that message is on a thread, its thread wins."
},
"topic": {
"type": "string",
"description": "A topic key in this workspace. Recipients opted out of the topic are dropped, and a marketing send's unsubscribe link opts out of this topic only. A transactional send with a topic and exactly one recipient is treated as a notification: it gets a one-click List-Unsubscribe header and a short footer that opt out of this topic only, and no postal address is required. Leave topic off mail nobody should be able to stop (sign-in codes, password resets). A key that does not exist is 422 unknown_topic rather than a send in which everyone looks unsubscribed."
}
},
"$defs": {
"Attachment": {
"type": "object",
"required": [
"filename",
"content"
],
"properties": {
"filename": {
"type": "string",
"minLength": 1,
"maxLength": 255,
"pattern": "^[^\\x00-\\x1F\\x7F]+$",
"description": "No line breaks or other control characters; such a name is refused with 422, not cleaned. Quotes and non-ASCII characters are allowed and encoded for you."
},
"content": {
"type": "string",
"contentEncoding": "base64",
"description": "The file, base64-encoded. At most 10 MB decoded, per attachment. The whole JSON body is limited to 15 MB on POST /v1/emails, so several large files belong in separate sends or behind a link."
},
"content_type": {
"type": "string",
"maxLength": 255,
"default": "application/octet-stream",
"description": "A media type as type/subtype with optional ; name=value parameters, e.g. application/pdf or text/plain; charset=utf-8. Anything else, including a value with a line break, is 422 invalid_request."
},
"content_id": {
"type": "string",
"minLength": 1,
"maxLength": 255,
"pattern": "^[^\\x00-\\x1F\\x7F<>\\s]+$",
"description": "Makes the attachment inline, for an image the HTML references as cid: followed by this value. No spaces, angle brackets or control characters. Without it the file is a regular attachment."
}
}
}
}
}
Work with this as data
Every JSON Schema here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for schemas
4 MCP tools reach this
find_json_schemasBrowse and filter every JSON Schema in the catalog.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.
Call it yourself
curl for this page
curl "https://apis.io/api/v1/json-schemas/sendraven-ai-send-email-request"
curl "https://apis.io/api/v1/json-schemas?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.