ahasend 1.0.0
ahasend: ^1.0.0 copied to clipboard
Pure Dart client for the AhaSend email API v2, with webhook signature verification. Works on the Dart VM, Flutter and the web.
1.0.0 #
AhaSend changes message IDs in the API and in webhooks on 9 November 2026. This release follows those changes. See Important: two changes to message IDs in the AhaSend API and webhooks.
Breaking changes #
These come from the API, not from the package's Dart API: code built against 0.1.0 still compiles, but values change from 9 November 2026.
CreateSingleMessageResponse.id(frommessages.create,messages.createFromTemplateandmessages.createConversation) is a bare UUID instead of the Message-ID header (<…@…>). If you compare it withMessageEventData.messageIdHeaderof webhook events, or pass it as themessageIdHeaderfilter ofmessages.list, use the newCreateSingleMessageResponse.messageIdHeaderinstead, ormessageIdHeader ?? idto also cover responses from before the change.messages.getandmessages.cancelaccept both forms, so stored IDs keep working.MessageEventData.idandMessageClickedEventData.idin message webhook events are the API message ID (a hyphenated UUID of 36 characters, the same value asCreateSingleMessageResponse.id) instead of the internal AhaSend ID (32 hex characters). A message sent before 9 November 2026 can receive events with both IDs for up to 30 days: group events bymessageIdHeader, which does not change. If you validate the format ofid, accept the new one. The old and the new ID are different values, not the same UUID in two spellings. Campaign messages send the same events with the same ID format, butmessages.getcannot fetch campaign messages by it.
Changes #
- New
CreateSingleMessageResponse.messageIdHeader: the Message-ID header of the sent email exactly as sent, including the angle brackets. ThemessageIdHeaderfilter ofmessages.listis an exact match on it. It isnullwhen the message was not sent, in responses from before 9 November 2026, and in idempotent replays of such requests (for up to 24 hours). - Documentation of
CreateSingleMessageResponse.id,MessageEventData.id,MessageEventData.messageIdHeader, the click event data,messages.get,messages.canceland themessageIdHeaderfilter ofmessages.listdescribes the new IDs, the forms each accepts, and which one to use for matching sends with webhook events. - Bundled OpenAPI and webhook specs updated for the new fields and ID formats.
0.1.0 #
- Initial release.
- Client for the complete AhaSend API v2 (101 operations): messages, templates, campaigns, campaign templates, contacts, lists, suppressions, domains, webhooks, routes, SMTP credentials, API keys, accounts, sub-accounts and statistics.
- Automatic retries with exponential backoff and
Retry-Aftersupport. - Automatic idempotency keys for operations that support them.
- Cursor pagination with
CursorPageandlistAllstreams. - Typed exception hierarchy.
- Forward compatible: enums are extension types that keep values the API
adds later, and new webhook event types arrive as
UnknownWebhookEvent, so neither breaks existing code. client.forAccount(id, apiKey: ...)to work inside sub-accounts over the same connection.AhaSendClientand its resources are interface classes, so they can be faked or mocked in tests.package:ahasend/webhooks.dart: webhook and route signature verification and typed event models. Verification failures (WebhookVerificationException) are kept apart from authentic payloads that cannot be decoded (InvalidPayloadException).