SendResult or throws a RepostException subclass that tells you exactly what happened and whether the event may already have reached Repost. This page covers the outcome model end to end.
Idempotency
Repost dedupes on the idempotency key. When you don’t pass one, the runtime mints a stable key per operation and reuses it across every internal retry, so a flaky connection cannot produce a duplicate. That minted key protects only the retries inside that one call. To make repeats safe across process restarts and queue redeliveries, pass your own key naming the business fact:Delivery outcomes
Every failure is aRepostException carrying a stable ErrorCode, a best-known DeliveryState, the IdempotencyKey, the started AttemptCount, and a Retryable flag — never a raw server body, header, or nested exception. The five delivery states:
RepostConfigurationException (bad config), RepostValidationException (your model failed validation, NotSent), RepostSerializationException, RepostTransportException (connect/TLS/timeout/cancel/overload), RepostPublishException (the server rejected the request or returned a retryable failure), and RepostDescriptorVersionException (regenerate or upgrade — the generated client and runtime are incompatible).
What retries automatically
Up to three retries follow the initial attempt (four attempts total by default). Retryable outcomes include DNS, connect, proxy, TLS, and I/O failures, an attempt timeout,5xx, 429, 409, and a malformed 2xx body. Any other 4xx (400, 401, 403, 413, …) is thrown immediately. Backoff is full jitter in integer milliseconds from zero through min(60_000, RetryBaseDelay × 2^(attempt−1)); a valid Retry-After delta or HTTP-date raises that delay, still capped at 60 seconds. Each attempt gets a fresh timeout budget; the whole operation is bounded by OperationTimeout.
A payload over 1 MiB is rejected before the first attempt with a RepostSerializationException (RequestTooLarge), so an oversized event never reaches the network.
Cancellation
Every send method takes an optionalCancellationToken. Cancelling before the request commits settles NotSent; cancelling after it may have been written settles CancelledUnknown — reconcile with the same key. Either way the operation settles exactly once and closes only the work it owns.
Bounded admission
MaxInFlightOperations is a hard bulkhead, not a queue. When more operations are in flight than the budget allows, a new send is rejected immediately with a RepostTransportException whose ErrorCode is Overloaded and DeliveryState is NotSent — the runtime never buffers unbounded work or paces your traffic. Treat it as backpressure and retry with the same key.
What goes on the wire
Payloads serialize deterministically: model fields in schema declaration order under their wire names, absent optional fields omitted (or their@default injected), explicit null only where the schema allows it, and timestamps in the ISO-8601 millisecond UTC form. Unknown input properties are dropped, and a value you provide is never overridden by a default.
Continue
Testing
Exercise these paths without a network.
Configuration
The transport options behind the retry behavior.
Delivery & retries
What happens to the message once Repost accepts it.