<!-- BusyBot node reference — https://busybot.net/tools/sendgrid/ -->

> Node: SendGrid (`sendgrid`) · Action (binary) · v1
> Category: Communication · Credentials: SendGrid API (`sendGridApi`)
> Updated: 2026-08-16

# SendGrid

> Send emails and manage contacts/lists via SendGrid

## Overview

The SendGrid tool integrates with the Twilio SendGrid email delivery platform. It supports three resources: (1) Contact — create/update (upsert), get by ID or email, get many with SGQL queries, and delete contacts. Note that contact upsert is a bulk/batch operation that collects all input items into a single API call. (2) List — create, get, get many, update, and delete mailing lists. (3) Mail — send transactional emails with plain text or HTML content, or use dynamic templates with template data. Emails can include binary file attachments from upstream items (base64-encoded in the JSON payload). Supports CC, BCC, reply-to, custom headers, categories, IP pool selection, scheduled send, and sandbox mode. Uses the SendGrid v3 REST API with Bearer token authentication.

**Category:** Communication  
**Tool Name:** `sendgrid`  
**Version:** 1

**Appearance:** Icon: `lucide-Mail` | Color: `#1A82E2`

## Node Type

**Action (Binary)** — handles file/binary data operations

## Input / Output

| Direction | Port(s) |
|-----------|--------|
| Input | `Input` |
| Output | `Output`, `Error` |

## Credentials

This tool requires **SendGrid API** credentials.
See the [Credentials Guide](https://busybot.net/credentials/send-grid-api/) for setup instructions.

### Resources

| Resource | Value |
|----------|-------|
| Contact | `contact` |
| List | `list` |
| Mail | `mail` |

### Operations

| Operation | Value | Description |
|-----------|-------|-------------|
| Contact: Create or Update | `upsert` | Create a new contact or update if it already exists (upsert) |
| Contact: Delete | `delete` | Delete contacts |
| Contact: Get | `get` | Get a contact by ID or email |
| Contact: Get Many | `getAll` | Get many contacts |
| List: Create | `create` | Create a mailing list |
| List: Delete | `delete` | Delete a mailing list |
| List: Get | `get` | Get a mailing list |
| List: Get Many | `getAll` | Get many mailing lists |
| List: Update | `update` | Update a mailing list |
| Mail: Send | `send` | Send an email |

### Parameters

#### Contact: Create or Update

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Email | `string` | Yes | — | Primary email for the contact. Supports expressions. |
| Additional Fields | `collection` | No | `{}` | Optional contact details to set alongside the email address. |
| — First Name | `string` | No | — | Contact first name. |
| — Last Name | `string` | No | — | Contact last name. |
| — Address Line 1 | `string` | No | — | Street address line 1. |
| — Address Line 2 | `string` | No | — | Street address line 2. |
| — City | `string` | No | — | City. |
| — Country | `string` | No | — | Country. |
| — Postal Code | `string` | No | — | Postal / ZIP code. |
| — State/Province/Region | `string` | No | — | State, province, or region. |
| — Alternate Emails | `string` | No | — | Comma-separated list of alternate email addresses for this contact. |
| — List IDs | `string` | No | — | Comma-separated list IDs to add the contact to. Get list IDs from List: Get Many. |
| — Custom Fields (JSON) | `json` | No | `{}` | JSON object mapping custom field IDs to values. E.g., {"e1_T":"value1","e2_N":123}. Get field IDs from GET /marketing/field_definitions. |

#### Contact: Delete

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Delete All | `boolean` | No | `false` | Whether to delete all contacts. |
| Contact IDs | `string` | No | — | Comma-separated contact IDs to delete. _(shown when Delete All is `false`)_ |

#### Contact: Get

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| By | `options` | Yes | `id` | Look up contact by ID or email. |
| | | | | Options: `id`, `email` |
| Contact ID | `string` | Yes | — | The ID of the contact to retrieve. _(shown when By is `id`)_ |
| Email | `string` | Yes | — | The email address of the contact to retrieve. _(shown when By is `email`)_ |

#### Contact: Get Many

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Return All | `boolean` | No | `false` | Whether to return all results or only up to a given limit. |
| Limit | `number` | No | `100` | Max number of results to return. _(shown when Return All is `false`)_ |
| Filters | `collection` | No | `{}` | Optional filter applied to the contact lookup. |
| — Query | `string` | No | — | SGQL query to filter contacts. E.g., "email LIKE '%@example.com%'". |

#### List: Create

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Name | `string` | Yes | — | Name of the mailing list. Supports expressions. |

#### List: Delete

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| List ID | `string` | Yes | — | ID of the mailing list to delete. |
| Delete Contacts | `boolean` | No | `false` | Whether to also delete all contacts on the list. |

#### List: Get

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| List ID | `string` | Yes | — | ID of the mailing list. |
| Contact Sample | `boolean` | No | `false` | Whether to include a sample of contacts in the response. |

#### List: Get Many

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Return All | `boolean` | No | `false` | Whether to return all results or only up to a given limit. |
| Limit | `number` | No | `100` | Max number of results to return. _(shown when Return All is `false`)_ |

#### List: Update

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| List ID | `string` | Yes | — | ID of the mailing list to update. |
| Name | `string` | Yes | — | New name for the mailing list. |

#### Mail: Send

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Sender Email | `string` | No | — | Email address of the sender. |
| Sender Name | `string` | No | — | Display name of the sender. |
| Recipient Email | `string` | No | — | Comma-separated list of recipient email addresses. Supports expressions. |
| Dynamic Template | `boolean` | Yes | `false` | Whether this email will use a dynamic template. |
| Subject | `string` | No | — | Subject line of the email. _(shown when Dynamic Template is `false`)_ |
| MIME Type | `options` | No | `text/plain` | Content type of the email body. _(shown when Dynamic Template is `false`)_ |
| | | | | Options: `text/plain`, `text/html` |
| Message Body | `string` | Yes | — | The body content of the email. _(shown when Dynamic Template is `false`)_ |
| Template ID | `string` | No | — | ID of the dynamic template. Get template IDs from GET /templates?generations=dynamic. _(shown when Dynamic Template is `true`)_ |
| Dynamic Template Fields | `fixedCollection` | No | `{}` | Merge variables passed to the dynamic template, added under a `fields` group. _(shown when Dynamic Template is `true`)_ |
| — Key | `string` | No | — | Template variable name. |
| — Value | `string` | No | — | Value for the template variable. |
| Additional Fields | `collection` | No | `{}` | Optional delivery settings for the message. |
| — Attachments | `string` | No | — | Comma-separated list of binary property names to attach to the email. Names are case-sensitive — see the upstream node's Binary Data panel for the exact names to use. |
| — BCC Email | `string` | No | — | Comma-separated list of BCC recipient email addresses. |
| — CC Email | `string` | No | — | Comma-separated list of CC recipient email addresses. |
| — Categories | `string` | No | — | Comma-separated list of categories. Each may not exceed 255 characters. |
| — Enable Sandbox | `boolean` | No | `false` | Whether to use the sandbox for testing email-sending functionality. |
| — Headers | `fixedCollection` | No | `{}` | Custom headers added to the message, under a `details` group. |
| — — Key | `string` | No | — | Header key. |
| — — Value | `string` | No | — | Header value. |
| — IP Pool Name | `string` | No | — | The IP Pool to send this email from. |
| — Reply-To Email | `string` | No | — | Comma-separated list of reply-to email addresses. |
| — Send At | `dateTime` | No | — | When to deliver the email. Scheduling more than 72 hours in advance is forbidden. |

#### All Operations

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| Max Concurrency | `number` | No | `10` | Maximum number of items to process concurrently. |

## Output Data

The SendGrid response is merged onto the item JSON at the top level, so downstream nodes read its fields directly (`{{ $json.id }}`). The rest of the incoming item JSON passes through unchanged and binary data is forwarded. Most operations produce one output item per input item; the two Get Many operations fan out instead.

| Operation | What lands on the output item |
|-----------|-------------------------------|
| `contact` / `upsert` | One item per input item. Every input item is collected into a **single** API call, and that one response is merged onto all of them. |
| `contact` / `get` | One item per input item, carrying the matched contact record. Looking up by email searches and keeps the first match, so an unknown address yields no contact fields. |
| `contact` / `getAll` | **Fans out** — one output item per contact returned. When nothing matches, a single item is emitted carrying `contacts: []`. |
| `contact` / `delete` | One item per input item, carrying the delete response. |
| `list` / `create`, `get`, `update` | One item per input item, carrying the mailing list record. |
| `list` / `getAll` | **Fans out** — one output item per mailing list returned. When nothing matches, a single item is emitted carrying `lists: []`. |
| `list` / `delete` | One item per input item, carrying `success: true`. |
| `mail` / `send` | One item per input item, carrying `messageId` — SendGrid's message ID for the accepted send, or an empty string when the API returns none. The message body itself is not echoed back. |

Failed items are routed to the `Error` port in `errorPort` mode, carrying an `_error` object.

## Usage Examples

- Send an HTML email with a PDF attachment via SendGrid
- Send a dynamic template email with merge variables
- Create or update a marketing contact in SendGrid
- Get all contacts matching an SGQL query
- Create a new mailing list
- Delete a mailing list and its contacts
- Send a scheduled email with CC and BCC recipients

## Example Configuration

Create or update a marketing contact from each incoming item and add it to a list:

```json
{
  "type": "sendgrid",
  "parameters": {
    "resource": "contact",
    "operation": "upsert",
    "email": "{{ $json.email }}",
    "additionalFields": {
      "firstName": "{{ $json.firstName }}",
      "lastName": "{{ $json.lastName }}",
      "city": "{{ $json.city }}",
      "listIds": "{{ $json.listId }}",
      "customFields": "{\"e1_T\": \"{{ $json.company }}\"}"
    }
  }
}
```

Look a contact up by email address:

```json
{
  "type": "sendgrid",
  "parameters": {
    "resource": "contact",
    "operation": "get",
    "by": "email",
    "email": "{{ $json.email }}"
  }
}
```

Fetch contacts matching an SGQL query, one output item per contact:

```json
{
  "type": "sendgrid",
  "parameters": {
    "resource": "contact",
    "operation": "getAll",
    "returnAll": false,
    "limit": 100,
    "filters": {
      "query": "email LIKE '%@company.com%'"
    }
  }
}
```

Delete specific contacts by ID:

```json
{
  "type": "sendgrid",
  "parameters": {
    "resource": "contact",
    "operation": "delete",
    "deleteAll": false,
    "ids": "{{ $json.contactIds }}"
  }
}
```

Create a mailing list:

```json
{
  "type": "sendgrid",
  "parameters": {
    "resource": "list",
    "operation": "create",
    "name": "Newsletter Subscribers"
  }
}
```

Rename an existing mailing list:

```json
{
  "type": "sendgrid",
  "parameters": {
    "resource": "list",
    "operation": "update",
    "listId": "{{ $json.id }}",
    "name": "Updated Newsletter List"
  }
}
```

Delete a mailing list along with the contacts on it:

```json
{
  "type": "sendgrid",
  "parameters": {
    "resource": "list",
    "operation": "delete",
    "listId": "{{ $json.id }}",
    "deleteContacts": true
  }
}
```

Send an HTML email with an upstream file attached, a CC address and a custom header:

```json
{
  "type": "sendgrid",
  "parameters": {
    "resource": "mail",
    "operation": "send",
    "fromEmail": "billing@company.com",
    "fromName": "Billing Department",
    "toEmail": "{{ $json.email }}",
    "dynamicTemplate": false,
    "subject": "Your invoice {{ $json.invoiceNumber }}",
    "contentType": "text/html",
    "contentValue": "<p>Please find your invoice attached.</p>",
    "additionalFields": {
      "attachments": "data",
      "ccEmail": "accounting@company.com",
      "categories": "billing,invoice",
      "headers": {
        "details": [
          {
            "key": "X-Invoice-Number",
            "value": "{{ $json.invoiceNumber }}"
          }
        ]
      }
    }
  }
}
```

Send a dynamic template email with merge variables, a BCC archive address and a scheduled delivery time:

```json
{
  "type": "sendgrid",
  "parameters": {
    "resource": "mail",
    "operation": "send",
    "fromEmail": "orders@shop.com",
    "fromName": "Online Shop",
    "toEmail": "{{ $json.email }}",
    "dynamicTemplate": true,
    "templateId": "d-123456789",
    "dynamicTemplateFields": {
      "fields": [
        {
          "key": "customerName",
          "value": "{{ $json.name }}"
        },
        {
          "key": "orderNumber",
          "value": "{{ $json.orderId }}"
        }
      ]
    },
    "additionalFields": {
      "bccEmail": "orders-archive@shop.com",
      "sendAt": "{{ $json.deliverAt }}"
    }
  }
}
```

### Error Handling

| Mode | Behavior |
|------|----------|
| **stop** | Halts workflow on first error |
| **continue** | Skips failed items, passes successful ones through |
| **errorPort** | Routes failed items to Error output port |

## Tips

Manage SendGrid contacts, mailing lists, and send transactional or template-based emails with binary file attachments.

### Notes

- **Create or Update is a batch call.** Every input item reaching the node is folded into one contact upsert request, and the List IDs supplied by all of those items are combined into a single set applied to the whole batch. Every item still gets an output item.
- **Attachments name binary properties, not files.** Put the property names from the upstream node's Binary Data panel in Attachments — for example `data` — not file paths. A name that is not on the item is skipped, and the send still goes out.
- **Attachment size is capped.** The node refuses a send whose attachments total more than 25 MB of raw bytes, because base64 encoding inflates them past SendGrid's request size limit.
- **Dynamic Template switches the whole content model.** With it on, Subject, MIME Type and Message Body disappear and the template plus its merge fields supply the content; with it off, Template ID and Dynamic Template Fields disappear.
- **Sandbox mode validates without delivering.** Turn on Enable Sandbox to exercise a send end to end without SendGrid actually mailing anyone.