Message .schedule
Hold one email for a set time, such as 9:10 in the buyer’s morning.
- Action class
- None
- Approval
- Runs on its own
- Emits
Message.scheduled- Sites
- Gmail, LinkedIn, Outlook, X
- Price
- Free
POST https: //api.sb/ {your-domain}/ messages/ schedule
Holds one email until the minute you set, such as 9:10 in the buyer’s morning, then sends it from your Mailbox. The hub’s definition of Message.schedule.
Inputs
| Name | Type | Default | Meaning |
|---|---|---|---|
message | Message | Required | The Message to hold. |
at | datetime | Required | When it goes out. |
Outputs
| Field | Type | What null means |
|---|---|---|
message | Message | Never null. |
message.from | string | Never null: the Mailbox address it sends from. |
message.to | string | Never null for email: the one recipient. |
message.subject | string | Null for a medium with no subject line, such as SMS. |
message.purpose | string | Never null: the Consent and Suppression checks read it before it sends. |
Effects
- Action class
None: no approval rule names it, so it runs within its seat’s Permissions and Limits
- Modes
try: Runs the send checks againstatand renders the Message; nothing is held or sent.send: Returns the held Message at once; it sends atat.do: Returns the held Message at once; it sends atat.
- Idempotency
Only with a key: the same
Idempotency-Keyand input return the first Action, and the same key with other input returns409. Scheduling a held Message again moves it to the newat; it never sends twice.- Saved or shared
The Message is saved on its Contact and held as a pending Action,
reason:, until'awaitingTime' at. Canceling that Action before then stops it.- Emits
Message.scheduledwith{ message,at } - Performed by
- Price
Free on your own account: the platform charges nothing for the call.
On each Venue
Gmail
Through Gmail.
| Our field | Gmail’s field |
|---|---|
Message.from | raw: (Your address, or a send-as alias you set up in Gmail) |
Message.to | raw: |
Message.subject | raw: (A reply keeps the thread’s subject, so Gmail threads it) |
Message.body | raw: |
- Replies. Gmail pushes each new message within seconds; the platform renews the mailbox watch daily, inside the 7 days Gmail allows.
Through LinkedIn.
| Our field | LinkedIn’s field |
|---|---|
Message.body | invitation note or message (Typed into LinkedIn’s own screens by the browser agent) |
- Connection requests. Capped by your standing approval at 20 a weekday, about 100 a week; LinkedIn publishes no number, and a request past your standing approval waits with
over-mandate. - Pending requests. A request unanswered after 3 weeks is withdrawn, so pending requests never pile up.
- Replies. Read from your LinkedIn inbox every 30 minutes on weekdays, since LinkedIn sends no webhook for member messages.
Outlook
Through Outlook.
| Our field | Outlook’s field |
|---|---|
Message.to | message.toRecipients |
Message.subject | message.subject |
Message.body | message.body (contentType html or text) |
X
Through X account.
| Our field | X account’s field |
|---|---|
Message.body | text |
- Each direct message. X bills 1.5¢.
- Replies to strangers. Only to posts that describe your problem, and never twice in one thread without an answer back.
What try does
| Account | What try does |
|---|---|
| Gmail | Renders the exact email, headers included, and returns it with the time it would send; nothing reaches Gmail and no draft is saved. |
| Posts render as LinkedIn will show them and nothing is sent; requests and messages return each person, the note and the day it goes, and no browser session opens. | |
| Outlook | Renders the exact email or invite and returns it with the time it would go; nothing reaches Outlook and no draft or event is saved. |
| X account | Renders each post at X’s weighted count, with links at 23 characters, and returns the price X would bill; nothing is posted and nothing is billed. |
Refuses when
| Check | Error | Fix | Then call |
|---|---|---|---|
| A first cold email from a Mailbox that has not finished warming | mailbox-warm | Wait for the warm-up to finish, 14 days from day 0; warm intros keep running. | Mailbox.warm |
| A send from a Domain whose DNS records do not resolve | domain-authenticated | Add the 3 DNS records shown; it passes once they resolve, often within an hour. | Domain.authenticate |
Every call through an account can also meet the shared account refusals: grant-missing, needs-reauth, account-not-connected, over-mandate, quota-reached, venue-rejected.
The mailbox-warm payload
{
"type": "https://startupbuilder.dev/errors/mailbox-warm" ,
"title": "Inbox not warmed up",
"status": 422,
"detail": "A first cold email from a Mailbox that has not finished warming.",
"fix": "Wait for the warm-up to finish, 14 days from day 0; warm intros keep running." ,
"next": {
"verb": "Mailbox.warm",
"input": {}
},
"instance": "https://api.sb/leaseline.app/actions/action_1"
}When it waits
Returns in one response; nothing waits.
Example
Send Rosa at Northgate Rentals my follow-up at 9:10 a.m. her time on
Thursday.To retry, send the same Idempotency-Key: the retry returns the first answer for $0. A new key reads again.
Test values
A sk_test_ key answers these the same way every time, at $0 (every test value).
| Test value | Always returns | What it is for |
|---|---|---|
msg_test_unwarmed | Refuses with mailbox-warm | Its Mailbox is on day 6 of a 14-day warm-up, so the first cold email holds until the warm-up ends. |
maxCost: | Refuses with max-cost | Any priced call with a maxCost of 0.0001 is refused before it spends: the price is above the cap. |
rate-limited.test | Refuses with rate-limited | Any call naming this hostname answers 429 with Retry-After, so your retry logic runs. |
sources-busy.test | Refuses with sources-busy | Any call naming this hostname answers 503 as if every route were busy, and nothing is spent. |
Used by
- Workflows: Review requests
- Agent tasks: Referral ask · Link pitches · Upgrade note at the limit · Save and win back
- Jobs: Earn first links · Keep and grow customers · Reach out
- Integrations: Gmail · LinkedIn · Outlook · X account