# Message

URL: /business/nouns/message · Id: `noun:message`

> A Message is one communication from any party over one medium, such as email, SMS, or chat, inbound or outbound.

A Message is one communication from any party over one medium, such as email, SMS, or chat, inbound or outbound.

## Properties
| Property | Type | Required | Description |
| --- | --- | --- | --- |
| `medium` | `string` | Yes | One of `email`, `sms`, `voice`, or `chat`. |
| `direction` | `string` | Yes | One of `inbound` or `outbound`. |
| `body` | `text` | Yes | What it says. |
| `from` | `string` | No | The sender: an address, a number, or a Channel id. |
| `to` | `string` | No | The recipient: an address, a number, or a Person id. |
| `subject` | `string` | No | The subject line, for email. |
| `purpose` | `string` | No | Why it goes out, such as onboarding; consent and suppression rules read it. |

## Object
```json
{
  "$id": "https://api.sb/routewise.dev/messages/message_1",
  "$type": "Message",
  "medium": "email",
  "direction": "inbound",
  "body": "Example body",
  "from": "Example from",
  "to": "Example to",
  "subject": "Example subject",
  "purpose": "Example purpose"
}
```

## Relationships
- <a id="rel-posted-in"></a>A Message **is posted in** one [Channel](/business/nouns/channel): every Message flows through one [Channel](/business/nouns/channel). `postedIn`, inverse [`messages`](/business/nouns/channel#rel-messages).
- <a id="rel-scheduled-by"></a>A Message **is scheduled by** one [Sequence](/business/nouns/sequence): a [Sequence](/business/nouns/sequence) sends Messages, each at its own step and wait. `scheduledBy`, inverse [`schedules`](/business/nouns/sequence#rel-schedules).
- <a id="rel-screened-by"></a>A Message **is screened by** many [Guards](/business/nouns/guard): [Guards](/business/nouns/guard) check every outbound Message before it goes out. `screenedBy`, inverse [`screens`](/business/nouns/guard#rel-screens).
- <a id="rel-thread"></a>A Message **has** one [Thread](/business/nouns/thread): a [Thread](/business/nouns/thread) groups Messages that reply to one another. `thread`, inverse [`groups`](/business/nouns/thread#rel-groups).

## Verbs
| Verb | Description | Subject | Event | Class |
| --- | --- | --- | --- | --- |
| [Message.broadcast](/business/nouns/message/broadcast) | Broadcast sends one Message to an Audience, now or at a set time, split by Variant when an Experiment runs. | [Marketing Lead](/agents/marketing/marketing-lead) | [`Message.broadcasted`](/business/events/Message.broadcasted) | One-way (brand, customer): `send`, `do` |
| [Message.schedule](/business/nouns/message/schedule) | Schedule holds a Message until a set time and sends it then, unless it is canceled first. | [Marketing Lead](/agents/marketing/marketing-lead) | [`Message.scheduled`](/business/events/Message.scheduled) | Two-way: `try`, `send`, `do` |
| <a id="create"></a>[Message.create](/business/nouns/message/create) | Creates a Message. Inherited from [Noun](/business/nouns/noun). | None. | `Message.created` | Two-way: `try`, `send`, `do` |
| <a id="get"></a>[Message.get](/business/nouns/message/get) | Returns one Message by id. Inherited from [Noun](/business/nouns/noun). | None. | None. | Read: `try`, `do` |
| <a id="list"></a>[Message.list](/business/nouns/message/list) | Returns Messages, newest first, one page at a time. Inherited from [Noun](/business/nouns/noun). | None. | None. | Read: `try`, `do` |
| <a id="update"></a>[Message.update](/business/nouns/message/update) | Changes the given properties of a Message. Inherited from [Noun](/business/nouns/noun). | None. | `Message.updated` | Two-way: `try`, `send`, `do` |
| <a id="delete"></a>[Message.delete](/business/nouns/message/delete) | Deletes a Message; its history is kept. Inherited from [Noun](/business/nouns/noun). | None. | `Message.deleted` | One-way: `send`, `do` |

## Permissions
Which Access level may call each Verb. One-way Verbs wait their delay window.

| Operation | `owner` | `admin` | `member` | `viewer` |
| --- | --- | --- | --- | --- |
| `Message.create` | Yes | Yes | Yes | No |
| `Message.get` | Yes | Yes | Yes | Yes |
| `Message.list` | Yes | Yes | Yes | Yes |
| `Message.update` | Yes | Yes | Yes | No |
| `Message.delete` | Yes | Yes | Yes | No |
| `Message.broadcast` | Yes | No | No | No |
| `Message.schedule` | Yes | Yes | Yes | No |

## Call it

**Ask**

```text
Broadcast the latest message with an audience.
```

**API**

```bash
curl -X POST https://api.sb/kilnbakery.com/messages/message_1/broadcast \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"audience":"audience_1"}'
```

```json
{
  "api": "https://api.sb/kilnbakery.com",
  "messages": [
    {
      "$id": "https://api.sb/kilnbakery.com/messages/message_1",
      "$type": "Message",
      "medium": "email",
      "direction": "inbound",
      "body": "Example body"
    }
  ],
  "message": {
    "$id": "https://api.sb/kilnbakery.com/messages/message_1",
    "$type": "Message",
    "medium": "email",
    "direction": "inbound",
    "body": "Example body"
  },
  "action": {
    "$id": "https://api.sb/kilnbakery.com/actions/action_1",
    "operation": "Message.broadcast",
    "status": "done"
  },
  "links": {
    "self": "https://api.sb/kilnbakery.com/actions/action_1"
  }
}
```

**SDK**

```ts
import { $ } from 'startup-builder'

const { messages, message } = await $.Message.broadcast({ message: 'message_1', audience: 'audience_1' })
```

**CLI**

```bash
npx startup-builder do Message.broadcast --json '{"message":"message_1","audience":"audience_1"}'
```

**MCP**

```json
{
  "name": "do",
  "arguments": {
    "code": "return await $.Message.broadcast({ message: 'message_1', audience: 'audience_1' })"
  }
}
```

## Example
A text from a parent asking to move tomorrow's tutoring session is one inbound Message. The tutor's reply in the same [Thread](/business/nouns/thread) is another, outbound.