Skip to content

Sheets — append a row ​

Appends a row to a Google Sheets spreadsheet. A deduplication column avoids a duplicate row on a retry.

This node appends one row to a Google Sheets spreadsheet: the register use case, where every email that arrives adds a line (a request, an invoice, a lead). Values can be written under their column headers, or in order from column A.

It needs the Google Sheets access of a Google account, shown as the Spreadsheets capability in Connections. See Google. The row is written with the account of the member running the workflow.

To extract the values from the email first, place an Extract step before it. For an Excel workbook on SharePoint or OneDrive, use the Excel node; for a table kept inside the product, see Tables.

At a glance ​

  • Type: google_sheets.append · version 1
  • Category: Actions
  • Kind: Step — one stage of a run
  • Effect: Writes outside (external_write) — writes outside Mankomail; described instead of performed during a test run
  • Needs a carrier email: No
  • Connection: Google (capability sheets)
  • Inputs: main
  • Outputs: main

Connection ​

This node needs a Google connection with the sheets capability granted.

Parameters ​

credential ​

Google account — The account holding Google Sheets access. Connect it once in Connections; the workflow always runs with the account of the member running it.

  • Type: Connection (credential)
  • Required: Yes
  • Default: "" (empty)

spreadsheet ​

Spreadsheet — Picked from the list, by id, or by pasting the spreadsheet URL.

  • Type: Remote resource (resourceLocator)
  • Required: Yes
  • Ways to choose: pick from a list, type an ID, paste a URL (sheet)
  • Listed with the connection in: credential

sheetName ​

Sheet tab — Left empty, the row lands in the first tab of the spreadsheet.

  • Type: Text (string)
  • Required: No
  • Default: "" (empty)
  • 200 characters at most
  • Example: Sheet1
  • Expressions: {{ }} accepted

mode ​

How to describe the row

  • Type: One choice (options)
  • Required: Yes
  • Default: columns
  • Options:
    • columns — By columns (headers): Each value lands under its header. Inserting a column in the middle breaks nothing.
    • row — Ordered row (A, B, C…): Values in order, starting at column A. For a spreadsheet with no header row.

values ​

Values by column

  • Type: List of items (collection)
  • Required: No
  • Default: []
  • At most 40 items
  • Each item has:
    • column — Column header
      • Type: Text (string)
      • Required: Yes
      • Default: "" (empty)
      • 200 characters at most
      • Expressions: {{ }} not accepted
    • value — Value
      • Type: Text (string)
      • Required: No
      • Default: "" (empty)
      • 10000 characters at most
  • Shown when: mode is columns

row ​

Values, in order — The first entry goes to column A, the second to B, and so on.

  • Type: List of items (collection)
  • Required: No
  • Default: []
  • At most 40 items
  • Each item has:
    • value — Value
      • Type: Text (string)
      • Required: No
      • Default: "" (empty)
      • 10000 characters at most
  • Shown when: mode is row

keyColumn ​

Deduplication column — ⚠️ Without it, a retry after an outage may add the row twice — Google’s API offers no idempotency key. Filled in, the row is only added if its value is not already there.

  • Type: Text (string)
  • Required: No
  • Default: "" (empty)
  • 200 characters at most
  • Example: Reference
  • Shown when: mode is columns
  • Expressions: {{ }} not accepted

Outputs ​

  • main

Data produced ​

What this node adds to the run data, and how to read it in an expression. <step> stands for the step key: the node name turned into an identifier (see Data and expressions).

  • {{ data.<step>.rowNumber }} — number. The number of the row written, as the spreadsheet displays it (the header row is row 1). Absent when the row was a duplicate and in a test run.
  • {{ data.<step>.updatedRange }} — string. The range Google reports as written, for example Sheet1!A7:D7. Absent when the row was a duplicate and in a test run.
  • {{ data.<step>.duplicate }} — boolean. true when the Deduplication column already held the value: nothing was written. Always false without a deduplication column and in a test run.
  • {{ data.<step>.simulated }} — boolean. true in a test run: nothing was written to the spreadsheet.
  • {{ data.<step>.summary }} — string. A readable sentence saying where the row was added, or that it was already there.

Example ​

Every quote request is logged in a Requests tab whose header row reads Date, Reference, Client, Amount. An extraction step named Extract reads the reference and the amount. The node is named Log request:

spreadsheet: (url mode) https://docs.google.com/spreadsheets/d/1Bx…/edit
sheetName: Requests
mode: columns
values:
  - column: Reference
    value: {{ data.extract.reference }}
  - column: Client
    value: {{ email.from.email }}
  - column: Amount
    value: {{ data.extract.amount }}
keyColumn: Reference

The first time, the row is added under the right headers (the Date cell stays empty) and the step data reads:

json
{
  "updatedRange": "Requests!A12:D12",
  "rowNumber": 12,
  "duplicate": false,
  "simulated": false
}

If the step is replayed, or if a second email carries the same reference, the node finds that reference in the Reference column and writes nothing: duplicate is true.

Tips ​

  • Avoid duplicates. Google's API offers no idempotency key: without a Deduplication column, a replay of the step after an incident can add the same row twice. With one, the node reads that column first and only writes when the value is not already there. Pick a column whose value is truly unique (an email id, an order reference). The deduplication column is only available in By columns mode, and its value is the one you set for that same column in Values by column.
  • Headers. In By columns mode, the node reads row 1 of the tab and puts each value under its header, whatever the column order; header matching ignores case and surrounding spaces. A value whose header is not found is added at the end of the row rather than lost. A deduplication column that is not found in the headers deduplicates nothing: the row is written.
  • Ordered row. In Ordered row mode, the first value goes to column A, the second to B, and so on; an empty value keeps its cell empty so the following values do not shift. Use it for a sheet with no header row.
  • Tab. Left empty, the row goes to the first tab of the spreadsheet. Column headers are structure fields and cannot contain expressions.
  • Values are typed in. Values are written as if typed by hand: 2026-04-12 becomes a date and =SUM(B2:B11) a formula.
  • Limits. At most 40 values per row. The deduplication check reads the column up to row 5,000.
  • Spreadsheet. Pick it from the list, type its id, or paste its URL (https://docs.google.com/spreadsheets/d/<id>/edit). The tab in the URL (#gid=) is not read: set Sheet tab instead.
  • Nothing to write. A row with no value (every column name empty, or no entry) fails with node_nothing_to_do; no spreadsheet selected fails with node_invalid_param.
  • Test runs. In test runs nothing is written and no deduplication is checked: the step returns simulated: true, duplicate: false and no row number.
  • Errors. credential.capability_missing: Google Sheets is not connected for the member running the workflow. google.not_found: the spreadsheet does not exist or the account cannot open it. google.bad_locator: the pasted value is neither an id nor a spreadsheet URL. google.rejected: Google refused the write (for example a tab name that does not exist). google.unavailable is retried automatically. See Error handling.