Skip to main content

Make.com Custom Apps: Create Your Own Integration Modules

· 13 min read
Yassine El Haddad
Software Developer & Automation Specialist

I build production AI agents, web scrapers, and automation pipelines. Most of what I publish here comes from the actual problems they run into: proxies that get banned, anti-bot stacks that fingerprint your client, RAG that drifts when the underlying data moves. Stack: Python, TypeScript, Go, FastAPI, LangChain, Crawlee, Playwright, deployed on AWS, GCP, and Cloudflare.

Yes, you can build your own Make.com app. If the service you need isn't in Make's library of 1,000+ apps, the Custom Apps tool lets you define your own modules, map them to any REST API, handle authentication, transform data with IML, and publish the result for your team or the broader Make community. Custom apps give you full control over the API surface — something no pre-built module can match for niche or internal services.

This guide walks through the full process: from opening the Apps Editor to shipping a working custom module backed by a real API call.

What Are Make.com Custom Apps?

A custom app in Make is a user-built integration module that behaves identically to any built-in app. Once created, it appears in the Scenario builder, supports connection credentials, exposes typed input parameters, and returns structured output bundles.

Custom apps are the right tool when:

  • The service you need has no Make module (niche SaaS, internal APIs, proprietary databases)
  • An existing module is too limited (missing endpoints, wrong output format)
  • You want to standardize API access across your team without everyone needing to understand the raw API

Custom apps are not the right tool when:

  • The service already has a Make module that covers your use case
  • You only need one ad-hoc call — use the HTTP module instead
  • You have no API documentation for the target service

The Two Editors

Make gives you two ways to write custom apps:

EditorBest for
Web interfaceBeginners, quick iterations, no local tooling
VS Code extensionProduction apps, version control, team collaboration

Both editors share the same underlying JSON config format. Start with the web interface to prototype, then migrate to VS Code for anything you'll maintain long-term.

Accessing the Web Interface

  1. Log in to Make.com
  2. Click More in the left sidebar, then Custom Apps
  3. Click + Create a new app

The Custom Apps dashboard shows all your private apps, their version, and publication status.

Setting Up the VS Code Extension

The VS Code extension syncs your local JSON files with Make's backend in real time.

Step 1 — Generate an API key

Navigate to your Make profile → API access+ Add token. Enable these two scopes:

  • sdk-apps:read
  • sdk-apps:write

Copy the token immediately — Make only shows it once.

Step 2 — Install the extension

Search for Make Apps Editor in the VS Code Marketplace, or install Integromat.apps-sdk from the Extensions panel.

Step 3 — Connect to your organization

Open the Command Palette (Ctrl+Shift+P / Cmd+Shift+P) and run > Add SDK environment. Paste your API key and your zone URL (e.g., https://us1.make.com/api).

Your apps appear in the Make sidebar. All edits auto-upload to Make on Ctrl+S.

App Anatomy

Every Make custom app has the same five building blocks:

my-app/
├── base # Shared HTTP settings (base URL, default headers)
├── connections/ # Authentication definitions (API key, OAuth 2.0)
├── modules/ # Individual actions exposed in Scenario builder
├── rpcs/ # Remote Procedure Calls (dynamic dropdowns)
└── webhooks/ # Instant trigger endpoints

Start with connection → base → modules. RPCs and webhooks are optional unless you need dynamic UI or real-time triggers.

Step 1 — Create the App

In the web interface, click + Create a new app and fill in:

FieldNotes
LabelShown in Scenario builder — match the service's brand name
App IDLowercase alphanumeric, hyphen-separated (open-meteo, not OpenMeteo) — cannot be changed
VersionAlways 1 for new apps
ColorHex color for module icons (e.g., #0066cc)

For this guide we'll build a custom app for Open-Meteo, a free weather API with no API key required.

Step 2 — Define the Connection

Even if your API is unauthenticated, Make requires a connection object. For a key-based API, the connection definition looks like this:

{
"type": "basic",
"fields": [
{
"name": "apiKey",
"type": "text",
"label": "API key",
"required": true
}
],
"validation": {
"condition": "{{connection.apiKey}}",
"throw": [
{
"message": "API key is missing."
}
]
}
}

For Open-Meteo (no auth needed), set the connection type to basic with no fields. This creates a placeholder connection so Make's module system works correctly.

OAuth 2.0 Connections

For services requiring OAuth, the connection type changes to oauth2. The required fields are:

{
"type": "oauth2",
"clientId": "{{common.clientId}}",
"clientSecret": "{{common.clientSecret}}",
"authorizeUrl": "https://api.example.com/oauth/authorize",
"tokenUrl": "https://api.example.com/oauth/token",
"scope": "read write",
"scopeSeparator": " "
}

Make handles the full PKCE flow, token refresh, and credential storage. You don't implement any of that yourself.

Step 3 — Set the Base URL

The Base section defines the root URL and any headers shared across all modules:

{
"baseUrl": "https://api.open-meteo.com/v1",
"headers": {
"Content-Type": "application/json"
}
}

All module URLs are relative to this base. If you later need to change the API domain, you update it in one place.

Step 4 — Build Your First Module

This is where the app becomes useful. Make supports five module types:

TypeUse caseReturns
ActionWrite, update, or delete a single recordSingle bundle
SearchQuery a list of records (with optional filters)Multiple bundles
TriggerPoll for new items on a scheduleMultiple bundles
Instant triggerReceive a webhook from the serviceSingle bundle
Universal (Make an API call)Catch-all for endpoints not covered by other modulesRaw response

Example: Get Current Weather (Action module)

We'll create an Action module that calls GET /forecast on Open-Meteo and returns current temperature data.

In the web editor, navigate to Modules+ Add module → select Action.

The module config is split across tabs:

Communication tab

This defines the HTTP request:

{
"url": "/forecast",
"method": "GET",
"qs": {
"latitude": "{{parameters.latitude}}",
"longitude": "{{parameters.longitude}}",
"current": "temperature_2m,wind_speed_10m",
"temperature_unit": "{{parameters.unit}}"
},
"response": {
"output": "{{body}}"
}
}

{{parameters.latitude}} refers to an input parameter defined in the next tab. {{body}} maps the entire JSON response to the module's output.

Parameters tab

Input parameters are what users configure in the Scenario builder:

[
{
"name": "latitude",
"type": "number",
"label": "Latitude",
"required": true,
"help": "WGS84 coordinate between -90 and 90."
},
{
"name": "longitude",
"type": "number",
"label": "Longitude",
"required": true
},
{
"name": "unit",
"type": "select",
"label": "Temperature unit",
"required": false,
"default": "celsius",
"options": [
{ "label": "Celsius", "value": "celsius" },
{ "label": "Fahrenheit", "value": "fahrenheit" }
]
}
]

Output tab

The output tab defines the bundle structure returned that downstream modules can use:

[
{
"name": "temperature",
"type": "number",
"label": "Temperature",
"path": "current.temperature_2m"
},
{
"name": "windSpeed",
"type": "number",
"label": "Wind speed",
"path": "current.wind_speed_10m"
},
{
"name": "time",
"type": "text",
"label": "Time",
"path": "current.time"
}
]

path uses dot-notation to navigate the JSON response and pluck specific values.

Step 5 — Data Transformation with IML

IML (Integromat Markup Language) is Make's built-in expression language. You use it to transform values inside module configurations — anywhere you see {{ }} syntax.

IML gives you access to:

  • Variables: {{parameters.name}}, {{body.field}}, {{connection.apiKey}}
  • String functions: {{toLower(parameters.name)}}, {{trim(body.title)}}
  • Math: {{add(parameters.qty, 1)}}, {{round(body.price, 2)}}
  • Date/time: {{formatDate(now, "YYYY-MM-DD")}}, {{parseDate("2026-01-01", "YYYY-MM-DD")}}
  • Arrays: {{first(body.results)}}, {{map(body.items, "id")}}
  • Conditionals: {{if(body.active, "yes", "no")}}

Practical IML example

The Open-Meteo API returns timestamps in ISO 8601 format (2026-03-15T12:00). To format them for display:

{
"name": "formattedTime",
"type": "text",
"label": "Formatted time",
"value": "{{formatDate(parseDate(body.current.time, \"YYYY-MM-DDTHH:mm\"), \"MMM D, YYYY h:mm A\")}}"
}

You can also write custom IML functions in the Functions section of your app for reusable logic across multiple modules.

Step 6 — Dynamic Dropdowns with RPCs

RPCs (Remote Procedure Calls) power dynamic select fields — dropdowns populated at runtime from an API call rather than hardcoded values.

Example: a "Project" dropdown that fetches real projects from the API when the user opens the module:

RPC definition:

{
"url": "/projects",
"method": "GET",
"response": {
"output": {
"label": "{{item.name}}",
"value": "{{item.id}}"
}
}
}

Parameter referencing the RPC:

{
"name": "projectId",
"type": "select",
"label": "Project",
"options": {
"rpc": "listProjects"
}
}

When the user opens the module, Make calls the RPC, gets the project list, and renders a live dropdown. No hardcoded option arrays needed.

Step 7 — Instant Triggers (Webhooks)

Instant triggers fire immediately when the source service pushes an event — no polling delay. Use them when the API supports webhooks.

The webhook definition registers a URL endpoint with Make and specifies how to parse the incoming payload:

{
"url": "/webhooks",
"method": "POST",
"body": {
"url": "{{webhook.url}}"
},
"response": {
"data": {
"id": "{{body.webhookId}}"
}
},
"detach": {
"url": "/webhooks/{{connection.webhookId}}",
"method": "DELETE"
}
}

Make provides the unique {{webhook.url}} — your module POSTs this to the service's webhook registration endpoint. The detach block tells Make how to unsubscribe when the user disconnects the module.

Step 8 — Test Your App

Before publishing, test each module in a live Scenario:

  1. In Make, open Scenarios → create a blank scenario
  2. Click the + icon and search for your custom app name
  3. Add the module, create a connection, fill in the parameters
  4. Click Run once and inspect the output bundles

Common errors to check:

ErrorLikely cause
401 UnauthorizedConnection credentials not mapped correctly in the request headers
400 Bad RequestA required parameter is empty or incorrectly formatted
Empty outputThe path in the Output tab doesn't match the actual JSON response shape
Module not visibleApp still in draft — check Custom Apps dashboard status

Use Make's built-in log viewer (Custom Apps dashboard → Logs) to inspect raw HTTP requests and responses for each test run.

Step 9 — Publish Your App

Custom apps start as private. You have two publication paths:

Private (Team use)

Your app is available only to your Make organization. No review needed. Useful for internal APIs, proprietary systems, or apps still in development.

Public (Make Marketplace)

Submit for review by the Make team. Requirements:

  • App logo (SVG, 512×512, transparent background)
  • Complete module descriptions following Make's naming conventions
  • All modules tested against live API
  • Documentation URL
  • Privacy policy and terms of service URLs

The review timeline varies — Make's documentation notes the process involves a structured review but does not publish a fixed SLA. Budget several weeks for review and any requested revisions. Make only accepts apps connecting to services not already covered by default Make apps. If a built-in Make app already covers the service, the custom app won't be approved.

To submit: Custom Apps dashboard → your app → Request review → fill in the submission form.

Full Example: Open-Meteo Weather App

Here's a complete working app configuration you can paste into the Make web editor:

Base:

{
"baseUrl": "https://api.open-meteo.com/v1"
}

Connection (no auth):

{
"type": "basic",
"fields": []
}

Module — Get current weather:

{
"communication": {
"url": "/forecast",
"method": "GET",
"qs": {
"latitude": "{{parameters.latitude}}",
"longitude": "{{parameters.longitude}}",
"current": "temperature_2m,wind_speed_10m,weather_code",
"temperature_unit": "{{parameters.unit}}"
},
"response": {
"output": "{{body}}"
}
},
"parameters": [
{
"name": "latitude",
"type": "number",
"label": "Latitude",
"required": true
},
{
"name": "longitude",
"type": "number",
"label": "Longitude",
"required": true
},
{
"name": "unit",
"type": "select",
"label": "Temperature unit",
"default": "celsius",
"options": [
{ "label": "Celsius", "value": "celsius" },
{ "label": "Fahrenheit", "value": "fahrenheit" }
]
}
],
"output": [
{
"name": "temperature",
"type": "number",
"label": "Temperature",
"path": "current.temperature_2m"
},
{
"name": "windSpeed",
"type": "number",
"label": "Wind speed (km/h)",
"path": "current.wind_speed_10m"
},
{
"name": "weatherCode",
"type": "integer",
"label": "WMO weather code",
"path": "current.weather_code"
},
{
"name": "time",
"type": "text",
"label": "Observation time",
"path": "current.time"
}
]
}

Paste the base and connection configs into the respective editors, then create one module named "Get current weather" with the communication, parameters, and output sections above. Run a test with latitude: 48.8566 (Paris) and you'll see live temperature data flowing through.

When to Use HTTP Module vs. Custom App

ScenarioUse
One-off API call in a single scenarioHTTP module
Same API called in 5+ scenariosCustom app
Multiple people on the team need accessCustom app
You want typed fields and output mappingCustom app
Publishing to the marketplaceCustom app
API changes frequentlyReconsider — custom apps require manual updates

The HTTP module is faster to set up but produces raw JSON output that every scenario must parse independently. A custom app absorbs that complexity once and exposes clean, mapped fields everywhere.

Custom Apps vs. Pre-Built Apify Make Integration

If your goal is to connect a web scraping workflow to Make.com without building a custom app, Apify's native Make integration is the faster path. The Apify module in Make already handles Actor runs, dataset retrieval, and webhook triggers — no custom app required.

Build a custom Make app when you control the API you're connecting to, or when no Make module exists for the service you need.

Start building on Make.com — free account available.

Frequently Asked Questions

Yes. Make's Custom Apps tool lets any user with a Make account create their own integration modules. You define the API connection, map endpoints to module types (action, search, trigger), and configure typed parameters. The app then appears in the Scenario builder like any built-in Make app.

The Make Apps Editor is a JSON-based configuration environment available in two forms: a browser-based web editor built into Make's dashboard, and a VS Code extension (Integromat.apps-sdk) that syncs files to Make via API. Both editors support code suggestions, IML syntax highlighting, and real-time validation.

Navigate to Custom Apps in your Make dashboard, create a new app, define a connection, set a base URL, then add a module. Each module has a Communication tab (HTTP request definition), a Parameters tab (user inputs), and an Output tab (response mapping). Save, add it to a Scenario, and test with Run once.

Make custom apps support five module types: Action (single-record write/read), Search (multi-record query), Trigger (scheduled polling), Instant trigger (webhook push), and Universal/Make an API call (catch-all). The correct choice depends on whether the operation returns one or many records and whether it requires real-time or scheduled execution.

IML (Integromat Markup Language) is Make's expression language used inside custom app configurations. It lets you reference parameters ({{parameters.name}}), transform strings and numbers ({{toLower(body.title)}}), handle dates ({{formatDate(now, 'YYYY-MM-DD')}}), and write conditional logic — all within the JSON config. IML runs server-side and does not require JavaScript knowledge.

Yes, but only for services not already covered by Make's built-in app library. To publish, your app must pass Make's review process (typically 4–6 weeks), include a complete app logo, module descriptions following Make's naming conventions, and a privacy policy. Private apps require no review and are immediately available to your Make organization.

A simple action module against a documented REST API with API key auth can be working in under an hour for a developer familiar with REST concepts. An app with multiple modules, OAuth 2.0, dynamic dropdowns via RPCs, and instant trigger webhooks will take considerably longer depending on API complexity. The Make Academy offers a free course on getting started with custom apps if you're new to the process.