{"openapi":"3.1.0","info":{"title":"AhaSend (BYOK) API","version":"0.1.0","description":"AhaSend (BYOK) lets an AI assistant read your own AhaSend data through the AhaSend API with a key you supply (AhaSend API key (v2, starts with aha-sk-, with read scopes)). Read-only: 10 tools (get_account, list_messages, list_campaigns, get_campaign_stats, list_domains, list_suppressions, list_webhooks, list_templates, list_lists, get_deliverability_report). The BYOK key travels with each...\n\nEvery operation is read-only or compute-only. The same tools are available over MCP (streamable HTTP) at https://byok-ahasend.connectorbay.com/mcp.","contact":{"name":"Unify Dynamics LLC","email":"agent@connectorbay.com","url":"https://connectorbay.com/byok-ahasend/docs"},"termsOfService":"https://connectorbay.com/byok-ahasend/terms"},"servers":[{"url":"https://byok-ahasend.connectorbay.com"}],"externalDocs":{"url":"https://connectorbay.com/byok-ahasend/docs"},"security":[{"upstreamKey":[]}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"Optional. A Pro API key raises rate limits; no credentials are required."},"upstreamKey":{"type":"apiKey","in":"header","name":"X-Upstream-Key","description":"Your own key for the service this connector wraps (bring your own key). Used for that one call only; never stored, logged or cached."}},"schemas":{"Error":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object"}}}}},"paths":{"/v1/tools/get_account":{"post":{"operationId":"get_account","summary":"Show the account name, website, open and click tracking settings and message retention periods. Use for \"What are my Aha","description":"Show the account name, website, open and click tracking settings and message retention periods. Use for \"What are my AhaSend account tracking and retention settings\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"account_id":{"description":"AhaSend account ID (a UUID), shown in the dashboard and returned with your API keys.","maxLength":200,"title":"Account Id","type":"string"}},"required":["account_id"],"title":"get_accountArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_messages":{"post":{"operationId":"list_messages","summary":"List sent message summaries (without body) filtered by status, sender, recipient, subject, tags and time range, newest f","description":"List sent message summaries (without body) filtered by status, sender, recipient, subject, tags and time range, newest first, with cursor paging. Use for \"Which emails bounced or failed on AhaSend recently\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"account_id":{"description":"AhaSend account ID (a UUID), shown in the dashboard and returned with your API keys.","maxLength":200,"title":"Account Id","type":"string"},"status":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Comma-separated statuses, for example 'Bounced,Failed'. Values: Received, Delivered, Opened, Clicked, Deferred, Bounced, Failed, Suppressed, and Sandbox variants.","title":"Status"},"sender":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Sender email address to filter by.","title":"Sender"},"recipient":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Recipient email address to filter by.","title":"Recipient"},"subject":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Subject text to filter by.","title":"Subject"},"tags":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Comma-separated tags (at most 20).","title":"Tags"},"from_time":{"anyOf":[{"maxLength":40,"type":"string"},{"type":"null"}],"default":null,"description":"Only messages created after this RFC 3339 time, for example 2026-01-01T00:00:00Z.","title":"From Time"},"to_time":{"anyOf":[{"maxLength":40,"type":"string"},{"type":"null"}],"default":null,"description":"Only messages created before this RFC 3339 time.","title":"To Time"},"limit":{"anyOf":[{"maximum":100,"minimum":1,"type":"integer"},{"type":"null"}],"default":25,"description":"How many results to return (1 to 100).","title":"Limit"},"after":{"anyOf":[{"maxLength":300,"type":"string"},{"type":"null"}],"default":null,"description":"Pagination cursor: the next_cursor value from the previous answer.","title":"After"}},"required":["account_id"],"title":"list_messagesArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_campaigns":{"post":{"operationId":"list_campaigns","summary":"List marketing campaigns with name, subject, status and schedule, optionally only one status. Use for \"Which AhaSend cam","description":"List marketing campaigns with name, subject, status and schedule, optionally only one status. Use for \"Which AhaSend campaigns are scheduled or sending\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"account_id":{"description":"AhaSend account ID (a UUID), shown in the dashboard and returned with your API keys.","maxLength":200,"title":"Account Id","type":"string"},"status":{"anyOf":[{"enum":["draft","validating","waiting_for_review","scheduled","sending","paused","sent","canceled","failed"],"type":"string"},{"type":"null"}],"default":null,"description":"Only campaigns in this status.","title":"Status"},"limit":{"anyOf":[{"maximum":100,"minimum":1,"type":"integer"},{"type":"null"}],"default":25,"description":"How many results to return (1 to 100).","title":"Limit"},"after":{"anyOf":[{"maxLength":300,"type":"string"},{"type":"null"}],"default":null,"description":"Pagination cursor: the next_cursor value from the previous answer.","title":"After"}},"required":["account_id"],"title":"list_campaignsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_campaign_stats":{"post":{"operationId":"get_campaign_stats","summary":"Get one campaign's recipients, delivered, opens, clicks, unsubscribes and complaints counts with open, click, bounce and","description":"Get one campaign's recipients, delivered, opens, clicks, unsubscribes and complaints counts with open, click, bounce and deferral rates. Use for \"How did my AhaSend campaign perform: opens and clicks\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"account_id":{"description":"AhaSend account ID (a UUID), shown in the dashboard and returned with your API keys.","maxLength":200,"title":"Account Id","type":"string"},"campaign_id":{"description":"Campaign ID from list_campaigns.","maxLength":200,"title":"Campaign Id","type":"string"}},"required":["account_id","campaign_id"],"title":"get_campaign_statsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_domains":{"post":{"operationId":"list_domains","summary":"List sending domains with DNS validity, sending type (transactional or marketing), tracking subdomains and paused state.","description":"List sending domains with DNS validity, sending type (transactional or marketing), tracking subdomains and paused state. Use for \"Are my AhaSend sending domains verified\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"account_id":{"description":"AhaSend account ID (a UUID), shown in the dashboard and returned with your API keys.","maxLength":200,"title":"Account Id","type":"string"},"dns_valid":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":null,"description":"True for domains with valid DNS only, false for invalid ones.","title":"Dns Valid"},"sending_type":{"anyOf":[{"enum":["transactional","marketing"],"type":"string"},{"type":"null"}],"default":null,"description":"Only this sending type.","title":"Sending Type"},"limit":{"anyOf":[{"maximum":100,"minimum":1,"type":"integer"},{"type":"null"}],"default":25,"description":"How many results to return (1 to 100).","title":"Limit"},"after":{"anyOf":[{"maxLength":300,"type":"string"},{"type":"null"}],"default":null,"description":"Pagination cursor: the next_cursor value from the previous answer.","title":"After"}},"required":["account_id"],"title":"list_domainsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_suppressions":{"post":{"operationId":"list_suppressions","summary":"List suppressed recipient addresses with domain, reason and expiry, filtered by domain, email or time. Use for \"Which ad","description":"List suppressed recipient addresses with domain, reason and expiry, filtered by domain, email or time. Use for \"Which addresses are on my AhaSend suppression list\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"account_id":{"description":"AhaSend account ID (a UUID), shown in the dashboard and returned with your API keys.","maxLength":200,"title":"Account Id","type":"string"},"domain":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Only suppressions for this sending domain.","title":"Domain"},"email":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Only this recipient email address.","title":"Email"},"from_time":{"anyOf":[{"maxLength":40,"type":"string"},{"type":"null"}],"default":null,"description":"Only entries created after this RFC 3339 time.","title":"From Time"},"to_time":{"anyOf":[{"maxLength":40,"type":"string"},{"type":"null"}],"default":null,"description":"Only entries created before this RFC 3339 time.","title":"To Time"},"limit":{"anyOf":[{"maximum":100,"minimum":1,"type":"integer"},{"type":"null"}],"default":25,"description":"How many results to return (1 to 100).","title":"Limit"},"after":{"anyOf":[{"maxLength":300,"type":"string"},{"type":"null"}],"default":null,"description":"Pagination cursor: the next_cursor value from the previous answer.","title":"After"}},"required":["account_id"],"title":"list_suppressionsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_webhooks":{"post":{"operationId":"list_webhooks","summary":"List webhooks with name, enabled flag, subscribed event types, scope, and success and error counters. The webhook URL is","description":"List webhooks with name, enabled flag, subscribed event types, scope, and success and error counters. The webhook URL is left out. Use for \"Are my AhaSend webhooks healthy\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"account_id":{"description":"AhaSend account ID (a UUID), shown in the dashboard and returned with your API keys.","maxLength":200,"title":"Account Id","type":"string"},"enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"default":null,"description":"True for enabled webhooks only, false for disabled.","title":"Enabled"},"limit":{"anyOf":[{"maximum":100,"minimum":1,"type":"integer"},{"type":"null"}],"default":25,"description":"How many results to return (1 to 100).","title":"Limit"},"after":{"anyOf":[{"maxLength":300,"type":"string"},{"type":"null"}],"default":null,"description":"Pagination cursor: the next_cursor value from the previous answer.","title":"After"}},"required":["account_id"],"title":"list_webhooksArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_templates":{"post":{"operationId":"list_templates","summary":"List email templates with name, subject, preheader, editor and whether a draft exists. Template content is left out. Use","description":"List email templates with name, subject, preheader, editor and whether a draft exists. Template content is left out. Use for \"What email templates do I have in AhaSend\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"account_id":{"description":"AhaSend account ID (a UUID), shown in the dashboard and returned with your API keys.","maxLength":200,"title":"Account Id","type":"string"},"limit":{"anyOf":[{"maximum":100,"minimum":1,"type":"integer"},{"type":"null"}],"default":25,"description":"How many results to return (1 to 100).","title":"Limit"},"after":{"anyOf":[{"maxLength":300,"type":"string"},{"type":"null"}],"default":null,"description":"Pagination cursor: the next_cursor value from the previous answer.","title":"After"}},"required":["account_id"],"title":"list_templatesArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_lists":{"post":{"operationId":"list_lists","summary":"List contact lists with name, description, tags and contact count, optionally filtered by name. Use for \"How many contac","description":"List contact lists with name, description, tags and contact count, optionally filtered by name. Use for \"How many contacts are in each AhaSend list\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"account_id":{"description":"AhaSend account ID (a UUID), shown in the dashboard and returned with your API keys.","maxLength":200,"title":"Account Id","type":"string"},"name":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Only lists matching this name.","title":"Name"},"limit":{"anyOf":[{"maximum":100,"minimum":1,"type":"integer"},{"type":"null"}],"default":25,"description":"How many results to return (1 to 100).","title":"Limit"},"after":{"anyOf":[{"maxLength":300,"type":"string"},{"type":"null"}],"default":null,"description":"Pagination cursor: the next_cursor value from the previous answer.","title":"After"}},"required":["account_id"],"title":"list_listsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_deliverability_report":{"post":{"operationId":"get_deliverability_report","summary":"Get transactional delivery counts per time bucket: received, delivered, deferred, bounced, failed, suppressed, opened an","description":"Get transactional delivery counts per time bucket: received, delivered, deferred, bounced, failed, suppressed, opened and clicked. Use for \"What was my AhaSend delivery and bounce count per day this month\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"account_id":{"description":"AhaSend account ID (a UUID), shown in the dashboard and returned with your API keys.","maxLength":200,"title":"Account Id","type":"string"},"from_time":{"anyOf":[{"maxLength":40,"type":"string"},{"type":"null"}],"default":null,"description":"Start of range as RFC 3339 time.","title":"From Time"},"to_time":{"anyOf":[{"maxLength":40,"type":"string"},{"type":"null"}],"default":null,"description":"End of range as RFC 3339 time.","title":"To Time"},"sender_domain":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Only this sender domain.","title":"Sender Domain"},"recipient_domains":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Only these recipient domains (comma-separated).","title":"Recipient Domains"},"tags":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Only messages with these tags (comma-separated).","title":"Tags"},"group_by":{"anyOf":[{"enum":["hour","day","week","month"],"type":"string"},{"type":"null"}],"default":"day","description":"Bucket size.","title":"Group By"}},"required":["account_id"],"title":"get_deliverability_reportArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}}}}