Scheduled messages
Schedule, list, edit and cancel one-time reminders to your own Slack DM over the API.
A scheduled message is a one-time reminder that nima sends to your own Slack DM at a time you choose. You save the exact text and the send time now. At that time nima posts the saved text as a plain direct message from the nima bot to your linked Slack account. Nothing is researched, run or rewritten later, and a reminder never goes to a channel or to another person.
On for every workspace. A reminder needs your Slack account linked to nima in
the workspace; without the link, scheduling fails with 400. Scheduled
messages do not depend on the workspace triggersEnabled setting that
watches need. For the concept, see
Watches and reminders.
Operations for scheduled messages
| Method | Path | Scope | MCP tool |
|---|---|---|---|
GET | /v1/scheduled-messages/context | subscriptions:read | get_scheduling_context |
POST | /v1/scheduled-messages | subscriptions:write | schedule_message |
GET | /v1/scheduled-messages | subscriptions:read | list_scheduled_messages |
PATCH | /v1/scheduled-messages/{id} | subscriptions:write | update_scheduled_message |
DELETE | /v1/scheduled-messages/{id} | subscriptions:write | cancel_scheduled_message |
Paths are relative to https://api.getnima.io. Every call carries
Authorization: Bearer <your key> and needs the scope in the table. The routes
are personal: you only ever see and change your own reminders. Another person's
reminder id answers 404, exactly like a missing one. Every call also
re-checks that you are still an owner, admin or member of the workspace; if not,
it answers 403 INSUFFICIENT_PERMISSIONS. See
Scopes and permissions and Errors.
Get the scheduling context
/v1/scheduled-messages/contextsubscriptions:readMCP toolget_scheduling_contextReturns the current time, a suggested time zone and whether your Slack account is linked. Call it before you schedule, so you can confirm the zone with the person instead of guessing.
nowstringThe server time, ISO 8601 UTC.
suggestedTimeZonestringAn IANA zone. nima takes it from your Slack profile time zone (cached for 24
hours) and falls back to UTC when Slack does not answer. It is a
suggestion, not a setting: nima has no per-user time zone, so confirm it.
slackConnectedbooleantrue when the workspace has a Slack install and your account is mapped to a
Slack user. Scheduling needs true.
guidancestringA short reminder to confirm the zone and ask for a clock time when only a date is given.
Schedule a message
/v1/scheduled-messagessubscriptions:writeMCP toolschedule_messageSaves a one-time reminder and returns it in state pending. The request is
idempotent per requestKey: send the same key when you retry.
requestKeystringrequiredA stable idempotency key you choose, 1 to 128 characters. Reuse it on a retry.
messagestringrequiredThe exact text to send, 1 to 12,000 characters after trimming leading and trailing whitespace. It is otherwise sent as written.
sendAtstringrequiredISO 8601 datetime with a UTC offset, for example 2026-10-05T09:00:00+03:00.
It must be in the future and no more than 366 days ahead.
timeZonestringrequiredA confirmed IANA zone, 1 to 100 characters, such as Asia/Jerusalem. nima
checks it is a real zone and uses it to render localDeliveryTime.
Unknown fields are rejected. The response is a ScheduleDto.
A retry with the same requestKey returns the original reminder, even after its
due time. Reusing a requestKey with a different message, sendAt or
timeZone answers 409; edit the reminder by id instead.
Errors when scheduling
| Status | error | When |
|---|---|---|
400 | VALIDATION_ERROR | The body does not match the schema. details.issues names the field. |
400 | VALIDATION_ERROR | "Choose a future time within the next 366 days": sendAt is in the past or more than 366 days out. |
400 | VALIDATION_ERROR | "Choose a valid IANA timezone". |
400 | VALIDATION_ERROR | "Link your Slack account in this workspace before scheduling a message". |
403 | INSUFFICIENT_PERMISSIONS | Your role no longer allows managing reminders, or the key lacks subscriptions:write. |
409 | CONFLICT | You already have 100 pending reminders. Cancel one first. |
409 | CONFLICT | The requestKey already belongs to a different reminder. |
409 | CONFLICT | Scheduled messages are switched off platform-wide (an operator kill switch; on today). |
List scheduled messages
/v1/scheduled-messagessubscriptions:readMCP toollist_scheduled_messagesReturns your own reminders as an array of ScheduleDto,
at most 200. Pending reminders come first, ordered by sendAt ascending. Every
other reminder (delivering, sent, cancelled, failed and uncertain) follows,
latest sendAt first. The 200 cap covers both groups together. There are no
query parameters and no pagination.
Read id and version from this list before you edit or cancel a reminder. A
reminder in state uncertain may or may not have reached Slack: check Slack
before you tell anyone it was sent.
Edit a scheduled message
/v1/scheduled-messages/{id}subscriptions:writeMCP toolupdate_scheduled_messageChanges the text, time or time zone of a reminder that is still pending, and
returns it with version increased. The new time is validated again with the
same rules as scheduling.
versionintegerrequiredThe current version from the list, 1 or more. It stops you overwriting a
change made in between.
messagestringNew text, 1 to 12,000 characters.
sendAtstringNew send time, ISO 8601 with a UTC offset, future and within 366 days.
timeZonestringNew confirmed IANA zone.
Fields you omit keep their current value. Unknown fields are rejected. The MCP
tool takes the same fields plus id.
Errors when editing
| Status | error | When |
|---|---|---|
400 | VALIDATION_ERROR | The body does not match the schema, or the new time or zone is invalid. |
403 | INSUFFICIENT_PERMISSIONS | Your role no longer allows managing reminders, or the key lacks subscriptions:write. |
404 | RESOURCE_NOT_FOUND | The id does not exist or is not yours. |
409 | CONFLICT | The reminder is no longer pending, delivery has started, or version is stale. List reminders again before editing. |
409 | CONFLICT | Scheduled messages are switched off platform-wide (on today). |
Cancel a scheduled message
/v1/scheduled-messages/{id}subscriptions:writeMCP toolcancel_scheduled_messageCancels a pending reminder. It answers 200 with the reminder in state
cancelled, not 204, and the row stays in your list as history. Cancelling an
already cancelled reminder returns it unchanged.
Errors when cancelling
| Status | error | When |
|---|---|---|
403 | INSUFFICIENT_PERMISSIONS | Your role no longer allows managing reminders, or the key lacks subscriptions:write. |
404 | RESOURCE_NOT_FOUND | The id does not exist or is not yours. |
409 | CONFLICT | The reminder is no longer pending (delivering, sent, failed or uncertain) or changed in between, so cancellation was not confirmed. |
The schedule object
Every operation except the context call returns a ScheduleDto (the list
returns an array of them).
idstringThe reminder id, a UUID.
messagestringThe saved text.
sendAtstringThe send time, ISO 8601 UTC.
localDeliveryTimestringThe same moment written out in timeZone, for showing back to a person.
timeZonestringThe IANA zone you gave.
stateenumOne of the states below.
versionintegerStarts at 1 and increases with each edit. Send it back when editing.
deliverystringAlways slack_dm.
sentAtstring | nullWhen Slack confirmed the post, otherwise null.
failureReasonstring | nullWhy a reminder ended failed or uncertain, otherwise null.
createdAtstringWhen the reminder was saved, ISO 8601 UTC.
Scheduled message states
A scheduled message moves pending to delivering to sent, failed or
uncertain, or from pending to cancelled. Only pending reminders can be
edited or cancelled.
| State | Meaning |
|---|---|
pending | Waiting for sendAt. The only state you can edit or cancel. |
delivering | A worker has claimed it and is posting. Edit and cancel answer 409. |
sent | Slack confirmed the post. sentAt is set. |
cancelled | Cancelled before delivery. |
failed | Not sent. failureReason says why, for example membership_or_permission_revoked when you lost access before the send, or a refusal such as no_installation, not_a_member or not_mapped when the Slack link is missing. |
uncertain | Delivery could not be confirmed: the Slack post failed (post_failed) or a worker stopped mid-delivery (delivery_interrupted). nima never resends an uncertain reminder, so it cannot arrive twice. |
Delivery timing and limits for scheduled messages
nima checks for due reminders every 60 seconds, so a reminder arrives within
about a minute of sendAt. Each check queues at most 100 due reminders, and any
beyond that go out on the next check. Each due reminder is delivered as its own
job. The Slack post itself is attempted once: a job that fails before the post
is retried up to 3 times, and a failed post ends uncertain rather than being
retried. A reminder stuck in delivering for more than 5 minutes becomes
uncertain.
| Limit | Value |
|---|---|
| Pending reminders per person | 100 |
Furthest sendAt | 366 days ahead |
| Message length | 12,000 characters |
| Reminders returned by the list | 200 |
| Destination | Your own linked Slack DM only. Not channels, other people or email. |
| Recurrence | None. Each reminder is sent once. |