From cc608b97d34ba1fe49c8e65547dba27a681e4cca Mon Sep 17 00:00:00 2001 From: Narek Hovhannisyan Date: Thu, 9 Oct 2025 19:39:55 +0400 Subject: [PATCH 01/20] examples: add example script for sending domains API usage --- examples/sending-domains/everything.ts | 39 ++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 examples/sending-domains/everything.ts diff --git a/examples/sending-domains/everything.ts b/examples/sending-domains/everything.ts new file mode 100644 index 0000000..aa06ef3 --- /dev/null +++ b/examples/sending-domains/everything.ts @@ -0,0 +1,39 @@ +import MailtrapClient from "../../src/lib/MailtrapClient"; + +const client = new MailtrapClient({ + token: "YOUR_API_TOKEN", + accountId: 12345, // Your account ID +}); + +async function sendingDomainsExample() { + try { + // Get all sending domains§ + const sendingDomains = await client.sendingDomains.getList(); + console.log("Sending domains:", sendingDomains); + + // Create a new sending domain + const newDomain = await client.sendingDomains.create({ + domain_name: "example.com", + }); + console.log("Created domain:", newDomain); + + // Get a specific sending domain by ID + const domain = await client.sendingDomains.get(newDomain.id); + console.log("Domain details:", domain); + + // Send setup instructions + const setupResponse = await client.sendingDomains.sendSetupInstructions( + newDomain.id, + "admin@example.com" + ); + console.log("Setup instructions response:", setupResponse); + + // Delete the sending domain + await client.sendingDomains.delete(newDomain.id); + console.log("Domain deleted successfully"); + } catch (error) { + console.error("Error:", error); + } +} + +sendingDomainsExample(); From c2d72be534c66c72a9c4bac6440d8b2e88e4fb57 Mon Sep 17 00:00:00 2001 From: Narek Hovhannisyan Date: Thu, 9 Oct 2025 19:40:06 +0400 Subject: [PATCH 02/20] test: add unit tests for sending domains API in MailtrapClient --- src/__tests__/lib/mailtrap-client.test.ts | 27 +++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/__tests__/lib/mailtrap-client.test.ts b/src/__tests__/lib/mailtrap-client.test.ts index 65b5890..c4123a4 100644 --- a/src/__tests__/lib/mailtrap-client.test.ts +++ b/src/__tests__/lib/mailtrap-client.test.ts @@ -13,6 +13,7 @@ import ContactLists from "../../lib/api/ContactLists"; import Contacts from "../../lib/api/Contacts"; import TemplatesBaseAPI from "../../lib/api/Templates"; import SuppressionsBaseAPI from "../../lib/api/Suppressions"; +import SendingDomainsBaseAPI from "../../lib/api/SendingDomains"; const { ERRORS, CLIENT_SETTINGS } = CONFIG; const { TESTING_ENDPOINT, BULK_ENDPOINT, SENDING_ENDPOINT } = CLIENT_SETTINGS; @@ -873,5 +874,31 @@ describe("lib/mailtrap-client: ", () => { expect(suppressionsClient).toBeInstanceOf(SuppressionsBaseAPI); }); }); + + describe("get sendingDomains(): ", () => { + it("rejects with Mailtrap error, when `accountId` is missing.", () => { + expect.assertions(1); + + const client = new MailtrapClient({ + token: "test-token", + }); + + expect(() => client.sendingDomains).toThrow( + "accountId is missing, some features of testing API may not work properly." + ); + }); + + it("returns sending domains API object when accountId is provided.", () => { + expect.assertions(1); + + const client = new MailtrapClient({ + token: "test-token", + accountId: 123, + }); + + const sendingDomainsClient = client.sendingDomains; + expect(sendingDomainsClient).toBeInstanceOf(SendingDomainsBaseAPI); + }); + }); }); }); From f9b0760974ffb7a8363d1c447417f02516623056 Mon Sep 17 00:00:00 2001 From: Narek Hovhannisyan Date: Thu, 9 Oct 2025 19:40:17 +0400 Subject: [PATCH 03/20] test: implement unit tests for SendingDomains API methods including getList, get, create, delete, and sendSetupInstructions --- .../lib/api/resources/SendingDomains.test.ts | 236 ++++++++++++++++++ 1 file changed, 236 insertions(+) create mode 100644 src/__tests__/lib/api/resources/SendingDomains.test.ts diff --git a/src/__tests__/lib/api/resources/SendingDomains.test.ts b/src/__tests__/lib/api/resources/SendingDomains.test.ts new file mode 100644 index 0000000..b30991d --- /dev/null +++ b/src/__tests__/lib/api/resources/SendingDomains.test.ts @@ -0,0 +1,236 @@ +import axios, { AxiosInstance } from "axios"; +import MockAdapter from "axios-mock-adapter"; + +import SendingDomainsBaseAPI from "../../../../lib/api/SendingDomains"; +import { + SendingDomain, + DnsRecord, + SendingDomainPermissions, + SetupInstructionsResponse, +} from "../../../../types/api/sending-domains"; + +describe("lib/api/SendingDomains: ", () => { + const axiosInstance: AxiosInstance = axios.create(); + const mock = new MockAdapter(axiosInstance); + + // Add the response interceptor that returns response.data + axiosInstance.interceptors.response.use((response) => response.data); + + const testAccountId = 100; + const sendingDomainsAPI = new SendingDomainsBaseAPI( + axiosInstance, + testAccountId + ); + + describe("class SendingDomainsBaseAPI(): ", () => { + describe("init: ", () => { + it("initializes with all necessary params.", () => { + expect(sendingDomainsAPI).toHaveProperty("get"); + expect(sendingDomainsAPI).toHaveProperty("getList"); + expect(sendingDomainsAPI).toHaveProperty("create"); + expect(sendingDomainsAPI).toHaveProperty("delete"); + expect(sendingDomainsAPI).toHaveProperty("sendSetupInstructions"); + }); + }); + + describe("sendingDomains.getList(): ", () => { + it("should get sending domains list.", async () => { + const mockDnsRecords: DnsRecord[] = [ + { + key: "verification", + domain: "ve6wza2rbpe60x7z.example.com", + type: "CNAME", + value: "smtp.mailtrap.live", + status: "pass", + name: "ve6wza2rbpe60x7z", + }, + { + key: "spf", + domain: "example.com", + type: "TXT", + value: "v=spf1 include:_spf.smtp.mailtrap.live ~all", + status: "pass", + name: "", + }, + ]; + + const mockPermissions: SendingDomainPermissions = { + can_read: true, + can_update: true, + can_destroy: true, + }; + + const mockSendingDomains: SendingDomain[] = [ + { + id: 435, + domain_name: "example.com", + demo: false, + compliance_status: "compliant", + dns_verified: true, + dns_verified_at: "2024-12-26T09:40:44.161Z", + dns_records: mockDnsRecords, + open_tracking_enabled: true, + click_tracking_enabled: true, + auto_unsubscribe_link_enabled: true, + custom_domain_tracking_enabled: true, + health_alerts_enabled: true, + critical_alerts_enabled: true, + alert_recipient_email: "john.doe@example.com", + permissions: mockPermissions, + }, + ]; + + mock + .onGet( + `https://mailtrap.io/api/accounts/${testAccountId}/sending_domains` + ) + .reply(200, mockSendingDomains); + + const result = await sendingDomainsAPI.getList(); + + expect(result).toEqual(mockSendingDomains); + }); + }); + + describe("sendingDomains.get(): ", () => { + it("should get a single sending domain by id.", async () => { + const mockDnsRecords: DnsRecord[] = [ + { + key: "verification", + domain: "ve6wza2rbpe60x7z.example.com", + type: "CNAME", + value: "smtp.mailtrap.live", + status: "pass", + name: "ve6wza2rbpe60x7z", + }, + ]; + + const mockPermissions: SendingDomainPermissions = { + can_read: true, + can_update: true, + can_destroy: true, + }; + + const mockSendingDomain: SendingDomain = { + id: 999, + domain_name: "example.com", + demo: false, + compliance_status: "compliant", + dns_verified: true, + dns_verified_at: "2024-12-26T09:40:44.161Z", + dns_records: mockDnsRecords, + open_tracking_enabled: true, + click_tracking_enabled: true, + auto_unsubscribe_link_enabled: true, + custom_domain_tracking_enabled: true, + health_alerts_enabled: true, + critical_alerts_enabled: true, + alert_recipient_email: "john.doe@example.com", + permissions: mockPermissions, + }; + + mock + .onGet( + `https://mailtrap.io/api/accounts/${testAccountId}/sending_domains/${mockSendingDomain.id}` + ) + .reply(200, mockSendingDomain); + + const result = await sendingDomainsAPI.get(mockSendingDomain.id); + + expect(result).toEqual(mockSendingDomain); + }); + }); + + describe("sendingDomains.create(): ", () => { + it("should create a new sending domain.", async () => { + const mockDnsRecords: DnsRecord[] = [ + { + key: "verification", + domain: "ve6wza2rbpe60x7z.newdomain.com", + type: "CNAME", + value: "smtp.mailtrap.live", + status: "pass", + name: "ve6wza2rbpe60x7z", + }, + ]; + + const mockPermissions: SendingDomainPermissions = { + can_read: true, + can_update: true, + can_destroy: true, + }; + + const mockSendingDomain: SendingDomain = { + id: 436, + domain_name: "newdomain.com", + demo: false, + compliance_status: "pending", + dns_verified: false, + dns_verified_at: "", + dns_records: mockDnsRecords, + open_tracking_enabled: true, + click_tracking_enabled: true, + auto_unsubscribe_link_enabled: true, + custom_domain_tracking_enabled: true, + health_alerts_enabled: true, + critical_alerts_enabled: true, + alert_recipient_email: "admin@newdomain.com", + permissions: mockPermissions, + }; + + const createParams = { + domain_name: "newdomain.com", + }; + + mock + .onPost( + `https://mailtrap.io/api/accounts/${testAccountId}/sending_domains` + ) + .reply(200, mockSendingDomain); + + const result = await sendingDomainsAPI.create(createParams); + + expect(result).toEqual(mockSendingDomain); + }); + }); + + describe("sendingDomains.delete(): ", () => { + it("should delete a sending domain by id.", async () => { + const sendingDomainId = 999; + + mock + .onDelete( + `https://mailtrap.io/api/accounts/${testAccountId}/sending_domains/${sendingDomainId}` + ) + .reply(204); + + const result = await sendingDomainsAPI.delete(sendingDomainId); + + expect(result).toBeUndefined(); + }); + }); + + describe("sendingDomains.sendSetupInstructions(): ", () => { + it("should send setup instructions for a sending domain.", async () => { + const sendingDomainId = 999; + const email = "admin@example.com"; + const mockResponse: SetupInstructionsResponse = { + message: "Setup instructions sent successfully.", + }; + + mock + .onPost( + `https://mailtrap.io/api/accounts/${testAccountId}/sending_domains/${sendingDomainId}/setup_instructions` + ) + .reply(200, mockResponse); + + const result = await sendingDomainsAPI.sendSetupInstructions( + sendingDomainId, + email + ); + + expect(result).toEqual(mockResponse); + }); + }); + }); +}); From b6449f8b00835a333cdb6f92dd5c05fe2c4d92a6 Mon Sep 17 00:00:00 2001 From: Narek Hovhannisyan Date: Thu, 9 Oct 2025 19:40:33 +0400 Subject: [PATCH 04/20] lib: add getter for SendingDomainsBaseAPI in MailtrapClient --- src/lib/MailtrapClient.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/lib/MailtrapClient.ts b/src/lib/MailtrapClient.ts index 7e22a6f..f5607d2 100644 --- a/src/lib/MailtrapClient.ts +++ b/src/lib/MailtrapClient.ts @@ -14,6 +14,7 @@ import ContactListsBaseAPI from "./api/ContactLists"; import ContactFieldsBaseAPI from "./api/ContactFields"; import TemplatesBaseAPI from "./api/Templates"; import SuppressionsBaseAPI from "./api/Suppressions"; +import SendingDomainsBaseAPI from "./api/SendingDomains"; import CONFIG from "../config"; @@ -167,6 +168,15 @@ export default class MailtrapClient { return new SuppressionsBaseAPI(this.axios, this.accountId); } + /** + * Getter for Sending Domains API. + */ + get sendingDomains() { + this.validateAccountIdPresence(); + + return new SendingDomainsBaseAPI(this.axios, this.accountId!); + } + /** * Returns configured host. Checks if `bulk` and `sandbox` modes are activated simultaneously, * then reject with Mailtrap Error. From 51a77c77e33d6c03ef6fe9f624c639267b8c9656 Mon Sep 17 00:00:00 2001 From: Narek Hovhannisyan Date: Thu, 9 Oct 2025 19:40:42 +0400 Subject: [PATCH 05/20] api: implement SendingDomainsBaseAPI class for managing sending domains --- src/lib/api/SendingDomains.ts | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/lib/api/SendingDomains.ts diff --git a/src/lib/api/SendingDomains.ts b/src/lib/api/SendingDomains.ts new file mode 100644 index 0000000..db1f623 --- /dev/null +++ b/src/lib/api/SendingDomains.ts @@ -0,0 +1,28 @@ +import { AxiosInstance } from "axios"; + +import SendingDomainsApi from "./resources/SendingDomains"; + +export default class SendingDomainsBaseAPI { + private client: AxiosInstance; + + public get: SendingDomainsApi["get"]; + + public getList: SendingDomainsApi["getList"]; + + public create: SendingDomainsApi["create"]; + + public delete: SendingDomainsApi["delete"]; + + public sendSetupInstructions: SendingDomainsApi["sendSetupInstructions"]; + + constructor(client: AxiosInstance, accountId: number) { + this.client = client; + const sendingDomains = new SendingDomainsApi(this.client, accountId); + this.get = sendingDomains.get.bind(sendingDomains); + this.getList = sendingDomains.getList.bind(sendingDomains); + this.create = sendingDomains.create.bind(sendingDomains); + this.delete = sendingDomains.delete.bind(sendingDomains); + this.sendSetupInstructions = + sendingDomains.sendSetupInstructions.bind(sendingDomains); + } +} From 808d825ad4c12a672d596a7d7d3856b88eee3db8 Mon Sep 17 00:00:00 2001 From: Narek Hovhannisyan Date: Thu, 9 Oct 2025 19:40:56 +0400 Subject: [PATCH 06/20] resources: add SendingDomainsApi class for managing sending domains with methods for listing, retrieving, creating, deleting, and sending setup instructions --- src/lib/api/resources/SendingDomains.ts | 78 +++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 src/lib/api/resources/SendingDomains.ts diff --git a/src/lib/api/resources/SendingDomains.ts b/src/lib/api/resources/SendingDomains.ts new file mode 100644 index 0000000..40613ab --- /dev/null +++ b/src/lib/api/resources/SendingDomains.ts @@ -0,0 +1,78 @@ +import { AxiosInstance } from "axios"; + +import CONFIG from "../../../config"; +import { + CreateSendingDomainParams, + SendingDomain, + SetupInstructionsResponse, +} from "../../../types/api/sending-domains"; + +const { CLIENT_SETTINGS } = CONFIG; +const { GENERAL_ENDPOINT } = CLIENT_SETTINGS; + +export default class SendingDomainsApi { + private client: AxiosInstance; + + private sendingDomainsURL: string; + + constructor(client: AxiosInstance, accountId: number) { + this.client = client; + this.sendingDomainsURL = `${GENERAL_ENDPOINT}/api/accounts/${accountId}/sending_domains`; + } + + /** + * Get a list of sending domains. + * @returns Returns the list of sending domains for the account. + */ + public async getList() { + const url = this.sendingDomainsURL; + + return this.client.get(url); + } + + /** + * Get a single sending domain by ID. + * @param id Sending domain ID + * @returns Returns a single sending domain + */ + public async get(id: number) { + const url = `${this.sendingDomainsURL}/${id}`; + + return this.client.get(url); + } + + /** + * Create a new sending domain. + */ + public async create(params: CreateSendingDomainParams) { + const url = this.sendingDomainsURL; + const data = { domain: params }; + + return this.client.post(url, data); + } + + /** + * Delete a sending domain by ID. + * @param id Sending domain ID + */ + public async delete(id: number) { + const url = `${this.sendingDomainsURL}/${id}`; + + return this.client.delete(url); + } + + /** + * Send setup instructions for a sending domain to an email address. + * @param id Sending domain ID + * @param email Email address to send setup instructions to + * @returns Returns a success message + */ + public async sendSetupInstructions(id: number, email: string) { + const url = `${this.sendingDomainsURL}/${id}/setup_instructions`; + + return this.client.post< + SetupInstructionsResponse, + SetupInstructionsResponse + >(url, { email }); + } +} From f5e1be12aae1dcf20e399c80f389e51c3396f6a5 Mon Sep 17 00:00:00 2001 From: Narek Hovhannisyan Date: Thu, 9 Oct 2025 19:41:02 +0400 Subject: [PATCH 07/20] types: add TypeScript interfaces for sending domains and DNS records --- src/types/api/sending-domains.ts | 40 ++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/types/api/sending-domains.ts diff --git a/src/types/api/sending-domains.ts b/src/types/api/sending-domains.ts new file mode 100644 index 0000000..342bd0c --- /dev/null +++ b/src/types/api/sending-domains.ts @@ -0,0 +1,40 @@ +export interface DnsRecord { + key: string; + domain: string; + type: string; + value: string; + status: string; + name: string; +} + +export interface SendingDomainPermissions { + can_read: boolean; + can_update: boolean; + can_destroy: boolean; +} + +export interface SendingDomain { + id: number; + domain_name: string; + demo: boolean; + compliance_status: string; + dns_verified: boolean; + dns_verified_at: string; + dns_records: DnsRecord[]; + open_tracking_enabled: boolean; + click_tracking_enabled: boolean; + auto_unsubscribe_link_enabled: boolean; + custom_domain_tracking_enabled: boolean; + health_alerts_enabled: boolean; + critical_alerts_enabled: boolean; + alert_recipient_email: string; + permissions: SendingDomainPermissions; +} + +export interface CreateSendingDomainParams { + domain_name: string; +} + +export interface SetupInstructionsResponse { + message: string; +} From 04166b4f7ff76c185438b9bddbff6f73129efdfa Mon Sep 17 00:00:00 2001 From: Narek Hovhannisyan Date: Fri, 10 Oct 2025 15:40:07 +0400 Subject: [PATCH 08/20] types: add documentation for ContactFields and ContactField interfaces to clarify their purpose and structure --- src/types/api/contact-fields.ts | 5 +++++ src/types/mailtrap.ts | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/src/types/api/contact-fields.ts b/src/types/api/contact-fields.ts index 410368b..2beba43 100644 --- a/src/types/api/contact-fields.ts +++ b/src/types/api/contact-fields.ts @@ -1,3 +1,8 @@ +/** + * Contact field definition/schema used for managing field types. + * Represents the structure and metadata of a contact field (e.g., field name, data type, merge tag). + * Used by Contact Fields API for CRUD operations on field definitions. + */ export interface ContactField { id: number; name: string; diff --git a/src/types/mailtrap.ts b/src/types/mailtrap.ts index baa5982..2ad9714 100644 --- a/src/types/mailtrap.ts +++ b/src/types/mailtrap.ts @@ -125,6 +125,10 @@ export interface BatchSendRequest { }[]; } +/** + * Dynamic contact field values used when creating or updating contacts. + * Represents the actual data stored in contact fields (e.g., first_name: "John", phone: "123-456-7890"). + */ export interface ContactFields { [key: string]: string | number | boolean | undefined; } From 7764c04df6a155966ea4935019f800c50b7cf188 Mon Sep 17 00:00:00 2001 From: Narek Hovhannisyan Date: Fri, 10 Oct 2025 15:47:56 +0400 Subject: [PATCH 09/20] types: add SendingDomainsResponse interface to define the structure of sending domains response data --- src/types/api/sending-domains.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/types/api/sending-domains.ts b/src/types/api/sending-domains.ts index 342bd0c..905c4ba 100644 --- a/src/types/api/sending-domains.ts +++ b/src/types/api/sending-domains.ts @@ -38,3 +38,7 @@ export interface CreateSendingDomainParams { export interface SetupInstructionsResponse { message: string; } + +export interface SendingDomainsResponse { + data: SendingDomain[]; +} From c641885fa386560fac4b5e05e478dcd2be86b0fd Mon Sep 17 00:00:00 2001 From: Narek Hovhannisyan Date: Fri, 10 Oct 2025 15:48:04 +0400 Subject: [PATCH 10/20] refactor: update getList method in SendingDomainsApi to return SendingDomainsResponse data structure --- src/lib/api/resources/SendingDomains.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/lib/api/resources/SendingDomains.ts b/src/lib/api/resources/SendingDomains.ts index 40613ab..ef59229 100644 --- a/src/lib/api/resources/SendingDomains.ts +++ b/src/lib/api/resources/SendingDomains.ts @@ -4,6 +4,7 @@ import CONFIG from "../../../config"; import { CreateSendingDomainParams, SendingDomain, + SendingDomainsResponse, SetupInstructionsResponse, } from "../../../types/api/sending-domains"; @@ -27,7 +28,12 @@ export default class SendingDomainsApi { public async getList() { const url = this.sendingDomainsURL; - return this.client.get(url); + const response = await this.client.get< + SendingDomainsResponse, + SendingDomainsResponse + >(url); + + return response.data; } /** From a944630ed9bd7d52000bb83f00d7d138580f3987 Mon Sep 17 00:00:00 2001 From: Narek Hovhannisyan Date: Fri, 10 Oct 2025 15:48:17 +0400 Subject: [PATCH 11/20] test: update SendingDomains test to match new response structure with data wrapper --- src/__tests__/lib/api/resources/SendingDomains.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/__tests__/lib/api/resources/SendingDomains.test.ts b/src/__tests__/lib/api/resources/SendingDomains.test.ts index b30991d..789ebf1 100644 --- a/src/__tests__/lib/api/resources/SendingDomains.test.ts +++ b/src/__tests__/lib/api/resources/SendingDomains.test.ts @@ -84,7 +84,7 @@ describe("lib/api/SendingDomains: ", () => { .onGet( `https://mailtrap.io/api/accounts/${testAccountId}/sending_domains` ) - .reply(200, mockSendingDomains); + .reply(200, { data: mockSendingDomains }); const result = await sendingDomainsAPI.getList(); From 8c9a923f1654ea73086fbdda4e3086c25b54b1c2 Mon Sep 17 00:00:00 2001 From: Narek Hovhannisyan Date: Fri, 10 Oct 2025 15:48:22 +0400 Subject: [PATCH 12/20] refactor: update sending domains example to improve flow and structure --- examples/sending-domains/everything.ts | 65 +++++++++++++------------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/examples/sending-domains/everything.ts b/examples/sending-domains/everything.ts index aa06ef3..b742175 100644 --- a/examples/sending-domains/everything.ts +++ b/examples/sending-domains/everything.ts @@ -1,39 +1,38 @@ -import MailtrapClient from "../../src/lib/MailtrapClient"; +import { MailtrapClient } from "mailtrap"; + +const TOKEN = ""; +const ACCOUNT_ID = ""; const client = new MailtrapClient({ - token: "YOUR_API_TOKEN", - accountId: 12345, // Your account ID + token: TOKEN, + accountId: ACCOUNT_ID, }); -async function sendingDomainsExample() { - try { - // Get all sending domains§ - const sendingDomains = await client.sendingDomains.getList(); - console.log("Sending domains:", sendingDomains); - - // Create a new sending domain - const newDomain = await client.sendingDomains.create({ - domain_name: "example.com", - }); - console.log("Created domain:", newDomain); - - // Get a specific sending domain by ID - const domain = await client.sendingDomains.get(newDomain.id); - console.log("Domain details:", domain); - - // Send setup instructions - const setupResponse = await client.sendingDomains.sendSetupInstructions( - newDomain.id, - "admin@example.com" - ); - console.log("Setup instructions response:", setupResponse); - - // Delete the sending domain - await client.sendingDomains.delete(newDomain.id); - console.log("Domain deleted successfully"); - } catch (error) { - console.error("Error:", error); - } +async function sendingDomainsFlow() { + // Get all sending domains + const all = await client.sendingDomains.getList(); + console.log("All sending domains:", all); + + // Get a specific sending domain + const one = await client.sendingDomains.get(all[0].id); + console.log("One sending domain:", one); + + // Send setup instructions + const setupResponse = await client.sendingDomains.sendSetupInstructions( + all[0].id, + "admin@example.com" + ); + console.log("Setup instructions sent:", setupResponse); + + // Create a new sending domain + const created = await client.sendingDomains.create({ + domain_name: "example.com", + }); + console.log("Created sending domain:", created); + + // Delete a sending domain + await client.sendingDomains.delete(created.id); + console.log("Sending domain deleted"); } -sendingDomainsExample(); +sendingDomainsFlow(); From 643dcf4c9f1e0332b4afd4e65d00fc75138a6fb4 Mon Sep 17 00:00:00 2001 From: Narek Hovhannisyan Date: Mon, 13 Oct 2025 18:36:14 +0400 Subject: [PATCH 13/20] types: update SendingDomain interface to allow null values for dns_verified_at and alert_recipient_email --- src/types/api/sending-domains.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/types/api/sending-domains.ts b/src/types/api/sending-domains.ts index 905c4ba..2e7fae4 100644 --- a/src/types/api/sending-domains.ts +++ b/src/types/api/sending-domains.ts @@ -19,7 +19,7 @@ export interface SendingDomain { demo: boolean; compliance_status: string; dns_verified: boolean; - dns_verified_at: string; + dns_verified_at: string | null; dns_records: DnsRecord[]; open_tracking_enabled: boolean; click_tracking_enabled: boolean; @@ -27,7 +27,7 @@ export interface SendingDomain { custom_domain_tracking_enabled: boolean; health_alerts_enabled: boolean; critical_alerts_enabled: boolean; - alert_recipient_email: string; + alert_recipient_email: string | null; permissions: SendingDomainPermissions; } From a0aa0cbb890b01e946cab57731fe1a66a5ed23f9 Mon Sep 17 00:00:00 2001 From: Narek Hovhannisyan Date: Mon, 13 Oct 2025 18:36:23 +0400 Subject: [PATCH 14/20] refactor: simplify getList method and update create method to use correct data structure for sending domain --- src/lib/api/resources/SendingDomains.ts | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/lib/api/resources/SendingDomains.ts b/src/lib/api/resources/SendingDomains.ts index ef59229..855301a 100644 --- a/src/lib/api/resources/SendingDomains.ts +++ b/src/lib/api/resources/SendingDomains.ts @@ -28,12 +28,7 @@ export default class SendingDomainsApi { public async getList() { const url = this.sendingDomainsURL; - const response = await this.client.get< - SendingDomainsResponse, - SendingDomainsResponse - >(url); - - return response.data; + return this.client.get(url); } /** @@ -52,7 +47,7 @@ export default class SendingDomainsApi { */ public async create(params: CreateSendingDomainParams) { const url = this.sendingDomainsURL; - const data = { domain: params }; + const data = { sending_domain: params }; return this.client.post(url, data); } From 64b885e06da150632e10eadf3f1d135b2a9b1cfa Mon Sep 17 00:00:00 2001 From: Narek Hovhannisyan Date: Mon, 13 Oct 2025 18:53:18 +0400 Subject: [PATCH 15/20] test: adjust SendingDomains test to validate updated response structure and correct HTTP status code --- src/__tests__/lib/api/resources/SendingDomains.test.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/__tests__/lib/api/resources/SendingDomains.test.ts b/src/__tests__/lib/api/resources/SendingDomains.test.ts index 789ebf1..a67698d 100644 --- a/src/__tests__/lib/api/resources/SendingDomains.test.ts +++ b/src/__tests__/lib/api/resources/SendingDomains.test.ts @@ -88,7 +88,7 @@ describe("lib/api/SendingDomains: ", () => { const result = await sendingDomainsAPI.getList(); - expect(result).toEqual(mockSendingDomains); + expect(result).toEqual({ data: mockSendingDomains }); }); }); @@ -184,9 +184,10 @@ describe("lib/api/SendingDomains: ", () => { mock .onPost( - `https://mailtrap.io/api/accounts/${testAccountId}/sending_domains` + `https://mailtrap.io/api/accounts/${testAccountId}/sending_domains`, + { sending_domain: createParams } ) - .reply(200, mockSendingDomain); + .reply(201, mockSendingDomain); const result = await sendingDomainsAPI.create(createParams); From 89f5a271bda268684ffae286d4a1ff660fa5a130 Mon Sep 17 00:00:00 2001 From: Narek Hovhannisyan Date: Mon, 13 Oct 2025 19:11:25 +0400 Subject: [PATCH 16/20] types: remove SetupInstructionsResponse interface as it is no longer needed --- src/types/api/sending-domains.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/types/api/sending-domains.ts b/src/types/api/sending-domains.ts index 2e7fae4..4333867 100644 --- a/src/types/api/sending-domains.ts +++ b/src/types/api/sending-domains.ts @@ -35,10 +35,6 @@ export interface CreateSendingDomainParams { domain_name: string; } -export interface SetupInstructionsResponse { - message: string; -} - export interface SendingDomainsResponse { data: SendingDomain[]; } From 977a9d90abb135c330a714bbfb96052c7781e4dd Mon Sep 17 00:00:00 2001 From: Narek Hovhannisyan Date: Mon, 13 Oct 2025 19:11:32 +0400 Subject: [PATCH 17/20] refactor: rename setup instructions endpoint and simplify post request in SendingDomainsApi --- src/lib/api/resources/SendingDomains.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/lib/api/resources/SendingDomains.ts b/src/lib/api/resources/SendingDomains.ts index 855301a..d95b041 100644 --- a/src/lib/api/resources/SendingDomains.ts +++ b/src/lib/api/resources/SendingDomains.ts @@ -5,7 +5,6 @@ import { CreateSendingDomainParams, SendingDomain, SendingDomainsResponse, - SetupInstructionsResponse, } from "../../../types/api/sending-domains"; const { CLIENT_SETTINGS } = CONFIG; @@ -69,11 +68,8 @@ export default class SendingDomainsApi { * @returns Returns a success message */ public async sendSetupInstructions(id: number, email: string) { - const url = `${this.sendingDomainsURL}/${id}/setup_instructions`; + const url = `${this.sendingDomainsURL}/${id}/send_setup_instructions`; - return this.client.post< - SetupInstructionsResponse, - SetupInstructionsResponse - >(url, { email }); + return this.client.post(url, { email }); } } From 20f7294d9ec65cd5822c68a88bc7716ac5449591 Mon Sep 17 00:00:00 2001 From: Narek Hovhannisyan Date: Mon, 13 Oct 2025 19:11:41 +0400 Subject: [PATCH 18/20] test: update SendingDomains test to reflect changes in setup instructions endpoint and response handling --- src/__tests__/lib/api/resources/SendingDomains.test.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/__tests__/lib/api/resources/SendingDomains.test.ts b/src/__tests__/lib/api/resources/SendingDomains.test.ts index a67698d..6353ed3 100644 --- a/src/__tests__/lib/api/resources/SendingDomains.test.ts +++ b/src/__tests__/lib/api/resources/SendingDomains.test.ts @@ -215,22 +215,19 @@ describe("lib/api/SendingDomains: ", () => { it("should send setup instructions for a sending domain.", async () => { const sendingDomainId = 999; const email = "admin@example.com"; - const mockResponse: SetupInstructionsResponse = { - message: "Setup instructions sent successfully.", - }; mock .onPost( - `https://mailtrap.io/api/accounts/${testAccountId}/sending_domains/${sendingDomainId}/setup_instructions` + `https://mailtrap.io/api/accounts/${testAccountId}/sending_domains/${sendingDomainId}/send_setup_instructions` ) - .reply(200, mockResponse); + .reply(204); const result = await sendingDomainsAPI.sendSetupInstructions( sendingDomainId, email ); - expect(result).toEqual(mockResponse); + expect(result).toBeUndefined(); }); }); }); From cae8810edd84c1e98afa947d2c164b768ee4c693 Mon Sep 17 00:00:00 2001 From: Narek Hovhannisyan Date: Mon, 13 Oct 2025 19:21:03 +0400 Subject: [PATCH 19/20] refactor: enhance sending domains example with improved error handling and structured logging --- examples/sending-domains/everything.ts | 62 +++++++++++++++----------- 1 file changed, 36 insertions(+), 26 deletions(-) diff --git a/examples/sending-domains/everything.ts b/examples/sending-domains/everything.ts index b742175..a2f361b 100644 --- a/examples/sending-domains/everything.ts +++ b/examples/sending-domains/everything.ts @@ -1,38 +1,48 @@ -import { MailtrapClient } from "mailtrap"; +import { MailtrapClient } from "../../src/index"; const TOKEN = ""; const ACCOUNT_ID = ""; const client = new MailtrapClient({ token: TOKEN, - accountId: ACCOUNT_ID, + accountId: Number(ACCOUNT_ID), }); async function sendingDomainsFlow() { - // Get all sending domains - const all = await client.sendingDomains.getList(); - console.log("All sending domains:", all); - - // Get a specific sending domain - const one = await client.sendingDomains.get(all[0].id); - console.log("One sending domain:", one); - - // Send setup instructions - const setupResponse = await client.sendingDomains.sendSetupInstructions( - all[0].id, - "admin@example.com" - ); - console.log("Setup instructions sent:", setupResponse); - - // Create a new sending domain - const created = await client.sendingDomains.create({ - domain_name: "example.com", - }); - console.log("Created sending domain:", created); - - // Delete a sending domain - await client.sendingDomains.delete(created.id); - console.log("Sending domain deleted"); + try { + // Get all sending domains + const all = await client.sendingDomains.getList(); + console.log("All sending domains:", JSON.stringify(all, null, 2)); + + if (!all.data || all.data.length === 0) { + console.log("No sending domains found for this account."); + return; + } + + // Get a specific sending domain + const one = await client.sendingDomains.get(all.data[0].id); + console.log("One sending domain:", JSON.stringify(one, null, 2)); + + // Send setup instructions + const setupResponse = await client.sendingDomains.sendSetupInstructions( + all.data[0].id, + "admin@example.com" + ); + console.log("Setup instructions sent"); + + // Create a new sending domain + const created = await client.sendingDomains.create({ + domain_name: "test-domain-" + Date.now() + ".com", + }); + console.log("Created sending domain:", JSON.stringify(created, null, 2)); + + // Delete the created domain + await client.sendingDomains.delete(created.id); + console.log("Sending domain deleted"); + + } catch (error) { + console.error("Error in sendingDomainsFlow:", error instanceof Error ? error.message : String(error)); + } } sendingDomainsFlow(); From eedec50f0db23508846a67ceea2d070adb5be424 Mon Sep 17 00:00:00 2001 From: Narek Hovhannisyan Date: Mon, 13 Oct 2025 19:22:59 +0400 Subject: [PATCH 20/20] test: remove unused SetupInstructionsResponse import from SendingDomains test file --- src/__tests__/lib/api/resources/SendingDomains.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/__tests__/lib/api/resources/SendingDomains.test.ts b/src/__tests__/lib/api/resources/SendingDomains.test.ts index 6353ed3..7f6193f 100644 --- a/src/__tests__/lib/api/resources/SendingDomains.test.ts +++ b/src/__tests__/lib/api/resources/SendingDomains.test.ts @@ -6,7 +6,6 @@ import { SendingDomain, DnsRecord, SendingDomainPermissions, - SetupInstructionsResponse, } from "../../../../types/api/sending-domains"; describe("lib/api/SendingDomains: ", () => {