1. Start
  2. Concepts

The terms used throughout these docs, from the largest container down to a single delivery attempt.

​
Organization

Your organization is the account you join when you accept an invitation. Everything you create belongs to it. Greatwait takes the organization from your signed-in session or your credential, never from anything in a request.

​
Project

A project holds schedules, destinations, and API credentials. A signed-in person creates projects in the dashboard: projects.create accepts only a signed-in session, never an API credential.

​
Environment

An environment separates work inside a project. Every resource and every API credential belongs to exactly one project and one environment.

A credential acts in exactly one project and environment, and nothing you send can widen that. The organization, project, and environment come from the verified credential, never from a request body, query string, or path. A resource that belongs to another project or environment answers not_found, exactly as if it did not exist.

​
API credential

An API credential lets your code, the CLI, or an agent call the API. A signed-in person creates one in the dashboard (credentials.create accepts only a signed-in session). Its secret is shown once, when it is created, and can never be read back. Keep it in an environment variable or a secret store, not on a command line.

A credential’s scopes are named resource:action and can be no wider than the creating member’s role allows.

​
Destination (endpoint)

A destination is the HTTPS address callbacks are delivered to. The API calls it an endpoint: endpoints.create, and identifiers that start with ep_.

  • The URL must be HTTPS on port 443, contain no username, password, or fragment, and resolve only to public addresses.
  • The endpoints.create response is the only API response that includes the signing secret, in secret (with its keyId, marked shownOnce: true). Your receiver uses it to verify callbacks, so store it when you create the endpoint. A signed-in member can reveal it again from the endpoint’s page in the dashboard. API credentials cannot.
  • A disabled endpoint receives nothing. endpoints.enable turns it back on.

Signing keys can be rotated. See Verifying callbacks.

​
Schedule

A schedule (sch_) says when to call which endpoint, and what data to send. Give exactly one of:

FieldKindMeaning
atone-shotAn instant, in RFC 3339 UTC with milliseconds, such as 2026-07-28T15:00:00.000Z
delaySecondsone-shotA delay, converted to an absolute instant when the request is accepted
everySecondsrecurringA fixed interval
cronrecurringA wall-clock expression, read in the timeZone sent with it

A schedule can be paused (schedules.pause), resumed (schedules.resume), replaced with a new definition (schedules.replace), cancelled (schedules.cancel), and archived (schedules.archive). Recurrence and time zones covers the recurring kinds.

​
Occurrence

An occurrence (occ_) is one planned run of a schedule, due at plannedFor. A recurring schedule plans one occurrence at a time: the next is planned once the current one is due.

stateMeaning
plannedWaiting for its instant.
dueIts instant has arrived and it is waiting to be dispatched.
dispatchingA delivery attempt is in progress.
retry_waitAn attempt failed in a way worth retrying, and the next attempt is waiting.
ambiguousThe last attempt got no answer, so your receiver may have acted. It will be tried again.
succeededDelivered. Final.
terminal_failedDelivery stopped without success. Final.
cancelledThe schedule was cancelled before this occurrence was delivered. Final.
skipped_staleNot delivered: it came due too late to run, or its schedule was replaced first. Final.

​
Attempt

An attempt (att_) is one try at delivering an occurrence. Attempts never change after they are recorded, so an occurrence’s attempts are its delivery history.

stateMeaning
succeededYour receiver answered 2xx.
retryable_failureYour receiver answered with a status worth retrying.
terminal_failureYour receiver answered with a status that retrying will not change.
ambiguousNo answer came back, for example a timeout or dropped connection. It may have run.

Each attempt also records attemptNumber, startedAt, durationMs, responseStatus when there was a response, a diagnostic naming the classified cause, a remediation naming the next action, and a trigger: automatic for Greatwait’s own attempts, or redelivery when a person asked for the occurrence to be delivered again. Failures and retries explains how to read them.

​
Problem details

Every error response is an RFC 9457 problem document, served as application/problem+json.

FieldAlways presentMeaning
codeyesA stable, machine-readable name for the refusal, such as not_found.
statusyesThe HTTP status.
titleyesA short human-readable summary. It can change.
typeyesabout:blank.
detailnoA human-readable explanation. It can change.
errorsnoField problems, each with a JSON pointer to the field and a reason.
retryAfterSecondsnoHow long to wait before trying again.
traceIdnoAn identifier for this request.

Branch on code, never on title or detail. The problem codes reference lists what each code means. Of the codes, only rate_limited and service_unavailable are worth retrying unchanged.

​
Identifiers and time

Identifiers are opaque strings with a type prefix, such as sch_, occ_, att_, and ep_. Compare them for equality only. Instants are always RFC 3339 in UTC with millisecond precision and a literal Z.