PTENES
MODULE 4.3

🔌 Integrations and data

Your automation needs to connect with the world. Here, you’ll master HTTP Request and REST APIs, Bearer and OAuth authentication, reading from and writing to Supabase and Google Sheets, pagination with SplitInBatches, and handling nulls in field mapping.

6
Topics
55
Minutes
Intermediate
Level
Hands-on practice
Type
HTTP Request + Bearer/OAuth auth REST API Supabase Google Sheets SplitInBatches

Illustrative — the HTTP Request in the center communicates with any service; pagination processes lists in batches.

1

🌐 HTTP Request and REST APIs

O HTTP Request node is the Swiss Army knife: when there’s no native node, it talks to any REST API. You define the method, URL, headers, and body, and receive the response as an item.

# GET with dynamic query params
GET  https://api.exemplo.com/v1/pedidos
?status=={{ $json.status }}&limit=50

// a resposta vira item; acesse com: ={{ $json.data }}

📊 The REST verbs that matter

  • GET - read data (doesn't change anything on the server).
  • POST - create a new record.
  • PUT/PATCH - update an existing record.
  • DELETE - remove. Always check the status code: 2xx success, 4xx your error, 5xx their error.
2

🪪 Authentication

The error 401 Unauthorized is the #1 integration pitfall. The API needs proof of who you are: a token in the header (Bearer) or a consent flow (OAuth2).

# Bearer authentication header
Authorization: Bearer ={{ $env.API_TOKEN }}
Content-Type:  application/json

✓ Bearer token

  • ✓Simple: 1 fixed key in the header.
  • ✓Good for server APIs (OpenAI, Stripe).
  • ✓Store the key in $env/credential.

✓ OAuth2

  • ✓To access a user's account (Google, Slack).
  • ✓n8n refreshes the token automatically (refresh).
  • ✓Configure it once in the credential and reuse it.

⚠️ Got a 401? Check in this order

Correct key? Header with the exact name (Authorization)? Prefix Bearer with room? Expired token (OAuth)? Sufficient scope? 90% of 401s happen here.

3

🗄️ Supabase / database: read and write

The database is the memory of automation. Without it, every run forgets everything. With Supabase/Postgres, you read with SELECT and write with INSERT/UPDATE—or better, UPSERT, which records or updates by unique key.

# UPSERT in Supabase via HTTP Request
POST https://abcd.supabase.co/rest/v1/leads
Headers:
  apikey: ={{ $env.SUPABASE_SERVICE_KEY }}
  Prefer: resolution=merge-duplicates
Body:
  { "email": "={{ $json.email }}", "intencao": "={{ $json.intencao }}" }

🔑 Unique key = your anchor

Define a unique column (e.g., email). The UPSERT uses it to decide between creating and updating—that’s what prevents duplicates (covered in module 4.4).

  • •SELECT with a filter ?email=eq.ana@x.com to read.
  • •Prefer: resolution=merge-duplicates performs the UPSERT in Supabase.
4

📊 Spreadsheets (Google Sheets)

Google Sheets is the favorite “database” of people who aren’t developers. Clients understand spreadsheets. Delivering results in a tab is the fastest way to show value without training anyone—read by row, write by append or update.

# append row mapping fields to columns
Nome:       ={{ $json.nome }}
Email:      ={{ $json.email }}
Prioridade: ={{ $json.prioridade }}
Data:       ={{ $now.format('dd/MM/yyyy') }}
Append row

Adds a new row

Update

Per key/column

Read rows

Spreadsheet as input

Range

Tab and range

💡 Practical tip

Spreadsheets are great for visible delivery, but a poor choice as a transactional database. For deduplication and volume, use Supabase; for the client see the result, mirror it in a tab.

5

🔄 Pagination and list processing

APIs limit how many items they return per call and impose rate limit. Processing everything at once breaks. SplitInBatches (Loop Over Items) splits the list into batches; a cursor/offset fetches pages one by one.

# fetch the next page with a cursor
GET https://api.exemplo.com/v1/itens?cursor=={{ $json.next_cursor }}
// repita o HTTP node em loop enquanto next_cursor não for null
// SplitInBatches: tamanho 50 + Wait 1s entre lotes p/ respeitar rate limit

⚠️ The N+1 error and rate limit

Firing one call per item, with no batching or waiting, leads to 429 Too Many Requests and at an absurd cost. Always group them into batches and add a Wait between them.

1

Split the list

SplitInBatches with a batch size (e.g., 50) splits 500 items into 10 rounds.

2

Process the batch and wait

Do the batch work, add a Wait node, and return to SplitInBatches.

3

Stop when it runs out

The loop ends when there are no more batches (or next_cursor is null).

6

🧮 Handle nulls and map fields

A field unexpected null breaks the flow halfway through. n8n expressions ={{ }} with a default value and optional chaining make the automation resilient to dirty data.

# defensive expressions in n8n
// valor padrão quando vem nulo/undefined
={{ $json.email ?? 'sem-email@placeholder.com' }}

// optional chaining evita "cannot read property of undefined"
={{ $json.cliente?.endereco?.cidade ?? 'N/D' }}

// renomear/formatar ao mapear
={{ $json.valor ? 'R$ ' + $json.valor.toFixed(2) : 'R$ 0,00' }}

✓ Resilient mapping

  • ✓Always ?? valor_padrao in a field that may be missing.
  • ✓?. in nested objects from an external source.
  • ✓Format types (date, number) in the mapping.

✗ Fragile mapping

  • ✗Assume every item has all the fields.
  • ✗Access $json.a.b.c without protection.
  • ✗Record undefined in the database/spreadsheet.

📌 Module Summary

✓
HTTP Request - talks to any REST API; always check the status code.
✓
Authentication - Bearer for servers, OAuth2 for user accounts; 401 = checklist.
✓
Supabase - the database is the memory; UPSERT by unique key creates or updates.
✓
Spreadsheets - visible delivery to the customer; append/update by column.
✓
Pagination - SplitInBatches + Wait respects rate limits and avoids N+1.
✓
Nulls and mapping - ?? e ?. in expressions ={{ }} make the workflow resilient.

Next Module:

4.4 - Reliability (errors, retries, idempotency, observability, production checklist)