From d6b8e65abeb411f86538c1630dcce832ee0846a9 Mon Sep 17 00:00:00 2001
From: Jon <jonathan.bennetts@gmail.com>
Date: Mon, 16 Dec 2024 13:44:52 +0000
Subject: [PATCH] feat(MailerLite Node): Update node to support new api
 (#11933)

---
 .../credentials/MailerLiteApi.credentials.ts  |  40 +-
 .../nodes/MailerLite/GenericFunctions.ts      |  70 ++-
 .../nodes/MailerLite/MailerLite.node.ts       | 220 +--------
 .../nodes/MailerLite/MailerLite.svg           |  33 ++
 .../MailerLite/MailerLiteTrigger.node.ts      | 195 +-------
 .../nodes/MailerLite/mailerLite.png           | Bin 893 -> 0 bytes
 .../MailerLite/tests/GenericFunctions.test.ts | 253 ++++++++++
 .../nodes/MailerLite/tests/apiResponses.ts    | 411 ++++++++++++++++
 .../tests/v1/MailerLite.v1.workflow.json      | 460 ++++++++++++++++++
 .../tests/v1/MailerLite.v1.workflow.test.ts   |  31 ++
 .../tests/v2/MailerLite.v2.workflow.json      | 370 ++++++++++++++
 .../tests/v2/MailerLite.v2.workflow.test.ts   |  34 ++
 .../MailerLite/v1/MailerLiteTriggerV1.node.ts | 184 +++++++
 .../nodes/MailerLite/v1/MailerLiteV1.node.ts  | 199 ++++++++
 .../{ => v1}/SubscriberDescription.ts         |   0
 .../MailerLite/v2/MailerLite.Interface.ts     |  35 ++
 .../MailerLite/v2/MailerLiteTriggerV2.node.ts | 179 +++++++
 .../nodes/MailerLite/v2/MailerLiteV2.node.ts  | 206 ++++++++
 .../MailerLite/v2/SubscriberDescription.ts    | 304 ++++++++++++
 19 files changed, 2830 insertions(+), 394 deletions(-)
 create mode 100644 packages/nodes-base/nodes/MailerLite/MailerLite.svg
 delete mode 100644 packages/nodes-base/nodes/MailerLite/mailerLite.png
 create mode 100644 packages/nodes-base/nodes/MailerLite/tests/GenericFunctions.test.ts
 create mode 100644 packages/nodes-base/nodes/MailerLite/tests/apiResponses.ts
 create mode 100644 packages/nodes-base/nodes/MailerLite/tests/v1/MailerLite.v1.workflow.json
 create mode 100644 packages/nodes-base/nodes/MailerLite/tests/v1/MailerLite.v1.workflow.test.ts
 create mode 100644 packages/nodes-base/nodes/MailerLite/tests/v2/MailerLite.v2.workflow.json
 create mode 100644 packages/nodes-base/nodes/MailerLite/tests/v2/MailerLite.v2.workflow.test.ts
 create mode 100644 packages/nodes-base/nodes/MailerLite/v1/MailerLiteTriggerV1.node.ts
 create mode 100644 packages/nodes-base/nodes/MailerLite/v1/MailerLiteV1.node.ts
 rename packages/nodes-base/nodes/MailerLite/{ => v1}/SubscriberDescription.ts (100%)
 create mode 100644 packages/nodes-base/nodes/MailerLite/v2/MailerLite.Interface.ts
 create mode 100644 packages/nodes-base/nodes/MailerLite/v2/MailerLiteTriggerV2.node.ts
 create mode 100644 packages/nodes-base/nodes/MailerLite/v2/MailerLiteV2.node.ts
 create mode 100644 packages/nodes-base/nodes/MailerLite/v2/SubscriberDescription.ts

diff --git a/packages/nodes-base/credentials/MailerLiteApi.credentials.ts b/packages/nodes-base/credentials/MailerLiteApi.credentials.ts
index 54a97b4cc7..fa5add1b6a 100644
--- a/packages/nodes-base/credentials/MailerLiteApi.credentials.ts
+++ b/packages/nodes-base/credentials/MailerLiteApi.credentials.ts
@@ -1,4 +1,10 @@
-import type { ICredentialType, INodeProperties } from 'n8n-workflow';
+import type {
+	ICredentialDataDecryptedObject,
+	ICredentialTestRequest,
+	ICredentialType,
+	IHttpRequestOptions,
+	INodeProperties,
+} from 'n8n-workflow';
 
 export class MailerLiteApi implements ICredentialType {
 	name = 'mailerLiteApi';
@@ -15,5 +21,37 @@ export class MailerLiteApi implements ICredentialType {
 			typeOptions: { password: true },
 			default: '',
 		},
+		{
+			displayName: 'Classic API',
+			name: 'classicApi',
+			type: 'boolean',
+			default: true,
+			description:
+				'If the Classic API should be used, If this is your first time using this node this should be false.',
+		},
 	];
+
+	async authenticate(
+		credentials: ICredentialDataDecryptedObject,
+		requestOptions: IHttpRequestOptions,
+	): Promise<IHttpRequestOptions> {
+		if (credentials.classicApi === true) {
+			requestOptions.headers = {
+				'X-MailerLite-ApiKey': credentials.apiKey as string,
+			};
+		} else {
+			requestOptions.headers = {
+				Authorization: `Bearer ${credentials.apiKey as string}`,
+			};
+		}
+		return requestOptions;
+	}
+
+	test: ICredentialTestRequest = {
+		request: {
+			baseURL:
+				'={{$credentials.classicApi ? "https://api.mailerlite.com/api/v2" : "https://connect.mailerlite.com/api"}}',
+			url: '/groups',
+		},
+	};
 }
diff --git a/packages/nodes-base/nodes/MailerLite/GenericFunctions.ts b/packages/nodes-base/nodes/MailerLite/GenericFunctions.ts
index 2459f349d1..a7f9283d5d 100644
--- a/packages/nodes-base/nodes/MailerLite/GenericFunctions.ts
+++ b/packages/nodes-base/nodes/MailerLite/GenericFunctions.ts
@@ -3,39 +3,38 @@ import type {
 	IExecuteFunctions,
 	IHookFunctions,
 	ILoadOptionsFunctions,
+	INodePropertyOptions,
 	JsonObject,
-	IRequestOptions,
+	IHttpRequestOptions,
 	IHttpRequestMethods,
 } from 'n8n-workflow';
 import { NodeApiError } from 'n8n-workflow';
 
+import type { CustomField } from './v2/MailerLite.Interface';
+
 export async function mailerliteApiRequest(
 	this: IExecuteFunctions | ILoadOptionsFunctions | IHookFunctions,
 	method: IHttpRequestMethods,
 	path: string,
-
 	body: any = {},
 	qs: IDataObject = {},
 	_option = {},
 ): Promise<any> {
-	const credentials = await this.getCredentials('mailerLiteApi');
-
-	const options: IRequestOptions = {
-		headers: {
-			'X-MailerLite-ApiKey': credentials.apiKey,
-		},
+	const options: IHttpRequestOptions = {
 		method,
 		body,
 		qs,
-		uri: `https://api.mailerlite.com/api/v2${path}`,
+		url:
+			this.getNode().typeVersion === 1
+				? `https://api.mailerlite.com/api/v2${path}`
+				: `https://connect.mailerlite.com/api${path}`,
 		json: true,
 	};
 	try {
 		if (Object.keys(body as IDataObject).length === 0) {
 			delete options.body;
 		}
-		//@ts-ignore
-		return await this.helpers.request.call(this, options);
+		return await this.helpers.httpRequestWithAuthentication.call(this, 'mailerLiteApi', options);
 	} catch (error) {
 		throw new NodeApiError(this.getNode(), error as JsonObject);
 	}
@@ -45,21 +44,56 @@ export async function mailerliteApiRequestAllItems(
 	this: IExecuteFunctions | ILoadOptionsFunctions | IHookFunctions,
 	method: IHttpRequestMethods,
 	endpoint: string,
-
 	body: any = {},
 	query: IDataObject = {},
 ): Promise<any> {
 	const returnData: IDataObject[] = [];
-
 	let responseData;
 
 	query.limit = 1000;
 	query.offset = 0;
 
-	do {
-		responseData = await mailerliteApiRequest.call(this, method, endpoint, body, query);
-		returnData.push.apply(returnData, responseData as IDataObject[]);
-		query.offset = query.offset + query.limit;
-	} while (responseData.length !== 0);
+	if (this.getNode().typeVersion === 1) {
+		do {
+			responseData = await mailerliteApiRequest.call(this, method, endpoint, body, query);
+			returnData.push(...(responseData as IDataObject[]));
+			query.offset += query.limit;
+		} while (responseData.length !== 0);
+	} else {
+		do {
+			responseData = await mailerliteApiRequest.call(this, method, endpoint, body, query);
+			returnData.push(...(responseData.data as IDataObject[]));
+			query.cursor = responseData.meta.next_cursor;
+		} while (responseData.links.next !== null);
+	}
+
+	return returnData;
+}
+
+export async function getCustomFields(
+	this: ILoadOptionsFunctions,
+): Promise<INodePropertyOptions[]> {
+	const returnData: INodePropertyOptions[] = [];
+	const endpoint = '/fields';
+	const fieldsResponse = await mailerliteApiRequest.call(this, 'GET', endpoint);
+
+	if (this.getNode().typeVersion === 1) {
+		const fields = fieldsResponse as CustomField[];
+		fields.forEach((field) => {
+			returnData.push({
+				name: field.key,
+				value: field.key,
+			});
+		});
+	} else {
+		const fields = (fieldsResponse as IDataObject).data as CustomField[];
+		fields.forEach((field) => {
+			returnData.push({
+				name: field.name,
+				value: field.key,
+			});
+		});
+	}
+
 	return returnData;
 }
diff --git a/packages/nodes-base/nodes/MailerLite/MailerLite.node.ts b/packages/nodes-base/nodes/MailerLite/MailerLite.node.ts
index 6fe7c621b1..fbd9c3a125 100644
--- a/packages/nodes-base/nodes/MailerLite/MailerLite.node.ts
+++ b/packages/nodes-base/nodes/MailerLite/MailerLite.node.ts
@@ -1,206 +1,26 @@
-import type {
-	IExecuteFunctions,
-	IDataObject,
-	ILoadOptionsFunctions,
-	INodeExecutionData,
-	INodePropertyOptions,
-	INodeType,
-	INodeTypeDescription,
-} from 'n8n-workflow';
-import { NodeConnectionType } from 'n8n-workflow';
+import type { INodeTypeBaseDescription, IVersionedNodeType } from 'n8n-workflow';
+import { VersionedNodeType } from 'n8n-workflow';
 
-import { mailerliteApiRequest, mailerliteApiRequestAllItems } from './GenericFunctions';
+import { MailerLiteV1 } from './v1/MailerLiteV1.node';
+import { MailerLiteV2 } from './v2/MailerLiteV2.node';
 
-import { subscriberFields, subscriberOperations } from './SubscriberDescription';
+export class MailerLite extends VersionedNodeType {
+	constructor() {
+		const baseDescription: INodeTypeBaseDescription = {
+			displayName: 'MailerLite',
+			name: 'mailerLite',
+			icon: 'file:MailerLite.svg',
+			group: ['input'],
+			subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
+			description: 'Consume MailerLite API',
+			defaultVersion: 2,
+		};
 
-export class MailerLite implements INodeType {
-	description: INodeTypeDescription = {
-		displayName: 'MailerLite',
-		name: 'mailerLite',
-		// eslint-disable-next-line n8n-nodes-base/node-class-description-icon-not-svg
-		icon: 'file:mailerLite.png',
-		group: ['input'],
-		version: 1,
-		subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
-		description: 'Consume Mailer Lite API',
-		defaults: {
-			name: 'MailerLite',
-		},
-		inputs: [NodeConnectionType.Main],
-		outputs: [NodeConnectionType.Main],
-		credentials: [
-			{
-				name: 'mailerLiteApi',
-				required: true,
-			},
-		],
-		properties: [
-			{
-				displayName: 'Resource',
-				name: 'resource',
-				type: 'options',
-				noDataExpression: true,
-				options: [
-					{
-						name: 'Subscriber',
-						value: 'subscriber',
-					},
-				],
-				default: 'subscriber',
-			},
-			...subscriberOperations,
-			...subscriberFields,
-		],
-	};
+		const nodeVersions: IVersionedNodeType['nodeVersions'] = {
+			1: new MailerLiteV1(baseDescription),
+			2: new MailerLiteV2(baseDescription),
+		};
 
-	methods = {
-		loadOptions: {
-			// Get all the available custom fields to display them to user so that they can
-			// select them easily
-			async getCustomFields(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]> {
-				const returnData: INodePropertyOptions[] = [];
-				const fields = await mailerliteApiRequest.call(this, 'GET', '/fields');
-				for (const field of fields) {
-					returnData.push({
-						name: field.key,
-						value: field.key,
-					});
-				}
-				return returnData;
-			},
-		},
-	};
-
-	async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
-		const items = this.getInputData();
-		const returnData: INodeExecutionData[] = [];
-		const length = items.length;
-		const qs: IDataObject = {};
-		let responseData;
-		const resource = this.getNodeParameter('resource', 0);
-		const operation = this.getNodeParameter('operation', 0);
-		for (let i = 0; i < length; i++) {
-			try {
-				if (resource === 'subscriber') {
-					//https://developers.mailerlite.com/reference#create-a-subscriber
-					if (operation === 'create') {
-						const email = this.getNodeParameter('email', i) as string;
-
-						const additionalFields = this.getNodeParameter('additionalFields', i);
-
-						const body: IDataObject = {
-							email,
-							fields: [],
-						};
-
-						Object.assign(body, additionalFields);
-
-						if (additionalFields.customFieldsUi) {
-							const customFieldsValues = (additionalFields.customFieldsUi as IDataObject)
-								.customFieldsValues as IDataObject[];
-
-							if (customFieldsValues) {
-								const fields = {};
-
-								for (const customFieldValue of customFieldsValues) {
-									//@ts-ignore
-									fields[customFieldValue.fieldId] = customFieldValue.value;
-								}
-
-								body.fields = fields;
-								delete body.customFieldsUi;
-							}
-						}
-
-						responseData = await mailerliteApiRequest.call(this, 'POST', '/subscribers', body);
-					}
-					//https://developers.mailerlite.com/reference#single-subscriber
-					if (operation === 'get') {
-						const subscriberId = this.getNodeParameter('subscriberId', i) as string;
-
-						responseData = await mailerliteApiRequest.call(
-							this,
-							'GET',
-							`/subscribers/${subscriberId}`,
-						);
-					}
-					//https://developers.mailerlite.com/reference#subscribers
-					if (operation === 'getAll') {
-						const returnAll = this.getNodeParameter('returnAll', i);
-
-						const filters = this.getNodeParameter('filters', i);
-
-						Object.assign(qs, filters);
-
-						if (returnAll) {
-							responseData = await mailerliteApiRequestAllItems.call(
-								this,
-								'GET',
-								'/subscribers',
-								{},
-								qs,
-							);
-						} else {
-							qs.limit = this.getNodeParameter('limit', i);
-
-							responseData = await mailerliteApiRequest.call(this, 'GET', '/subscribers', {}, qs);
-						}
-					}
-					//https://developers.mailerlite.com/reference#update-subscriber
-					if (operation === 'update') {
-						const subscriberId = this.getNodeParameter('subscriberId', i) as string;
-
-						const updateFields = this.getNodeParameter('updateFields', i);
-
-						const body: IDataObject = {};
-
-						Object.assign(body, updateFields);
-
-						if (updateFields.customFieldsUi) {
-							const customFieldsValues = (updateFields.customFieldsUi as IDataObject)
-								.customFieldsValues as IDataObject[];
-
-							if (customFieldsValues) {
-								const fields = {};
-
-								for (const customFieldValue of customFieldsValues) {
-									//@ts-ignore
-									fields[customFieldValue.fieldId] = customFieldValue.value;
-								}
-
-								body.fields = fields;
-								delete body.customFieldsUi;
-							}
-						}
-
-						responseData = await mailerliteApiRequest.call(
-							this,
-							'PUT',
-							`/subscribers/${subscriberId}`,
-							body,
-						);
-					}
-				}
-			} catch (error) {
-				if (this.continueOnFail()) {
-					const executionErrorData = this.helpers.constructExecutionMetaData(
-						this.helpers.returnJsonArray({ error: error.message }),
-						{ itemData: { item: i } },
-					);
-					returnData.push(...executionErrorData);
-					continue;
-				}
-				throw error;
-			}
-
-			const executionData = this.helpers.constructExecutionMetaData(
-				this.helpers.returnJsonArray(responseData as IDataObject[]),
-				{ itemData: { item: i } },
-			);
-
-			returnData.push(...executionData);
-		}
-
-		return [returnData];
+		super(nodeVersions, baseDescription);
 	}
 }
diff --git a/packages/nodes-base/nodes/MailerLite/MailerLite.svg b/packages/nodes-base/nodes/MailerLite/MailerLite.svg
new file mode 100644
index 0000000000..c19029d033
--- /dev/null
+++ b/packages/nodes-base/nodes/MailerLite/MailerLite.svg
@@ -0,0 +1,33 @@
+<svg version="1.1" id="Layer_1" xmlns:x="ns_extend;" xmlns:i="ns_ai;" xmlns:graph="ns_graphs;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 62.8 50.2" style="enable-background:new 0 0 62.8 50.2;" xml:space="preserve">
+ <style type="text/css">
+  .st0{fill:#09C269;}
+	.st1{fill:#FFFFFF;}
+ </style>
+ <metadata>
+  <sfw xmlns="ns_sfw;">
+   <slices>
+   </slices>
+   <sliceSourceBounds bottomLeftOrigin="true" height="50.2" width="62.8" x="236.9" y="-225.3">
+   </sliceSourceBounds>
+  </sfw>
+ </metadata>
+ <g id="mailerlite-light">
+  <g>
+   <g id="lite" transform="translate(137.000000, 0.000000)">
+    <path id="Shape-path" class="st0" d="M-81.2,0h-48.9c-3.8,0-6.9,3.1-6.9,6.8v22.8v4.5v16.2l9.5-9.3h46.4c3.8,0,6.9-3.1,6.9-6.8
+				V6.8C-74.3,3.1-77.4,0-81.2,0z">
+    </path>
+    <path id="Shape-path-3" class="st1" d="M-90.2,15.8c5.2,0,7.6,4.1,7.6,8c0,1-0.8,1.8-1.8,1.8H-94c0.5,2.3,2.1,3.6,4.7,3.6
+				c1.9,0,2.9-0.4,3.9-0.9c0.2-0.1,0.5-0.2,0.7-0.2c0.9,0,1.7,0.7,1.7,1.6c0,0.6-0.4,1.1-1,1.5c-1.3,0.7-2.7,1.4-5.5,1.4
+				c-5.2,0-8.3-3.1-8.3-8.4C-97.9,18.1-93.7,15.8-90.2,15.8z M-105.5,13.2c0.6,0,1,0.5,1,1v1.9h2.9c0.9,0,1.7,0.7,1.7,1.6
+				c0,0.9-0.7,1.6-1.7,1.6h-2.9V28c0,1.2,0.6,1.3,1.5,1.3c0.5,0,0.8-0.1,1.1-0.1c0.2,0,0.5-0.1,0.7-0.1c0.7,0,1.6,0.6,1.6,1.5
+				c0,0.6-0.4,1.1-1,1.4c-0.9,0.4-1.7,0.6-2.7,0.6c-3.2,0-4.9-1.5-4.9-4.4v-8.8h-1.7c-0.6,0-1-0.5-1-1c0-0.3,0.1-0.6,0.4-0.9l4-4
+				C-106.3,13.5-106,13.2-105.5,13.2z M-124.2,9.4c1,0,1.8,0.8,1.8,1.8v19.4c0,1-0.8,1.8-1.8,1.8s-1.8-0.8-1.8-1.8V11.2
+				C-126,10.2-125.2,9.4-124.2,9.4z M-115.6,16c1,0,1.8,0.8,1.8,1.8v12.8c0,1-0.8,1.8-1.8,1.8c-1,0-1.8-0.8-1.8-1.8V17.8
+				C-117.4,16.8-116.6,16-115.6,16z M-90.1,19.1c-1.7,0-3.6,1-3.9,3.5h7.9C-86.6,20.1-88.4,19.1-90.1,19.1z M-115.5,9.9
+				c1.1,0,2,0.9,2,2V12c0,1.1-0.9,2-2,2h-0.2c-1.1,0-2-0.9-2-2v-0.1c0-1.1,0.9-2,2-2H-115.5z">
+    </path>
+   </g>
+  </g>
+ </g>
+</svg>
\ No newline at end of file
diff --git a/packages/nodes-base/nodes/MailerLite/MailerLiteTrigger.node.ts b/packages/nodes-base/nodes/MailerLite/MailerLiteTrigger.node.ts
index 697720aa72..3fcb1d34ac 100644
--- a/packages/nodes-base/nodes/MailerLite/MailerLiteTrigger.node.ts
+++ b/packages/nodes-base/nodes/MailerLite/MailerLiteTrigger.node.ts
@@ -1,180 +1,25 @@
-import type {
-	IHookFunctions,
-	IWebhookFunctions,
-	IDataObject,
-	INodeType,
-	INodeTypeDescription,
-	IWebhookResponseData,
-} from 'n8n-workflow';
-import { NodeConnectionType } from 'n8n-workflow';
+import type { INodeTypeBaseDescription, IVersionedNodeType } from 'n8n-workflow';
+import { VersionedNodeType } from 'n8n-workflow';
 
-import { mailerliteApiRequest } from './GenericFunctions';
+import { MailerLiteTriggerV1 } from './v1/MailerLiteTriggerV1.node';
+import { MailerLiteTriggerV2 } from './v2/MailerLiteTriggerV2.node';
 
-export class MailerLiteTrigger implements INodeType {
-	description: INodeTypeDescription = {
-		displayName: 'MailerLite Trigger',
-		name: 'mailerLiteTrigger',
-		// eslint-disable-next-line n8n-nodes-base/node-class-description-icon-not-svg
-		icon: 'file:mailerLite.png',
-		group: ['trigger'],
-		version: 1,
-		description: 'Starts the workflow when MailerLite events occur',
-		defaults: {
-			name: 'MailerLite Trigger',
-		},
-		inputs: [],
-		outputs: [NodeConnectionType.Main],
-		credentials: [
-			{
-				name: 'mailerLiteApi',
-				required: true,
-			},
-		],
-		webhooks: [
-			{
-				name: 'default',
-				httpMethod: 'POST',
-				responseMode: 'onReceived',
-				path: 'webhook',
-			},
-		],
-		properties: [
-			{
-				displayName: 'Event',
-				name: 'event',
-				type: 'options',
-				options: [
-					{
-						name: 'Campaign Sent',
-						value: 'campaign.sent',
-						description: 'Fired when campaign is sent',
-					},
-					{
-						name: 'Subscriber Added Throught Webform',
-						value: 'subscriber.added_through_webform',
-						description: 'Fired when a subscriber is added though a form',
-					},
-					{
-						name: 'Subscriber Added to Group',
-						value: 'subscriber.add_to_group',
-						description: 'Fired when a subscriber is added to a group',
-					},
-					{
-						name: 'Subscriber Autonomation Completed',
-						value: 'subscriber.automation_complete',
-						description: 'Fired when subscriber finishes automation',
-					},
-					{
-						name: 'Subscriber Autonomation Triggered',
-						value: 'subscriber.automation_triggered',
-						description: 'Fired when subscriber starts automation',
-					},
-					{
-						name: 'Subscriber Bounced',
-						value: 'subscriber.bounced',
-						description: 'Fired when an email address bounces',
-					},
-					{
-						name: 'Subscriber Complained',
-						value: 'subscriber.complaint',
-						description: 'Fired when subscriber marks a campaign as a spam',
-					},
-					{
-						name: 'Subscriber Created',
-						value: 'subscriber.create',
-						description: 'Fired when a new subscriber is added to an account',
-					},
-					{
-						name: 'Subscriber Removed From Group',
-						value: 'subscriber.remove_from_group',
-						description: 'Fired when a subscriber is removed from a group',
-					},
-					{
-						name: 'Subscriber Unsubscribe',
-						value: 'subscriber.unsubscribe',
-						description: 'Fired when a subscriber becomes unsubscribed',
-					},
-					{
-						name: 'Subscriber Updated',
-						value: 'subscriber.update',
-						description: "Fired when any of the subscriber's custom fields are updated",
-					},
-				],
-				required: true,
-				default: [],
-				description: 'The events to listen to',
-			},
-		],
-	};
-
-	webhookMethods = {
-		default: {
-			async checkExists(this: IHookFunctions): Promise<boolean> {
-				const webhookUrl = this.getNodeWebhookUrl('default');
-				const webhookData = this.getWorkflowStaticData('node');
-				const event = this.getNodeParameter('event') as string;
-				// Check all the webhooks which exist already if it is identical to the
-				// one that is supposed to get created.
-				const endpoint = '/webhooks';
-				const { webhooks } = await mailerliteApiRequest.call(this, 'GET', endpoint, {});
-				for (const webhook of webhooks) {
-					if (webhook.url === webhookUrl && webhook.event === event) {
-						// Set webhook-id to be sure that it can be deleted
-						webhookData.webhookId = webhook.id as string;
-						return true;
-					}
-				}
-				return false;
-			},
-			async create(this: IHookFunctions): Promise<boolean> {
-				const webhookData = this.getWorkflowStaticData('node');
-				const webhookUrl = this.getNodeWebhookUrl('default');
-				const event = this.getNodeParameter('event') as string;
-
-				const endpoint = '/webhooks';
-
-				const body = {
-					url: webhookUrl,
-					event,
-				};
-
-				const responseData = await mailerliteApiRequest.call(this, 'POST', endpoint, body);
-
-				if (responseData.id === undefined) {
-					// Required data is missing so was not successful
-					return false;
-				}
-
-				webhookData.webhookId = responseData.id as string;
-				return true;
-			},
-			async delete(this: IHookFunctions): Promise<boolean> {
-				const webhookData = this.getWorkflowStaticData('node');
-				if (webhookData.webhookId !== undefined) {
-					const endpoint = `/webhooks/${webhookData.webhookId}`;
-
-					try {
-						await mailerliteApiRequest.call(this, 'DELETE', endpoint);
-					} catch (error) {
-						return false;
-					}
-
-					// Remove from the static workflow data so that it is clear
-					// that no webhooks are registered anymore
-					delete webhookData.webhookId;
-				}
-				return true;
-			},
-		},
-	};
-
-	async webhook(this: IWebhookFunctions): Promise<IWebhookResponseData> {
-		const body = this.getBodyData();
-
-		const events = body.events as IDataObject[];
-
-		return {
-			workflowData: [this.helpers.returnJsonArray(events)],
+export class MailerLiteTrigger extends VersionedNodeType {
+	constructor() {
+		const baseDescription: INodeTypeBaseDescription = {
+			displayName: 'MailerLite Trigger',
+			name: 'mailerLiteTrigger',
+			icon: 'file:MailerLite.svg',
+			group: ['trigger'],
+			description: 'Starts the workflow when MailerLite events occur',
+			defaultVersion: 2,
 		};
+
+		const nodeVersions: IVersionedNodeType['nodeVersions'] = {
+			1: new MailerLiteTriggerV1(baseDescription),
+			2: new MailerLiteTriggerV2(baseDescription),
+		};
+
+		super(nodeVersions, baseDescription);
 	}
 }
diff --git a/packages/nodes-base/nodes/MailerLite/mailerLite.png b/packages/nodes-base/nodes/MailerLite/mailerLite.png
deleted file mode 100644
index fde7f6d6b6018e6468e7422728792ce6dd2e8771..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 893
zcmV-@1A_dCP)<h;3K|Lk000e1NJLTq002Ay002A)0{{R34I(K(0002SP)t-s3Bqar
z|NjBPX#M{F{QmtL!fXJ)THWyC0KHNGy;Uv5aCy*|jntzk!*2k*PMz7XEW>d6{rlwf
z>C)`k0KQns>CynaOa;Pe;PT}FzhCwH_vZEMZ_bc0#Bu<@Ve9tqe9)OB!)+D9Y5>7y
z0J%5t`SZ-`)gZ%d0J=Zf@8A!@YWMv3)$QD};lP&ItA^8`f6<#x$bJC4N&vSkW6Oy^
z#&<Wxblvgez~#%5*QklqqG!yESjmIM=g+y~#iQG_0JRYSv;gRSuv-8C0&+=2K~zY`
z?Um_rqCgOUZDxc4m1F=>ZV&};<C$}_yYK%}+r%W8XmO-!|M^MvOm*?mJ;>BFu3V`>
zPpCxik~>YKW(A^jdZr75roqGtFnQ1vzO_6Mj8!64AZd$n^K0$t)Ovu5B(X5~(saZY
zKxj4Kfknb;)A8O03Y8$hU;LBCg^s+!<QtTf*%ThtTj4}z?RS|RFH-Of0ynC1NhV-(
zAjfHee6cbC#|viwqvda&B`B#OQ}{LZHGsvRZ5Js1pqAWKBL_h0tOFnvw8^nJ&Jj{7
zn@tS|PBYgrT5mUhv_PxLa|uJ=Gu^q4EfARLudn(HNU4l%-;bFC6HD~`&DOI4^tHO(
zZq_=G^2(r#mIMoLA1k}{lEa*_&Qse{4SWR^WW(wM<*RYawlVvxzVrc{o#_%F6=i4-
z@3LIqm%D(>4FR*&WDZZmkP;4EHgNC4@UG>l`0v-KOmKKmmCbNG9FApmUPlfoa7bi-
zG0~Akg5ouAzO5N?1mh<EHj8AYI4E0jCO?_aK@b3}%=l4qw4`-|O_y$r#AFh1SZsyE
zl=UIlZ&afhn}1WgaLrom+5o{}o!!PCeM5Ff*%sYf%s8~QqP8)NY#_&&Wdcddwg~F?
zllu{1szAn=UwMj>d|MUBST>J1A|I2_9E3)6xia~znN7)ihU5?6p!rjj&SU}=n7Lxw
zJC|v>PWWVJM7^`h=<=l-wu*U?MO^TijBYp<<r2g+MfbbRfw$Cya;p^6X`p*1<BMR5
zP)e?z9(49IQ+kd12)E{v@0cevej=x0%T?>T`RVRk9dv(cXJ`G7?Ox-`mH)s$kPSrn
Tqz<W000000NkvXXu0mjf#x=q%

diff --git a/packages/nodes-base/nodes/MailerLite/tests/GenericFunctions.test.ts b/packages/nodes-base/nodes/MailerLite/tests/GenericFunctions.test.ts
new file mode 100644
index 0000000000..f23963b084
--- /dev/null
+++ b/packages/nodes-base/nodes/MailerLite/tests/GenericFunctions.test.ts
@@ -0,0 +1,253 @@
+/* eslint-disable n8n-nodes-base/node-param-display-name-miscased */
+import {
+	type IExecuteFunctions,
+	type ILoadOptionsFunctions,
+	type IHookFunctions,
+	NodeApiError,
+} from 'n8n-workflow';
+
+import {
+	getCustomFields,
+	mailerliteApiRequest,
+	mailerliteApiRequestAllItems,
+} from '../GenericFunctions';
+
+describe('MailerLite -> mailerliteApiRequest', () => {
+	let mockExecuteFunctions: IExecuteFunctions | ILoadOptionsFunctions | IHookFunctions;
+
+	const setupMockFunctions = (typeVersion: number) => {
+		mockExecuteFunctions = {
+			getNode: jest.fn().mockReturnValue({ typeVersion }),
+			helpers: {
+				httpRequestWithAuthentication: jest.fn(),
+			},
+		} as unknown as IExecuteFunctions | ILoadOptionsFunctions | IHookFunctions;
+		jest.clearAllMocks();
+	};
+
+	beforeEach(() => {
+		setupMockFunctions(1);
+	});
+
+	it('should make a successful API request for type version 1', async () => {
+		const method = 'GET';
+		const path = '/test';
+		const body = {};
+		const qs = {};
+
+		const responseData = { success: true };
+
+		(mockExecuteFunctions.helpers.httpRequestWithAuthentication as jest.Mock).mockResolvedValue(
+			responseData,
+		);
+
+		const result = await mailerliteApiRequest.call(mockExecuteFunctions, method, path, body, qs);
+
+		expect(result).toEqual(responseData);
+		expect(mockExecuteFunctions.helpers.httpRequestWithAuthentication).toHaveBeenCalledWith(
+			'mailerLiteApi',
+			{
+				method,
+				qs,
+				url: 'https://api.mailerlite.com/api/v2/test',
+				json: true,
+			},
+		);
+	});
+
+	it('should make a successful API request for type version 2', async () => {
+		setupMockFunctions(2);
+
+		const method = 'GET';
+		const path = '/test';
+		const body = {};
+		const qs = {};
+
+		const responseData = { success: true };
+
+		(mockExecuteFunctions.helpers.httpRequestWithAuthentication as jest.Mock).mockResolvedValue(
+			responseData,
+		);
+
+		const result = await mailerliteApiRequest.call(mockExecuteFunctions, method, path, body, qs);
+
+		expect(result).toEqual(responseData);
+		expect(mockExecuteFunctions.helpers.httpRequestWithAuthentication).toHaveBeenCalledWith(
+			'mailerLiteApi',
+			{
+				method,
+				qs,
+				url: 'https://connect.mailerlite.com/api/test',
+				json: true,
+			},
+		);
+	});
+
+	it('should make an API request with an empty body', async () => {
+		const method = 'GET';
+		const path = '/test';
+		const body = {};
+		const qs = {};
+
+		const responseData = { success: true };
+
+		(mockExecuteFunctions.helpers.httpRequestWithAuthentication as jest.Mock).mockResolvedValue(
+			responseData,
+		);
+
+		const result = await mailerliteApiRequest.call(mockExecuteFunctions, method, path, body, qs);
+
+		expect(result).toEqual(responseData);
+		expect(mockExecuteFunctions.helpers.httpRequestWithAuthentication).toHaveBeenCalledWith(
+			'mailerLiteApi',
+			{
+				method,
+				qs,
+				url: 'https://api.mailerlite.com/api/v2/test',
+				json: true,
+			},
+		);
+	});
+
+	it('should throw an error if the API request fails', async () => {
+		const method = 'GET';
+		const path = '/test';
+		const body = {};
+		const qs = {};
+
+		const errorResponse = { message: 'Error' };
+
+		(mockExecuteFunctions.helpers.httpRequestWithAuthentication as jest.Mock).mockRejectedValue(
+			errorResponse,
+		);
+
+		await expect(
+			mailerliteApiRequest.call(mockExecuteFunctions, method, path, body, qs),
+		).rejects.toThrow(NodeApiError);
+	});
+});
+
+describe('MailerLite -> mailerliteApiRequestAllItems', () => {
+	let mockExecuteFunctions: IExecuteFunctions | ILoadOptionsFunctions | IHookFunctions;
+
+	const setupMockFunctions = (typeVersion: number) => {
+		mockExecuteFunctions = {
+			getNode: jest.fn().mockReturnValue({ typeVersion }),
+			helpers: {
+				httpRequestWithAuthentication: jest.fn(),
+			},
+		} as unknown as IExecuteFunctions | ILoadOptionsFunctions | IHookFunctions;
+		jest.clearAllMocks();
+	};
+
+	beforeEach(() => {
+		setupMockFunctions(1);
+	});
+
+	it('should handle pagination for type version 1', async () => {
+		const method = 'GET';
+		const endpoint = '/test';
+		const body = {};
+		const query = {};
+
+		const responseDataPage1 = [{ id: 1 }, { id: 2 }];
+		const responseDataPage2 = [{ id: 3 }, { id: 4 }];
+
+		(mockExecuteFunctions.helpers.httpRequestWithAuthentication as jest.Mock)
+			.mockResolvedValueOnce(responseDataPage1)
+			.mockResolvedValueOnce(responseDataPage2)
+			.mockResolvedValueOnce([]);
+
+		const result = await mailerliteApiRequestAllItems.call(
+			mockExecuteFunctions,
+			method,
+			endpoint,
+			body,
+			query,
+		);
+
+		expect(result).toEqual([...responseDataPage1, ...responseDataPage2]);
+	});
+
+	it('should handle pagination for type version 2', async () => {
+		setupMockFunctions(2);
+
+		const method = 'GET';
+		const endpoint = '/test';
+		const body = {};
+		const query = {};
+
+		const responseDataPage1 = {
+			data: [{ id: 1 }, { id: 2 }],
+			meta: { next_cursor: 'cursor1' },
+			links: { next: 'nextLink1' },
+		};
+		const responseDataPage2 = {
+			data: [{ id: 3 }, { id: 4 }],
+			meta: { next_cursor: null },
+			links: { next: null },
+		};
+
+		(mockExecuteFunctions.helpers.httpRequestWithAuthentication as jest.Mock)
+			.mockResolvedValueOnce(responseDataPage1)
+			.mockResolvedValueOnce(responseDataPage2);
+
+		const result = await mailerliteApiRequestAllItems.call(
+			mockExecuteFunctions,
+			method,
+			endpoint,
+			body,
+			query,
+		);
+
+		expect(result).toEqual([...responseDataPage1.data, ...responseDataPage2.data]);
+	});
+});
+
+describe('MailerLite -> getCustomFields', () => {
+	let mockExecuteFunctions: ILoadOptionsFunctions;
+
+	const v1FieldResponse = [
+		{ name: 'Field1', key: 'field1' },
+		{ name: 'Field2', key: 'field2' },
+	];
+
+	const v2FieldResponse = {
+		data: v1FieldResponse,
+	};
+
+	const setupMockFunctions = (typeVersion: number) => {
+		mockExecuteFunctions = {
+			getNode: jest.fn().mockReturnValue({ typeVersion }),
+			helpers: {
+				httpRequestWithAuthentication: jest
+					.fn()
+					.mockResolvedValue(typeVersion === 1 ? v1FieldResponse : v2FieldResponse),
+			},
+		} as unknown as ILoadOptionsFunctions;
+		jest.clearAllMocks();
+	};
+
+	beforeEach(() => {
+		setupMockFunctions(1);
+	});
+
+	it('should return custom fields for type version 1', async () => {
+		const result = await getCustomFields.call(mockExecuteFunctions);
+
+		expect(result).toEqual([
+			{ name: 'field1', value: 'field1' },
+			{ name: 'field2', value: 'field2' },
+		]);
+	});
+
+	it('should return custom fields for type version 2', async () => {
+		setupMockFunctions(2);
+		const result = await getCustomFields.call(mockExecuteFunctions);
+
+		expect(result).toEqual([
+			{ name: 'Field1', value: 'field1' },
+			{ name: 'Field2', value: 'field2' },
+		]);
+	});
+});
diff --git a/packages/nodes-base/nodes/MailerLite/tests/apiResponses.ts b/packages/nodes-base/nodes/MailerLite/tests/apiResponses.ts
new file mode 100644
index 0000000000..e1216e1ef5
--- /dev/null
+++ b/packages/nodes-base/nodes/MailerLite/tests/apiResponses.ts
@@ -0,0 +1,411 @@
+export const getUpdateSubscriberResponseClassic = {
+	id: 1343965485,
+	email: 'demo@mailerlite.com',
+	sent: 0,
+	opened: 0,
+	clicked: 0,
+	type: 'unsubscribed',
+	fields: [
+		{
+			key: 'email',
+			value: 'demo@mailerlite.com',
+			type: 'TEXT',
+		},
+		{
+			key: 'name',
+			value: 'Demo',
+			type: 'TEXT',
+		},
+		{
+			key: 'last_name',
+			value: '',
+			type: 'TEXT',
+		},
+		{
+			key: 'company',
+			value: '',
+			type: 'TEXT',
+		},
+		{
+			key: 'country',
+			value: '',
+			type: 'TEXT',
+		},
+		{
+			key: 'city',
+			value: '',
+			type: 'TEXT',
+		},
+		{
+			key: 'phone',
+			value: '',
+			type: 'TEXT',
+		},
+		{
+			key: 'state',
+			value: '',
+			type: 'TEXT',
+		},
+		{
+			key: 'zip',
+			value: '',
+			type: 'TEXT',
+		},
+	],
+	date_subscribe: null,
+	date_unsubscribe: '2016-04-04 12:07:26',
+	date_created: '2016-04-04',
+	date_updated: null,
+};
+export const getSubscriberResponseClassic = {
+	id: 1343965485,
+	name: 'John',
+	email: 'demo@mailerlite.com',
+	sent: 0,
+	opened: 0,
+	clicked: 0,
+	type: 'active',
+	signup_ip: '127.0.0.1',
+	signup_timestamp: '2018-01-01 01:01:01',
+	confirmation_ip: '127.0.0.2',
+	confirmation_timestamp: '2018-01-01 01:01:02',
+	fields: [
+		{
+			key: 'email',
+			value: 'demo@mailerlite.com',
+			type: 'TEXT',
+		},
+		{
+			key: 'name',
+			value: 'John',
+			type: 'TEXT',
+		},
+		{
+			key: 'last_name',
+			value: '',
+			type: 'TEXT',
+		},
+		{
+			key: 'company',
+			value: '',
+			type: 'TEXT',
+		},
+		{
+			key: 'country',
+			value: '',
+			type: 'TEXT',
+		},
+		{
+			key: 'city',
+			value: '',
+			type: 'TEXT',
+		},
+		{
+			key: 'phone',
+			value: '',
+			type: 'TEXT',
+		},
+		{
+			key: 'state',
+			value: '',
+			type: 'TEXT',
+		},
+		{
+			key: 'zip',
+			value: '',
+			type: 'TEXT',
+		},
+	],
+	date_subscribe: null,
+	date_unsubscribe: null,
+	date_created: '2016-04-04',
+	date_updated: null,
+};
+export const getCreateResponseClassic = {
+	id: 1343965485,
+	name: 'John',
+	email: 'demo@mailerlite.com',
+	sent: 0,
+	opened: 0,
+	clicked: 0,
+	type: 'active',
+	fields: [
+		{
+			key: 'email',
+			value: 'demo@mailerlite.com',
+			type: 'TEXT',
+		},
+		{
+			key: 'name',
+			value: 'John',
+			type: 'TEXT',
+		},
+		{
+			key: 'last_name',
+			value: '',
+			type: 'TEXT',
+		},
+		{
+			key: 'company',
+			value: 'MailerLite',
+			type: 'TEXT',
+		},
+		{
+			key: 'country',
+			value: '',
+			type: 'TEXT',
+		},
+		{
+			key: 'city',
+			value: '',
+			type: 'TEXT',
+		},
+		{
+			key: 'phone',
+			value: '',
+			type: 'TEXT',
+		},
+		{
+			key: 'state',
+			value: '',
+			type: 'TEXT',
+		},
+		{
+			key: 'zip',
+			value: '',
+			type: 'TEXT',
+		},
+	],
+	date_subscribe: null,
+	date_unsubscribe: null,
+	date_created: '2016-04-04 12:00:00',
+	date_updated: '2016-04-04 12:00:00',
+};
+export const getAllSubscribersResponseClassic = [
+	{
+		id: 1343965485,
+		name: 'John',
+		email: 'demo@mailerlite.com',
+		sent: 0,
+		opened: 0,
+		clicked: 0,
+		type: 'active',
+		fields: [
+			{
+				key: 'email',
+				value: 'demo@mailerlite.com',
+				type: 'TEXT',
+			},
+			{
+				key: 'name',
+				value: 'John',
+				type: 'TEXT',
+			},
+			{
+				key: 'last_name',
+				value: '',
+				type: 'TEXT',
+			},
+			{
+				key: 'company',
+				value: '',
+				type: 'TEXT',
+			},
+			{
+				key: 'country',
+				value: '',
+				type: 'TEXT',
+			},
+			{
+				key: 'city',
+				value: '',
+				type: 'TEXT',
+			},
+			{
+				key: 'phone',
+				value: '',
+				type: 'TEXT',
+			},
+			{
+				key: 'state',
+				value: '',
+				type: 'TEXT',
+			},
+			{
+				key: 'zip',
+				value: '',
+				type: 'TEXT',
+			},
+		],
+		date_subscribe: null,
+		date_unsubscribe: null,
+		date_created: '2016-04-04',
+		date_updated: null,
+	},
+];
+
+export const getUpdateSubscriberResponseV2 = {
+	data: {
+		id: '139872142007207563',
+		email: 'user@n8n.io',
+		status: 'junk',
+		source: 'api',
+		sent: 0,
+		opens_count: 0,
+		clicks_count: 0,
+		open_rate: 0,
+		click_rate: 0,
+		ip_address: null,
+		subscribed_at: '2024-12-05 09:54:29',
+		unsubscribed_at: null,
+		created_at: '2024-12-05 09:54:29',
+		updated_at: '2024-12-05 10:20:32',
+		fields: {
+			name: null,
+			last_name: null,
+			company: null,
+			country: null,
+			city: null,
+			phone: null,
+			state: null,
+			z_i_p: null,
+		},
+		groups: [],
+		opted_in_at: null,
+		optin_ip: '8.8.8.8',
+	},
+};
+export const getCreateResponseV2 = {
+	data: {
+		id: '139872142007207563',
+		email: 'user@n8n.io',
+		status: 'junk',
+		source: 'api',
+		sent: 0,
+		opens_count: 0,
+		clicks_count: 0,
+		open_rate: 0,
+		click_rate: 0,
+		ip_address: null,
+		subscribed_at: '2024-12-05 09:54:29',
+		unsubscribed_at: null,
+		created_at: '2024-12-05 09:54:29',
+		updated_at: '2024-12-05 10:20:32',
+		fields: {
+			name: null,
+			last_name: null,
+			company: null,
+			country: null,
+			city: null,
+			phone: null,
+			state: null,
+			z_i_p: null,
+		},
+		groups: [],
+		opted_in_at: null,
+		optin_ip: '8.8.8.8',
+	},
+};
+export const getSubscriberResponseV2 = {
+	data: {
+		id: '139872142007207563',
+		email: 'user@n8n.io',
+		status: 'junk',
+		source: 'api',
+		sent: 0,
+		opens_count: 0,
+		clicks_count: 0,
+		open_rate: 0,
+		click_rate: 0,
+		ip_address: null,
+		subscribed_at: '2024-12-05 09:54:29',
+		unsubscribed_at: null,
+		created_at: '2024-12-05 09:54:29',
+		updated_at: '2024-12-05 10:20:32',
+		fields: {
+			name: null,
+			last_name: null,
+			company: null,
+			country: null,
+			city: null,
+			phone: null,
+			state: null,
+			z_i_p: null,
+		},
+		groups: [],
+		opted_in_at: null,
+		optin_ip: '8.8.8.8',
+	},
+};
+export const getAllSubscribersResponseV2 = {
+	data: [
+		{
+			id: '139872142007207563',
+			email: 'user@n8n.io',
+			status: 'junk',
+			source: 'api',
+			sent: 0,
+			opens_count: 0,
+			clicks_count: 0,
+			open_rate: 0,
+			click_rate: 0,
+			ip_address: null,
+			subscribed_at: '2024-12-05 09:54:29',
+			unsubscribed_at: null,
+			created_at: '2024-12-05 09:54:29',
+			updated_at: '2024-12-05 10:20:32',
+			fields: {
+				name: null,
+				last_name: null,
+				company: null,
+				country: null,
+				city: null,
+				phone: null,
+				state: null,
+				z_i_p: null,
+			},
+			opted_in_at: null,
+			optin_ip: '8.8.8.8',
+		},
+		{
+			id: '139059851540038710',
+			email: 'nathan@n8n.io',
+			status: 'junk',
+			source: 'api',
+			sent: 0,
+			opens_count: 0,
+			clicks_count: 0,
+			open_rate: 0,
+			click_rate: 0,
+			ip_address: null,
+			subscribed_at: null,
+			unsubscribed_at: null,
+			created_at: '2024-11-26 10:43:28',
+			updated_at: '2024-11-27 10:09:34',
+			fields: {
+				name: 'Nathan',
+				last_name: 'Workflow',
+				company: null,
+				country: null,
+				city: null,
+				phone: null,
+				state: null,
+				z_i_p: null,
+			},
+			opted_in_at: null,
+			optin_ip: null,
+		},
+	],
+	links: {
+		first: null,
+		last: null,
+		prev: null,
+		next: null,
+	},
+	meta: {
+		path: 'https://connect.mailerlite.com/api/subscribers',
+		per_page: 2,
+		next_cursor: null,
+		prev_cursor: null,
+	},
+};
diff --git a/packages/nodes-base/nodes/MailerLite/tests/v1/MailerLite.v1.workflow.json b/packages/nodes-base/nodes/MailerLite/tests/v1/MailerLite.v1.workflow.json
new file mode 100644
index 0000000000..46f270f006
--- /dev/null
+++ b/packages/nodes-base/nodes/MailerLite/tests/v1/MailerLite.v1.workflow.json
@@ -0,0 +1,460 @@
+{
+	"name": "[TEST] MailerLite v1 Node",
+	"nodes": [
+		{
+			"parameters": {},
+			"id": "be5a39ea-04bf-49a3-969f-47d4a9496f08",
+			"name": "When clicking ‘Test workflow’",
+			"type": "n8n-nodes-base.manualTrigger",
+			"typeVersion": 1,
+			"position": [-340, 280]
+		},
+		{
+			"parameters": {
+				"email": "demo@mailerlite.com",
+				"additionalFields": {}
+			},
+			"id": "98d30bbe-cbdd-4313-933e-804cdf322860",
+			"name": "Create Subscriber",
+			"type": "n8n-nodes-base.mailerLite",
+			"typeVersion": 1,
+			"position": [-140, 40],
+			"credentials": {
+				"mailerLiteApi": {
+					"id": "bm7VHS2C7lRgVOhb",
+					"name": "Mailer Lite account"
+				}
+			}
+		},
+		{
+			"parameters": {},
+			"type": "n8n-nodes-base.noOp",
+			"typeVersion": 1,
+			"position": [80, 40],
+			"id": "93aa764f-5101-4961-9b51-9fa92f746337",
+			"name": "No Operation, do nothing"
+		},
+		{
+			"parameters": {},
+			"type": "n8n-nodes-base.noOp",
+			"typeVersion": 1,
+			"position": [80, 220],
+			"id": "4dccb059-c4f6-4eae-b68a-5c5c36d0b8d4",
+			"name": "No Operation, do nothing1"
+		},
+		{
+			"parameters": {
+				"operation": "get",
+				"subscriberId": "demo@mailerlite.com"
+			},
+			"type": "n8n-nodes-base.mailerLite",
+			"typeVersion": 1,
+			"position": [-140, 220],
+			"id": "82115adf-edf4-4ce4-9109-3ade129294d1",
+			"name": "Get Subscriber",
+			"credentials": {
+				"mailerLiteApi": {
+					"id": "bm7VHS2C7lRgVOhb",
+					"name": "Mailer Lite account"
+				}
+			}
+		},
+		{
+			"parameters": {
+				"operation": "update",
+				"subscriberId": "demo@mailerlite.com",
+				"updateFields": {
+					"type": "active"
+				}
+			},
+			"type": "n8n-nodes-base.mailerLite",
+			"typeVersion": 1,
+			"position": [-140, 420],
+			"id": "fae9c6bd-1bd1-4ee8-865d-283b7edb6004",
+			"name": "Update Subscriber",
+			"credentials": {
+				"mailerLiteApi": {
+					"id": "bm7VHS2C7lRgVOhb",
+					"name": "Mailer Lite account"
+				}
+			}
+		},
+		{
+			"parameters": {},
+			"type": "n8n-nodes-base.noOp",
+			"typeVersion": 1,
+			"position": [80, 420],
+			"id": "45937d69-3956-434d-b955-a67d77d43d57",
+			"name": "No Operation, do nothing2"
+		},
+		{
+			"parameters": {
+				"operation": "getAll",
+				"limit": 1,
+				"filters": {}
+			},
+			"type": "n8n-nodes-base.mailerLite",
+			"typeVersion": 1,
+			"position": [-180, 680],
+			"id": "6491d933-0929-44bd-89cf-977823dde650",
+			"name": "Get Many Subscrbers",
+			"credentials": {
+				"mailerLiteApi": {
+					"id": "bm7VHS2C7lRgVOhb",
+					"name": "Mailer Lite account"
+				}
+			}
+		},
+		{
+			"parameters": {},
+			"type": "n8n-nodes-base.noOp",
+			"typeVersion": 1,
+			"position": [40, 680],
+			"id": "6e35d6e1-1ce3-4410-8558-a5d573676d8a",
+			"name": "No Operation, do nothing3"
+		}
+	],
+	"pinData": {
+		"No Operation, do nothing": [
+			{
+				"json": {
+					"id": 1343965485,
+					"name": "John",
+					"email": "demo@mailerlite.com",
+					"sent": 0,
+					"opened": 0,
+					"clicked": 0,
+					"type": "active",
+					"fields": [
+						{
+							"key": "email",
+							"value": "demo@mailerlite.com",
+							"type": "TEXT"
+						},
+						{
+							"key": "name",
+							"value": "John",
+							"type": "TEXT"
+						},
+						{
+							"key": "last_name",
+							"value": "",
+							"type": "TEXT"
+						},
+						{
+							"key": "company",
+							"value": "MailerLite",
+							"type": "TEXT"
+						},
+						{
+							"key": "country",
+							"value": "",
+							"type": "TEXT"
+						},
+						{
+							"key": "city",
+							"value": "",
+							"type": "TEXT"
+						},
+						{
+							"key": "phone",
+							"value": "",
+							"type": "TEXT"
+						},
+						{
+							"key": "state",
+							"value": "",
+							"type": "TEXT"
+						},
+						{
+							"key": "zip",
+							"value": "",
+							"type": "TEXT"
+						}
+					],
+					"date_subscribe": null,
+					"date_unsubscribe": null,
+					"date_created": "2016-04-04 12:00:00",
+					"date_updated": "2016-04-04 12:00:00"
+				}
+			}
+		],
+		"No Operation, do nothing1": [
+			{
+				"json": {
+					"id": 1343965485,
+					"name": "John",
+					"email": "demo@mailerlite.com",
+					"sent": 0,
+					"opened": 0,
+					"clicked": 0,
+					"type": "active",
+					"signup_ip": "127.0.0.1",
+					"signup_timestamp": "2018-01-01 01:01:01",
+					"confirmation_ip": "127.0.0.2",
+					"confirmation_timestamp": "2018-01-01 01:01:02",
+					"fields": [
+						{
+							"key": "email",
+							"value": "demo@mailerlite.com",
+							"type": "TEXT"
+						},
+						{
+							"key": "name",
+							"value": "John",
+							"type": "TEXT"
+						},
+						{
+							"key": "last_name",
+							"value": "",
+							"type": "TEXT"
+						},
+						{
+							"key": "company",
+							"value": "",
+							"type": "TEXT"
+						},
+						{
+							"key": "country",
+							"value": "",
+							"type": "TEXT"
+						},
+						{
+							"key": "city",
+							"value": "",
+							"type": "TEXT"
+						},
+						{
+							"key": "phone",
+							"value": "",
+							"type": "TEXT"
+						},
+						{
+							"key": "state",
+							"value": "",
+							"type": "TEXT"
+						},
+						{
+							"key": "zip",
+							"value": "",
+							"type": "TEXT"
+						}
+					],
+					"date_subscribe": null,
+					"date_unsubscribe": null,
+					"date_created": "2016-04-04",
+					"date_updated": null
+				}
+			}
+		],
+		"No Operation, do nothing2": [
+			{
+				"json": {
+					"id": 1343965485,
+					"email": "demo@mailerlite.com",
+					"sent": 0,
+					"opened": 0,
+					"clicked": 0,
+					"type": "unsubscribed",
+					"fields": [
+						{
+							"key": "email",
+							"value": "demo@mailerlite.com",
+							"type": "TEXT"
+						},
+						{
+							"key": "name",
+							"value": "Demo",
+							"type": "TEXT"
+						},
+						{
+							"key": "last_name",
+							"value": "",
+							"type": "TEXT"
+						},
+						{
+							"key": "company",
+							"value": "",
+							"type": "TEXT"
+						},
+						{
+							"key": "country",
+							"value": "",
+							"type": "TEXT"
+						},
+						{
+							"key": "city",
+							"value": "",
+							"type": "TEXT"
+						},
+						{
+							"key": "phone",
+							"value": "",
+							"type": "TEXT"
+						},
+						{
+							"key": "state",
+							"value": "",
+							"type": "TEXT"
+						},
+						{
+							"key": "zip",
+							"value": "",
+							"type": "TEXT"
+						}
+					],
+					"date_subscribe": null,
+					"date_unsubscribe": "2016-04-04 12:07:26",
+					"date_created": "2016-04-04",
+					"date_updated": null
+				}
+			}
+		],
+		"No Operation, do nothing3": [
+			{
+				"json": {
+					"id": 1343965485,
+					"name": "John",
+					"email": "demo@mailerlite.com",
+					"sent": 0,
+					"opened": 0,
+					"clicked": 0,
+					"type": "active",
+					"fields": [
+						{
+							"key": "email",
+							"value": "demo@mailerlite.com",
+							"type": "TEXT"
+						},
+						{
+							"key": "name",
+							"value": "John",
+							"type": "TEXT"
+						},
+						{
+							"key": "last_name",
+							"value": "",
+							"type": "TEXT"
+						},
+						{
+							"key": "company",
+							"value": "",
+							"type": "TEXT"
+						},
+						{
+							"key": "country",
+							"value": "",
+							"type": "TEXT"
+						},
+						{
+							"key": "city",
+							"value": "",
+							"type": "TEXT"
+						},
+						{
+							"key": "phone",
+							"value": "",
+							"type": "TEXT"
+						},
+						{
+							"key": "state",
+							"value": "",
+							"type": "TEXT"
+						},
+						{
+							"key": "zip",
+							"value": "",
+							"type": "TEXT"
+						}
+					],
+					"date_subscribe": null,
+					"date_unsubscribe": null,
+					"date_created": "2016-04-04",
+					"date_updated": null
+				}
+			}
+		]
+	},
+	"connections": {
+		"When clicking ‘Test workflow’": {
+			"main": [
+				[
+					{
+						"node": "Create Subscriber",
+						"type": "main",
+						"index": 0
+					},
+					{
+						"node": "Get Subscriber",
+						"type": "main",
+						"index": 0
+					},
+					{
+						"node": "Update Subscriber",
+						"type": "main",
+						"index": 0
+					},
+					{
+						"node": "Get Many Subscrbers",
+						"type": "main",
+						"index": 0
+					}
+				]
+			]
+		},
+		"Create Subscriber": {
+			"main": [
+				[
+					{
+						"node": "No Operation, do nothing",
+						"type": "main",
+						"index": 0
+					}
+				]
+			]
+		},
+		"Get Subscriber": {
+			"main": [
+				[
+					{
+						"node": "No Operation, do nothing1",
+						"type": "main",
+						"index": 0
+					}
+				]
+			]
+		},
+		"Update Subscriber": {
+			"main": [
+				[
+					{
+						"node": "No Operation, do nothing2",
+						"type": "main",
+						"index": 0
+					}
+				]
+			]
+		},
+		"Get Many Subscrbers": {
+			"main": [
+				[
+					{
+						"node": "No Operation, do nothing3",
+						"type": "main",
+						"index": 0
+					}
+				]
+			]
+		}
+	},
+	"active": false,
+	"settings": {
+		"executionOrder": "v1"
+	},
+	"versionId": "826c1711-fcea-4564-809b-0258dbdd72f4",
+	"meta": {
+		"instanceId": "8c8c5237b8e37b006a7adce87f4369350c58e41f3ca9de16196d3197f69eabcd"
+	},
+	"id": "I0absgO5t7xV2f2V",
+	"tags": []
+}
diff --git a/packages/nodes-base/nodes/MailerLite/tests/v1/MailerLite.v1.workflow.test.ts b/packages/nodes-base/nodes/MailerLite/tests/v1/MailerLite.v1.workflow.test.ts
new file mode 100644
index 0000000000..1430ea8ec7
--- /dev/null
+++ b/packages/nodes-base/nodes/MailerLite/tests/v1/MailerLite.v1.workflow.test.ts
@@ -0,0 +1,31 @@
+import nock from 'nock';
+
+import { getWorkflowFilenames, testWorkflows } from '../../../../test/nodes/Helpers';
+import {
+	getCreateResponseClassic,
+	getSubscriberResponseClassic,
+	getAllSubscribersResponseClassic,
+	getUpdateSubscriberResponseClassic,
+} from '../apiResponses';
+
+describe('MailerLite', () => {
+	describe('Run v1 workflow', () => {
+		beforeAll(() => {
+			nock.disableNetConnect();
+
+			const mock = nock('https://api.mailerlite.com/api/v2');
+
+			mock.post('/subscribers').reply(200, getCreateResponseClassic);
+			mock.get('/subscribers/demo@mailerlite.com').reply(200, getSubscriberResponseClassic);
+			mock.get('/subscribers').query({ limit: 1 }).reply(200, getAllSubscribersResponseClassic);
+			mock.put('/subscribers/demo@mailerlite.com').reply(200, getUpdateSubscriberResponseClassic);
+		});
+
+		afterAll(() => {
+			nock.restore();
+		});
+
+		const workflows = getWorkflowFilenames(__dirname);
+		testWorkflows(workflows);
+	});
+});
diff --git a/packages/nodes-base/nodes/MailerLite/tests/v2/MailerLite.v2.workflow.json b/packages/nodes-base/nodes/MailerLite/tests/v2/MailerLite.v2.workflow.json
new file mode 100644
index 0000000000..29630950fa
--- /dev/null
+++ b/packages/nodes-base/nodes/MailerLite/tests/v2/MailerLite.v2.workflow.json
@@ -0,0 +1,370 @@
+{
+	"name": "[TEST] MailerLite v2 Node",
+	"nodes": [
+		{
+			"parameters": {},
+			"id": "3c72284b-2b88-4d5f-81bc-b1970b14f2af",
+			"name": "When clicking ‘Test workflow’",
+			"type": "n8n-nodes-base.manualTrigger",
+			"typeVersion": 1,
+			"position": [800, 240]
+		},
+		{
+			"parameters": {
+				"email": "user@n8n.io",
+				"additionalFields": {
+					"status": "active"
+				}
+			},
+			"id": "702c6598-cbe8-403e-962e-56621ec727a4",
+			"name": "Create Subscriber",
+			"type": "n8n-nodes-base.mailerLite",
+			"typeVersion": 2,
+			"position": [1000, 0],
+			"credentials": {
+				"mailerLiteApi": {
+					"id": "bm7VHS2C7lRgVOhb",
+					"name": "Mailer Lite account"
+				}
+			}
+		},
+		{
+			"parameters": {},
+			"type": "n8n-nodes-base.noOp",
+			"typeVersion": 1,
+			"position": [1220, 0],
+			"id": "540b98b5-b3bf-49a1-a406-acc6872f4b50",
+			"name": "No Operation, do nothing"
+		},
+		{
+			"parameters": {},
+			"type": "n8n-nodes-base.noOp",
+			"typeVersion": 1,
+			"position": [1220, 180],
+			"id": "17c0b8e7-a9d7-4a4f-882f-c3fb3f6bc289",
+			"name": "No Operation, do nothing1"
+		},
+		{
+			"parameters": {
+				"operation": "get",
+				"subscriberId": "user@n8n.io"
+			},
+			"type": "n8n-nodes-base.mailerLite",
+			"typeVersion": 2,
+			"position": [1000, 180],
+			"id": "5598f2b9-4d67-4ad7-a8e4-7b7bf723cd5a",
+			"name": "Get Subscriber",
+			"credentials": {
+				"mailerLiteApi": {
+					"id": "bm7VHS2C7lRgVOhb",
+					"name": "Mailer Lite account"
+				}
+			}
+		},
+		{
+			"parameters": {
+				"operation": "update",
+				"subscriberId": "user@n8n.io",
+				"additionalFields": {
+					"status": "junk",
+					"optin_ip": "8.8.8.8"
+				}
+			},
+			"type": "n8n-nodes-base.mailerLite",
+			"typeVersion": 2,
+			"position": [1000, 380],
+			"id": "223e4507-c88e-4066-a122-ccaf9cea7b49",
+			"name": "Update Subscriber",
+			"credentials": {
+				"mailerLiteApi": {
+					"id": "bm7VHS2C7lRgVOhb",
+					"name": "Mailer Lite account"
+				}
+			}
+		},
+		{
+			"parameters": {},
+			"type": "n8n-nodes-base.noOp",
+			"typeVersion": 1,
+			"position": [1220, 380],
+			"id": "94d04b52-8809-4670-a8ca-135921139fc9",
+			"name": "No Operation, do nothing2"
+		},
+		{
+			"parameters": {
+				"operation": "getAll",
+				"limit": 2,
+				"filters": {
+					"status": "junk"
+				}
+			},
+			"type": "n8n-nodes-base.mailerLite",
+			"typeVersion": 2,
+			"position": [960, 640],
+			"id": "30c6e797-ceda-4c84-8f34-b61200ffd9e9",
+			"name": "Get Many Subscrbers",
+			"credentials": {
+				"mailerLiteApi": {
+					"id": "bm7VHS2C7lRgVOhb",
+					"name": "Mailer Lite account"
+				}
+			}
+		},
+		{
+			"parameters": {},
+			"type": "n8n-nodes-base.noOp",
+			"typeVersion": 1,
+			"position": [1180, 640],
+			"id": "c8529a30-889b-4ac9-a509-73f5dd8eef4a",
+			"name": "No Operation, do nothing3"
+		}
+	],
+	"pinData": {
+		"No Operation, do nothing": [
+			{
+				"json": {
+					"id": "139872142007207563",
+					"email": "user@n8n.io",
+					"status": "junk",
+					"source": "api",
+					"sent": 0,
+					"opens_count": 0,
+					"clicks_count": 0,
+					"open_rate": 0,
+					"click_rate": 0,
+					"ip_address": null,
+					"subscribed_at": "2024-12-05 09:54:29",
+					"unsubscribed_at": null,
+					"created_at": "2024-12-05 09:54:29",
+					"updated_at": "2024-12-05 10:20:32",
+					"fields": {
+						"name": null,
+						"last_name": null,
+						"company": null,
+						"country": null,
+						"city": null,
+						"phone": null,
+						"state": null,
+						"z_i_p": null
+					},
+					"groups": [],
+					"opted_in_at": null,
+					"optin_ip": "8.8.8.8"
+				}
+			}
+		],
+		"No Operation, do nothing1": [
+			{
+				"json": {
+					"id": "139872142007207563",
+					"email": "user@n8n.io",
+					"status": "junk",
+					"source": "api",
+					"sent": 0,
+					"opens_count": 0,
+					"clicks_count": 0,
+					"open_rate": 0,
+					"click_rate": 0,
+					"ip_address": null,
+					"subscribed_at": "2024-12-05 09:54:29",
+					"unsubscribed_at": null,
+					"created_at": "2024-12-05 09:54:29",
+					"updated_at": "2024-12-05 10:20:32",
+					"fields": {
+						"name": null,
+						"last_name": null,
+						"company": null,
+						"country": null,
+						"city": null,
+						"phone": null,
+						"state": null,
+						"z_i_p": null
+					},
+					"groups": [],
+					"opted_in_at": null,
+					"optin_ip": "8.8.8.8"
+				}
+			}
+		],
+		"No Operation, do nothing2": [
+			{
+				"json": {
+					"data": {
+						"id": "139872142007207563",
+						"email": "user@n8n.io",
+						"status": "junk",
+						"source": "api",
+						"sent": 0,
+						"opens_count": 0,
+						"clicks_count": 0,
+						"open_rate": 0,
+						"click_rate": 0,
+						"ip_address": null,
+						"subscribed_at": "2024-12-05 09:54:29",
+						"unsubscribed_at": null,
+						"created_at": "2024-12-05 09:54:29",
+						"updated_at": "2024-12-05 10:20:32",
+						"fields": {
+							"name": null,
+							"last_name": null,
+							"company": null,
+							"country": null,
+							"city": null,
+							"phone": null,
+							"state": null,
+							"z_i_p": null
+						},
+						"groups": [],
+						"opted_in_at": null,
+						"optin_ip": "8.8.8.8"
+					}
+				}
+			}
+		],
+		"No Operation, do nothing3": [
+			{
+				"json": {
+					"id": "139872142007207563",
+					"email": "user@n8n.io",
+					"status": "junk",
+					"source": "api",
+					"sent": 0,
+					"opens_count": 0,
+					"clicks_count": 0,
+					"open_rate": 0,
+					"click_rate": 0,
+					"ip_address": null,
+					"subscribed_at": "2024-12-05 09:54:29",
+					"unsubscribed_at": null,
+					"created_at": "2024-12-05 09:54:29",
+					"updated_at": "2024-12-05 10:20:32",
+					"fields": {
+						"name": null,
+						"last_name": null,
+						"company": null,
+						"country": null,
+						"city": null,
+						"phone": null,
+						"state": null,
+						"z_i_p": null
+					},
+					"opted_in_at": null,
+					"optin_ip": "8.8.8.8"
+				}
+			},
+			{
+				"json": {
+					"id": "139059851540038710",
+					"email": "nathan@n8n.io",
+					"status": "junk",
+					"source": "api",
+					"sent": 0,
+					"opens_count": 0,
+					"clicks_count": 0,
+					"open_rate": 0,
+					"click_rate": 0,
+					"ip_address": null,
+					"subscribed_at": null,
+					"unsubscribed_at": null,
+					"created_at": "2024-11-26 10:43:28",
+					"updated_at": "2024-11-27 10:09:34",
+					"fields": {
+						"name": "Nathan",
+						"last_name": "Workflow",
+						"company": null,
+						"country": null,
+						"city": null,
+						"phone": null,
+						"state": null,
+						"z_i_p": null
+					},
+					"opted_in_at": null,
+					"optin_ip": null
+				}
+			}
+		]
+	},
+	"connections": {
+		"When clicking ‘Test workflow’": {
+			"main": [
+				[
+					{
+						"node": "Create Subscriber",
+						"type": "main",
+						"index": 0
+					},
+					{
+						"node": "Get Subscriber",
+						"type": "main",
+						"index": 0
+					},
+					{
+						"node": "Update Subscriber",
+						"type": "main",
+						"index": 0
+					},
+					{
+						"node": "Get Many Subscrbers",
+						"type": "main",
+						"index": 0
+					}
+				]
+			]
+		},
+		"Create Subscriber": {
+			"main": [
+				[
+					{
+						"node": "No Operation, do nothing",
+						"type": "main",
+						"index": 0
+					}
+				]
+			]
+		},
+		"Get Subscriber": {
+			"main": [
+				[
+					{
+						"node": "No Operation, do nothing1",
+						"type": "main",
+						"index": 0
+					}
+				]
+			]
+		},
+		"Update Subscriber": {
+			"main": [
+				[
+					{
+						"node": "No Operation, do nothing2",
+						"type": "main",
+						"index": 0
+					}
+				]
+			]
+		},
+		"Get Many Subscrbers": {
+			"main": [
+				[
+					{
+						"node": "No Operation, do nothing3",
+						"type": "main",
+						"index": 0
+					}
+				]
+			]
+		}
+	},
+	"active": false,
+	"settings": {
+		"executionOrder": "v1"
+	},
+	"versionId": "338331ef-1b38-47dc-9e2b-45340ea3fe3b",
+	"meta": {
+		"templateCredsSetupCompleted": true,
+		"instanceId": "8c8c5237b8e37b006a7adce87f4369350c58e41f3ca9de16196d3197f69eabcd"
+	},
+	"id": "0Ov6Vd62DUXrWWQH",
+	"tags": []
+}
diff --git a/packages/nodes-base/nodes/MailerLite/tests/v2/MailerLite.v2.workflow.test.ts b/packages/nodes-base/nodes/MailerLite/tests/v2/MailerLite.v2.workflow.test.ts
new file mode 100644
index 0000000000..d723e86908
--- /dev/null
+++ b/packages/nodes-base/nodes/MailerLite/tests/v2/MailerLite.v2.workflow.test.ts
@@ -0,0 +1,34 @@
+import nock from 'nock';
+
+import { getWorkflowFilenames, testWorkflows } from '../../../../test/nodes/Helpers';
+import {
+	getCreateResponseV2,
+	getSubscriberResponseV2,
+	getAllSubscribersResponseV2,
+	getUpdateSubscriberResponseV2,
+} from '../apiResponses';
+
+describe('MailerLite', () => {
+	describe('Run v2 workflow', () => {
+		beforeAll(() => {
+			nock.disableNetConnect();
+
+			const mock = nock('https://connect.mailerlite.com/api');
+
+			mock.post('/subscribers').reply(200, getCreateResponseV2);
+			mock.get('/subscribers/user@n8n.io').reply(200, getSubscriberResponseV2);
+			mock
+				.get('/subscribers')
+				.query({ 'filter[status]': 'junk', limit: 2 })
+				.reply(200, getAllSubscribersResponseV2);
+			mock.put('/subscribers/user@n8n.io').reply(200, getUpdateSubscriberResponseV2);
+		});
+
+		afterAll(() => {
+			nock.restore();
+		});
+
+		const workflows = getWorkflowFilenames(__dirname);
+		testWorkflows(workflows);
+	});
+});
diff --git a/packages/nodes-base/nodes/MailerLite/v1/MailerLiteTriggerV1.node.ts b/packages/nodes-base/nodes/MailerLite/v1/MailerLiteTriggerV1.node.ts
new file mode 100644
index 0000000000..faaa6db8c7
--- /dev/null
+++ b/packages/nodes-base/nodes/MailerLite/v1/MailerLiteTriggerV1.node.ts
@@ -0,0 +1,184 @@
+import {
+	type IHookFunctions,
+	type IWebhookFunctions,
+	type IDataObject,
+	type INodeType,
+	type INodeTypeDescription,
+	type IWebhookResponseData,
+	type INodeTypeBaseDescription,
+	NodeConnectionType,
+} from 'n8n-workflow';
+
+import { mailerliteApiRequest } from '../GenericFunctions';
+
+export class MailerLiteTriggerV1 implements INodeType {
+	description: INodeTypeDescription;
+
+	constructor(baseDescription: INodeTypeBaseDescription) {
+		this.description = {
+			...baseDescription,
+			displayName: 'MailerLite Trigger',
+			name: 'mailerLiteTrigger',
+			group: ['trigger'],
+			version: 1,
+			description: 'Starts the workflow when MailerLite events occur',
+			defaults: {
+				name: 'MailerLite Trigger',
+			},
+			inputs: [],
+			outputs: [NodeConnectionType.Main],
+			credentials: [
+				{
+					name: 'mailerLiteApi',
+					required: true,
+				},
+			],
+			webhooks: [
+				{
+					name: 'default',
+					httpMethod: 'POST',
+					responseMode: 'onReceived',
+					path: 'webhook',
+				},
+			],
+			properties: [
+				{
+					displayName: 'Event',
+					name: 'event',
+					type: 'options',
+					options: [
+						{
+							name: 'Campaign Sent',
+							value: 'campaign.sent',
+							description: 'Fired when campaign is sent',
+						},
+						{
+							name: 'Subscriber Added Through Webform',
+							value: 'subscriber.added_through_webform',
+							description: 'Fired when a subscriber is added though a form',
+						},
+						{
+							name: 'Subscriber Added to Group',
+							value: 'subscriber.add_to_group',
+							description: 'Fired when a subscriber is added to a group',
+						},
+						{
+							name: 'Subscriber Automation Completed',
+							value: 'subscriber.automation_complete',
+							description: 'Fired when subscriber finishes automation',
+						},
+						{
+							name: 'Subscriber Automation Triggered',
+							value: 'subscriber.automation_triggered',
+							description: 'Fired when subscriber starts automation',
+						},
+						{
+							name: 'Subscriber Bounced',
+							value: 'subscriber.bounced',
+							description: 'Fired when an email address bounces',
+						},
+						{
+							name: 'Subscriber Complained',
+							value: 'subscriber.complaint',
+							description: 'Fired when subscriber marks a campaign as a spam',
+						},
+						{
+							name: 'Subscriber Created',
+							value: 'subscriber.create',
+							description: 'Fired when a new subscriber is added to an account',
+						},
+						{
+							name: 'Subscriber Removed From Group',
+							value: 'subscriber.remove_from_group',
+							description: 'Fired when a subscriber is removed from a group',
+						},
+						{
+							name: 'Subscriber Unsubscribe',
+							value: 'subscriber.unsubscribe',
+							description: 'Fired when a subscriber becomes unsubscribed',
+						},
+						{
+							name: 'Subscriber Updated',
+							value: 'subscriber.update',
+							description: "Fired when any of the subscriber's custom fields are updated",
+						},
+					],
+					required: true,
+					default: [],
+					description: 'The events to listen to',
+				},
+			],
+		};
+	}
+
+	webhookMethods = {
+		default: {
+			async checkExists(this: IHookFunctions): Promise<boolean> {
+				const webhookUrl = this.getNodeWebhookUrl('default');
+				const webhookData = this.getWorkflowStaticData('node');
+				const event = this.getNodeParameter('event') as string;
+				// Check all the webhooks which exist already if it is identical to the
+				// one that is supposed to get created.
+				const endpoint = '/webhooks';
+				const { webhooks } = await mailerliteApiRequest.call(this, 'GET', endpoint, {});
+				for (const webhook of webhooks) {
+					if (webhook.url === webhookUrl && webhook.event === event) {
+						// Set webhook-id to be sure that it can be deleted
+						webhookData.webhookId = webhook.id as string;
+						return true;
+					}
+				}
+				return false;
+			},
+			async create(this: IHookFunctions): Promise<boolean> {
+				const webhookData = this.getWorkflowStaticData('node');
+				const webhookUrl = this.getNodeWebhookUrl('default');
+				const event = this.getNodeParameter('event') as string;
+
+				const endpoint = '/webhooks';
+
+				const body = {
+					url: webhookUrl,
+					event,
+				};
+
+				const responseData = await mailerliteApiRequest.call(this, 'POST', endpoint, body);
+
+				if (responseData.id === undefined) {
+					// Required data is missing so was not successful
+					return false;
+				}
+
+				webhookData.webhookId = responseData.id as string;
+				return true;
+			},
+			async delete(this: IHookFunctions): Promise<boolean> {
+				const webhookData = this.getWorkflowStaticData('node');
+				if (webhookData.webhookId !== undefined) {
+					const endpoint = `/webhooks/${webhookData.webhookId}`;
+
+					try {
+						await mailerliteApiRequest.call(this, 'DELETE', endpoint);
+					} catch (error) {
+						return false;
+					}
+
+					// Remove from the static workflow data so that it is clear
+					// that no webhooks are registered anymore
+					delete webhookData.webhookId;
+				}
+				return true;
+			},
+		},
+	};
+
+	async webhook(this: IWebhookFunctions): Promise<IWebhookResponseData> {
+		const body = this.getBodyData();
+
+		const events = body.events as IDataObject[];
+
+		return {
+			workflowData: [this.helpers.returnJsonArray(events)],
+		};
+	}
+}
diff --git a/packages/nodes-base/nodes/MailerLite/v1/MailerLiteV1.node.ts b/packages/nodes-base/nodes/MailerLite/v1/MailerLiteV1.node.ts
new file mode 100644
index 0000000000..357f8f799f
--- /dev/null
+++ b/packages/nodes-base/nodes/MailerLite/v1/MailerLiteV1.node.ts
@@ -0,0 +1,199 @@
+import type {
+	IExecuteFunctions,
+	IDataObject,
+	INodeExecutionData,
+	INodeType,
+	INodeTypeDescription,
+	INodeTypeBaseDescription,
+} from 'n8n-workflow';
+import { NodeConnectionType } from 'n8n-workflow';
+
+import { subscriberFields, subscriberOperations } from './SubscriberDescription';
+import {
+	getCustomFields,
+	mailerliteApiRequest,
+	mailerliteApiRequestAllItems,
+} from '../GenericFunctions';
+
+export class MailerLiteV1 implements INodeType {
+	description: INodeTypeDescription;
+
+	constructor(baseDescription: INodeTypeBaseDescription) {
+		this.description = {
+			...baseDescription,
+			displayName: 'MailerLite',
+			name: 'mailerLite',
+			group: ['input'],
+			version: 1,
+			subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
+			description: 'Consume Mailer Lite API',
+			defaults: {
+				name: 'MailerLite',
+			},
+			inputs: [NodeConnectionType.Main],
+			outputs: [NodeConnectionType.Main],
+			credentials: [
+				{
+					name: 'mailerLiteApi',
+					required: true,
+				},
+			],
+			properties: [
+				{
+					displayName: 'Resource',
+					name: 'resource',
+					type: 'options',
+					noDataExpression: true,
+					options: [
+						{
+							name: 'Subscriber',
+							value: 'subscriber',
+						},
+					],
+					default: 'subscriber',
+				},
+				...subscriberOperations,
+				...subscriberFields,
+			],
+		};
+	}
+
+	methods = {
+		loadOptions: {
+			getCustomFields,
+		},
+	};
+
+	async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
+		const items = this.getInputData();
+		const returnData: INodeExecutionData[] = [];
+		const length = items.length;
+		const qs: IDataObject = {};
+		let responseData;
+		const resource = this.getNodeParameter('resource', 0);
+		const operation = this.getNodeParameter('operation', 0);
+		for (let i = 0; i < length; i++) {
+			try {
+				if (resource === 'subscriber') {
+					//https://developers.mailerlite.com/reference#create-a-subscriber
+					if (operation === 'create') {
+						const email = this.getNodeParameter('email', i) as string;
+
+						const additionalFields = this.getNodeParameter('additionalFields', i);
+
+						const body: IDataObject = {
+							email,
+							fields: [],
+						};
+
+						Object.assign(body, additionalFields);
+
+						if (additionalFields.customFieldsUi) {
+							const customFieldsValues = (additionalFields.customFieldsUi as IDataObject)
+								.customFieldsValues as IDataObject[];
+
+							if (customFieldsValues) {
+								const fields = {};
+
+								for (const customFieldValue of customFieldsValues) {
+									//@ts-ignore
+									fields[customFieldValue.fieldId] = customFieldValue.value;
+								}
+
+								body.fields = fields;
+								delete body.customFieldsUi;
+							}
+						}
+
+						responseData = await mailerliteApiRequest.call(this, 'POST', '/subscribers', body);
+					}
+					//https://developers.mailerlite.com/reference#single-subscriber
+					if (operation === 'get') {
+						const subscriberId = this.getNodeParameter('subscriberId', i) as string;
+
+						responseData = await mailerliteApiRequest.call(
+							this,
+							'GET',
+							`/subscribers/${subscriberId}`,
+						);
+					}
+					//https://developers.mailerlite.com/reference#subscribers
+					if (operation === 'getAll') {
+						const returnAll = this.getNodeParameter('returnAll', i);
+
+						const filters = this.getNodeParameter('filters', i);
+
+						Object.assign(qs, filters);
+
+						if (returnAll) {
+							responseData = await mailerliteApiRequestAllItems.call(
+								this,
+								'GET',
+								'/subscribers',
+								{},
+								qs,
+							);
+						} else {
+							qs.limit = this.getNodeParameter('limit', i);
+
+							responseData = await mailerliteApiRequest.call(this, 'GET', '/subscribers', {}, qs);
+						}
+					}
+					//https://developers.mailerlite.com/reference#update-subscriber
+					if (operation === 'update') {
+						const subscriberId = this.getNodeParameter('subscriberId', i) as string;
+
+						const updateFields = this.getNodeParameter('updateFields', i);
+
+						const body: IDataObject = {};
+
+						Object.assign(body, updateFields);
+
+						if (updateFields.customFieldsUi) {
+							const customFieldsValues = (updateFields.customFieldsUi as IDataObject)
+								.customFieldsValues as IDataObject[];
+
+							if (customFieldsValues) {
+								const fields = {};
+
+								for (const customFieldValue of customFieldsValues) {
+									//@ts-ignore
+									fields[customFieldValue.fieldId] = customFieldValue.value;
+								}
+
+								body.fields = fields;
+								delete body.customFieldsUi;
+							}
+						}
+
+						responseData = await mailerliteApiRequest.call(
+							this,
+							'PUT',
+							`/subscribers/${subscriberId}`,
+							body,
+						);
+					}
+				}
+			} catch (error) {
+				if (this.continueOnFail()) {
+					const executionErrorData = this.helpers.constructExecutionMetaData(
+						this.helpers.returnJsonArray({ error: error.message }),
+						{ itemData: { item: i } },
+					);
+					returnData.push(...executionErrorData);
+					continue;
+				}
+				throw error;
+			}
+
+			const executionData = this.helpers.constructExecutionMetaData(
+				this.helpers.returnJsonArray(responseData as IDataObject[]),
+				{ itemData: { item: i } },
+			);
+
+			returnData.push(...executionData);
+		}
+
+		return [returnData];
+	}
+}
diff --git a/packages/nodes-base/nodes/MailerLite/SubscriberDescription.ts b/packages/nodes-base/nodes/MailerLite/v1/SubscriberDescription.ts
similarity index 100%
rename from packages/nodes-base/nodes/MailerLite/SubscriberDescription.ts
rename to packages/nodes-base/nodes/MailerLite/v1/SubscriberDescription.ts
diff --git a/packages/nodes-base/nodes/MailerLite/v2/MailerLite.Interface.ts b/packages/nodes-base/nodes/MailerLite/v2/MailerLite.Interface.ts
new file mode 100644
index 0000000000..f408e75ebb
--- /dev/null
+++ b/packages/nodes-base/nodes/MailerLite/v2/MailerLite.Interface.ts
@@ -0,0 +1,35 @@
+export interface CustomField {
+	name: string;
+	key: string;
+}
+
+export interface SubscriberFields {
+	city: string | null;
+	company: string | null;
+	country: string | null;
+	last_name: string | null;
+	name: string | null;
+	phone: string | null;
+	state: string | null;
+	z_i_p: string | null;
+}
+
+export interface Subscriber {
+	id: string;
+	email: string;
+	status: string;
+	source: string;
+	sent: number;
+	opens_count: number;
+	clicks_count: number;
+	open_rate: number;
+	click_rate: number;
+	ip_address: string | null;
+	subscribed_at: string;
+	unsubscribed_at: string | null;
+	created_at: string;
+	updated_at: string;
+	fields: SubscriberFields;
+	opted_in_at: string | null;
+	optin_ip: string | null;
+}
diff --git a/packages/nodes-base/nodes/MailerLite/v2/MailerLiteTriggerV2.node.ts b/packages/nodes-base/nodes/MailerLite/v2/MailerLiteTriggerV2.node.ts
new file mode 100644
index 0000000000..f7b17316dc
--- /dev/null
+++ b/packages/nodes-base/nodes/MailerLite/v2/MailerLiteTriggerV2.node.ts
@@ -0,0 +1,179 @@
+import {
+	type IHookFunctions,
+	type IWebhookFunctions,
+	type IDataObject,
+	type INodeType,
+	type INodeTypeDescription,
+	type IWebhookResponseData,
+	type INodeTypeBaseDescription,
+	NodeConnectionType,
+} from 'n8n-workflow';
+
+import { mailerliteApiRequest } from '../GenericFunctions';
+
+export class MailerLiteTriggerV2 implements INodeType {
+	description: INodeTypeDescription;
+
+	constructor(baseDescription: INodeTypeBaseDescription) {
+		this.description = {
+			...baseDescription,
+			displayName: 'MailerLite Trigger',
+			name: 'mailerLiteTrigger',
+			group: ['trigger'],
+			version: [2],
+			description: 'Starts the workflow when MailerLite events occur',
+			defaults: {
+				name: 'MailerLite Trigger',
+			},
+			inputs: [],
+			outputs: [NodeConnectionType.Main],
+			credentials: [
+				{
+					name: 'mailerLiteApi',
+					required: true,
+				},
+			],
+			webhooks: [
+				{
+					name: 'default',
+					httpMethod: 'POST',
+					responseMode: 'onReceived',
+					path: 'webhook',
+				},
+			],
+			properties: [
+				{
+					displayName: 'Events',
+					name: 'events',
+					type: 'multiOptions',
+					options: [
+						{
+							name: 'Campaign Sent',
+							value: 'campaign.sent',
+							description: 'Fired when campaign is sent',
+						},
+						{
+							name: 'Subscriber Added to Group',
+							value: 'subscriber.added_to_group',
+							description: 'Fired when a subscriber is added to a group',
+						},
+						{
+							name: 'Subscriber Automation Completed',
+							value: 'subscriber.automation_completed',
+							description: 'Fired when subscriber finishes automation',
+						},
+						{
+							name: 'Subscriber Automation Triggered',
+							value: 'subscriber.automation_triggered',
+							description: 'Fired when subscriber starts automation',
+						},
+						{
+							name: 'Subscriber Bounced',
+							value: 'subscriber.bounced',
+							description: 'Fired when an email address bounces',
+						},
+						{
+							name: 'Subscriber Created',
+							value: 'subscriber.created',
+							description: 'Fired when a new subscriber is added to an account',
+						},
+						{
+							name: 'Subscriber Removed From Group',
+							value: 'subscriber.removed_from_group',
+							description: 'Fired when a subscriber is removed from a group',
+						},
+						{
+							name: 'Subscriber Spam Reported',
+							value: 'subscriber.spam_reported',
+							description: 'Fired when subscriber marks a campaign as a spam',
+						},
+						{
+							name: 'Subscriber Unsubscribe',
+							value: 'subscriber.unsubscribed',
+							description: 'Fired when a subscriber becomes unsubscribed',
+						},
+						{
+							name: 'Subscriber Updated',
+							value: 'subscriber.updated',
+							description: "Fired when any of the subscriber's custom fields are updated",
+						},
+					],
+					required: true,
+					default: [],
+					description: 'The events to listen to',
+				},
+			],
+		};
+	}
+
+	webhookMethods = {
+		default: {
+			async checkExists(this: IHookFunctions): Promise<boolean> {
+				const webhookUrl = this.getNodeWebhookUrl('default');
+				const webhookData = this.getWorkflowStaticData('node');
+				const events = this.getNodeParameter('events') as string[];
+				// Check all the webhooks which exist already if it is identical to the
+				// one that is supposed to get created.
+				const endpoint = '/webhooks';
+				const { data } = await mailerliteApiRequest.call(this, 'GET', endpoint, {});
+				for (const webhook of data) {
+					if (webhook.url === webhookUrl && webhook.events === events) {
+						// Set webhook-id to be sure that it can be deleted
+						webhookData.webhookId = webhook.id as string;
+						return true;
+					}
+				}
+				return false;
+			},
+			async create(this: IHookFunctions): Promise<boolean> {
+				const webhookData = this.getWorkflowStaticData('node');
+				const webhookUrl = this.getNodeWebhookUrl('default');
+				const events = this.getNodeParameter('events') as string[];
+
+				const endpoint = '/webhooks';
+
+				const body = {
+					url: webhookUrl,
+					events,
+				};
+
+				const { data } = await mailerliteApiRequest.call(this, 'POST', endpoint, body);
+
+				if (data.id === undefined) {
+					// Required data is missing so was not successful
+					return false;
+				}
+
+				webhookData.webhookId = data.id as string;
+				return true;
+			},
+			async delete(this: IHookFunctions): Promise<boolean> {
+				const webhookData = this.getWorkflowStaticData('node');
+				if (webhookData.webhookId !== undefined) {
+					const endpoint = `/webhooks/${webhookData.webhookId}`;
+
+					try {
+						await mailerliteApiRequest.call(this, 'DELETE', endpoint);
+					} catch (error) {
+						return false;
+					}
+
+					// Remove from the static workflow data so that it is clear
+					// that no webhooks are registered anymore
+					delete webhookData.webhookId;
+				}
+				return true;
+			},
+		},
+	};
+
+	async webhook(this: IWebhookFunctions): Promise<IWebhookResponseData> {
+		const body = this.getBodyData();
+
+		const data = body.fields as IDataObject[];
+
+		return {
+			workflowData: [this.helpers.returnJsonArray(data)],
+		};
+	}
+}
diff --git a/packages/nodes-base/nodes/MailerLite/v2/MailerLiteV2.node.ts b/packages/nodes-base/nodes/MailerLite/v2/MailerLiteV2.node.ts
new file mode 100644
index 0000000000..953dc7232e
--- /dev/null
+++ b/packages/nodes-base/nodes/MailerLite/v2/MailerLiteV2.node.ts
@@ -0,0 +1,206 @@
+import type {
+	IExecuteFunctions,
+	IDataObject,
+	INodeExecutionData,
+	INodeType,
+	INodeTypeDescription,
+	INodeTypeBaseDescription,
+} from 'n8n-workflow';
+import { NodeConnectionType } from 'n8n-workflow';
+
+import type { Subscriber } from './MailerLite.Interface';
+import { subscriberFields, subscriberOperations } from './SubscriberDescription';
+import {
+	getCustomFields,
+	mailerliteApiRequest,
+	mailerliteApiRequestAllItems,
+} from '../GenericFunctions';
+
+export class MailerLiteV2 implements INodeType {
+	description: INodeTypeDescription;
+
+	constructor(baseDescription: INodeTypeBaseDescription) {
+		this.description = {
+			...baseDescription,
+			displayName: 'MailerLite',
+			name: 'mailerLite',
+			group: ['input'],
+			version: [2],
+			subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
+			description: 'Consume Mailer Lite API',
+			defaults: {
+				name: 'MailerLite',
+			},
+			inputs: [NodeConnectionType.Main],
+			outputs: [NodeConnectionType.Main],
+			credentials: [
+				{
+					name: 'mailerLiteApi',
+					required: true,
+				},
+			],
+			properties: [
+				{
+					displayName: 'Resource',
+					name: 'resource',
+					type: 'options',
+					noDataExpression: true,
+					options: [
+						{
+							name: 'Subscriber',
+							value: 'subscriber',
+						},
+					],
+					default: 'subscriber',
+				},
+				...subscriberOperations,
+				...subscriberFields,
+			],
+		};
+	}
+
+	methods = {
+		loadOptions: {
+			getCustomFields,
+		},
+	};
+
+	async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
+		const items = this.getInputData();
+		const returnData: INodeExecutionData[] = [];
+		const length = items.length;
+		const qs: IDataObject = {};
+		let responseData;
+		const resource = this.getNodeParameter('resource', 0);
+		const operation = this.getNodeParameter('operation', 0);
+		for (let i = 0; i < length; i++) {
+			try {
+				if (resource === 'subscriber') {
+					//https://developers.mailerlite.com/reference#create-a-subscriber
+					if (operation === 'create') {
+						const email = this.getNodeParameter('email', i) as string;
+
+						const additionalFields = this.getNodeParameter('additionalFields', i);
+
+						const body: IDataObject = {
+							email,
+							fields: [],
+						};
+
+						Object.assign(body, additionalFields);
+
+						if (additionalFields.customFieldsUi) {
+							const customFieldsValues = (additionalFields.customFieldsUi as IDataObject)
+								.customFieldsValues as IDataObject[];
+
+							if (customFieldsValues) {
+								const fields = {};
+
+								for (const customFieldValue of customFieldsValues) {
+									//@ts-ignore
+									fields[customFieldValue.fieldId] = customFieldValue.value;
+								}
+
+								body.fields = fields;
+								delete body.customFieldsUi;
+							}
+						}
+
+						responseData = await mailerliteApiRequest.call(this, 'POST', '/subscribers', body);
+						responseData = responseData.data;
+					}
+					//https://developers.mailerlite.com/reference#single-subscriber
+					if (operation === 'get') {
+						const subscriberId = this.getNodeParameter('subscriberId', i) as string;
+
+						responseData = await mailerliteApiRequest.call(
+							this,
+							'GET',
+							`/subscribers/${subscriberId}`,
+						);
+
+						responseData = responseData.data as Subscriber[];
+					}
+					//https://developers.mailerlite.com/reference#subscribers
+					if (operation === 'getAll') {
+						const returnAll = this.getNodeParameter('returnAll', i);
+
+						const filters = this.getNodeParameter('filters', i);
+
+						if (filters.status) {
+							qs['filter[status]'] = filters.status as string;
+						}
+
+						if (returnAll) {
+							responseData = await mailerliteApiRequestAllItems.call(
+								this,
+								'GET',
+								'/subscribers',
+								{},
+								qs,
+							);
+						} else {
+							qs.limit = this.getNodeParameter('limit', i);
+
+							responseData = await mailerliteApiRequest.call(this, 'GET', '/subscribers', {}, qs);
+							responseData = responseData.data;
+						}
+					}
+					//https://developers.mailerlite.com/reference#update-subscriber
+					if (operation === 'update') {
+						const subscriberId = this.getNodeParameter('subscriberId', i) as string;
+
+						const additionalFields = this.getNodeParameter('additionalFields', i);
+
+						const body: IDataObject = {};
+
+						Object.assign(body, additionalFields);
+
+						if (additionalFields.customFieldsUi) {
+							const customFieldsValues = (additionalFields.customFieldsUi as IDataObject)
+								.customFieldsValues as IDataObject[];
+
+							if (customFieldsValues) {
+								const fields = {};
+
+								for (const customFieldValue of customFieldsValues) {
+									//@ts-ignore
+									fields[customFieldValue.fieldId] = customFieldValue.value;
+								}
+
+								body.fields = fields;
+								delete body.customFieldsUi;
+							}
+						}
+
+						responseData = await mailerliteApiRequest.call(
+							this,
+							'PUT',
+							`/subscribers/${subscriberId}`,
+							body,
+						);
+					}
+				}
+			} catch (error) {
+				if (this.continueOnFail()) {
+					const executionErrorData = this.helpers.constructExecutionMetaData(
+						this.helpers.returnJsonArray({ error: error.message }),
+						{ itemData: { item: i } },
+					);
+					returnData.push(...executionErrorData);
+					continue;
+				}
+				throw error;
+			}
+
+			const executionData = this.helpers.constructExecutionMetaData(
+				this.helpers.returnJsonArray(responseData as IDataObject[]),
+				{ itemData: { item: i } },
+			);
+
+			returnData.push(...executionData);
+		}
+
+		return [returnData];
+	}
+}
diff --git a/packages/nodes-base/nodes/MailerLite/v2/SubscriberDescription.ts b/packages/nodes-base/nodes/MailerLite/v2/SubscriberDescription.ts
new file mode 100644
index 0000000000..10ddfe22f5
--- /dev/null
+++ b/packages/nodes-base/nodes/MailerLite/v2/SubscriberDescription.ts
@@ -0,0 +1,304 @@
+import type { INodeProperties } from 'n8n-workflow';
+
+export const subscriberOperations: INodeProperties[] = [
+	{
+		displayName: 'Operation',
+		name: 'operation',
+		type: 'options',
+		noDataExpression: true,
+		displayOptions: {
+			show: {
+				resource: ['subscriber'],
+			},
+		},
+		options: [
+			{
+				name: 'Create',
+				value: 'create',
+				description: 'Create a new subscriber',
+				action: 'Create a subscriber',
+			},
+			{
+				name: 'Get',
+				value: 'get',
+				description: 'Get an subscriber',
+				action: 'Get a subscriber',
+			},
+			{
+				name: 'Get Many',
+				value: 'getAll',
+				description: 'Get many subscribers',
+				action: 'Get many subscribers',
+			},
+			{
+				name: 'Update',
+				value: 'update',
+				description: 'Update an subscriber',
+				action: 'Update a subscriber',
+			},
+		],
+		default: 'create',
+	},
+];
+
+export const subscriberFields: INodeProperties[] = [
+	/* -------------------------------------------------------------------------- */
+	/*                                subscriber:create                           */
+	/* -------------------------------------------------------------------------- */
+	{
+		displayName: 'Email',
+		name: 'email',
+		type: 'string',
+		placeholder: 'name@email.com',
+		required: true,
+		default: '',
+		displayOptions: {
+			show: {
+				resource: ['subscriber'],
+				operation: ['create'],
+			},
+		},
+		description: 'Email of new subscriber',
+	},
+
+	/* -------------------------------------------------------------------------- */
+	/*                                subscriber:update                           */
+	/* -------------------------------------------------------------------------- */
+	{
+		displayName: 'Subscriber Email',
+		name: 'subscriberId',
+		type: 'string',
+		required: true,
+		displayOptions: {
+			show: {
+				resource: ['subscriber'],
+				operation: ['update'],
+			},
+		},
+		default: '',
+		description: 'Email of subscriber',
+	},
+	{
+		displayName: 'Additional Fields',
+		name: 'additionalFields',
+		type: 'collection',
+		placeholder: 'Add Field',
+		default: {},
+		displayOptions: {
+			show: {
+				resource: ['subscriber'],
+				operation: ['update', 'create'],
+			},
+		},
+		options: [
+			{
+				displayName: 'Custom Fields',
+				name: 'customFieldsUi',
+				placeholder: 'Add Custom Field',
+				type: 'fixedCollection',
+				typeOptions: {
+					multipleValues: true,
+				},
+				description: 'Filter by custom fields',
+				default: {},
+				options: [
+					{
+						name: 'customFieldsValues',
+						displayName: 'Custom Field',
+						values: [
+							{
+								displayName: 'Field Name or ID',
+								name: 'fieldId',
+								type: 'options',
+								typeOptions: {
+									loadOptionsMethod: 'getCustomFields',
+								},
+								default: '',
+								description:
+									'The ID of the field to add custom field to. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
+							},
+							{
+								displayName: 'Value',
+								name: 'value',
+								type: 'string',
+								default: '',
+								description: 'The value to set on custom field',
+							},
+						],
+					},
+				],
+			},
+			{
+				displayName: 'Status',
+				name: 'status',
+				type: 'options',
+				options: [
+					{
+						name: 'Active',
+						value: 'active',
+					},
+					{
+						name: 'Bounced',
+						value: 'bounced',
+					},
+					{
+						name: 'Junk',
+						value: 'junk',
+					},
+					{
+						name: 'Unconfirmed',
+						value: 'unconfirmed',
+					},
+					{
+						name: 'Unsubscribed',
+						value: 'unsubscribed',
+					},
+				],
+				default: '',
+			},
+			{
+				displayName: 'Subscribed At',
+				name: 'subscribed_at',
+				type: 'dateTime',
+				default: '',
+			},
+			{
+				displayName: 'IP Address',
+				name: 'ip_address',
+				type: 'string',
+				default: '',
+			},
+			{
+				displayName: 'Opted In At',
+				name: 'opted_in_at',
+				type: 'dateTime',
+				default: '',
+			},
+			{
+				displayName: 'Opt In IP',
+				name: 'optin_ip',
+				type: 'string',
+				default: '',
+			},
+			{
+				displayName: 'Unsubscribed At',
+				name: 'unsubscribed_at',
+				type: 'dateTime',
+				default: '',
+			},
+		],
+	},
+
+	/* -------------------------------------------------------------------------- */
+	/*                                subscriber:delete                           */
+	/* -------------------------------------------------------------------------- */
+	{
+		displayName: 'Subscriber Email',
+		name: 'subscriberId',
+		type: 'string',
+		required: true,
+		displayOptions: {
+			show: {
+				resource: ['subscriber'],
+				operation: ['delete'],
+			},
+		},
+		default: '',
+		description: 'Email of subscriber to delete',
+	},
+
+	/* -------------------------------------------------------------------------- */
+	/*                                  subscriber:get                            */
+	/* -------------------------------------------------------------------------- */
+	{
+		displayName: 'Subscriber Email',
+		name: 'subscriberId',
+		type: 'string',
+		required: true,
+		displayOptions: {
+			show: {
+				resource: ['subscriber'],
+				operation: ['get'],
+			},
+		},
+		default: '',
+		description: 'Email of subscriber to get',
+	},
+	/* -------------------------------------------------------------------------- */
+	/*                                  subscriber:getAll                         */
+	/* -------------------------------------------------------------------------- */
+	{
+		displayName: 'Return All',
+		name: 'returnAll',
+		type: 'boolean',
+		displayOptions: {
+			show: {
+				resource: ['subscriber'],
+				operation: ['getAll'],
+			},
+		},
+		default: false,
+		description: 'Whether to return all results or only up to a given limit',
+	},
+	{
+		displayName: 'Limit',
+		name: 'limit',
+		type: 'number',
+		displayOptions: {
+			show: {
+				resource: ['subscriber'],
+				operation: ['getAll'],
+				returnAll: [false],
+			},
+		},
+		typeOptions: {
+			minValue: 1,
+			maxValue: 100,
+		},
+		default: 50,
+		description: 'Max number of results to return',
+	},
+	{
+		displayName: 'Filters',
+		name: 'filters',
+		type: 'collection',
+		placeholder: 'Add Filter',
+		displayOptions: {
+			show: {
+				operation: ['getAll'],
+				resource: ['subscriber'],
+			},
+		},
+		default: {},
+		options: [
+			{
+				displayName: 'Status',
+				name: 'status',
+				type: 'options',
+				options: [
+					{
+						name: 'Active',
+						value: 'active',
+					},
+					{
+						name: 'Bounced',
+						value: 'bounced',
+					},
+					{
+						name: 'Junk',
+						value: 'junk',
+					},
+					{
+						name: 'Unconfirmed',
+						value: 'unconfirmed',
+					},
+					{
+						name: 'Unsubscribed',
+						value: 'unsubscribed',
+					},
+				],
+				default: '',
+			},
+		],
+	},
+];