# Drafts and approval

> Which sends wait for a person and which go out at once. The dashboard and an agent can hold a draft. A REST API call sends without an approval step.

URL: https://docs.xulo.io/concepts/drafts-and-approval

Every push and card is one record, a draft, whichever way it was made. What differs is whether it waits for a person.

| Source | Shown as | What happens |
| --- | --- | --- |
| Dashboard | Panel | **Send** sends at once, or at the time you chose. **Save draft** keeps a draft. Open it from the push list to change it, delete it, or press **Send**. |
| Agent | MCP | The agent writes a draft. Writing it never sends. The agent sends it when the person says yes in the chat. |
| REST API | API | The call sends at once, or schedules the send for `send_after`. There is no approval step. |

The source is shown in the push list, the in-app list and the app overview. Sending does not change it.

A draft or a scheduled send opens in the editor. A sent push or a published card opens its report, and can no longer be edited or deleted.

> **Warning:** REST API calls send without approval
>
> A `POST /api/v1/notifications` call with no `send_after` starts sending at once. With `send_after` it sends when that time arrives. Nobody approves it in the dashboard first. Test against the **Test devices** audience before you target real people.

## Agents

An agent writes the draft with `create_draft`, which does not send. It sends with `send_draft`. The expected flow is that the person says yes in the chat and the agent then calls `send_draft`.

A push with a set time works the same way. `create_draft` takes `delivery` of `now`, `at` or `local`. `at` needs a date, a time and an IANA time zone. `local` needs a date and a clock time, and sends at that time in each device's own time zone. The draft stays a draft. `send_draft` does not send it at once: it schedules it, and the push goes out when the time arrives. A time that has already passed is refused and the draft stays a draft. The dashboard **Send** button works the same way.

For an organization that is exempt from billing, the `app_counts` tool returns `bill` as `null` and `billing_exempt` as `true`.

The server does not read the chat and does not keep a separate approval flag. The yes is the `send_draft` call. An open agent connection can send for every app in the organization, so the control is the connection itself: disconnect an agent you no longer trust.

## When a draft stays a draft

A push stays a draft, and nothing is marked as delivered, when:

- the app has no Apple key or certificate, or
- Apple accepted none of the devices.

Once the cause is fixed, open it from the push list and press **Send** again.

## An empty audience

If nobody matches, the send is approved and nobody is marked as reached. Xulo does not record a delivery that did not happen.

## In-app cards

Approving a card publishes it. The dashboard card editor saves a draft, and an agent publishes its card when it sends the draft. A card is not sent through Apple. The app asks for the card the next time a rule matches. See [In-app cards](https://docs.xulo.io/concepts/in-app-cards).
