Message observability

  • Message timeline: every message records each step with a timestamp (accepted → validated → queued → sent_to_carrier → carrier_accepted → delivered/failed; inbound: received) as timeline on GET /v1/messages/{id}.
  • segments, encoding, price, destination_carrier on every message.
  • Readable failures: failed messages, message.failed events, and refused sends (opt-out, content block, rate limit, spend limit) carry a failure object with a stable code, a plain explanation, and what to do. See delivery failures.
  • List filters: status, direction, to, from, created_after, created_before (alongside customer_id) on GET /v1/messages, with full pages. Automatic carrier retries show up on the timeline per attempt.
  • Sandbox numbers for every failure, opt-out, rate limiting, and a really delayed delivery. The happy-path number now settles to delivered instead of staying sent.
  • Idempotency-Key now applies to scheduled sends too.
  • Console: message filters and a message inspector (timeline latencies, cost, failure, related webhook events).

All changes