# Sending model

## Sending model

<DataSchema id="608822" />

### Sending status

The Sending may have one of following statuses, which are grouped into `draft`, `scheduled` and `finished` types.

| Status         | Type        | Editable? | Cancellable? | Description                                                                                         |
|----------------|-------------|-----------|--------------|-----------------------------------------------------------------------------------------------------|
| `draft`        | `draft`     | yes       | no           | When API client didn't define the schedule (or has `draft: true` flag)                              |
| `scheduled`    | `scheduled` | yes       | no           | When scheduled to be sent at specific time by API client                                            |
| `preparing`    | `scheduled` | no        | yes          | Building Dispatches for Recipients and Audience members                                             |
| `prepared`     | `scheduled` | no        | yes          | Dispatches are built, ready for transmission                                                        |
| `transmitting` | `scheduled` | no        | yes          | Dispatches are being transmitted                                                                    |
| `transmitted`  | `finished`  | no        | no           | When the Dispatches have been transmitted                                                           |
| `cancelled`    | `finished`  | no        | no           | When cancelled by API client                                                                        |
| `failed`       | `finished`  | no        | no           | When the execution couldn't be finished                                                             |
| `skipped`      | `finished`  | no        | no           | When no recipients could be resolved for it (for example, Audience may lose its members over time). |

```mermaid
stateDiagram-v2
draft --> scheduled
scheduled --> draft
scheduled --> preparing
preparing --> prepared

prepared --> transmitting
transmitting --> transmitted
preparing --> skipped
preparing --> failed
prepared --> failed
transmitting --> failed
preparing --> cancelled
prepared --> cancelled
transmitting --> cancelled
```

Sending may have status changed from `draft` to `scheduled` and vice versa and is editable during this stage.

When processing starts (status >= `preparing`), it may only be [cancelled](api-3511366).

And after it reaches one of statuses of `finished` type, it cannot be modified anymore.

## Sending payload

A payload for a new/scheduled Sending is signically different from a persisted Sending record:

<DataSchema id="607338" />

### Examples

<Container>
Payload for Sending without schedule to audience defined by given conditions:
```json
{
  // Schedule is not provided, so message will not be scheduled
  "audience": {
    "type": "inline",
    "conditions": [
      {
        "condition_group": "member_properties", "field": "first_name", 
        "operator": "match", "value": "Piotr"
      }
    ]
  }
}
```
</Container>

<Container>
Payload for scheduling a Sending 2 days from now to members of an Audience defined by ID and 2 arbitrary recipients:
```json
{
  "schedule": { "type": "relative", "in": "2 days" },
  "audience": { "type": "inline", "id": 15 },
  "recipients": [
    { "member_id": 150, "properties": { "name": "Piotr" } },
    { "email": "jan@example.com", "properties": { "name": "Jan" } }
  ]
}
```
</Container>

### Defining recipients

There are two methods to define recipients of the sending:

* `audience` - members of the target Audience will be used as recipients (see below)
* `recipients` - inline receivers (see: [here](doc-354473#inline-recipients))

Both methods can be used at the same time.

#### Audience recipients

Sending Audience may be defined:
* by `id` (`reference` audience type)
* by `conditions` (`inline` audience type)

See: [DMP docs](https://dmp.boostcom.no/docs/#conditions)

<Container>
Example of providing Audience by reference:

```json
{ 
  "type": "inline", 
  "id": 532 
}
```
</Container>

<Container>
Example of providing Audience by inline conditions:

```json
{ 
  "type": "inline",
  "conditions": [{
    "condition_group": "member_properties", "field": "first_name", 
    "operator": "match", "value": "Piotr"
  }]
}
```
</Container>

#### Inline recipients

Recipient may be a MPC member (identified by `member_id`) or an arbitrary sending receiver - identified by at least one of: `msisdn`, `email` or `push`.

<DataSchema id="608824" />

<Container>
Example:

```json
{
  "member_id": 150,
  "msisdn": "4740769126",
  "email": "recipient@example.com",
  "app_token": "c6OE_joK28g:APA91bFkT5fzhdWJMJswPo3btVLxtMmhi7jKdOE_VL1IhkSmuoz3iEQMg4Cq",
  "properties": { "first_name": "Piotr" }
}
```
</Container>

##### MPC member recipient

When `member_id` is provided, other identifiers will be ignored and actual identifiers for sending execution will be fetched from MPC member's data (for example, for `sms` channel member's `msisdn` will be used as a sending receiver).

Merge-properties for template will be fetched from MPC Members - but may be extended/replaced with provided `properties`.

##### Arbitrary recipient

Without `member_id`, at least one identifier relevant to message's channels definition is required.

For example, if `sms` and `email` channels are defined on message, `msisdn` or `email` is required.

Given `properties` will be used as template's merge-tags.

### Channels preference

When message has [multiple channels](doc-354471#multiple-channels), it is possible to select which channels should be used for delivering the Message to the recipient and specify the preferred order (priority) with `channels_preference` attribute.

For example, `"channels_preference": ["sms", "email"]` means that `sms` and `email` channels should be used for Sending and `sms` is preffered.

### Schedule

The `schedule` is optional - when not provided, sending will not be scheduled (will have `draft` status).

<Container>
Example of an immediate schedule:

```json
{ "type": "immediate" }
```
</Container>

<Container>
Example of an absolute schedule:

```json
{ "type": "absolute", "at": "2020-10-18T10:59:32.340Z" }
```
</Container>

<Container>
Example of a relative schedule:

```json
{ "type": "relative", "in": "5 minutes" }
```
</Container>

#### Format of `in` parameter

You can provide `number` of time `unit`s the Sending will be scheduled at in format described by following regex:

<Container>
  `^(?<number>\d+) (?<unit>second|minute|hour|day|week|month|year)s?$`
</Container>

Examples: `30 minutes`, `1 day` `5 months`

### Prescheduling

Potentially Sendings may have very large Audiences assigned, so it may take some time to build Dispatches for all of them.

Therefore, by providing `prescheduled: true` schedule param, the preparation will start 5 minutes before the actual transmission to speed up the sending execution.
