Skip to content

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

NameTypeDefaultMeaning
messageMessageRequiredThe Message to hold.
atdatetimeRequiredWhen it goes out.

Outputs

FieldTypeWhat null means
messageMessageNever null.
message.fromstringNever null: the Mailbox address it sends from.
message.tostringNever null for email: the one recipient.
message.subjectstringNull for a medium with no subject line, such as SMS.
message.purposestringNever 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 against at and renders the Message; nothing is held or sent.
  • send: Returns the held Message at once; it sends at at.
  • do: Returns the held Message at once; it sends at at.
Idempotency

Only with a key: the same Idempotency-Key and input return the first Action, and the same key with other input returns 409. Scheduling a held Message again moves it to the new at; it never sends twice.

Saved or shared

The Message is saved on its Contact and held as a pending Action, reason: 'awaitingTime', until at. Canceling that Action before then stops it.

Emits

Message.scheduled with { message, at }

Performed by

Marketing lead

Price

Free on your own account: the platform charges nothing for the call.

On each Venue

SiteFieldsFormats
Gmailfrom, to, subject, bodyNone.
LinkedInbody3
Outlookto, subject, bodyNone.
Xbody2

Gmail

Through Gmail.

Our fieldGmail’s field
Message.fromraw: From header (Your address, or a send-as alias you set up in Gmail)
Message.toraw: To header
Message.subjectraw: Subject header (A reply keeps the thread’s subject, so Gmail threads it)
Message.bodyraw: text/plain and text/html parts
  • Replies. Gmail pushes each new message within seconds; the platform renews the mailbox watch daily, inside the 7 days Gmail allows.

LinkedIn

Through LinkedIn.

Our fieldLinkedIn’s field
Message.bodyinvitation 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.
Feed post Single image ad, 1200 × 628, 1200 × 1200 or 720 × 900 Document ad

Outlook

Through Outlook.

Our fieldOutlook’s field
Message.tomessage.toRecipients
Message.subjectmessage.subject
Message.bodymessage.body (contentType html or text)

X

Through X account.

Our fieldX account’s field
Message.bodytext
  • 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.
Standard post Promoted post

What try does

AccountWhat try does
GmailRenders the exact email, headers included, and returns it with the time it would send; nothing reaches Gmail and no draft is saved.
LinkedInPosts 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.
OutlookRenders 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 accountRenders 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

CheckErrorFixThen call
A first cold email from a Mailbox that has not finished warmingmailbox-warmWait 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 resolvedomain-authenticatedAdd 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
JSON
{
  "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

Text
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 valueAlways returnsWhat it is for
msg_test_unwarmedRefuses with mailbox-warmIts Mailbox is on day 6 of a 14-day warm-up, so the first cold email holds until the warm-up ends.
maxCost: 0.0001Refuses with max-costAny priced call with a maxCost of 0.0001 is refused before it spends: the price is above the cap.
rate-limited.testRefuses with rate-limitedAny call naming this hostname answers 429 with Retry-After, so your retry logic runs.
sources-busy.testRefuses with sources-busyAny call naming this hostname answers 503 as if every route were busy, and nothing is spent.

Used by