Contents

Chapter 1

Data Store Usage Guide

Make.com Data Stores are lightweight key-value databases built into the platform. Many scenarios in this library use data stores to track state between runs — abandoned cart status, drip campaign progress, approval records, loyalty points, and more.

This guide covers creation, schema design, and common patterns.

What Data Stores Solve

Make.com scenarios are stateless by default — each run processes new data without remembering what happened in previous runs. Data stores add memory:

  • Deduplication: "Have I already processed this item?"
  • Multi-step workflows: "Which step is this contact on in the drip sequence?"
  • Accumulation: "What's this customer's total loyalty points?"
  • Coordination: "Has an approver responded to this request?"

Creating a Data Store

1. In Make.com, go to Data stores in the left sidebar

2. Click Add data store

3. Enter the name — use the exact name referenced in the scenario (e.g., abandoned_cart_tracking)

4. Set the data structure — see schema definitions below

5. Set the data store size — the free tier includes 1 MB storage; most tracking use cases fit easily

Defining the Schema

When you create a data store, you define its fields (called a "data structure"):

1. Click Add to create a new data structure

2. Name it (e.g., "Abandoned Cart Schema")

3. Click Generator and paste a sample JSON object to auto-detect fields, OR manually add fields:

  • Name: Field identifier (e.g., checkout_id)
  • Type: Text, Number, Date, Boolean, Collection, Array
  • Required: Whether the field must have a value
  • Default: Value to use if not provided

Example: Creating the Abandoned Cart Tracking Store

Name: abandoned_cart_tracking

FieldTypeRequiredNotes
checkout_idNumberYesUsed as the record key
emailTextYesCustomer's email address
cart_valueNumberNoTotal cart value in dollars
first_email_sentBooleanYesDefault: false
second_email_sentBooleanYesDefault: false
first_sent_atDateNoWhen the first reminder was sent
second_sent_atDateNoWhen the discount follow-up was sent
discount_codeTextNoGenerated discount code, if applicable

Data Store Modules

Make.com provides these modules for working with data stores:

Search Records

Finds records matching filter criteria. Returns an array of matching records.

json
{
  "module": "datastore:search-records",
  "parameters": {
    "data_store": "store_name"
  },
  "mapper": {
    "filter": [
      { "key": "field_name", "value": "match_value", "operator": "equal" }
    ],
    "limit": 50
  }
}

Operators: equal, notequal, greater, less, greaterorequal, lessorequal, contain, notcontain

Output fields:

  • __KEY__ — The record's unique key (for updates/deletes)
  • __IMTLENGTH__ — Number of matching records (useful for existence checks)
  • All defined fields from the schema

Add Record

Creates a new record. Fails if a record with the same key already exists.

json
{
  "module": "datastore:add-record",
  "parameters": {
    "data_store": "store_name"
  },
  "mapper": {
    "key": "unique_identifier",
    "field1": "value1",
    "field2": "value2"
  }
}

Update Record

Updates an existing record by key.

json
{
  "module": "datastore:update-record",
  "parameters": {
    "data_store": "store_name"
  },
  "mapper": {
    "key": "{{previous_module.__KEY__}}",
    "field_to_update": "new_value"
  }
}

Upsert Record

Creates a new record OR updates an existing one. Combines add + update into one operation.

json
{
  "module": "datastore:upsert-record",
  "parameters": {
    "data_store": "store_name"
  },
  "mapper": {
    "key": "unique_identifier",
    "field1": "value1",
    "field2": "value2"
  }
}

Delete Record

Removes a record by key.

json
{
  "module": "datastore:delete-record",
  "parameters": {
    "data_store": "store_name"
  },
  "mapper": {
    "key": "{{previous_module.__KEY__}}"
  }
}

Data Stores Used in This Library

These scenarios reference specific data stores. Create each one before using the associated scenarios.

abandoned_cart_tracking

Used by: ecommerce/ecommerce-orders-fulfillment.json (Abandoned Cart Recovery)

FieldTypeKey?
checkout_idNumberYes
emailText
cart_valueNumber
first_email_sentBoolean
second_email_sentBoolean
first_sent_atDate
second_sent_atDate
discount_codeText

drip_campaign_contacts

Used by: marketing/marketing-campaign-automation.json (Drip Email Sequence)

FieldTypeKey?
emailTextYes
first_nameText
current_stepNumber
next_send_dateDate
statusText
enrolled_atDate
last_sent_atDate
completed_atDate

newsletter_subscribers

Used by: marketing/marketing-lead-capture.json (Newsletter Double Opt-In)

FieldTypeKey?
emailTextYes
first_nameText
source_pageText
confirmation_tokenText
statusText
signed_up_atDate
confirmed_atDate

review_request_queue

Used by: ecommerce/review-request-sequence.json

FieldTypeKey?
order_idTextYes
customer_emailText
customer_nameText
product_nameText
product_handleText
statusText
send_afterDate
attemptNumber
last_sent_atDate

loyalty_points

Used by: ecommerce/loyalty-points-tracker.json

FieldTypeKey?
emailTextYes
customer_nameText
total_pointsNumber
tierText
total_spentNumber
order_countNumber
last_order_atDate

invoice_reminders

Used by: finance/overdue-invoice-reminders.json

FieldTypeKey?
invoice_idTextYes
customer_emailText
amount_dueNumber
last_level_sentText
last_sent_atDate
days_overdue_at_last_sendNumber

approval_requests

Used by: operations/approval-workflow.json

FieldTypeKey?
request_idTextYes
requester_nameText
requester_emailText
requester_slack_idText
request_typeText
descriptionText
amountNumber
approval_levelText
approver_slack_idText
statusText
submitted_atDate
sla_deadlineDate
decided_atDate
decision_noteText

standup_tracking

Used by: operations/standup-collector.json

FieldTypeKey?
keyTextYes
nameText
slack_user_idText
dateDate
promptedBoolean
respondedBoolean
responseText

incident_tracker

Used by: operations/incident-response.json

FieldTypeKey?
incident_idTextYes
titleText
severityText
serviceText
sourceText
statusText
assigned_toText
created_atDate
resolved_atDate
resolution_notesText

referral_program

Used by: marketing/referral-tracking.json

FieldTypeKey?
referral_codeTextYes
referrer_emailText
referrer_nameText
successful_referralsNumber
total_reward_earnedNumber
last_referral_atDate

winback_tracking

Used by: marketing/customer-winback.json

FieldTypeKey?
keyTextYes
emailText
tier_sentText
sent_atDate
days_lapsedNumber

Design Patterns

Pattern: Existence Check → Route

The most common pattern. Search for a record, then route based on whether it exists:

Search → Router
├── Found (__IMTLENGTH__ > 0) → Update existing record
└── Not found (__IMTLENGTH__ = 0) → Create new record

Pattern: State Machine

Track an item through stages (e.g., pending → active → completed):

1. Search by key

2. Read current status

3. Apply transition rules

4. Update with new status

Pattern: Counter / Accumulator

Track running totals (loyalty points, referral counts):

1. Search by key

2. Read current value

3. Calculate new value: {{current + increment}}

4. Upsert with new total

Pattern: Deduplication Gate

Prevent processing the same item twice:

1. Search by unique identifier

2. Filter: only continue if __IMTLENGTH__ = 0

3. Process the item

4. Add a record to mark it as processed

Size and Performance

  • Free tier: 1 MB data store storage
  • Core plan: 10 MB
  • Pro plan: Unlimited

Rough capacity at 1 MB: ~5,000-10,000 simple records (depends on field sizes)

Performance tips:

  • Use short, specific key values
  • Avoid storing large text blobs (full email bodies, HTML content)
  • Clean up old records periodically with a maintenance scenario
  • If you outgrow data stores, consider migrating state tracking to Airtable or a database via HTTP modules
Chapter 2

Error Handling and Logging Patterns

How to make your Make.com scenarios resilient, debuggable, and production-ready using error handlers, logging, and monitoring patterns.

Why Error Handling Matters

A scenario without error handling will stop completely when any single module fails. For a scenario processing 50 orders, if order #3 fails, orders #4-50 never get processed. Error handling lets you decide what happens on failure — retry, skip, alert, or gracefully degrade.

Error Handler Types

Make.com provides four error handler types. Each is appropriate for different situations.

1. Retry

When to use: Transient failures — API rate limits, network timeouts, temporary service outages.

json
"error_handler": {
  "type": "retry",
  "max_retries": 3,
  "interval": 60
}
SettingRecommended ValueWhy
max_retries2-5More than 5 usually means the issue isn't transient
interval60-300 secondsGive the external service time to recover

Best for: Email sending, API calls to third-party services, webhook deliveries.

2. Ignore

When to use: The module's failure is acceptable and shouldn't block the rest of the scenario.

json
"error_handler": {
  "type": "ignore",
  "message": "Optional: why this failure is acceptable"
}

Best for: Non-critical notifications (Slack messages), duplicate record creation (subscriber already exists), optional enrichment steps.

Warning: Don't overuse ignore — you'll mask real problems. Always add a descriptive message so you can review ignored errors in the execution log.

3. Break

When to use: The failure is important but shouldn't crash the entire scenario. The current item is skipped, but processing continues with the next item.

json
"error_handler": {
  "type": "break",
  "message": "Failed to process order {{1.id}}: {{error.message}}"
}

Best for: Iterator-based flows where one bad item shouldn't stop the batch. Order processing, bulk imports, data sync operations.

4. Rollback

When to use: When partial execution would leave data in an inconsistent state. Rolls back the entire scenario run.

json
"error_handler": {
  "type": "rollback"
}

Best for: Financial transactions, multi-step operations where all-or-nothing is required.

Error Handler Decision Tree

Module failed → Is the data critical?
├── No → IGNORE (log the skip)
└── Yes → Is it likely a transient issue?
    ├── Yes → RETRY (2-3 attempts, 60s intervals)
    └── No → Is this inside an iterator?
        ├── Yes → BREAK (skip item, continue batch)
        └── No → Is partial execution dangerous?
            ├── Yes → ROLLBACK
            └── No → BREAK with alert notification

Logging Patterns

Pattern 1: Central Error Log Sheet

Add a Google Sheets module after your error handler to log all failures:

json
{
  "module": "google-sheets:add-row",
  "label": "Log Error",
  "parameters": {
    "spreadsheet_id": "YOUR_ERROR_LOG_SHEET",
    "sheet_name": "Errors"
  },
  "mapper": {
    "values": {
      "A": "{{formatDate(now; 'YYYY-MM-DD HH:mm')}}",
      "B": "Scenario Name",
      "C": "{{error.module}}",
      "D": "{{error.message}}",
      "E": "{{error.status_code}}",
      "F": "Item ID or context"
    }
  }
}

Error Log sheet columns: A=Timestamp, B=Scenario, C=Failed Module, D=Error Message, E=Status Code, F=Context.

Pattern 2: Slack Alert on Critical Failures

For high-priority scenarios, send a Slack alert when something fails:

json
{
  "module": "slack:send-message",
  "label": "Alert: Scenario Failure",
  "parameters": { "channel": "#alerts" },
  "mapper": {
    "text": ":x: *Scenario Failure*\n*Scenario:* Your Scenario Name\n*Module:* {{error.module}}\n*Error:* {{error.message}}\n*Time:* {{formatDate(now; 'YYYY-MM-DD HH:mm')}}"
  }
}

Pattern 3: Execution Summary Email

For batch scenarios, aggregate results and send a summary:

json
{
  "module": "builtin:set-variable",
  "label": "Track Results",
  "mapper": {
    "variables": [
      { "name": "processed", "value": "{{counter.processed + 1}}" },
      { "name": "failed", "value": "{{counter.failed + if(error; 1; 0)}}" }
    ]
  }
}

Then after the iterator completes, send:

Processed: {{processed}} items
Failed: {{failed}} items
Success rate: {{round((processed - failed) / processed * 100)}}%

Common Error Scenarios and Solutions

API Rate Limits

Symptom: 429 Too Many Requests or Rate limit exceeded

Solution:

1. Add a builtin:sleep module between iterations (200-500ms)

2. Reduce the schedule frequency

3. Use the retry handler with increasing intervals

json
{
  "module": "builtin:sleep",
  "parameters": { "delay": 500 },
  "label": "Rate Limit Buffer (500ms)"
}

Connection Expired

Symptom: 401 Unauthorized or Token expired

Solution:

  • Make.com auto-refreshes most OAuth tokens, but some expire after extended periods
  • Go to Connections in the left sidebar and re-authorize
  • For API key connections, update the key if it was rotated

Data Type Mismatches

Symptom: Cannot convert value or Expected number, got text

Solution:

  • Wrap values in conversion functions: {{toNumber(1.amount)}}, {{toString(1.id)}}
  • Use {{if(1.field; 1.field; "default")}} to handle missing fields

Webhook Timeout

Symptom: Webhook doesn't fire, or sending service reports timeout

Solution:

  • Make.com webhooks have a 30-second timeout for the initial response
  • Keep the scenario that handles the webhook lightweight
  • For heavy processing, have the webhook scenario write to a data store and process in a separate scheduled scenario

Monitoring Your Scenarios

Built-in Monitoring

  • History tab: Shows every execution with pass/fail status
  • Incomplete executions: Make.com automatically saves failed runs here — you can manually retry them
  • Notifications: Configure email alerts for scenario failures in Make.com settings

Custom Monitoring Dashboard

Create a Google Sheet with these columns to track all your scenarios:

ColumnContent
ADate
BScenario Name
CStatus (Success/Partial/Failed)
DItems Processed
EItems Failed
FDuration (seconds)
GOperations Used

Add a row to this sheet at the end of each scenario run using a Google Sheets module.

Health Check Scenario

Create a dedicated "health check" scenario that runs every hour:

1. Check that all critical data stores are accessible

2. Verify each connection is still valid (make a simple API call per app)

3. Post a daily summary to Slack: "All systems operational" or list any issues

Error Handling Checklist

For every scenario you deploy, verify:

  • [ ] Every external API module has an error handler
  • [ ] Critical failures trigger a Slack/email alert
  • [ ] Batch operations use break handlers inside iterators
  • [ ] A central error log captures all failures
  • [ ] Retry handlers have reasonable limits (not infinite loops)
  • [ ] Ignore handlers have descriptive messages explaining why the skip is acceptable
  • [ ] The scenario has been tested with both valid AND invalid data
Chapter 3
🔒 Available in full product

Setup and Import Guide

You’ve reached the end of the free preview

Get the full Make Integration Library and unlock everything.

All Chapters

Get the complete guide with every chapter unlocked, including code samples, diagrams, and best practices.

Full Tool Suite

Access all interactive tools with complete data, all workload profiles, and the full scenario library.

Source Files

Downloadable source code, configuration files, and working examples from every chapter.

Lifetime Updates

Free updates for life. Every new chapter, tool, and improvement included.

Buy Now — $29 →
📦 Free sample included — download another copy for the full product.
Make Integration Library v1.0.0 — Free Preview