AutomationFlowsData & Sheets › Create a Crud REST API with Google Sheets Database

Create a Crud REST API with Google Sheets Database

ByViktor Klepikovskyi @vklepikovskyi on n8n.io

This workflow template demonstrates how to quickly and easily create a simple REST API using n8n and a Google Sheet as a no-code database. It's a perfect starting point for building a backend for small applications, prototypes, or internal tools without writing any code.

Webhook trigger★★★★☆ complexity17 nodesGoogle Sheets
Data & Sheets Trigger: Webhook Nodes: 17 Complexity: ★★★★☆ Added:

This workflow corresponds to n8n.io template #8085 — we link there as the canonical source.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "id": "6QvxWwgaPghd06wj",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "REST API with Google Sheets",
  "tags": [],
  "nodes": [
    {
      "id": "4b53d6ea-e083-4d89-b8af-6c4e37e4066e",
      "name": "Append row in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        224,
        0
      ],
      "parameters": {
        "columns": {
          "value": {
            "name": "={{ $json.body.name }}",
            "email": "={{ $json.body.email }}",
            "status": "={{ $json.body.status }}"
          },
          "schema": [
            {
              "id": "name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "email",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1bQyl8pGVutkq1LRwK_-6TAAcXwNj4_TipeWHi-qmK1Q/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1bQyl8pGVutkq1LRwK_-6TAAcXwNj4_TipeWHi-qmK1Q",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1bQyl8pGVutkq1LRwK_-6TAAcXwNj4_TipeWHi-qmK1Q/edit?usp=drivesdk",
          "cachedResultName": "REST API data"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "70a88ee3-83ef-409f-b9fc-699b57aff26a",
      "name": "Webhook: Create",
      "type": "n8n-nodes-base.webhook",
      "position": [
        0,
        0
      ],
      "parameters": {
        "path": "items",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2.1
    },
    {
      "id": "4cb95925-d5be-4594-93d1-84cecaabc99d",
      "name": "Webhook: Read All",
      "type": "n8n-nodes-base.webhook",
      "position": [
        0,
        224
      ],
      "parameters": {
        "path": "items/all",
        "options": {},
        "responseMode": "responseNode"
      },
      "typeVersion": 2.1
    },
    {
      "id": "a18c5a15-92bf-4897-83c7-0c0a4aaeb58a",
      "name": "Respond to Webhook: Create",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        448,
        0
      ],
      "parameters": {
        "options": {},
        "respondWith": "json",
        "responseBody": "{\n  \"status\": \"success\",\n  \"message\": \"Record created.\"\n}"
      },
      "typeVersion": 1.4
    },
    {
      "id": "6ee8437b-6340-4cdc-b39b-1951461d4164",
      "name": "Respond to Webhook: Read All",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        448,
        224
      ],
      "parameters": {
        "options": {},
        "respondWith": "allIncomingItems"
      },
      "typeVersion": 1.4
    },
    {
      "id": "1560785d-b30e-49b5-94f4-27445538d086",
      "name": "Webhook: Read",
      "type": "n8n-nodes-base.webhook",
      "position": [
        0,
        448
      ],
      "parameters": {
        "path": "items",
        "options": {},
        "responseMode": "responseNode"
      },
      "typeVersion": 2.1
    },
    {
      "id": "46baff34-99e4-4c6a-9395-76fc5358c5a7",
      "name": "Get rows in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        224,
        224
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1bQyl8pGVutkq1LRwK_-6TAAcXwNj4_TipeWHi-qmK1Q/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1bQyl8pGVutkq1LRwK_-6TAAcXwNj4_TipeWHi-qmK1Q",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1bQyl8pGVutkq1LRwK_-6TAAcXwNj4_TipeWHi-qmK1Q/edit?usp=drivesdk",
          "cachedResultName": "REST API data"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "1cbcf7af-d1ba-4994-a795-d5c597439bad",
      "name": "Get row in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        224,
        448
      ],
      "parameters": {
        "options": {},
        "filtersUI": {
          "values": [
            {
              "lookupValue": "={{ $json.query.id }}",
              "lookupColumn": "=row_number"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1bQyl8pGVutkq1LRwK_-6TAAcXwNj4_TipeWHi-qmK1Q/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1bQyl8pGVutkq1LRwK_-6TAAcXwNj4_TipeWHi-qmK1Q",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1bQyl8pGVutkq1LRwK_-6TAAcXwNj4_TipeWHi-qmK1Q/edit?usp=drivesdk",
          "cachedResultName": "REST API data"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "ebaf7824-73af-47c2-8e3d-a19947a91892",
      "name": "Respond to Webhook: Read",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        448,
        448
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 1.4
    },
    {
      "id": "6cbd2531-b9f4-4a3f-b821-bec3caf2d09d",
      "name": "Webhook: Update",
      "type": "n8n-nodes-base.webhook",
      "position": [
        0,
        672
      ],
      "parameters": {
        "path": "items",
        "options": {},
        "httpMethod": "PUT",
        "responseMode": "responseNode"
      },
      "typeVersion": 2.1
    },
    {
      "id": "b91994a3-ef36-4770-99dc-926640496693",
      "name": "Update row in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        448,
        672
      ],
      "parameters": {
        "columns": {
          "value": {
            "name": "={{ $json.body.name }}",
            "email": "={{ $json.body.email }}",
            "status": "={{ $json.body.status }}",
            "row_number": "={{ $json.query.id }}"
          },
          "schema": [
            {
              "id": "name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "email",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "number",
              "display": true,
              "removed": false,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "autoMapInputData",
          "matchingColumns": [
            "row_number"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1bQyl8pGVutkq1LRwK_-6TAAcXwNj4_TipeWHi-qmK1Q/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1bQyl8pGVutkq1LRwK_-6TAAcXwNj4_TipeWHi-qmK1Q",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1bQyl8pGVutkq1LRwK_-6TAAcXwNj4_TipeWHi-qmK1Q/edit?usp=drivesdk",
          "cachedResultName": "REST API data"
        },
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "5180a531-5efa-4fba-a870-61f7223fcb93",
      "name": "Respond to Webhook: Update",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        672,
        672
      ],
      "parameters": {
        "options": {},
        "respondWith": "json",
        "responseBody": "{\n  \"status\": \"success\",\n  \"message\": \"Record updated.\"\n}"
      },
      "typeVersion": 1.4
    },
    {
      "id": "ec3b5abd-17ae-4964-b792-5d320ad7a65b",
      "name": "Webhook: Delete",
      "type": "n8n-nodes-base.webhook",
      "position": [
        0,
        896
      ],
      "parameters": {
        "path": "items",
        "options": {},
        "httpMethod": "DELETE",
        "responseMode": "responseNode"
      },
      "typeVersion": 2.1
    },
    {
      "id": "b3950509-6173-4a30-bbaa-42ef34b15878",
      "name": "Delete rows or columns from sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        224,
        896
      ],
      "parameters": {
        "operation": "delete",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1bQyl8pGVutkq1LRwK_-6TAAcXwNj4_TipeWHi-qmK1Q/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1bQyl8pGVutkq1LRwK_-6TAAcXwNj4_TipeWHi-qmK1Q",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1bQyl8pGVutkq1LRwK_-6TAAcXwNj4_TipeWHi-qmK1Q/edit?usp=drivesdk",
          "cachedResultName": "REST API data"
        },
        "startIndex": "={{ $json.query.id }}",
        "authentication": "serviceAccount"
      },
      "credentials": {
        "googleApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "0361a349-a259-4a3c-877e-2bb7bee0f9be",
      "name": "Respond to Webhook: Delete",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        448,
        896
      ],
      "parameters": {
        "options": {},
        "respondWith": "json",
        "responseBody": "{\n  \"status\": \"success\",\n  \"message\": \"Record deleted.\"\n}"
      },
      "typeVersion": 1.4
    },
    {
      "id": "ba367266-005d-42a0-aeba-2b48db0fea05",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -688,
        0
      ],
      "parameters": {
        "width": 592,
        "height": 992,
        "content": "## Simple REST API with Google Sheets\n\n### Introduction\n\nThis workflow template demonstrates how to quickly and easily create a simple REST API using n8n and a Google Sheet as a no-code database. It's a perfect starting point for building a backend for small applications, prototypes, or internal tools without writing any code.\n\n### Purpose\n\nThe purpose of this template is to provide a complete, ready-to-use n8n workflow that handles all fundamental CRUD (Create, Read, Update, Delete) operations. The workflow uses a single Webhook trigger to handle POST, GET, PUT, and DELETE requests, allowing you to manage data in your Google Sheet through standard API calls.\n\n### Setup Instructions\n\nTo get started with this template, follow these steps:\n\n1. **Prepare your Google Sheet:** Create a new Google Sheet and add the following column headers in the first row: `name`, `email`, and `status`. You can use this [example Google Sheet](https://docs.google.com/spreadsheets/d/1bQyl8pGVutkq1LRwK_-6TAAcXwNj4_TipeWHi-qmK1Q/edit?usp=sharing) as a starting point. This sheet will serve as your database.\n2. **Authenticate:** In the n8n workflow, connect your Google Account credentials to the Google Sheets nodes.\n3. **Select your data:** Choose the Google Sheet and the corresponding sheet name from the drop-down lists in each of the Google Sheets nodes.\n4. **Activate:** Save and activate the workflow.\n5. Test the API: Use a tool like `curl`, Postman, or Insomnia to test your new API endpoints. The base URL will be your n8n webhook URL followed by `/items`.\n\n#### Example `curl` Commands:\n* **POST (Create):** `curl -X POST YOUR_N8N_WEBHOOK_URL/items -H \"Content-Type: application/json\" -d '{\"name\": \"Alice\", \"email\": \"alice@example.com\", \"status\": \"active\"}'`\n* **GET (Read All):** `curl -X GET YOUR_N8N_WEBHOOK_URL/items/all`\n* **GET (Read Single):** `curl -X GET YOUR_N8N_WEBHOOK_URL/items?id=2`\n* **PUT (Update):** `curl -X PUT YOUR_N8N_WEBHOOK_URL/items?id=2 -H \"Content-Type: application/json\" -d '{\"status\": \"inactive\"}'`\n* **DELETE (Delete):** `curl -X DELETE YOUR_N8N_WEBHOOK_URL/items?id=2`\n\nFor more detailed instructions, including building the workflow in n8n, check out the full blog post: [Build a Simple REST API in 10 Minutes with n8n & Google Sheets](https://n8nplaybook.com/post/2025/08/n8n-google-sheets-rest-api/)"
      },
      "typeVersion": 1
    },
    {
      "id": "8264647e-c5b2-4bf1-90a7-6fc0e8e5c2b9",
      "name": "Prepare Fields for Update",
      "type": "n8n-nodes-base.set",
      "position": [
        224,
        672
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "={\n  \"row_number\": {{ $json.query.id }}\n  {{ $if($json.body.keys().length > 0, ', ' + $json.body.toJsonString().replace('{', '').replace('}', ''), '') }}\n}\n"
      },
      "typeVersion": 3.4
    }
  ],
  "active": true,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "a0da6d17-701f-4d0f-a49d-b66b5fecd7b2",
  "connections": {
    "Webhook: Read": {
      "main": [
        [
          {
            "node": "Get row in sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook: Create": {
      "main": [
        [
          {
            "node": "Append row in sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook: Delete": {
      "main": [
        [
          {
            "node": "Delete rows or columns from sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook: Update": {
      "main": [
        [
          {
            "node": "Prepare Fields for Update",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get row in sheet": {
      "main": [
        [
          {
            "node": "Respond to Webhook: Read",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get rows in sheet": {
      "main": [
        [
          {
            "node": "Respond to Webhook: Read All",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook: Read All": {
      "main": [
        [
          {
            "node": "Get rows in sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Append row in sheet": {
      "main": [
        [
          {
            "node": "Respond to Webhook: Create",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update row in sheet": {
      "main": [
        [
          {
            "node": "Respond to Webhook: Update",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Fields for Update": {
      "main": [
        [
          {
            "node": "Update row in sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Delete rows or columns from sheet": {
      "main": [
        [
          {
            "node": "Respond to Webhook: Delete",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This workflow template demonstrates how to quickly and easily create a simple REST API using n8n and a Google Sheet as a no-code database. It's a perfect starting point for building a backend for small applications, prototypes, or internal tools without writing any code.

Source: https://n8n.io/workflows/8085/ — original creator credit. Request a take-down →

More Data & Sheets workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Data & Sheets

[SANTOBET] FLUXO TODO - BACKUP. Uses googleSheets, httpRequest, googleSheetsTrigger. Webhook trigger; 57 nodes.

Google Sheets, HTTP Request, Google Sheets Trigger
Data & Sheets

FLUXO DISPARO DATA E HORA. Uses itemLists, googleSheets, httpRequest. Webhook trigger; 48 nodes.

Item Lists, Google Sheets, HTTP Request
Data & Sheets

This workflow allows you to accept online payments via YooKassa and log both orders and transactions in Google Sheets — all without writing a single line of code. It supports full payment flow: produc

Google Sheets, HTTP Request
Data & Sheets

Transform your n8n instance management with this advanced automation system featuring artificial intelligence-driven workflow selection. This template provides comprehensive maintenance operations wit

n8n, HTTP Request, Google Sheets +1
Data & Sheets

Nexus_v6(ล่าสุดจริงๆ)ล่าสุดไกไก. Uses googleSheets, httpRequest. Webhook trigger; 41 nodes.

Google Sheets, HTTP Request