{
  "openapi": "3.0.1",
  "info": {
    "title": "Sendfinch — Send Email via SMTP, Resend, SendGrid & Mailgun",
    "description": "Send email from Apify runs, webhooks and AI agents through your own SMTP, Resend, SendGrid, Mailgun or Postmark: mail merge from datasets, result digests with CSV, attachments, per-recipient status. $0.001 per email; failures free.",
    "version": "0.1",
    "x-build-id": "CGMWkuH3HAVFi3qjW"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/cybermax~send-email/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-cybermax-send-email",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/cybermax~send-email/runs": {
      "post": {
        "operationId": "runs-sync-cybermax-send-email",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/cybermax~send-email/run-sync": {
      "post": {
        "operationId": "run-sync-cybermax-send-email",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "properties": {
          "provider": {
            "title": "Provider",
            "enum": [
              "smtp",
              "resend",
              "sendgrid",
              "mailgun",
              "postmark"
            ],
            "type": "string",
            "description": "How to send: your own SMTP server (Gmail/Google Workspace, Microsoft 365, Amazon SES, Zoho, Fastmail, any host) or the API of Resend, SendGrid, Mailgun or Postmark. Sendfinch never sends through shared servers: mail goes out from your account and your domain.",
            "default": "smtp"
          },
          "from": {
            "title": "From",
            "type": "string",
            "description": "Sender, e.g. \"Acme Alerts <alerts@acme.com>\". Must be an address your SMTP login or provider lets you send from (a verified sender/domain)."
          },
          "to": {
            "title": "To",
            "type": "string",
            "description": "Recipient(s), separated by commas: \"ann@acme.com, Bob <bob@acme.com>\". In digest mode, who gets the digest. Not used in merge mode (addresses come from each row)."
          },
          "subject": {
            "title": "Subject",
            "type": "string",
            "description": "Subject line. {{field}} placeholders are filled from each row (merge), from \"variables\", or with {{count}}/{{date}} (digest)."
          },
          "html": {
            "title": "HTML body",
            "type": "string",
            "description": "HTML body with {{field}} placeholders (values are HTML-escaped; use {{{field}}} for raw HTML). In digest mode, put {{{table}}} where the results table goes (leave empty for the default layout). A plain-text part is generated automatically unless you set \"text\"."
          },
          "text": {
            "title": "Plain-text body",
            "type": "string",
            "description": "Plain-text body (or the only body). Same {{field}} placeholders as HTML."
          },
          "mode": {
            "title": "Mode",
            "enum": [
              "auto",
              "single",
              "messages",
              "merge",
              "digest"
            ],
            "type": "string",
            "description": "auto = \"messages\" if given, else digest if a dataset/items are given, else one email to \"to\". single = one email to \"to\". messages = a list of different emails. merge = one personalised email per dataset row (mail merge). digest = one email containing all rows as a table + CSV (e.g. the results of another Actor run).",
            "default": "auto"
          },
          "datasetId": {
            "title": "Dataset ID (rows for merge/digest)",
            "type": "string",
            "description": "An Apify dataset to read rows from, e.g. another run's defaultDatasetId. In an Apify webhook or integration use {{resource.defaultDatasetId}} to email the results of any Actor run."
          },
          "items": {
            "title": "Rows (inline)",
            "type": "array",
            "description": "Rows given directly instead of a dataset: a JSON array of objects, e.g. [{\"email\": \"ann@acme.com\", \"firstName\": \"Ann\"}]."
          },
          "toField": {
            "title": "Recipient field (merge)",
            "type": "string",
            "description": "Row field holding the recipient address. Default: the first of email, emailAddress, contactEmail, emails.0, Email."
          },
          "nameField": {
            "title": "Recipient name field (merge)",
            "type": "string",
            "description": "Optional row field used as the recipient's display name, e.g. firstName or fullName."
          },
          "digestFields": {
            "title": "Digest columns",
            "type": "array",
            "description": "Which fields to show in the digest table (dotted paths allowed, e.g. company.name). Default: the first 6 simple fields. The attached CSV always has every field.",
            "items": {
              "type": "string"
            }
          },
          "digestTitle": {
            "title": "Digest heading",
            "type": "string",
            "description": "Heading above the digest table. Default \"12 rows\" (\"12 new rows\" in monitor mode); placeholders {{count}}, {{total}}, {{date}}."
          },
          "maxDigestRows": {
            "title": "Max rows shown in the digest table",
            "minimum": 1,
            "maximum": 1000,
            "type": "integer",
            "description": "Rows beyond this go only into the attached CSV.",
            "default": 200
          },
          "attachCsv": {
            "title": "Attach the rows as CSV (digest)",
            "type": "boolean",
            "description": "Adds results-YYYY-MM-DD.csv with every row and field.",
            "default": true
          },
          "skipIfEmpty": {
            "title": "Don't send an empty digest",
            "type": "boolean",
            "description": "When there are no rows, send nothing (free).",
            "default": true
          },
          "maxItems": {
            "title": "Max rows read from the dataset",
            "minimum": 1,
            "maximum": 50000,
            "type": "integer",
            "description": "Upper limit on rows read from the dataset.",
            "default": 5000
          },
          "onlyNew": {
            "title": "Monitor mode: only rows not emailed before",
            "type": "boolean",
            "description": "Remembers what earlier runs with the same monitor name already emailed. Digest: the email contains only new rows (nothing is sent when there are none). Merge: each address (or idField) gets the email once. Put it on an Apify Schedule for daily \"what's new\" emails.",
            "default": false
          },
          "monitorName": {
            "title": "Monitor name",
            "type": "string",
            "description": "Keeps separate memories for different schedules, e.g. \"new-leads\" and \"price-drops\".",
            "default": "default"
          },
          "idField": {
            "title": "Row ID field",
            "type": "string",
            "description": "Field that identifies a row across runs (e.g. url or id). Default: digest compares whole rows; merge compares the recipient address."
          },
          "messages": {
            "title": "Messages (list of different emails)",
            "type": "array",
            "description": "Send several different emails in one run: [{\"to\": \"a@x.com\", \"subject\": \"...\", \"html\": \"...\", \"text\": \"...\", \"cc\": \"...\", \"bcc\": \"...\", \"replyTo\": \"...\", \"attachments\": [{\"filename\": \"a.txt\", \"text\": \"...\"}]}]. Messages with problems are skipped for free and reported."
          },
          "variables": {
            "title": "Variables",
            "type": "object",
            "description": "Extra values for {{placeholders}} in every email, e.g. {\"product\": \"Acme\"}."
          },
          "sendSeparately": {
            "title": "Send separately to each \"to\" address",
            "type": "boolean",
            "description": "One email per address instead of one email with everyone in To (recipients don't see each other).",
            "default": false
          },
          "cc": {
            "title": "Cc",
            "type": "string",
            "description": "Comma-separated addresses."
          },
          "bcc": {
            "title": "Bcc",
            "type": "string",
            "description": "Comma-separated addresses (in merge mode added to every email, e.g. a CRM dropbox)."
          },
          "replyTo": {
            "title": "Reply-To",
            "type": "string",
            "description": "Where replies go, if not the From address."
          },
          "attachments": {
            "title": "Attachments",
            "type": "array",
            "description": "Files added to every email: {\"filename\": \"report.pdf\", \"url\": \"https://...\"}, {\"key\": \"OUTPUT\", \"filename\": \"report.pdf\"} (a record from the key-value store set below, e.g. a PDF or screenshot made by another Actor), {\"filename\": \"a.txt\", \"text\": \"...\"} or {\"filename\": \"a.png\", \"contentBase64\": \"...\"}. 20 MB total."
          },
          "keyValueStoreId": {
            "title": "Key-value store for attachments",
            "type": "string",
            "description": "An Apify key-value store to read attachment records from (e.g. another run's defaultKeyValueStoreId holding a PDF, screenshot or report). Attachments given as {\"key\": \"OUTPUT\", \"filename\": \"report.pdf\"} are read from here."
          },
          "headers": {
            "title": "Extra headers",
            "type": "object",
            "description": "Custom headers, e.g. {\"X-Campaign\": \"q3\"}."
          },
          "unsubscribeUrl": {
            "title": "Unsubscribe URL",
            "type": "string",
            "description": "Adds List-Unsubscribe (and one-click List-Unsubscribe-Post for https URLs) so Gmail/Yahoo show an unsubscribe button. Placeholders allowed: https://acme.com/unsub?e={{email}}."
          },
          "smtpHost": {
            "title": "SMTP host",
            "type": "string",
            "description": "e.g. smtp.gmail.com, smtp.office365.com, email-smtp.us-east-1.amazonaws.com, smtp.zoho.com, smtp.resend.com, smtp.sendgrid.net."
          },
          "smtpPort": {
            "title": "SMTP port",
            "type": "integer",
            "description": "587 (STARTTLS, default) or 465 (TLS). Port 25 is usually blocked in the cloud.",
            "default": 587
          },
          "smtpSecure": {
            "title": "Use TLS from the start",
            "type": "boolean",
            "description": "Default: on for port 465, off (STARTTLS) otherwise."
          },
          "smtpUser": {
            "title": "SMTP username",
            "type": "string",
            "description": "Usually your full email address."
          },
          "smtpPassword": {
            "title": "SMTP password",
            "type": "string",
            "description": "Stored encrypted by Apify (secret input). Gmail/Google Workspace and Outlook need an app password, not your normal password."
          },
          "smtpAllowSelfSigned": {
            "title": "Allow self-signed TLS certificates",
            "type": "boolean",
            "description": "Only for your own mail server with a self-signed certificate.",
            "default": false
          },
          "apiKey": {
            "title": "API key (Resend, SendGrid, Mailgun, Postmark)",
            "type": "string",
            "description": "Your provider API key (Postmark: server token). Stored encrypted by Apify (secret input)."
          },
          "mailgunDomain": {
            "title": "Mailgun sending domain",
            "type": "string",
            "description": "e.g. mg.acme.com (Mailgun only)."
          },
          "region": {
            "title": "Region (Mailgun/SendGrid)",
            "enum": [
              "us",
              "eu"
            ],
            "type": "string",
            "description": "eu for Mailgun EU domains or SendGrid EU subusers.",
            "default": "us"
          },
          "postmarkStream": {
            "title": "Postmark message stream",
            "type": "string",
            "description": "Default outbound (transactional)."
          },
          "dryRun": {
            "title": "Dry run (preview, send nothing, free)",
            "type": "boolean",
            "description": "Renders every email (recipients, subject, text and HTML) into the dataset without sending or charging. No credentials needed. Turn it off to send.",
            "default": false
          },
          "maxEmails": {
            "title": "Max emails per run",
            "minimum": 1,
            "maximum": 5000,
            "type": "integer",
            "description": "Safety cap on emails sent in one run.",
            "default": 100
          },
          "maxConcurrency": {
            "title": "Parallel sends",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "How many emails are sent at the same time.",
            "default": 3
          },
          "delayBetweenEmailsMs": {
            "title": "Pause between emails (ms)",
            "minimum": 0,
            "maximum": 60000,
            "type": "integer",
            "description": "Per parallel sender; use it to stay under your provider's rate limit (e.g. Gmail).",
            "default": 0
          },
          "autoText": {
            "title": "Generate a plain-text part from HTML",
            "type": "boolean",
            "description": "Adds a plain-text version of HTML emails (better deliverability).",
            "default": true
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}