Reply attempt
A reply attempt is the durable record of one request to answer one stored message. It separates local intent from SMTP acceptance and makes caller retries idempotent.
Overview#
A reply attempt is the durable record of one request to answer one stored message. It separates local intent from SMTP acceptance and makes caller retries idempotent.
Shape#
The resource contains id, message_id, idempotency_key, the plain-text body, status, optional provider_message_id, optional error_code/error_message, and created_at, updated_at, and optional sent_at timestamps.
State machine#
pending -> sending -> sent
-> failed
-> uncertainSkrzynka inserts pending before resolving credentials or opening SMTP, immediately records sending, and then records the terminal evidence. sent means the configured SMTP server accepted the message; it does not prove final recipient delivery. A task that disappears after send begins becomes uncertain with REPLY_UNCERTAIN. On database startup, any attempt left in sending is also recovered as uncertain.
These five values are one enum, DeliveryStatus, shared with the outbound message that a mailbox originates rather than answers. The serialized values are identical in both resources; only the stored error_code differs, REPLY_UNCERTAIN against OUTBOUND_UNCERTAIN.
Idempotency#
The idempotency key is database-unique. Repeating the same key with the same message and normalized body returns the existing attempt without sending again. Reusing it for another message or body is refused. A retry after failed or uncertain must use a new key and therefore expresses a new provider mutation.
CLI callers may omit the key; Skrzynka generates a fresh UUID. Retrying automation should supply and retain its own key.
Message construction#
The reply uses the source mailbox's From, targets Reply-To or From, prefixes Re: only when absent, emits a new local Message-ID, and preserves thread headers. The body is UTF-8 plain text; the SMTP server accepts or refuses its size. SMTP requires STARTTLS or implicit TLS and uses password or Gmail XOAUTH2 credentials resolved for the source mailbox.
Refusals#
IDEMPOTENCY_KEY_INVALID—idempotency_key must contain non-whitespace characters only.IDEMPOTENCY_KEY_REUSED—idempotency key already belongs to a different reply request.IDEMPOTENCY_CONFLICT—reply request already exists.REPLY_BODY_INVALID—reply body must not be empty.MESSAGE_REPLY_TARGET_INVALID—message has no valid Reply-To or From address.REPLY_MESSAGE_INVALID—reply could not be encoded as an email message.SMTP_TLS_FAILED,SMTP_REJECTED, andSMTP_UNCERTAINdescribe provider-facing failure boundaries; see the runbook.
A mailbox deletion cascades to all of its reply evidence. See message. Mail this mailbox originates instead of answering is an outbound message, a separate resource with its own recipients and subject.