From 3862a81a3466b9be2a3f3b230c03946140d23077 Mon Sep 17 00:00:00 2001 From: Maksim Horbachevsky Date: Thu, 15 Jan 2026 13:58:59 +0100 Subject: [PATCH 1/6] feat(arrays): Add arrays payload support for transactional email api --- README.md | 3 ++- src/index.ts | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 09613fe..1b11cab 100644 --- a/README.md +++ b/README.md @@ -624,7 +624,7 @@ Send a transactional email to a contact. [Learn about sending transactional emai | `transactionalId` | string | Yes | The ID of the transactional email to send. | | `email` | string | Yes | The email address of the recipient. | | `addToAudience` | boolean | No | If `true`, a contact will be created in your audience using the `email` value (if a matching contact doesn’t already exist). | -| `dataVariables` | object | No | An object containing data as defined by the data variables added to the transactional email template.
Values can be of type `string` or `number`. | +| `dataVariables` | object | No | An object containing data as defined by the data variables added to the transactional email template.
Values can be of type `string`, `number`, or an array of objects with `string` or `number` values. | | `attachments` | object[] | No | A list of attachments objects.
**Please note**: Attachments need to be enabled on your account before using them with the API. [Read more](https://loops.so/docs/transactional/attachments) | | `attachments[].filename` | string | No | The name of the file, shown in email clients. | | `attachments[].contentType` | string | No | The MIME type of the file. | @@ -768,6 +768,7 @@ const resp = await loops.getTransactionalEmails({ perPage: 15 }); ## Version history +- `v6.0.2` (Jan 15, 2026) - Updated `TransactionalVariables` type to support arrays of objects with `string` or `number` values in [`sendTransactionalEmail()`](#sendtransactionalemail). - `v6.0.1` (Oct 15, 2025) - Added `optInStatus` to contact object in [`findContact()`](#findcontact) for the new double opt-in feature. - `v6.0.0` (Aug 22, 2025) - [`createContact()`](#createcontact) and [`updateContact()`](#updatecontact) now have a single object parameter instead of named parameters (breaking change). This allows support for using either `email` or `userId` when updating contacts. - `v5.0.1` (May 13, 2025) - Added a `headers` parameter for [`sendEvent()`](#sendevent) and [`sendTransactionalEmail()`](#sendtransactionalemail), enabling support for the `Idempotency-Key` header. diff --git a/src/index.ts b/src/index.ts index c678c90..c6c2858 100644 --- a/src/index.ts +++ b/src/index.ts @@ -111,7 +111,10 @@ type EventProperties = Record; type MailingLists = Record; -type TransactionalVariables = Record; +type TransactionalVariables = Record< + string, + string | number | Array> +>; interface TransactionalAttachment { /** From 11db35983ad40860cd19de210fff8c561945d999 Mon Sep 17 00:00:00 2001 From: Dan Date: Thu, 5 Feb 2026 13:44:50 +0200 Subject: [PATCH 2/6] Fixed version numbers --- README.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 47fa2dd..520ec80 100644 --- a/README.md +++ b/README.md @@ -621,17 +621,17 @@ Send a transactional email to a contact. [Learn about sending transactional emai #### Parameters -| Name | Type | Required | Notes | -| --------------------------- | -------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `transactionalId` | string | Yes | The ID of the transactional email to send. | -| `email` | string | Yes | The email address of the recipient. | -| `addToAudience` | boolean | No | If `true`, a contact will be created in your audience using the `email` value (if a matching contact doesn’t already exist). | -| `dataVariables` | object | No | An object containing data as defined by the data variables added to the transactional email template.
Values can be of type `string`, `number`, or an array of objects with `string` or `number` values. | -| `attachments` | object[] | No | A list of attachments objects.
**Please note**: Attachments need to be enabled on your account before using them with the API. [Read more](https://loops.so/docs/transactional/attachments) | -| `attachments[].filename` | string | No | The name of the file, shown in email clients. | -| `attachments[].contentType` | string | No | The MIME type of the file. | -| `attachments[].data` | string | No | The base64-encoded content of the file. | -| `headers` | object | No | Additional headers to send with the request. | +| Name | Type | Required | Notes | +| --------------------------- | -------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `transactionalId` | string | Yes | The ID of the transactional email to send. | +| `email` | string | Yes | The email address of the recipient. | +| `addToAudience` | boolean | No | If `true`, a contact will be created in your audience using the `email` value (if a matching contact doesn’t already exist). | +| `dataVariables` | object | No | An object containing data as defined by the data variables added to the transactional email template.
Values can be of type `string`, `number`, or an array of objects with `string` or `number` values. | +| `attachments` | object[] | No | A list of attachments objects.
**Please note**: Attachments need to be enabled on your account before using them with the API. [Read more](https://loops.so/docs/transactional/attachments) | +| `attachments[].filename` | string | No | The name of the file, shown in email clients. | +| `attachments[].contentType` | string | No | The MIME type of the file. | +| `attachments[].data` | string | No | The base64-encoded content of the file. | +| `headers` | object | No | Additional headers to send with the request. | #### Examples @@ -770,8 +770,8 @@ const resp = await loops.getTransactionalEmails({ perPage: 15 }); ## Version history -- `v6.1.1` (Feb 5, 2026) - Updated `TransactionalVariables` type to support arrays of objects with `string` or `number` values in [`sendTransactionalEmail()`](#sendtransactionalemail). -- `v6.1.0` (Jan 29, 2026) - Added `rawBody` to `APIError` in the case no JSON is received from the server (thanks to [@leipert](https://github.com/leipert)). +- `v6.1.3` (Feb 5, 2026) - Updated `TransactionalVariables` type to support arrays of objects with `string` or `number` values in [`sendTransactionalEmail()`](#sendtransactionalemail). +- `v6.1.2` (Jan 29, 2026) - Added `rawBody` to `APIError` in the case no JSON is received from the server (thanks to [@leipert](https://github.com/leipert)). - `v6.0.1` (Oct 15, 2025) - Added `optInStatus` to contact object in [`findContact()`](#findcontact) for the new double opt-in feature. - `v6.0.0` (Aug 22, 2025) - [`createContact()`](#createcontact) and [`updateContact()`](#updatecontact) now have a single object parameter instead of named parameters (breaking change). This allows support for using either `email` or `userId` when updating contacts. - `v5.0.1` (May 13, 2025) - Added a `headers` parameter for [`sendEvent()`](#sendevent) and [`sendTransactionalEmail()`](#sendtransactionalemail), enabling support for the `Idempotency-Key` header. From b50a551f3ee8745f3e214d4ae11125e3e28b8e5f Mon Sep 17 00:00:00 2001 From: Maksim Horbachevsky Date: Thu, 5 Feb 2026 12:57:39 +0100 Subject: [PATCH 3/6] update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 520ec80..5816c69 100644 --- a/README.md +++ b/README.md @@ -770,7 +770,7 @@ const resp = await loops.getTransactionalEmails({ perPage: 15 }); ## Version history -- `v6.1.3` (Feb 5, 2026) - Updated `TransactionalVariables` type to support arrays of objects with `string` or `number` values in [`sendTransactionalEmail()`](#sendtransactionalemail). +- `v6.2.0` (Feb 5, 2026) - Support for the new arrays feature in sendTransactionalEmail. - `v6.1.2` (Jan 29, 2026) - Added `rawBody` to `APIError` in the case no JSON is received from the server (thanks to [@leipert](https://github.com/leipert)). - `v6.0.1` (Oct 15, 2025) - Added `optInStatus` to contact object in [`findContact()`](#findcontact) for the new double opt-in feature. - `v6.0.0` (Aug 22, 2025) - [`createContact()`](#createcontact) and [`updateContact()`](#updatecontact) now have a single object parameter instead of named parameters (breaking change). This allows support for using either `email` or `userId` when updating contacts. From e5416201b13fc0e5ebaed43f3250bc44da208fff Mon Sep 17 00:00:00 2001 From: Maksim Horbachevsky Date: Thu, 5 Feb 2026 13:05:58 +0100 Subject: [PATCH 4/6] updates test --- src/__tests__/LoopsClient.test.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/__tests__/LoopsClient.test.ts b/src/__tests__/LoopsClient.test.ts index c6d75f1..61d2cd1 100644 --- a/src/__tests__/LoopsClient.test.ts +++ b/src/__tests__/LoopsClient.test.ts @@ -499,7 +499,10 @@ describe("LoopsClient", () => { email: "test@example.com", dataVariables: { name: "John", - product: "Widgets", + products: [ + { name: "Widget", price: 29.99 }, + { name: "Gadget", price: 49.99 }, + ], }, }; const mockResponse = { success: true }; From e573c4c1612eacbaff18a8ce3e43ca33582ed89a Mon Sep 17 00:00:00 2001 From: Maksim Horbachevsky Date: Thu, 5 Feb 2026 13:06:08 +0100 Subject: [PATCH 5/6] 6.2.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6a7bc53..3accb3e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "loops", - "version": "6.1.2", + "version": "6.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "loops", - "version": "6.1.2", + "version": "6.2.0", "license": "MIT", "devDependencies": { "@types/jest": "^29.5.12", diff --git a/package.json b/package.json index 6e6b758..e0fa840 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "loops", - "version": "6.1.2", + "version": "6.2.0", "author": "Dan Rowden ", "license": "MIT", "main": "./dist/index.cjs", From 6adb7a888d42fd1399040bb2ada6e471553c15c2 Mon Sep 17 00:00:00 2001 From: Maksim Horbachevsky Date: Mon, 9 Feb 2026 10:33:41 +0100 Subject: [PATCH 6/6] update date --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5816c69..f3ddff2 100644 --- a/README.md +++ b/README.md @@ -770,7 +770,7 @@ const resp = await loops.getTransactionalEmails({ perPage: 15 }); ## Version history -- `v6.2.0` (Feb 5, 2026) - Support for the new arrays feature in sendTransactionalEmail. +- `v6.2.0` (Feb 9, 2026) - Support for the new arrays feature in sendTransactionalEmail. - `v6.1.2` (Jan 29, 2026) - Added `rawBody` to `APIError` in the case no JSON is received from the server (thanks to [@leipert](https://github.com/leipert)). - `v6.0.1` (Oct 15, 2025) - Added `optInStatus` to contact object in [`findContact()`](#findcontact) for the new double opt-in feature. - `v6.0.0` (Aug 22, 2025) - [`createContact()`](#createcontact) and [`updateContact()`](#updatecontact) now have a single object parameter instead of named parameters (breaking change). This allows support for using either `email` or `userId` when updating contacts.