KEEP LEARNING
Build the bigger picture.
The Workflow Engineer connects individual n8n concepts to testing, deployment and running a complete workflow.
Tips > Building Workflows
Different SaaS platforms structure data in incompatible ways.
When two SaaS platforms structure data differently, place a Code node between them as an adapter. It reshapes the upstream node's output into the exact structure the downstream node expects, mapping IDs, renaming fields, and translating values such as status labels. Centralizing this mapping in one Code node keeps future field changes easy to make.
Different SaaS platforms structure data in incompatible ways. A Code node between them acts as an adapter layer, reshaping the output of one node to match the expected input of another.
Real-world example: Syncing records from Airtable (which returns linked records as arrays of IDs) to Notion (which expects relation properties as arrays of page IDs with specific formatting).
// Mode: Run Once for All Items
// Mapping of Airtable record IDs to Notion page IDs (pre-built or fetched)
const idMap = $input.first().json.idMapping; // { airtableId: notionPageId }
return $input.all().slice(1).map(item => {
const record = item.json;
// Airtable returns: { "Assignees": ["recABC", "recDEF"], "Status": "In Progress" }
// Notion expects: specific property format per type
return {
json: {
parent: { database_id: 'your-notion-database-id' },
properties: {
// Title property
'Task Name': {
title: [{ text: { content: record['Task Name'] || 'Untitled' } }]
},
// Select property
'Status': {
select: { name: mapStatus(record['Status']) }
},
// Relation property -- map Airtable IDs to Notion page IDs
'Assignees': {
relation: (record['Assignees'] || [])
.map(airtableId => idMap[airtableId])
.filter(Boolean)
.map(notionId => ({ id: notionId }))
},
// Date property
'Due Date': {
date: record['Due Date']
? { start: record['Due Date'], end: null }
: null
},
// Number property
'Story Points': {
number: parseInt(record['Story Points'], 10) || null
},
}
}
};
});
function mapStatus(airtableStatus) {
const statusMap = {
'To Do': 'Not started',
'In Progress': 'In progress',
'Done': 'Complete',
'Blocked': 'Blocked',
};
return statusMap[airtableStatus] || 'Not started';
}This pattern is reusable for any SaaS-to-SaaS sync. Keep the mapping logic centralized in one Code node to make future field changes easy.
Related: Use Edit Fields in "Map Each" Mode for Simple Renames · Configure Payload Size and Binary Data Mode for Large Files
KEEP LEARNING
The Workflow Engineer connects individual n8n concepts to testing, deployment and running a complete workflow.
APPLY IT TO YOUR SYSTEM
Bring the process, the tools involved and an example of where the current workflow gets stuck.