# Nothing leaves at 3am

Paint the hours mail may go out in, in the timezone that matters. Anything your code sends outside them waits and leaves the minute the window opens. Add a limit and it trickles out instead of landing at once.

[Get started](/signup)
[Documentation](https://docs.aiinbx.com/guides/pacing#sending-hours)

The rule editor: a Business hours rule painted on a weekly grid reads as Mon–Fri 09:00–17:00, 40 hours a week. A follow-up from nora@northwind.io to sales@lindmetall.de sent outside those hours is held, and goes out when the window next opens.

The console's editor, live. Drag to paint hours, change the zone, and the send under it is replanned by the same code that decides in production.

Whose morning

## A schedule keeps its own timezone

Nine in the morning is four different instants for an agent writing to four countries, so the zone belongs to the rule rather than to the workspace. Write one per region and point it at the people it is about — the same address patterns every pacing rule takes.

Rule “EU hours” (time lock): Mon–Fri 09:00–17:00 · Berlin, for to \*@\*.de, to \*@\*.at, to \*@\*.nl.

Rule “UK hours” (time lock): Mon–Fri 09:00–17:30 · London, for to \*@\*.co.uk.

Rule “APAC hours” (time lock): Mon–Fri 08:30–17:00 · Sydney, for to \*@\*.com.au.

Rules stack rather than compete: mail addressed into two of these leaves in the overlap, when both are open. Clock changes are the zone’s own — a window moves with the country it belongs to, on the night that country moves.

In the console

## Everything waiting for a window

The console's pacing queue: 1,284 emails waiting, the next going out tomorrow at 09:00 when the Business hours rule lets it. A bar shows what holds them back (Business hours 812, Warm-up 340, on its way 132), and every waiting email is listed with its sender, recipient, subject, send time and the rule holding it.

Held, not refused

The send is accepted the moment you call it. It sits in the queue with the hour it leaves on it, and your code has nothing to retry.

It drains itself

Nothing has to run at nine. The window opening is what releases the mail behind it, in the order it arrived.

Out of hours anyway

Something that cannot wait for Monday goes out on one click, or one call, whether or not the window was open.

In your code

## One rule, and nothing to schedule

No cron, no queue of your own, no send that has to be tried again at nine. Your code calls send when it has something to say, and the rule decides the minute it says it.

Step 1, pacingRules.create: written once, in code or in the console.

```
await aiinbx.pacingRules.create({
  name: "Business hours",
  kind: "hours",
  match: [{ field: "to", pattern: "*@*.de" }],
  schedule: {
    timezone: "Europe/Berlin",
    windows: [{ days: [0, 1, 2, 3, 4], start_minute: 540, end_minute: 1020 }],
  },
})
```

Step 2, emails.send: accepted either way, and honest about which.

```
const email = await aiinbx.emails.send(payload)

if (email.pacing?.held_by.kind === "hours") {
  console.log("goes out", email.pacing.estimated_send_at)
}
```

Step 3, the one that must not wait: password resets, login codes, security alerts.

```
await aiinbx.emails.send({
  ...reset,
  pacing: { skip: true, count: false },
})
```

Around it

## What else decides when mail leaves

Rate limits

The other kind of rule in the same list: how many may go, per sender, domain or person. Hours say when, limits say how fast, and a send answers to both.

Scheduled sends

scheduled\_at is the earliest a message may go, not a promise of the instant — one scheduled for 03:00 still waits for the window to open.

One space per customer

A schedule in a customer's space reads their mail alone. They can keep their own quiet hours inside yours, never outside them.

Replies are mail too

An agent that answers at 02:40 is the same tell as one that opens at 02:40. Hours apply to everything leaving, whatever prompted it.

## Give your product an inbox. The hard parts are already handled.

[Get started](/signup)
