Whenever you create a new package of changes, you can commit them to create a new version in the Git repository.
1
In the GitHub Desktop app, open the repository with the latest version of your app. You should see a list of new changes.
2
Enter the Summary and Description of the commit, and click Commit to main.
The new version of your app is logged.
Next, you will .
Pull changes from Make
Once you finish the development of new changes and components in Make, you can push the changes to the local app.
1
In Visual Studio Code, open the local directory with the local app file.
2
Locate the makecomapp.json file and right-click. Select Pull All Components from Make (beta) option.
3
Select the testing app origin.
All changes in the existing components will be pulled into the local components. If there is a new component, a dialog will appear. Either confirm the creation of the component by pressing Enter or click Ignore permanently/do not map with the remote option.
Overview
Make Custom Apps documentation is a guide for developers to create apps for themselves or others to use on the Make platform.
If you need to interact with a third-party application in Make and there is not an app created for it yet, you can make your own.
This documentation helps you prepare to build an app, walks you through the process of creating your first app, and provides you with best practices and specifications for your project.
By the end of the course, you will understand what custom apps are and the benefits of using them, use the API documentation to help you design and create your first app, and identify the components that form a custom app.
Get started
Step 1: Select your editor
you want to use to build your custom app:
,
, or
with vibe coding (information coming soon)
Step 2: Determine your starting point
If you're already familiar with Make, you're ready to .
If you're new to Make, we recommend that you begin with a practice exercise (see ).
Step 3: Practice connecting an API in Make
Before creating your first app, to practice connecting to your selected API on the Make platform. This will help you get comfortable with the process.
Develop app in a local workspace (offline)
Unlike online development within the Make web interface, local development doesn't provide access to advanced features such as prefilled code templates, IML object suggestions, and seamless integration with the Scenario Builder for continuous testing.
Instead, it offers a self-contained environment for app creation and modification, ideal for situations where internet connectivity is unreliable or where comprehensive testing within the Scenario Builder isn't required.
Additionally, local development allows synchronization with Git repositories and provides full search capabilities across the entire codebase.
Create or edit a current component in a local app
Live Stream
Live Stream displays what is happening in the background once you've hit the Run once button.
You can view the following information for each module in your scenario:
Request Headers (API endpoint URL, HTTP method, time and date the request has been called, request headers, and query string)
Request Body
Develop apps collaboratively
Collaborative development is facilitated by the Git for apps feature in the VS Code extension. The supported operations are documented in this .
Prerequisites
To start collaborative development, make sure that you have set up the .
Each collaborating developer should have their testing app in Make, connected to the local app from the Git repository.
Set the app icon in VS Code
Before setting the app icon in VS Code, make sure that your icon meets .
To set the app icon:
1
Right-click the app name and select Edit icon.
You will see a preview of the current app's icon inside the app module.
2
Create an app in VS Code
Now that you have and , you can now create your app.
To create an app in VS Code:
1
Click the + icon in the header of the My apps section or call the >New app command directly from the command palette.
Make supports writing custom apps in Visual Studio Code (VS Code) with the Make Apps Editor extension.
You can get the VS Code extension from the VS Code Marketplace or install it in the Extensions tab in VS Code.
Write and edit the custom app configuration with the VS Code extension as you would edit a JSON of JavaScript file on your PC. The custom app configuration is downloaded to your PC when you open it from VS Code and uploaded to Make when you save it. The custom app configuration is stored on your PC as temporary files. The temporary files are deleted after you close the configuration.
The custom app configuration is associated with your account in Make. Communication with the VS Code extension and your Make account is authorized with an API key.
To set up the VS Code extension you must provide an API key with the appropriate API key scopes. Generate a new Make API key if you don't have one.
If you notice any bugs in the Make Apps Editor, please don't hesitate to contact our support team.
Each group of components, such as RPCs, modules, or custom IML functions, contains the component directories with corresponding code files.
If you need to edit the current code, click the file you want to edit and develop your changes in the opened tab. Save the changes.
If you need to create a new component:
1
Right-click the corresponding components' folder and select New Local Component: <component's name> (beta). For example, New Local Component: Module (beta).
2
Enter the component's name, label, and other corresponding parameters.
3
A new component with the corresponding files is created.
4
Write the code in the corresponding files and save the changes.
After you run a scenario, select Live Stream from the left-side panel and click one of the tabs in the right panel of Make DevTool to view the desired information.
Search in Logs
Enter the search term in the search field in the left panel of Make DevTool to only display requests and responses that contain the search term.
Clear the list of recorded requests
To clear the list of requests recorded by Make DevTool, click the bin icon next to the search field.
Enable console logging
To enable logging in the console, click the computer icon next to the search field.
When logging is enabled, the color of the computer icon switches to green.
Click the same icon again if you want to disable logging. The icon turns gray when the feature is disabled.
Retrieve the request in the raw JSON format or cURL
To retrieve the raw JSON content of the request, click the Copy RAW icon in the top-right corner of the DevTool's panel.
Similarly, you can retrieve cURL using the Copy cURL button next to the Copy RAW button in the top-right corner of the Make DevTool's panel.
Roles
Owner of the production app: Every app in Make can be owned by a single Make account. The owner of the production app manages the deployment of the new local app version to the Make app.
Developers of the testing apps: Each developer manages their own testing app in Make, which is connected to the local app from the Git repository.
Collaborative development flow
Below is a diagram explaining how developers can collaborate on app development.
Enter a label. This is the app name that users will see in the Scenario builder.
3
A placeholder app ID is generated for you. It will be used in the URL paths and in the scenario blueprint. It should be clear to which app it leads and it has to match (^[a-z][0-9a-z-]+[0-9a-z]$) regular expression.
This value can't be changed.
4
Enter the app version. Currently, you can only create apps in version 1.
5
Enter a description of your app.
6
Enter a color theme for your app. This is the color of the app's modules as seen in scenarios. The theme is in hexadecimal format. For example, the Make app's color is #6e21cc.
7
Enter the language of the app's interface. Most aps in Make are in English.
8
Enter countries where the app will be available. If you do not select any countries, Make will consider the app to be global.
9
Confirm the last dialog.
Your app is in the My Apps view and you can start coding.
A private app can only be used by the author of the app until the app is installed in an organization to which the author and other users have access.
If you want to make your app available to everyone in your organization, create a new scenario with your app and save the scenario there.
In the dialog box, confirm the installation.
A private tag is displayed after your app's name on the app's page.
Deletion of a private app
If your private app is not used in any of your scenarios, you can delete the private app.
Deletion of a module
You can delete a module for a private app only if it is not used in any scenario. If you try to delete a module used in a scenario, you will see a warning dialog with a request to remove the module from the scenario first.
Deletion of a webhook, connection, RPC, or custom IML function
You can delete a webhook, connection, RPC, or custom IML function only if it is not used in any module. If you try to do so, you will see a warning dialog in the lower-right corner.
Public app
If you want to share your app outside of your organization, you need to publish your app to generate an invite link.
Go to your app and open your app's page. Click Publish in the right upper corner.
Once you publish the app, the invite link is generated. You can share it with any other Maker who will then install it in their organization. It doesn't matter where the organization is located (EU1 or US1).
Deletion of a public app
Once the app is published, it is not possible to delete the app or make it private again.
If you wish to have your public app deleted, and we will remove the app from your account.
Deletion of a module, webhook, connection, RPC, or custom IML function
Once the app is published, it is not possible to delete any module or component.
We recommend you change the component's label to indicate that the component should not be used, e.g. [DO NOT USE] My unwanted module. Make sure the module is hidden.
Distribution control of modules
If you actively share your public app via an invite link, you can control the distribution of modules that you have in your public app by making them hidden/visible.
If you hide an already visible module that is currently in use in a scenario, the module will continue working in the scenario. However, the hidden module will not be available in the app selector in a new scenario.
Approved app
Approved apps are available to any user in Make. If you want to have your app available to all Makers, review the to ensure that your app follows best practices.
Once you make sure your app follows our conditions and best practices, you can .
If the app , it becomes available for everyone to use. That mean's that any user on Make can add your app to his/her scenario and use it.
Useful resources
A collection of resources to help you develop your custom app and learn more about using Make.
Resource
Description
Our online course where you can learn all aspects of custom apps development in Make.
Our community dedicated to Makers who develop custom apps.
Create a new app origin
In the app development process, there are situations where it can be highly beneficial to push changes to multiple app origins. This is especially useful when managing different versions of an app, such as maintaining both a testing and a production app.
Create a testing app in Make and name it <App Label> Testing.
3
Go to the makecomapp.json file in the local app repository. Locate the origins array of the collection and enter a new item by copying the code below and editing the values as instructed under the code.
label - the label of the local origin
4
Save the changes in the makecomapp.json file.
You have created a new app origin.
Test your app
To test your app in Make, create a new scenario.
1
In the Scenario Builder, add the Geocodify > Search geolocation module that you have just created.
Note that is has the Private tag.
2
Click Create a connection.
3
Enter your API Key from the Geocodify API.
4
Click Save.
5
Insert the address you want to geolocate, for example: Champ de Mars, 5 Avenue Anatole France, 75007 Paris, France.
This is the Location parameter you set up in the Mappable parameters tab.
6
Click Save to save the module.
7
Save the scenario. A pop-up appears appears asking for confirmation to install the app in your organization.
Click Yes on the pop-up to install the app in your organization.
Click Run once to run the scenario.
8
Open the output to retrieve the coordinates. They are under Output> Bundle 1>response> features> 1> geometry> coordinates.
The coordinates are output this way because you chose to return the response as is, without filtering or customization.
Your app works. Congratulations!
At this point, your module is hidden by default. Even if the app is installed in the organization, it won't appear in the scenario editor for other users until you make it visible.
To let other users see your module, go to the module in the app setup and slide the toggle from hidden to visible.
To learn more about app and module visibility, see the .
Make DevTool
With Make DevTool you can debug your Make scenarios by adding an extra pane to the Chrome Developer Tools. Using this new debugger pane, you can check all the manual runs of your scenarios, review all the performed operations, and see the details of every API call performed. Additionally, you can see which module, operation, or response caused an error in your scenario.
Install Make DevTool
To install Make DevTool:
1
Open the and search for to install the extension.
2
Click the Add to Chrome button. Confirm installation in the pop-up window.
Make DevTool is now installed in the Chrome Developer Tools pane.
Use Make DevTool
To start using Make DevTool, open a scenario in Make, press Control+Shift+I (Windows) or Command+Option+I (Mac) on your keyboard to open Chrome Developer Tools, and switch to the Make tab.
We recommend docking the Chrome Developer Console to the bottom to maintain a better view of your scenario.
There are three main features accessible in the left side of the docked console - , , and .
Compare changes between local and Make
Please be advised that this feature is in beta so it may encounter occasional bugs or inconsistencies.
The Compare with Make tool allows you to compare the code in your local app with the code in your Make app.
With this feature you can easily identify differences, track changes, and ensure consistency between the local and Make apps.
To compare the code of a local component with a remote component, right-click the local component block and select Compare with Make (beta).
The local code is on the right side and the remote code is on the left.
Make app environment
On the Custom Apps page, click on your app to view the Make app environment for your custom app.
Across the top you will see eight tabs.
In this overview, we will focus on the app's main components:
In our step-by-step examples, we use the Geocodify API. You can follow along with our example or you can select a different API to build your first custom app.
In this section, we will walk through the steps to create a custom app.
To set up the VS Code extension you must provide an API key with the appropriate API key scopes.
To generate your API key:
1
Navigate to your profile settings in Make.
2
Click API access in the left navigation.
3
Click + Add token.
4
Set the API scopes for the API key.
The required scopes for the Make Apps Editor are:
sdk-apps:read
5
Click Save to confirm the selected permissions.
6
Copy your new API key to your clipboard and store it in a safe place. This is the only time you can see the whole API key. The API key is required to set up the VS code extension.
You have created a new Make API key. All your Make API keys are listed in your Make profile in the API access section. You can view permissions for all your keys and delete unused Make API keys.
Base
The Base component contains the common settings of the app that are inherited by all modules.
The common settings include:
Base URL: The API base URL used as the main address for all requests to the API.
Authorization: Authentication information and credentials.
Make web interface
The Make web interface lets you create and manage the custom apps configuration directly within the Make platform.
Access the Make web interface
To access the web interface:
1
App logo
Every app in Make has its own logo and color. The combination of logo and color represents the app. With a distinct logo and color, the users quickly see which module belongs to which app.
App theme
The app theme is the module color in hexadecimal format. For example, the Make module's color is #6e21cc.
Documentation guide
The custom apps documentation is divided into topic groups. The topic groups are structured the same way as you would navigate inside the Apps builder in Make.
App components
The describes how to define and configure the basic elements of a custom app. The basic custom app components are listed in the top menu in the custom app configuration, for example: , , and .
Scenario Debugger
The Scenario Debugger shows you the historical logs of your scenario, including the history of the scenario runs. You can search for modules by their name or ID.
Search for modules
To search for the module by name or ID number, enter the search term in the search field in the left panel of the DevTool.
100+ questions regarding custom apps development in Make. You can check if someone already asked the same question and got a response. If not, feel free to post a new question there.
If the local app is shared among multiple developers, the originsarray will contain records for each connection between their local and Make (remote) app. Do not edit the current records to prevent breaking the connections.
Add more API scopes to your API key as needed. You can find descriptions of the API scopes in the Make API documentation.
Error Handling and Sanitization: Same as the Connections component.
If a module doesn’t define a setting, it follows what’s in the Base. However, if a module specifies a different value for the same setting, for example a different error handling directive, this overrides what's present in the Base.
The Base component is the code where you specify the common directives and the common data if needed. When you create a new app, the Base is filled in with default code.
After completing the initial set up of your app, you can use the web code editor to build your app.
The following are helpful features of the editor:
Hints with links to documentation for more information.
A format code button with a label showing the data format. The available data formats are:
jsonc
json
javascript
markdown
Context-aware code suggestions for the jsonc data format. The web code editor gives you hints about parameters or properties you can add to the custom app code. The code suggestions even work for RPCs.
Hints displayed when hovering over the custom app configuration.
Custom app code validation for the jsonc data format. If you misspell a code property name or if you place a property in an invalid code section, the web code editor highlights the error.
A Save changes button to save changes in all editor boxes on the page.
Controls to expand and collapse the code. To view the controls, hover over the space between your code and editor line numbers.
The editor highlights the IML syntax so it's distinct from the rest of the code.
Web code editor keyboard shortcuts
The web code editor is built on the same backend as the Visual Studio Code. If you know VS Code, you will find that some shortcuts also work in the web code editor. Some of the most useful web code editor shortcuts are:
For Windows users:
Shortcut
Description
Ctrl + Shift + H
Show a cheat sheet with selected shortcuts
Ctrl + S
Save changes to all of the editor boxes on the page
Ctrl + F
Search in the editor box content
Ctrl + H
For MacOS users:
Shortcut
Description
Ctrl + Shift + H
Show a cheat sheet with selected shortcuts
Cmd + S
Save changes to all of the editor boxes on the page
Cmd + F
Search in the editor box content
Opt + Cmd + F
For a full reference of the web code editor shortcuts check the official VSCode documentation and the official VSCode shortcuts cards:
Your browser might interpret some keyboard shortcuts differently. For example, the shortcut Ctrl + N creates a new file in VSCode, but in Google Chrome the shortcut creates a new browser window instead.
App logo
To add a logo to your custom app, make sure your logo file meets these requirements:
an image file in .png format
square dimensions: minimum size 512 x 512 px and maximum size 2048 x 2048 px
a maximum size of 500 kB
Make processes the logo file so that:
Areas in the logo that are white or transparent will be displayed as the color specified in the Theme field.
Areas in the logo that are black will be converted to full opacity and will be displayed as white.
Areas in the logo that are in color or are semi-transparent will be displayed as the color between white and the color specified in the Theme field.
If you don't have any tool to edit your file with the logo, you can use the Lunapic free editor.
For creating a transparent layer, you can use the Transparent Background tool that is available in Lunapic.
Examples of how logos are rendered
Example of logos with one color
Example of grayscale logos
Example of color logos
Work with semi-transparent pixels
An app can have only one theme color. You can use multiple transparency levels to give your logo multiple shades of the theme color. You can also create a 3D effect.
Example of apps with multiple transparency levels
Update the app's theme and/or logo
You can update the custom app's logo anytime. Navigate to your custom app settings and click Options > Edit.
If your app has been approved, the change of theme/logo needs to be approved by Make.
After you upload or update the logo or theme color, it may take up to 1 hour for the changes to be propagated across the Make platform.
Component blocks
Every structure element is divided into blocks. Some of these blocks appear in multiple places and share the same purpose, while others do not.
For example, parameters (static or mappable) are available everywhere apart from Base and Functions. Meanwhile, common data exists only inside Base and Connection.
The Make app environment main app tabs correspond to the app components in the documentation.
Open module settings
To open the module settings, double-click the module's name in the list.
View request or response details
To view request or response details, click the operation in the list.
Write IML tests
You can write tests for your custom IML functions. Use the it function and asserts.
functionformatUsername(user){if (
it("should format full name correctly",()=>{
The it function accepts exactly two parameters, the name of the test and the code to run. In this code, we can verify expected outputs using assert.ok() function.
When using IML functions that work with date and time, remember to set the correct timezone in extension settings. The accepted format is the .
For example "Europe/Prague"
Common asserts functions
Function
Description
Run a test
To run a test on a specific function, right-click the function name in the tree and select Run IML test.
The test starts and the output is in the IML tests output channel.
Manage testing and production app versions
When developing an application, to manage the production and test versions:
the developer writes and tests the code with the test application in Make.
the developer tracks changes in the local git repository, pulling changes from the test application.
the developer pushes the changes to the production application from the local testing app when they finish the development and testing.
This process improves the maintenance and stability of the application because the development does not influence the production version of the application. In addition, all changes can be tracked in a git repository, providing a clear and organized development workflow.
Prerequisites
To start the development of testing and production app versions, the following is needed:
The production version of an app in Make. If you already have an app that is in use, use it as the production app.
The cloned production version in a local workspace. , if you haven't done so already.
The testing version of an app in Make. Create a new app in Make, with no content, that will function as the testing version of the app.
Development flow
Below is a diagram explaining how a developer can develop testing and production app versions.
Create a testing version of an app
First, .
Once the origin for the testing app is successfully created, you need to deploy the current code from the app that already exists, which we can call "Production".
1
Right-click on the makecomapp.json file and select Deploy to Make (beta).
2
Select the app origin that represents the testing app.
3
The app is deployed to Make.
Develop the components in the testing app
Now, you can start developing new components or editing the current components in the Testing app in Make, and thoroughly test the app in the Scenario Builder.
Pull changes from the testing app to the local app
Once you finish the development of new changes and components in the testing app, you can .
Deploy the changes from the local app to the production app
To synchronize the changes made to the testing app with the production app,
Deploy changes to Make
You can partially deploy changes in components or new components to Make or the whole app can be deployed.
To deploy only a specific code file in a component to Make, right-click the code file and select Deploy to Make (beta).
To deploy a component to Make, right-click the component directory and select Deploy to Make (beta).
To deploy the whole app to Make, right-click the makecomapp.json file and select Deploy to Make (beta).
In the dialog, select the origin where the changes should be deployed.
The changes or new components are now available in the Make app.
The new app version can be tested in Scenario Builder. If you use testing and production apps, you can deploy the changes or new components to the production after the testing app passes the testing phase.
Use general controls
The following are basic controls in VS Code.
Add a new item
To add a new item such as a module, connection, or webhook, right-click the corresponding folder and click the New <item> option.
Each time the prompt appears, you are asked to fill in information about the newly created item. Follow the indicated prompts to create an item. Your new item appears under the corresponding folder.
Approved app
When Make approves your app, your app becomes available to all Make users in their scenarios. To the users, an app developed by Make looks the same as the app developed by you. You need to take your custom app's management responsibly, since any Make user might be using your custom app in their scenario.
After a custom app is published, Make provides you with a development version of your custom app. You can find the development version of your app by searching for your app in the scenario editor:
The search now has two results:
App
Description
Input parameters
In this section, you will learn best practices regarding different types of input parameters and how to process them.
Static parameters
A static parameter is a value or setting that is fixed, predefined, or constant.
Static parameters are only used for trigger modules.
For all other modules, the Static Parameters tab is no longer applicable and should be left empty. All fields should be added in the Mappable Parameters tab instead.
Modules
In this section, you will learn the naming conventions used for modules in an app.
Overview
In this section, you will learn the best practices for developing custom apps.
Naming conventions
In this section, you will learn the naming conventions used for elements of an app.
Modules names
Module names are unique identifiers for each module in your app.
They are internal names and differ from the that a user sees when using the app.
Module names:
must be between 3 and 48 characters long
must match pattern /^[a-zA-Z][0-9a-zA-Z]+[0-9a-zA-Z]$/
{
// Default request configuration
"baseUrl": "https://api.geocodify.com/v2", // Default base URL for all modules and RPCs.
"qs": { // Default query parameters for all modules.
"api_key": "{{connection.apiKey}}" // API key, which user will provide in the connection as parameter.
},
// Default response handling
"response": {
"error": { // Error handling
"message": "[{{body.meta.code}}] {{body.meta.error_detail}}" // On error, returns error detail
}
},
"log": {
"sanitize": [ // Excludes sensitive parameters from logs.
"request.qs.api_key" // remove api_key query param from logs.
]
}
}
Optional: use version control with Git. To properly track all changes in the local app, it is recommended to use a Git repository, for example, GitHub.
Press Enter to confirm the creation of the component.
If you don't want to create the component, click Ignore permanently/do not map with remote option.
Contains the base URL of the API. Note that it contains the API version.
"api_key": "{{connection.apiKey}}"
Contains the query parameter for authentication.
Note that the apiKey parameter is taken from the Connections component and accessed using connecotin.apiKey.
In custom apps that haven't been approved by Make, it's not possible to keep track of changes as there is no Diff tool available.
If you need to keep track of your changes and you are not planning to have your app approved by Make, you can export the current version of your app every time you make a change using the VS Code extension and store the files on GitHub or any similar tool.
All changes take effect immediately. Before saving a change, make sure it will not negatively affect existing scenarios.
You must ensure that you do not have JavaScript syntax warnings or errors in your custom IML functions in your app.
Otherwise, all scenarios that are using the app will throw the error message about JavaScript syntax and will be stopped immediately.
This affects all scenarios even if they run app modules that do not contain the faulty custom IML functions.
Versioning
If you find out that there has been a new API version implemented, or there have been major changes in the current API made, you should create a new app.
This will ensure that everything is consistent and that there are no breaking changes made in the current app.
assert.throws(fn, [error])
Passes if the function throws an error.
assert.doesNotThrow(fn)
Passes if the function does not throw an error.
assert.match(string, regex)
Passes if the string matches the regex.
assert.doesNotMatch(string, regex)
Passes if the string does not match the regex.
!
user
||
!
user
.
firstName
||
!
user
.
lastName
)
{
returnnull;
}
return`${user.firstName}${user.lastName}`;
}
constuser={firstName:"Jane",lastName:"Doe"};
constresult=formatUsername(user);
assert.strictEqual(result,"Jane Doe");
});
it("should return null if last name missing",()=>{
This is a development version of your app that only you can see and work with. When you update your custom app, the development version of your app will have your changes.
App name without a tag
This is a public version of your app. Anyone can use this version of the app. Changes to this version have to be approved by Make.
If you need to make changes to the app's public version, you have to test your changes in the version labeled custom app first.
When you are done with the updates and testing, review the Updating your apps article for the next steps.
It is important to keep your app up to date and react to API changes on time, e.g. when the API is going to shut down. You also need to fix issues reported by users.
To start editing the source code, find the item to edit in the left menu and click it.
A new editor will appear and the current source will be downloaded from Make.
You can edit it as a normal file. If your app contains some RPCs or IML functions, you will see auto-complete suggestions for them.
Use the shortcut CTRL+S to upload the source code back to Make.
Edit metadata
To edit metadata (for example, to change the label of a module), right-click the desired item and select the Edit metadata option from the menu.
In the prompt, change allowed values. If you don't want to change a value, skip the field by pressing the Enter key.
Change the connection or webhook
To change the attached connection or webhook of an item, right-click the item and select the Change connection (or webhook) option from the menu.
In the prompt, change the connection or webhook. If possible, there will also be an option to unassign the current connection without assigning a new one.
You will also see a prompt to assign an alternative (secondary) connection. The alternative connection should not be the same as the main connection. You can leave it empty.
Delete an item
To delete an item, right-click it and select Delete.
You will be asked to confirm the deletion. If you answer Yes, the item will be deleted from the app.
Deleting items is only possible in private apps. Once an app is published, the capability to delete items within the app is disabled. Learn more about your apps' visibility and the deletion of items.
Output (interface) labels should be clear and consistent so it is easy for users to understand their data and confidently map values between different modules.
Consider the following when creating output labels:
Match terminology exactly. The output label must be identical to the corresponding mappable parameter.
Follow the same order. The output labels and mappable parameters should be listed in the same order in both locations.
Raw values (the actual keys returned by the API) shouldn’t be updated. They must be left as-is so they accurately reflect the external service's API documentation.
Output label examples
Correct
Incorrect
This example from Make AI Toolkit > Simple text prompt follows the standard practices listed above.
This example from Make AI Toolkit > Simple text prompt follows the standard practices listed above. The match the output labels for consistency and clarity.
Apps
Follow these conventions when naming your app:
Start with your brand guidelines as the primary reference.
When uncertain about naming conventions, use title case.
If your app name requires suffixes, use title case for the suffix as well.
Correct
Incorrect
Note
Base URL
Base URL is the main URL to a web service that should be used for every module and remote procedure in an app, e.g. https://mywebservice.com/api/v1.
There might be situations when you need to have a variable base URL. For example, if the web service uses multiple domains you may want to let your users have access to the one they use.
Base URL example: two types of accounts
This is an example of how to handle two types of accounts - sandbox and production.
1
Add a checkbox in your connection parameters that can be checked when the condition is met:
2
Implement a condition in both the connection and the base:
All modules and remote procedures can then use hard-coded "url": "/uniqueEndpoint"
Base URL example: two environments
This is an example of how to handle two types of accounts - eu and us.
1
Set up select in your connection parameters, where you let your users choose from available environments:
2
Map the environment in both the connection and the base.
All modules and remote procedures can then use hard-coded "url": "/uniqueEndpoint"
See the for more information.
Groups
If an app has over 10 modules, the modules should be put into groups. These groups should be named after the entity with which the modules work or the type of job the modules are executing.
Consider the following when you decide the order of groups and modules in your app:
Triggers
All instant triggers
All polling triggers
Generic modules
Sorted in groups, if possible
Example of a group: RECORDS
Typical modules divided by business logic
Sorted in groups (examples: TASKS, DEALS, CONTACTS)
Sorted from the most important to the least important
Other
Examples: Make an API call, Execute a GraphQL query
Example of the order of groups
Example of the order of modules in a group
When dividing modules into groups by business logic, if every group only has one module, do not apply custom grouping. Instead, use the default groups: ACTIONS and OTHER.
Then install the Make Apps Editor. You can get the Make Apps Editor from the VS Code Marketplace or install it in the Extensions tab in VS Code.
1
Click the Make icon on the VS code sidebar. This activates the Map Apps Editor.
If you haven't set up a development environment, you will see a message in a pop-up window.
2
Click the Add environment button to launch the environment setup or execute the command: >Make Apps: Add SDK Environment from the command palette.
3
Fill in the API URL in the next pop-up window. The API URL depends on your Make zone.
For example, the US1 Make zone has the API URL: us1.make.com/api.
If the app you want to access originates from a different zone than your account, enter the app's zone.
4
Fill in the label for the environment in the next pop-up window. Press Enter to confirm the environment label.
5
Enter your that you previously created in Make.
The Make Apps Editor extension restarts with the environment configuration.
A new sidebar appears in VS code with a list of your custom apps and Make open-source apps. If you previously created any, your custom apps are listed in the block My apps. The Make open-source apps are listed in the Open source apps field at the bottom of the VS code sidebar.
The open-source apps code is only available in the EU1 zone.
If your zone is different and you want to access their code, create a new environment with the eu1.make.com/api environment URL.
Switch between environments
In the Make Apps Editor, you can work across multiple environments.
To identify the active environment, check the indicator in the bottom status bar. Click the environment indicator to switch between environments.
Add another environment by executing the >Add SDK environment command again, as described in Step 2 above.
Useful settings
Navigate to Extensions > Make Apps Editor > Extension Settings > Edit in settings.json to add more settings.
Here are some settings for better performance and experience:
Set editor.formatOnSave to true in VS Code settings. Source codes will be formatted automatically when you save them.
Set editor.quickSuggetions.strings to true in VS Code settings. Keyword recommendations will automatically show up while you're typing in IML strings too.
Log out and log in of an environment
You can log out using the >Logout command and log back in with the >Login command.
When you log out, the API key is removed from the settings.json file.
To log in again, you will need to enter your API key.
You can use this flow to change your API key in an environment.
Overview
When you create a custom app, you can use it any time. When you finish developing and testing your app, you might share the app with selected users with an invite link.
If you want to share your custom app with all Make users, we have created an app review process to ensure that your app meets our app standards.
Prerequisites
If you want to provide your app to other Make users, you have to request a review of your app first. Check the app review prerequisites for rules and requirements.
When you request an app review, the Make QA team will check your custom app's code. If your app meets Make's requirements and follows the app development , Make will publish your app and make the app available to all Make users. Otherwise, the Make QA team will contact you with instructions for how you should improve your custom app.
Request app review
After you confirm that your app complies with the prerequisites, you can .
Check the review status
The review process consists of multiple stages. You can of the review in the Flow tab.
Approved app
When Make , the app becomes available to all Make users. After approval, the process of your custom app management changes.
Maintenance of approved app
It is important to and provide support to your app's users.
Connection metadata
We recommend you use the metadata parameter to store the account's name or email. This allows users to easily distinguish their stored connections.
Always save the metadata in the connection if:
the endpoint that can obtain the authenticated user’s information is available, and
the information provided is able to distinguish the connection.
Saving the metadata allows for better identification on the Connections page.
We suggest saving the following information:
Name
Email
User ID
Organization, Company, Location, etc.
When a string is stored as metadata, Make sets a limit of 512 characters.
The value in the brackets after the user's connection name is taken from the metadata parameter.
Base
The Base section should contain data that is common to all (or most) requests. At the minimum, it should include the root URL, the authorization headers, the error-handling section, and the sanitization.
{"baseUrl": "https://www.example.com/api/v1",
Bulk actions
Bulk action modules can perform an action on multiple records in a single call.
To use bulk action modules, the user needs to create an array of records and map the array into the bulk module.
In the bulk module UI, the mapping should always be turned ON by default.
Types of output:
If the response returns a single success / fail, the module should be an action module.
If the response returns an output bundle of success / fail for an individual record, the module should be a search module.
If possible, bulk modules should output the updated range/rows.
For more information for labeling and describing bulk action modules, see the best practices guide to and .
Update your app
When maintaining your app, you might need to apply changes or create a new app version.
Changes and versioning in private/public custom apps
All changes take effect immediately in running scenarios with private and public custom apps. You should take this into account while changing your code.
Changes and versioning in approved custom apps
Every change made to your is visible only to you unless we commit it. You can safely add and test new functions and, when they are stable, you must contact us to check and release your updates to users.
Approved apps
Once an app is approved by Make, the code is locked and it starts to be versioned. When a new change is made in the code of the app, it automatically creates Diff files, which contain detailed information about the changes.
Every change made to the app is visible only to you unless we commit it. You can safely add and test new functions and when they are stable, you must follow our guidelines to have the changes checked and released to users.
The changes you make will become available only after triggering your scenario in your web browser. This can be done by clicking the Run once button, or by selecting the Run this module only option after right-clicking on a module with your mouse.
To make the changes available to all users in Make, you must request . Once approved, the changes will be available to all users. Additionally, you will have the ability to schedule your scenario with the updated modules that were previously run in "run-once" mode.
We recommend you create a new version of the app when there are major changes in the current API and/or there is a new API version available and it is not possible to update the current app without breaking changes.
Modules
In this section, you will learn best practices for the following regarding modules:
In our step-by-step examples, we use the Geocodify API. You can follow along with our example or you can select a different API to build your first custom app.
Now that you have , we recommend completing these first steps before :
Pagination in list/search modules
Debug pagination issues in list and search modules by creating test records and results
If the API supports pagination, it should be implemented. To test that the pagination works as intended, we recommended you set the page size to a low number, if possible.
Create test records
Next, create as many records to equal one page and a few more.
Use the Flow Control > Repeater
Approval of changes
All changes to approved apps require Make approval. Changes will not be available in the public version of the app prior to our approval.
Once you decide that the changes you have made so far should be applied to the public version of your app as well, you will need to request a review of your changes and wait for approval.
To request a review, open the Review tab in your app, and update the form.
Enter links to your updated scenarios with new logs where we can see the functionality of the updated modules, and/or links to new scenarios with logs where we can see the functionality of your new modules.
Then, submit the form by clicking Update review.
Track code changes
Make web interface
After you save a change in an approved app, a new Changes tab is available. On this page, there is a list of all changes available in the particular app.
After clicking on a Diff log, you will see a dialog box informing you about available changes.
For a detailed Diff file, click Show diff button.
Base URL
is the main URL to a web service that should be used for every module and remote procedure in an app, for example: https://mywebservice.com/api/v1.
Make sure that the base URL is a productionendpoint with a domain that belongs to the app itself.
Apps with development or staging URLs, or apps with a domain belonging to a cloud computing service, will not be approved.
Interface
The interface describes the structure of output bundles and specifies the parameters seen in the mapping modal. It should contain the full response from the API, including nested parameters.
You can generate an interface using our .
Dynamic interface according to user-defined fields
Retrieving all fields from the endpoint could be difficult, especially when integrating an ERP or other business-related backend that has hundreds of fields.
Review status
You can check the status of your custom app review in the App flow tab. The App flow tab contains a list of apps under review, their status, and their description. When you click the App flow tab, your browser automatically scrolls and highlights the current review status of your app.
If you have published your app or requested a review for a new app or an app update, you will see the Review tab. You can check the Review Status section at the bottom of the Review tab to see all activity that happened during the review.
Every entry contains 4 columns:
Connection types
If there are multiple types of connection, use parentheses for the connection type specification:
In this example, the additional type of connection is correctly specified with information in parentheses.
Overview
Learn how to use the Make DevTool to debug your app.
During the development of your app, you may experience issues with your app and/or API. Therefore, you will need to use the to debug your app.
Here are some examples of specific debugging issues you may encounter:
Output parameters
In this section, you will learn best practices regarding the interface and how to process output parameters.
After submitting the form, you will receive a new email confirming that we have logged your request. You can find the email by subject's name: "App Update Review: YourApp'sName".
Our senior developers will check your changes. The changes will be either approved or rejected.
If approved, you will be informed by email that your changes have been approved.
If rejected, our senior developer will contact you with further details and/or recommendations for the correct solutions.
Changes that require approval by Make
The following are changes that need to be approved by Make:
changes in the current connection, modules, RPCs, custom IML functions, and webhooks
a new connection, modules, RPCs, custom IML functions, and webhooks
a new theme and/or logo of the app
Rollback of changes in Make
If you need to roll back any changes you have made so far, contact us.
Got to the Geocodify website and click Sign Up to create an account.
2
Enter your details and click Register (or log in Google or GitHub).
3
At the bottom of the Overview page in your dashboard, copy your API Key and store it in a safe place.
You will use the Geocodify API key later, when you create your app.
Review the API documentation
To plan the HTTP call, study the Geocodify API documentation, paying particular attention to the information regarding authentication, the API Base URL, the API endpoints, and the query parameters for the Search API.
API documentation section
Description
Authentication
This section provides authentication details.
For this API you need to use an API key, which should be included in your request query string using the api_key parameter, along with the value that you obtained from the Geocodify website.
API Base URL
This section provides the base URL that you will use to access all the API endpoints.
The base URL is https://api.geocodify.com/v2
API Endpoints
This section lists all the available endpoints.
For this use case, you will use the /geocode endpoint to get the coordinates of a specific address.
Query parameters for the Search API
The documentation doesn't specify the HTTP method, but since you are retrieving coordinates, you should use the GET method.
Do a Postman test
It is good practice to test the HTTP call using Postman before building it in Make. This ensures that everything is working properly and helps you plan the HTTP call setup in Make.
1
In Postman, create a new request and add the necessary elements to make the HTTP call:
module to do this, which also returns the ID of the repeat.
Map this ID in the following module to differentiate the records.
Once the test records are created, you can test your search module.
Test search module
With the help of the ID from the repeater, you can see if the records are ordered and how, and whether the records are correctly retrieved (for example, they are not being duplicated).
Example of array output
In the console, you can also control every retrieved page and its size.
Example of paginated response
Possible pagination issues:
The stop condition limit set by the user doesn't work. Therefore all the records that exist in the account are retrieved (or only the first page if there is also the issue from the point below).
The next page condition isn't set correctly so the next page isn't retrieved, even though it should according to the user's limit and the content of the account.
The next page condition isn't set correctly so the next pages are retrieved, even though all records were already retrieved. They can either be duplicated or without any records. Without looking into the console, you will not see them.
The pagination is not optimized so even though there is a parameter saying “there is no other page to retrieve”, it still retrieves the next page that is empty (developer implements the pagination for offset even though he/she could implement it using the cursor parameter).
The value in the parameter page is too low so there are too many pages being retrieved (= too many calls).
Uncommon: the records are duplicated because the pages are overlapped (1st page 1-100, 2nd page 100-199 instead of 1-100, 101-200).
{"url": "/contacts/filters/{{parameters.filter_id}}","method": "GET","qs": { //"per_page": 100"per_page":10//set value for testing},"response": {"output":"{{item.contact}}","iterate":"{{body.data.contacts}}","limit":"{{parameters.limit}}"},"pagination": {"qs":{"page":"{{pagination.page}}"},"condition":"{{body.data.max_page > body.data.page}}"}}
You will see a comparison view with the changes that have been made.
VS Code extension
After you save a change in an approved app, the app is marked with a * next to the name. Every module with blocks where the changes are available is marked with a * as well.
To view changes, right click the item and select the Show changes option.
You will see a comparison view with the changes that have been made.
When the service has a different domain for each user, the domain should be requested in the connection and then the value should be used in the Base tab.
All of the modules should build on top of the baseURL from the Base section (starting with a forward slash /). It is very unlikely that a single module will need to have a completely different URL than the rest.
The underlined part, which is the same for each module, should be in the Base tab.
Status - Available only with the action "Review status updated". The status of the app's review.
Comment (manual) - A comment with additional information or context.
Possible actions are:
Action
Explanation
App has been published.
You have published the app with the Publish button.
Approval requested.
You have submitted the review form. This action marks the start of the app review process.
Review form updated.
You have updated the review form.
Review status updated.
You can also check your app review status in your email. The email has the subject: "App review: YourAppName". Make keeps all communication about the app review in this email thread.
Clone Make app to local workspace
Please be advised that this feature is in beta so it may encounter occasional bugs or inconsistencies.
To start the development of an app in a local directory or git repository, or start tracking changes in your app, you need to clone the Make app to the local workspace.
Step 1: Open the local folder
Open the folder where you intend to store the app in Visual Studio Code.
Select the section that corresponds to your development setup:
'Local Directory' if you are working directly on your computer's file system
'Git Repository' if you are using version control with Git
The 'Git Repository' section describes the development in the Git repository using the app. However, any preferred or CLI can be used.
Local directory
Open Visual Studio Code and navigate to File > Open Folder.
In the file manager, select the folder where the app should be cloned.
Git repository using the GitHub Desktop app
Navigate to the GitHub Desktop app and open the repository where you intend to store the app.
Click Open in Visual Studio Code.
Step 2: Clone the app to the local folder
Once the repository in Visual Studio is set, you can proceed to cloning the app to the local folder.
1
In the opened window of Visual Studio Code, go to the Make Apps Editor and right-click the app you wish to save to your repository. Select Clone to Local Folder (beta).
2
Read the text in the dialog window and confirm reading by clicking Continue.
3
The app is now cloned to the local folder.
Step 3: Versioning the local app
Versioning is only available if you are using version control with Git.
The following steps describe the development in the Git repository using the app as an example.
The .secrets file with your Make API keys is only stored in the local folder. By default, the file is excluded from the git versioning.
To properly start the versioning of your app in the Git repository:
1
Go to the GitHub Desktop app and open the repository where you deployed the current version of your app. You will see a list of new files.
2
Enter the Summary of the commit and click Commit to main. Or optionally, click Publish branch.
3
The first version of your app is logged. Every new change or a new component in the app will be considered a new change.
Prerequisites
When you want to make your custom app public and share it with all Make users, your app has to conform to Make standards. Following Make app development standards is a prerequisite to get an app review. Make app standards encompass:
Review the following sections to learn more about each prerequisite.
Custom app functionality
In Make, we develop apps to provide value to our users. Your custom app should use a service that Make doesn't integrate yet. All apps in Make require from the user only credentials that are necessary to create a connection to the service API. If you want to make your custom app public, your app functionality has to follow the same principles:
Your custom app uses a web service that is not already available in Make.
Your custom app and its modules have to connect to a web service API. Avoid duplicating the same functionality as iterators, aggregators, or other tools in Make.
Avoid using APIs that have strong dependencies on other APIs, or APIs that function as redirects to other APIs.
Custom app code
When developing a custom app in Make, you should first go through our and apply them to your code. By following our best practices, you will ensure that the review and publication process of your app is as smooth as possible.
Before sending an app for review, check that:
The base and connection have of sensitive data, e. g. API key or token.
The base and connection have .
The and connection use an endpoint in the app's API.
The items above are mandatory for each app.
Testing your custom app
After you check the code of your custom app, you must create test scenarios to show that the custom app works. Use each module of the custom app in at least one test scenario.
Make sure that the testing scenarios and their execution logs don't contain personal or sensitive data.
Best practices for test scenarios
Do not use scenarios with another app's webhook.
Try to put all of the app's modules in one scenario and run the scenario without errors. Connect the app modules based on the object the modules work with or the action the modules perform.
For example, Create a Task > Create a Subtask (in order to create a subtask, the task has to be created first).
Put the search and list modules at the end of separate scenario routes to avoid multiple runs of the subsequent modules.
Run your search and list modules to have logs with pagination. If you don't know how to test pagination, .
Create a separate scenario that produces an error message. Run the scenario to get an error:
Run the test scenarios right before you request the custom app review and every time you fix issues. The scenario execution logs have a data retention limit and the reviewer won't be able to access old logs.
Remote Procedure Calls
Use the Make web interface to debug Remote Procedure Calls (RPCs)
To find the RPC debug tool:
1
Navigate to the Custom apps area.
2
Select your custom app from the list.
3
Click the Remote Procedures tab.
4
Select the RPC you want to debug.
5
Click Test RPC.
RPC page
Compare the tabs below to learn how to access information about your RPCs in Make.
Communication tab
After creating a new RPC, you can modify the default template in the Communications tab for your needs.
Inside RPC, you can use the relative path and the full form of the URL.
However, we advise using the relative path across all your RPCs and modules.
A relative path is added to the "baseUrl" that you need to specify inside the app Base.
Parameters tab
By default, the Parameters tab is empty. Here you can add any parameter you need. You can also add mappable parameters from a module. .
Any parameter created inside an RPC will be available only for RPC debugging. It will not be visible inside your modules or inside scenarios.
To preview and test parameters, click on the Test RPC button.
RPC debug tool
The RPC debug tool works the same way modules do.
Specify the connection and other fields (parameters) if needed.
Click the Test button.
The call, which you specified before in the RPC communication, will be executed.
You will see the output that you specified in the RPC communication.
If you specified output as "label" and "value" (with the purpose of using it inside a Select parameter), do not expect to see the full server response there.
Sometimes you might get an empty array as a response. If that's not the response that you expected, check that you correctly specified the path to the object, which you use inside iterate.
Debug RPCs in the dev console
Sometimes you may need to look into the request you're sending and the response from the API.
You can see more details about the RPC you're testing by opening your browser's dev console: Network tab.
The debug values show the request being sent and the response received by the API.
Editable connection
We recommend allowing users to edit their connections after they create them. Updating a connection simplifies scenario and user credential maintenance when there's a change in the user's organization.
To allow users to edit a connection:
1
Go to the Parameters tab of the connection.
2
For each parameter with a value that should be kept secret, make sure that it is marked as type password.
Parameters with the password type don't show the original connection's parameter value, while the parameters with the text type show the value used by the current connection.
3
Add the editable: true property for each parameter in the connection.
Exception: If the service provides each user with a unique URL or domain, the corresponding URL or domain parameter must be non-editable to prevent any potential credential leaks.
Custom IML functions
Debug custom IML functions with a variety of tools
To debug your IML functions, output the code and use a tool of your choosing.
Output a message to the dev console
You can use debug inside your IML functions to print a message or mid-results of your code.
During the function execution, debug messages are visible inside the console of your browser.
To open the developer console in Google Chrome, open the Chrome Menu in the upper-right-hand corner of the browser window and select More Tools > Developer Tools. You can also use Option + ⌘ + J (on macOS), or Shift + CTRL + J (on Windows/Linux).
By using debug() you can understand what data you are manipulating inside a function.
Debug the JavaScript snippet
To debug the output, you can use a variety of tools. Search online to find a JavaScript debugging tool that you prefer.
Here are some to choose from:
You can use this code to test the functionality of the JavaScript debugger to see how it works.
429 error handling
An error with the status code 429 is an API rate limit error.
However, the default module error type for an error code between 400 - 500 is always a RuntimeError.
There are advantages to handling a 429 error as a RateLimitError instead.
RuntimeError handling vs RateLimitError handling
In a scenario with scheduling turned on, if one of the scenario modules throws a RuntimeError, your scenario will break and retry to run according to the number of consecutive errors from your scenario settings (the default is 3 times).
If the number of consecutive errors is consumed, the scenario scheduling will be switched off and you will need to manually switch your scenario scheduling on again.
To prevent this, use the module error type RateLimitError to handle the 429 error. This error type has the same functionality as ConnectionError and returns the warning message instead of the error sign.
The advantage of using RateLimitError is that, instead of using the number of consecutive errors and then switching the scheduling off, the retries continue with .
For example:
A scenario with scheduling turned on suddenly has one module throw a RateLimitError.
It will retry after 1 minute.
If it throws the RateLimitError again, it will retry after 2 minutes.
Modules
In Make, you can set up , each with a specific function.
In this tutorial, you will set up a Search module to retrieve the coordinates of an address.
The Search module sends a request and returns multiple results. Use this module when you want to let users search for records.
Inside the Search module component there are five tabs:
Communication
Request app review
Once you make sure that your app meets Make's and follows Make's , you can request an app review:
Request a review
To request an app review:
1
Base
Base serves as the repository for all components that are common across all modules and remote procedures. Any elements placed in Base will be inherited by each module and remote procedure.
These components are:
Polling triggers
A polling trigger checks for new data in a service account since the last scenario run, based on the scenario's schedule.
The polling trigger sends a request to the service. If new data exists, the scenario runs and you see the data in the module’s output as bundles. If not, you see no bundles.
Use a polling trigger only if the results:
consist of either a numeric ID or a date as the identifier, or
Authorization and sanitization
The Base section should also have and that is common for all modules. The authorization should use the API key, access token, or username and password entered in the connection. The sanitization should hide all these sensitive parameters.
Module types
Module types
Modules should be associated with the correct type depending on their functionality.
Detailed descriptions of different types of modules can be found in our documentation as well as in the .
In the pop-up window, click "Yes, I trust the authors" option.
The current local directory in Visual Studio is set.
In the pop-up window, click "Yes, I trust the authors" option.
The current repository in Visual Studio is set.
Enter the workspace subdirectory name where the app should be cloned to.
If the subdirectory doesn't exist yet, it will be created. The default subdirectory is set to src. Click Enter.
If you are going to store more than one app in the repository, you can create a subfolder by using the src/app-name path, where the app-name is the name of the app folder.
4
A dialog window asking whether common data should be included or not will pop up.
Exclude (more secure) - Select, if your app contains sensitive data, such as Client ID and Secret. Common data will not be stored in your local workspace or a repository.
Include (for advanced users only) - Select, if you want to store the common data in your local workspace or a repository. Be aware that storing common data outside of Make could potentially expose the app to vulnerabilities.
Information on what the engine needs to do to manage the API call (call the endpoint, process the response, pagination, etc). Remember that the following elements are inherited from the Base: base URL, error handling, log sanitize. If something needs to be changed, you can write it here, and it will override the settings of the Base component.
Static parameters
Input parameters that the user cannot map from other modules. They are only used for polling triggers, which don't have mappable parameters.
Mappable parameters
Input parameters in the interface that the user can either enter manually or map from the output of other modules.
Interface
Labels of the module's output added to make the output more straightforward and easy to interpret. By specifying it, there’s no need to first run the module in your scenario to get the output structure for mapping the elements.
Samples
Examples of data to help the users set up the module.
Create a Search module
To create a new module for your Geocodify app:
1
In the Modules tab, click Create Module.
2
In the pop-up window, fill in the module details. The chart below contains the values to use for your Geocodify app.
Field
Values
3
Click Save.
4
Click the Mappable Parameters tab for your new search module.
5
Copy and paste the following code:
Mappable parameters
Description
6
Click Save changes.
7
Click the Communications tab for your new search module.
8
Copy and paste the following code:
Specification
Description
9
Click Save changes.
Leave all the other tabs as they are, including the Interface. This means that you won't apply any filtering or customization to the output, but all the information from the API will be returned as is.
Remove the test modules or test connections before you publish an app. When your app is public, you can't delete its modules, connections, or other components.
2
Navigate to your custom app's code and click the Publish button.
Once you publish your app, you can't unpublish it. See the app visibility section for more details.
3
In the Modules tab, click the switch to set the visible status of each module in the app that you want to publish.
4
You will see a new Review tab in the top panel.
5
Complete the form on the Review page.
Add a link to the API documentation of the service for which you are creating a custom app.
Add a link to scenarios with the custom app modules. Check the testing scenarios section in the App review prerequisites.
6
Click the Request review button at the bottom of the page.
The data you submit is sent to Make QA developers for review. At the top of the page, the Request review button changes to Review process started and becomes inactive. Also, the app status changes to pending approval.
Once you request the app review, Make sends you an email with the subject: "App review: YourApp'sName". If you have any questions or additional information to share, reply to the email.
Each time you update your app based on reviewer feedback, run your scenarios to generate new logs.
If you need to edit your links, you can update your form and submit the changes by clicking the Update review button
Review process
The review process contains three phases: form submission, automatic review, and manual review.
Form submission
Once you hit the Request Review button, you will receive an e-mail containing a link to our form where you will be prompted to share the following information about you and your app:
Developer information - What is your relationship with the vendor of the API service?
Partnership contact - Applicable for ISV. The details of a contact person or team on your end responsible for partnership-related discussions.
Support contact - Details of the contact person or team that should be contacted in case of any app issues reported by users.
Categories and subcategories of your app - The categories and subcategories in which you wish to have the app listed on the .
Logo of your company - Applicable for ISV. The logo should appear on the app's landing page on make.com.
URL to the service - The URL leading to your website that should appear on the app's landing page on make.com.
Trademark compliance - Confirm that you have obtained all necessary written licenses for any trademarks, service marks, or brand names used in your app and that you understand that unauthorized use of third-party intellectual property is grounds for immediate rejection or removal without prior notice.
External Service T&C compliance - Confirm that the app and its data-handling practices comply with any applicable terms and conditions and API policies of all integrated third-party components of the app. Also, confirm that you agree to indemnify and hold Make harmless for any claims, damages, or legal fees arising from your breach of this form or any third-party terms applicable to the app. Make reserves the right to audit or disable any app reported for violation of any terms and conditions applicable to it.
Upon completing the form, you will receive feedback from the automatic review.
Automatic review (beta)
Your app is first reviewed by our application. The automatic review checks for common issues and generates a PDF file with the issues found.
The PDF file with feedback from the automatic review is sent to the existing app review email thread.
The automatic review is in beta and is still in the process of improvement. Therefore, there might be inconsistencies.
Manual review
Once your app passes the automatic review, it is reviewed by our QA engineer who makes sure that your app follows our best practices and is user-friendly.
The QA engineer shares the feedback in the existing app review email thread.
Once your app successfully passes the manual review, your app is listed in our planned release. You will be informed about the app approval as well as the app release.
Base URL is the main URL to a web service. It should be used for every module and remote procedure in an app.
headers
Object
Default headers that every module will use.
{"baseUrl":"https://my.api.cz/2.0",
Everything specified in the base is inherited by all modules and RPCs. You can see the baseUrl, authorization being sent in headers, an error handler and sanitization. Those parameters will be used across all the modules and RPCs.
Common data
Once the app is approved, the common data gets locked and it cannot be changed due to security reasons.
Common data can be accessed by the common.variable IML expression.
Common data is stored in encrypted form in Make.
The secret is defined in the common data. Then it can be used in base and in all other communication objects inside modules and RPCs. Once the app becomes approved, it will not be possible to change the secret.
By default, requests time out after 40 seconds. If your API typically performs tasks that
exceed this duration, you can increase the timeout up to a maximum of 300 seconds (or
300,000 milliseconds).
To adjust the timeout, specify the desired duration in the base and common data settings
(in milliseconds). This timeout will apply to the entire custom app. We recommend the
following approach (example using a 300 seconds timeout):
The timeout should only be extended if the API performs legitimately
resource-intensive operations, such as video/image processing, file conversion, or
complex AI computations.
the results can be sorted or defaulted in descending order.
Using unordered or asc order in a polling trigger may not work due to a 3200 pagination limit, which could result in the trigger not returning new items.
However, if the API accepts filtering and gets results only after a specified numeric ID or date, this could reduce the number of items.
Epoch
The Epoch tab of a polling trigger defines the look of the Choose where to start setting so a user can select a point in the past from where the trigger should start to process data.
Use the limit parameter to restrict the number of results returned in the RPC, to avoid issues should the user have too many objects.
The limit parameter should be a static number that should be equal to, at maximum, 300 or 3 times the number of objects per page.
The code is missing a limit parameter.
The code includes a limit parameter.
API endpoint requires from and/or to date parameters
Some API services require date parameters that define the interval of records to be retrieved, for example from and to, fromDate and toDate, etc.
In this case, it is important to handle the date parameters correctly.
In this module example, the From and To parameters are required.
Since triggers don't allow mapping/functions, the user has to hardcode the From and To dates. Therefore, Make will always request the same interval of records.
In this module example, there aren't any required From or To fields.
The mapped data.lastDate IML variable is available to the user in the Choose where to start setting, defined in the .
The behavior of the supported options:
The List campaigns module in this example is incorrectly identified as an Action module.
The List campaigns module in this example is correctly identified as a Search module.
Universal modules
Each app should have a universal module. This module allows users to use API endpoints that are not supported, using their connection created to the app.
More about universal modules can be found in our modules documentation.
When building the Connections component, you will set up the form that appears when the user clicks Create a connection in a module.
You will define the parameters the user has to input and how these are handled by the apps engine to verify the authentication parameters.
The Connections component defines the details needed to authenticate with the API and ensures everything works when the user enters their credentials in the scenario editor.
It has three main jobs:
to get any relevant information from the user that adds the connection (credentials, API key, etc.)
to process the authentication
to check if the authentication works by making a test API call
You set this up in the Communication tab, while the Parameters tab holds the information the user needs to provide.
The code in the Communication tab is divided into three sections:
Request
The first part defines the HTTP request the app uses to validate the user's credentials.
This call happens when the user enters their credentials and clicks Create a Connection.
The usual way to validate credentials is to call an API endpoint that returns user details. If the API doesn't provide this, you can use a generic endpoint to validate the credentials by making a GET request to ensure that the authentication is correct. The default HTTP method is GET, so you don’t need to specify it.
Adding this validation call is a good practice to make sure the credentials are correct.
Response
The second part contains directives on how to handle the response:
metadata: Stores the user details that are returned by the API call and displays them next to the connection in the Connections page, for ease of identification.
Log
The third part contains instructions regarding the log and the information recorded in it:
sanitize: specifies which information shouldn't be recorded in the logs for security reasons.
The code in the Parameters tab contains only one parameter: apiKey. This is the information the user has to provide in the scenario. Note that the parameter is used in the Communication tab using the notation {{parameters.name}}.
Set up connections for your Geocodify custom app
To set up the connections for your custom app:
1
In the Connections component, click Create Connection.
You can use RPCs to retrieve dynamic options in a field to clarify the expected input for a user. For example, selecting a country in a dropdown could trigger an RPC to retrieve corresponding states or cities.
In this example, the Priority field provides the expected values (Low, Medium, High, Urgent). In mapping mode, the user has to enter or map the option's ID instead of selecting a value.
In mapping mode, the user has to enter or map the option's ID instead of the label.
RPCs are also helpful when a user only needs to understand the functionality of the module, primarily the list of available parameters in the interface. In this case, the aim is not to offer a complete list of all items, but a sample of the last 100 or so items the user could select from when testing the module or setting up the scenario for the first time, before replacing it with mapped data used in automation.
Mode edit
Mode edit for Get, Update, and Delete modules
When adding an RPC to a Get, Update, or Delete module, it is required to add:
to the code so when a user first opens the module, they will be able to immediately map the value. However, if needed, they can also switch to get the value from an RPC.
Mode edit for Search and List modules
For Search and List modules, the use of mode edit depends on the hierarchy level of the entity. If the entity is higher in the hierarchy, for example a "customer" or a "deal" and there are not many RPCs in the input, the mode should not be set to "edit".
However, if the entity is low in the hierarchy, for example "email attachment", it should have the mode set to "edit" since the user will probably not want to list attachments of a single email repeatedly.
Mode edit for Create modules
Create modules should not have the mode set to "edit" unless it contains a very large number of RPCs in its input. This is because preloading a large number of RPCs would significantly increase the wait time for the user.
Pagination and limits
Just like modules, RPCs can use pagination to show more records than just the ones on the first page. However, limits should be also set how many objects the RPC shows to limit the load time.
The limit should be between 300-500 if the API returns 100 or more objects per page. If the API returns less than 100 per page, then the limit should be 3 times the amount of objects per page.
For example, if the API returns 25 records per page, the limit should be 75. You can also set a condition for the pagination to stop further requests when no more data is needed.
Additional OAuth scopes
The Make an API Call module connection will not work if the required scopes of the endpoint are not in the OAuth connection. To correct this, allow users to define additional scopes when they create a connection.
Make an API Call parameters: non-editable connection
{"type":"banner",
If you encounter the warning String is longer than the maximum length of 256. , wrap it in an RPC.
Make an API Call parameters: editable connection
Connection parameters
Connection communication
Search modules
are modules that returns multiple results, as opposed to that return only a single result.
If you want to retrieve all users who are registered on your service, you can't use an action module because it only returns one result. Instead, use a search module.
For example, if you call /users, you will get a list of users in body.data.
Error handling
It is important to implement in your app so your users clearly understand the cause of the error.
Each service sends an error message when an error occurs. This usually happens when the request has wrong parameters or values or when the service has an outage.
When an error occurs, the module should indicate the error as well as a detailed message that can then be used in filters. The message should be clear and user-friendly. For example, instead of "Error: contact_not_found", your message should be "[404] The specified contact was not found."
The error handling code should correspond to the structure of the server response.
Parameter labels
Static and mappable parameter labels should be clear and easy for users to understand. Consider the following when creating labels:
Give a short description (1–3 words) of the requested input.
Match the terminology that users see in the third-party’s UI, not the API documentation.
Initial setup in Make
In our step-by-step examples, we use the Geocodify API. You can follow along with our example or you can select a different API to build your first custom app.
To set up your custom app for Geocodify:
1
Log in to Make and go to the Custom Apps section.
Terms of approved app maintenance
After Make approves your custom app, any Make user can use your custom app. You have to maintain the app to keep the app working. That involves:
updating the custom app when a relevant part of the service API changes
checking feature requests on the Make Idea Exchange regularly
If you actively maintain the custom app, users can use the app with confidence. The users don't have to worry that their scenarios might stop working with new service updates.
Fix reported issues
When a user reports an issue, Make validates the issue. If the issue is valid, we contact you via email with a request to fix the reported issue.
At Make, we make sure that everything works for our customers. If you do not fix the validated issue or stop communicating with Make, we will access the app's code and fix it for the app's users.
API checkup
Make sends you a request to update the custom app's API checkup every six months.
The Make API checkup helps you and Make to:
watch changes in API and API's docs
make sure the app is up to date
manage deprecations of endpoints or API
manage new versions of the API
inform users about shutdowns and other cases in advance
Please ensure your integration is kept current with the latest API.
If the Make integration is not actively maintained, we reserve the right to assume ownership of the custom app to ensure uninterrupted service for its users.
We recommend you check the list of feature requests for your app regularly and respond to them. You can use the search bar for listing requests which mention your app.
"text":"Your connection must contain the required scopes for your API call. If you receive an error, create a new connection with the necessary Additional scopes.",
"theme":"info"
}
/// Defines "location" as module input parameters.
[
{
"name": "location_info", // Makes value accesible via "{{parameters.location_info}}".
"label": "Location", // Sets the user friendly label visible in the module
"type": "text", // Sets the type to text.
"help": "Type the location you want to geolocate", // Sets the help text with an example under input field in the module.
"required": true // Indicates this parameter is mandatory.
}
]
{
// Request to API endpoint.
"url": "/geocode", // Endpoint relative to base URL
"method": "GET",
"qs": {
"q": "{{parameters.location_info}}" // Required query parameter. Parameter "location_info" is defined in Mappable parameters.
},
// Response handling
"response": {
"output": "{{body}}" // Return the body of the response
}
}
{
"type": "banner",
"text": "Your connection must contain the required scopes for your API call. If you receive an error, edit your connection with the necessary Additional scopes.",
"theme": "info"
}
[
{
"name": "additionalScopes",
"label": "Additional Scopes",
"type": "array",
"spec": {
"type": "text",
"label": "Scope"
},
"help": "Additional scopes are required for the __Make an API Call__ module. For details, see the [App Name API Documentation](https://link-to-doc). Add scopes for every API call you will make with this connection.",
"labels": {
"add": "Add scope"
}
},
{
"name": "clientId",
"type": "text",
"label": "Client ID",
"advanced": true
},
{
"name": "clientSecret",
"type": "password",
"label": "Client Secret",
"advanced": true
}
]
error: Contains instructions on the information that is displayed when an error occurs to help the user understand the issue. Lets you set the type of error and the message that will appear if the API request fails.
Label: Geocodify API key
Type: API Key
3
Click Save.
4
Select the Parameters tab and remove the default parameter that is present.
5
Copy and paste the following code:
Parameter
Description
name
Required. Internal name of the parameter. Use it when you want to retrieve the parameter
label
6
Click Save changes.
7
In the Communication tab, remove the code present.
Since search modules return multiple results, they should contain pagination and iterative directives.
An action module should never contain pagination or the iterate directive. To return multiple objects, create a search module instead.
Pagination parameters
The pagination section should only contain parameters that relate to pagination. These will be merged with the rest of the parameters defined in the qs section, so there is no need to define them all again.
The pagination directive contains "since", "until" and "limit" parameters that are already defined in query string ("qs").
The pagination directive correctly contains only the "offset" parameter.
Page size in pagination
The page size should be as large as possible to reduce the number of requests, minimize delay, and avoid hitting the rate limit.
The number of results to display in each page (default = 20; max = 100).
offset
The starting point for the result set of a page. This is a zero-based index. For example, if there are 39 total records and the limit is the default of 20, use offset=20 to get the second page of results.
Search modules should allow users to limit their output (how many bundles they return).
This can be achieved by setting the limit parameter in the response.
By default, this parameter is added to the trigger (polling) modules and should be required. In search modules, this parameter should NOT be required so if a user leaves it empty, the search modules return everything. Its default value should be set to 10.
The limit parameter should not be set to "required":true (except for polling trigger modules).
The limit parameter should never be set to "advanced":true.
In this example, the JSON response has the following format in cases where something goes wrong:
{"error":{"
Here's how the error section should (and should not) look:
"response": {"error":
The error object in this example contains the code and message fields. It is also important to show the status code of the error. This can be accessed using the statusCode keyword. In the case of HTTP error 400, for example, the error message could look like this:
[400] The company with the given ID does not exist. (error code: E101)
"response": {"error":
The error object in this example contains the code and message fields, but not a text field.
Common error messages
4xx: Client Error
4xx errors indicate something wrong on the client side.
5xx: Server Error
5xx errors indicate something wrong on the side of the third-party service.
Handling status code 200
Sometimes the API returns status code 200 with an error in the body. In this situation, use the valid directive, which tells whether the response should be processed or an error should be thrown.
It is NOT possible to use specific HTTP code 200-399 error directives without the using valid directive.
Sometimes the API returns status code 200 without errors to an incorrect request. This can happen, for example, if the Get a/an [item] module is developed based on the search endpoint and not based on a separate endpoint. This may be the case if a separate endpoint for that action is not implemented on the service’s side.
Incorrect example of the search approach for a Get module:
If an incorrect ID is provided, this will return an empty response. It is important to validate the call's response and, if empty, return a formatted error message.
Correct example of Search approach with validation:
In this case, we mark the response as invalid if it has no ID, as the ID should always be returned with other data.
Note that this approach will trigger error handler from the Base, so make sure you have meaningful error messages there.
Proper nouns and trademarks. For example, names of people, companies, products, or other proper nouns
Official or trademarked terms
Acronyms. For example, Content ID, File URL
Avoid punctuation and articles (the, an, a).
Use plain terms rather than API formats.
Parameter label examples
Correct
Incorrect
Note
Custom data parameters
The Custom Data Parameters
First word capitalized, the rest in lowercase.
Do not use the article ‘the’.
Submit form
Submit Form
First word capitalized, the rest in lowercase.
Mappable parameter labels should match the output labels for consistency and clarity so it is easy for users to understand their data and confidently map values between different modules. Output labels and mappable parameters should be listed in the same order in both locations.
Parameter label for fields with a Map toggle
For select fields, the label of the field should be dependent on whether the Map toggle is ON or OFF by default.
If the Map toggle is ON by default, the field label should contain "ID".
If the Map toggle is OFF by default, the field label should NOT contain "ID".
2
In the upper-right corner, click + Create app.
3
In the pop-up window, fill in the app details. The chart below contains the values to use for your Geocodify app.
Field
Value
Description
Name
geocodify-app
4
Click Save.
You can now see your custom app listed on the Custom Apps page where you can view the Make app environment to continue with the setup of the connection, Base, and module for your app.
Module descriptions
Module descriptions should emphasize what a user can achieve with the module, not necessarily the process it takes to perform the task. Write the description in the third person and capitalize only the first letter of the word in the description.
There are 3 categories of information that the descriptions can include:
End result (mandatory): Clearly describes what the module achieves.
Restrictions/Requirements (when necessary): Include additional information if there is any other additional information that provides clarity for the user regarding what the end result will be, or specifics of the module.
Additional information (when necessary): Include additional information if the module has any requirements, such as a specific plan on the third-party or in Make, or requires a specific setting on the third-party side.
Watch modules
Watch modules watch for new data in a service and return it. They are trigger and instant trigger (webhook) modules.
The general format for trigger module descriptions:
Watch [items]
Triggers when a/an [item] is ...
Module name format
Module description format
Module name
Module description
Action modules
Action modules write data into a service, modify data in a service, or retrieve a single result.
The general format for action module descriptions:
&#xNAN;[Action] a/an [item]
[Actions] a/an [item] + details …
Module name format
Module description format
Module name
Module description
Search modules
Search modules retrieve data from a service and allow for one or more results.
The general format for search module descriptions:
&#xNAN;[Action] [items]
Returns a list of [items] + details ...
Module name format
Module description format
Module name
Module description
Universal modules
Universal modules are modules used to make an API call or query when a pre-built module does not exist.
The general format for Make an API call module descriptions:
Sends a custom API call to {app name}. You can use this to call endpoints that aren’t covered by existing modules.
Module name format
Module description format
Module name
Module description
Processing of output parameters
Response output
A module's response output should be defined for the case when a request is fulfilled successfully. The output definition should not contain error messages (this belongs in the Base section's error handling) nor the additional metadata which may arrive bundled with the actual response information.
No matter the module type, the output shouldn't be defined like this:
The best approach is to return the API response as it is. In many cases, the response varies based on the user who is using the app, as responses can contain different custom fields. If the response returned is unchanged and if all the parameters still aren't described in the output parameters, Make will automatically suggest additional parameters from incoming data.
Search modules
Action modules
Delete unnecessary output data
Your output data might include information related to a backend process. While you may use this information for error handling, for example, it's not necessary to pass this information to another service.
Sending superfluous information might cause confusion. For example, a 'status' value of a task could be easily mistaken for the 'status' of the processing of data.
To avoid confusion, structure your output in a user-friendly format and delete unnecessary output data.
Parse dates
You should always parse datetime in the module output with the following exceptions:
No date, only time. For example, 13:30.
No time, only date. For example, 2024-01-01.
With both date and time, but no time zone. For example: 2020-06-08 12:37:56
Examples
Pipedrive
Part of the response from Pipedrive API /activities :
from Pipedrive
Field
Parse?
Reason
Virtuagym
Part of the response from Virtuagym API /api/v0/activity:
Field
Parse?
Reason
Flatten nested outputs
Deeply nested outputs result in undesirable UX when the user maps the values.
Consider:
creating a mappable version of the key-value pairs, and
flattening unnecessary nested collections.
See an additional example of.
Error handling
Handling errors returned from HTTP API endpoints
Since any API endpoint can return an error during an execution of a scenario, Make provides methods to handle errors and keep scenarios reliable and functional.
All apps in Make should implement error handling to ensure that users understand the cause of any errors. Error handling should always be customized to the type of error and how the API returns the error.
Read more about error handling in the Help Center:
When the service returns an HTTP error, it is not possible to evaluate it as a success.
Error handling: 401 error
With error handling, details of the error are available and the user will know how to solve the problem.
HTTP 4xx and 5xx error handling
When the response returns a 4xx or 5xx HTTP error code, this is automatically considered an error. If the error directive is not specified, the user will only see the status code that was returned. You should customize the message shown to the user with the error or error.message directive.
HTTP 2xx and 3xx error handling
Some APIs signal an error with a 200 status code and a flag in the body. In this situation, use the valid directive to tell the user if the response is valid or not.
Custom error handling based on status codes
You can further customize what error message will be shown to the user based on the status code. To do this, add your status code to the error directive.
Available error types
When handling an error, you can specify the type of the error.
Error type
Description
Error handling with type
Tools
The Tools section of the Make DevTool has useful features that can help you build your scenario.
Focus a module
Opens settings of the selected module.
The module ID is the number you see in the Scenario Builder next to the name of the module. The same apps used multiple times in one scenario will have different IDs for each module.
Manage breaking changes
When you make changes in an app, make sure your changes will not break existing scenarios.
Ideally, the removal of the connections, modules, and fields should be announced to the users in advance.
Contact the with a request for email notification to users.
Common breaking changes
App's Element or Block
[
{
"name": "apiKey",
"label": "API Key",
"type": "password",
"help": "Enter the API Key provided by Geocodify. For details, see the [Geocodify account documentation](https://geocodify.com/account).",
"required": true,
"editable": true
}
]
{
// Request
"url": "https://api.geocodify.com/v2/geocode", // Absolute URL to the API endpoint which validates credentials
"qs": { // Query parameters
"api_key": "{{parameters.apiKey}}" // Authorizes user by api key, provided by user during the connection creation.
},
"response": {
"error": { // Error handling
"message": "[{body.meta.code}}] {body.meta.error_detail}}" // On error, returns error details
}
},
"log": {
"sanitize": [ // Excludes sensitive parameters from logs.
"request.qs.api_key" ] // Omit query string apy_key
}
}
{
"url": "/items",
"method": "GET",
"qs": {
"id": "{{parameters.itemId}}"
},
"response": {
"valid": {
"condition": "{{body.items[1].id}}",
"message": "Item with the given id does not exist."
},
"output": "{{body.items[1]}}"
}
}
code
"
:
"
E101
"
,
"message":"The company with the given ID does not exist."
Searches module(s)' values for the specified term.
Field
Description
Keyword
Enter the term you want to search for and click the Run button. The numbers in the output are IDs of modules tha contain the term you have entered.
Use only values
Enable this option to only search in module fields' values. Disable this option to also search in module fields' names.
Get app metadata
Retrieves app metadata by the app's module name or ID. This is useful when you need to get the app version used in your scenario for technical support or development of the app.
Copy mapping
Copies values from the source module to the target module. When the source and target modules are specified, click the Run button to copy the mapping.
Field
Description
Source module
Select the module or enter the module ID of the module from which you want to copy field values.
Target module
Select the module or enter the module ID of the module into which you want to insert the source module values. The values in the target module will be overwritten.
Copy filter
Copies the filter settings from the source module to the target module. The copy action is performed on the filter placed on the left side of the selected module. When the source and target modules are specified, click the Run button to copy the filter.
Field
Description
Source module
Select the module or enter the ID of the module from which you want to copy filter values.
Target module
Select the module or enter the ID of the module into which you want to insert the filter values from the source module. The values in the target module will be overwritten.
Preserve fallback route setting
If enabled and the source filter is set as the fallback route, then the target filter is also set at the fallback route.
Swap connection
Duplicates a connection from the source module to every module of the same app in the scenario.
Field
Description
Source module
Select the module or enter the ID of the module from which you want to duplicate the connection and set the same connection for every module of the same app in your scenario.
Swap variable
Searches for specified variables in the scenario and replaces them with a new variable.
Field
Description
Variable to find
Select the variable you want to replace from the module in your scenario and copy it to this field. You can also drag and drop the variable into the field.
Replace with
Copy and paste, or drag and drop the variable you want to use instead of the variable specified in the field above.
Module
Select the module in which you want to replace the variable. If no module is selected, the variable will be replaced in the entire scenario.
Swap app
Replaces the selected app version in your scenario with another app version.
Before swapping, make sure that the version you've selected supports all the modules and functions you might need for your scenario.
Base 64
Encodes the entered data to Base64 or decodes Base64. This is useful when you you want to search for particular data in the encoded request. When the input is specified, click the Run button to perform the action.
Field
Description
Operation
Select whether you want to encode the data from the Raw Data field to Base64 or decode Base64 to raw data.
Raw Data
Enter the data you want to encode to Base64 or the Base64 you want to decode to raw data, depending on the option selected in the Operation field above.
Copy module name
Copies the name of the selected module to your clipboard. When the module is selected, click the Run button to copy the module's name.
Field
Description
Module
Select the module whose name you want to copy.
Remap source
Changes the mapping source from one module to another. You can do this for an existing module in your scenario as well as a new one. Click the Run button to perform the action.
Field
Description
Source module
Select the module to be replaced as the mapping source for other modules in your scenario.
Target module
Select the module you want to use as the new mapping source.
Module to edit
If you don't want to change the mapping in the entire scenario, select the module you want to change the mapping for.
Highlight app
Highlights modules of the specified app in your scenario.
Field
Description
App to be highlighted
Select the app you want to highlight in your scenario.
Version
Select the version of the app you want to highlight.
Highlight color
Enter the hex color you want to use to highlight modules in your scenario.
Get blueprint size
Checks the size of modules in the scenario. This is useful when you are having trouble saving a blueprint that is too large.
Showcase mode
Toggles the showcase mode of the scenario editor. This mode is useful when you are building a scenario and don't want to set up the full module.
To leave showcase mode, run this tool again or save the scenario and refresh the browser window.
Mock labels
Changes the label and description of the given module. Changes made by this tool are not permanent and don't affect the real scenarios. This option is meant for presentation purposes only. To reset the text, refresh the browser window.
Field
Description
Module
Select the module to change the label and description.
Label
Enter the label of the module. An empty value equals no change. If you want a blank label, enter (space).
Description
Enter the description of the module. An empty value equals no change. If you want a blank label, enter (space).
Change background
Temporarily changes the background color of the scenario. This is useful when you need a white background for screenshots and mockups. To reset the background, refresh the browser window.
Instructions for the user displayed in the module setup. Supports Markdown for text formatting.
required
Specifies if the parameter is required.
editable
(Only for the connection) Specifies if the user can edit and modify the connection from the Connections page in Make.
Instructions on how to display any error: [error code] error message.
This information is typically present in the API docs. Since it isn’t available in this case, you need to retrieve it manually.
Send a request with incorrect credentials in Postman, then check the response body to identify where the error code and message appear.
If available, it's good practice to include the status code in the error response.
"log": {"sanitize": ["request.qs.api_key" ]}
Indicates to omit the api_key parameter present in the query string of the request from the log.
30 by default or the value you put in page[size]
max_page_size
200
New Instagram account name
New instagram account name
Instagram is a proper noun, remains capitalized.
Google Drive folder
Google drive folder
Google Drive is a proper noun, remains capitalized.
Content ID
Content id
ID is an acronym and remains capitalized.
Product API key
Product API Key
API is an acronym and remains capitalized. Key is lowercase.
Website URL
Website url
URL is an acronym and remains capitalized.
ID finder
ID Finder
ID is an acronym and the first word in the label.
User ID
userID or user_id
userID or user_ID are in an API format.
A unique identifier for your custom app. This is an internal name and is not visible in the scenario builder. Must match the following Regex: /^[a-z][0-9a-z-]+[0-9a-z]$/
Label
Geocodify
Name of the custom app in the scenario editor.
Description
Provides geocoding and access to a spatial database.
Optional: Description of the custom app.
Theme
#46367f
Color of the app in the scenario editor. Specified with a hex code.
Language
English
The language of your app.
Audience
Global
Where the app is available. At the moment, this parameter doesn't have any effect.
App logo
Optional: Logo of the app used in the scenario editor.
For more information on logo specs, see the App logo article.
Triggers when a contact is updated.
Watch deleted [items]
Triggers when a/an [item] is deleted.
Watch deleted contacts
Triggers when a contact is deleted.
Watch [items]
Triggers when a/an [item] is created or updated.
Watch contacts
Triggers when a contact is created or updated.
Watch [items]
(for events)
Triggers when an event occurs related to a/an [item].
Watch records
Triggers when an event occurs related to a record.
Watch events
Triggers when an event occurs [optional - location or time].
Watch events
Triggers when a new event occurs on Monday.
Creates a new contact or updates an existing one if a matching contact name or email is found.
Delete a/an [item]
Deletes a/an [item]…
Add if specified in API documentation:
…This action cannot be undone.
Delete a message
Deletes a message from a thread. This action cannot be undone.
Download a/an [item]
Downloads a/an [item]…
Download an document
Downloads a document in PDF format.
Get a/an [item]
Returns information about a specific [item] by its [x].
Get a user
Returns information about a specific user by their user ID.
Move a/an [item] to trash
Moves a [item] to the trash.
Move a file or folder to trash
Moves a file or folder to the trash.
Redact a/an [item]
Redacts [information] for a/an [item]…
Redact a contact
Redacts all personally identifiable information for a contact, but does not delete the contact record itself.
Update a/an [item]
Updates a/an [item]…
Update a message
Updates a message.
Add [items] to a/an [item]
*Adding multiple items to a single item
Add [items] to a/an [item]…
Add members to a list
Adds members to a specified list.
Bulk [verb] [items]
[Verbs] multiple [items]…
Bulk add rows
Adds multiple rows to the bottom of a table.
Returns a list of users filtered by [?].
Execute a GraphQL query
Execute a GraphQL query
Watch new [items]
Triggers when a new [item] is created.
Watch new contacts
Triggers when a new contact is created.
Watch updated [items]
Triggers when a/an [item] is updated.
Create a/an [item]
Creates a new [item]….
Create a supplier invoice
Creates a new supplier invoice.
Create or update a/an [item]
Creates a new [item] or updates an existing one if a matching [x] is found.
List [items]
Returns a list of [items]…
List users
Returns a list of users in a specific organization.
Search [items]
Returns a list of [items] filtered by [?]…
Make an API call
Sends a custom API call to {app name}. You can use this to call endpoints that aren’t covered by existing modules.
Make an API call
Sends a custom API call to Shopify. You can use this to call endpoints that aren’t covered by existing modules.
Make a SOAP API call
Watch updated contacts
Create or update a contact
Search users
Make a SOAP API call
.
Exception: If the API documentation specifies that the given datetime is in UTC or some other time zone.
Do not use the Make user’s time zone or the Make organization’s time zone, because it may be different from the time zone configured in the third-party services.
Time stamp in seconds or milliseconds.
Exception: If it has a clear indication by its name, in the API documentation or metadata endpoints, that shows such fields are a Date type field. DO NOT try to parse time stamps by assuming a lengthy number must be a time stamp.
No
No date, only time.
add_time
Yes
Only date and time with no time zone.
BUT we know it’s UTC.
marked_as_done_time
Yes
Only date and time with no time zone.
BUT we know it’s UTC.
update_time
Yes
Only date and time with no time zone.
BUT we know it’s UTC.
due_date
No
No time, only date.
due_time
No
No date, only time.
timestamp_edit
Yes
Timestamp in seconds with clear indication by it’s name.
timestamp
Yes
Timestamp in seconds with clear indication by it’s name.
Service responded with rate-limit related error. Applies delay to the next execution of a scenario.
OutOfSpaceError
The user is out of space.
ConnectionError
Connection-related problem. Applies delay to the next execution of a scenario.
InvalidConfigurationError
Configuration-related problem. Deactivates the scenario and notifies the user.
InvalidAccessTokenError
Access token-related problem. Deactivates the scenario and notifies the user.
UnexpectedError
MaxResultsExceededError
IncompleteDataError
Incoming data is incomplete.
DuplicateDataError
Reports error as warning and does not interrupt execution. If incomplete executions are enabled, execution is interrupted and the state is stored. The user is able to repair the data and resume execution.
UnknownError
RuntimeError (default)
Primary error type. Execution is interrupted and rolled back.
Incoming data is invalid. If incomplete executions are enabled, execution is interrupted and the state is stored. The user is able to repair the data and resume execution.
{
"response": {
"error": {
"message": "Generic error message",
"400": {
"message": "Your request was invalid"
},
"500": {
"message": "The server was not able to handle your request"
}
}
}
}
Changing type (If the original type can be coerced to the new type, it’s fine. e.g. number -> text. See .
Adding validate
Webhook's Communication
Any changes might break scenarios.
Remove a parameter from a module
It's important to avoid removing mappable parameters from a module without a clear indication or notification to the user. Even if it doesn't immediately cause a scenario to fail, it could still impact its functionality or disrupt the underlying process. Therefore, it's best to communicate any changes to the user. Also, the user should be able to see and work with the original input in the deprecated parameter/s.
In situations where a mappable parameter needs to be removed, there are several ways to handle the deprecation. The appropriate approach depends on the specific circumstances and how the API manages parameter deprecation in its endpoint.
Below, are methods ranked in order of least to greatest impact:
Add the [Deprecated] string to the module's label
The parameter should be put into advanced parameters and the [Deprecated] string should be attached to the label. Additionally, you can add instructions to the help.
Add a banner
If you need to make sure that the user notices the deprecated parameters, you can use the banner element.
There are three distinct message types available, each with a specific icon and guidelines for appropriate use. The recommended length of the message is 50 to 300 characters.
Perform an additional check before the request is sent and throw an error if the deprecated parameter is present in the payload
If the called API service is too strict about using the deprecated parameters, you can do the error execution on the app's side.
Shut down a module
If you need to make sure that the module is not used anymore, you can throw an error whenever the module is executed.
Deprecate a connection
If you need to deprecate a connection, create a new connection to use as the functional alternative and rename the now-deprecated connection so it contains the (deprecated) string.
Then, do the following:
1
Remove the current primary connection.
2
Map the new connection as the primary connection.
3
Map the deprecated connection as the alternative connection.
Hints play a very important role in the overall usability of an app and well-written hints can have a significant positive impact on the user experience.
When providing hints, take into consideration the following:
All fields that are not self-explanatory should contain a hint
Extra attention should be paid to Connection fields
All essential information should be included
The information should be clear and concise
The terminology used should be non-technical and easy to understand
Avoid using symbols
Information to include
There are six categories of information that hints can include. Each hint can contain at least one of the information types. If multiple information types are included, they should be organized in the order listed below.
Expected input
Result
Example
Additional information
Information type
Description
Example
Connection field hints
API key / API token / Access token
The name of the field should always match what the user sees in the 3rd party UI.
Where to direct users
Format
Example
Required client ID and client secret
The process to obtain these values should be documented in our Help Center if the fields are required.
Where to direct users
Format
Example
Optional client ID and client secret in advanced settings
The process to obtain these values do not need to be documented in our Help Center as the fields are not required.
Where to direct users
Format
Example
Limit field hints
Location
Field
Format
Link
The Limit field should also be the last standard field in the module. It should not be in the advanced settings.
Make an API call: URL field hints
If a hint includes a URL, the URL should contain the prefix path and an example of the URL. Additionally, the URL field hint should include an example endpoint that works without performing any additional steps (for example, where no {body} is required).
Use GET methods as the example endpoints. Do not use endpoints that create or delete records.
Do not hard code API versions in the prefix path. This ensures a user can work with any API version. Even if there is currently only one version, future compatibility should be considered.
Field
Format
Example
Special formatting
Two types of special formatting are used in hints: bold and code.
If a hint references another input field in the module, make sure to copy the input field’s name exactly and format it in bold.
If you include examples, default values, versions, or specific formats, make sure to use the red code formatting. This can include API versions, color codes, dates, time, and country codes.
Module labels
Every module should have a label that precisely describes the module's use. The label should be composed of the verb expressing the intended action (create, update, watch, etc.) and the name of the entity being processed (customer, invoice, table, etc.).
Module labels follow sentence case. Only the first word is capitalized.
There may be times when the third-party UI does not match these suggested naming conventions. In such cases, use the third-party terminology that is familiar to your users.
Watch modules
Watch modules watch for new data in a service and return it. They are trigger and instant trigger (webhook) modules.
Format (plural)
Correct
Incorrect
Action modules
Action modules write data into a service, modify data in a service, or retrieve a single result.
Module type
Format (singular)
Correct
Incorrect
Search modules
Search modules retrieve data from a service and allow for one or more results.
Module type
Format (plural)
Correct
Note
Bulk modules
Bulk modules can perform an action on multiple records in a single call.
Format (plural)
Correct
Additional information
Some modules will require additional information in the name, such as (advanced) for bulk modules, or (beta). In these cases, the singular adjective should be lowercase and placed between ( ).
Information type
Format
Correct
Incorrect
Processing of input parameters
Mapping all parameters
In this example you have to map every parameter correctly.
Batch actions
A batch action is an operation that lets a user complete more than one action in a module.
We advise that you do not use batch actions as the Make platform does not support the partial success of a call.
If your module involves two API calls, it's possible that one will succeed and the other will fail. The module will show an error message for this partial success.
Instead, we suggest using a separate module for each API call:
[
{
"name": "firstName",
"type": "text",
"label": "First Name",
"help": "This field is a replacement for the deprecated `Name` field."
},
{
"name": "lastName",
"type": "text",
"label": "Last Name",
"help": "This field is a replacement for the deprecated `Name` field."
},
{
"name": "email",
"type": "email",
"label": "Email"
},
{
"name": "name",
"type": "text",
"label": "Name [Deprecated]",
"advanced": true,
"help": "This field has been deprecated and divided into `First Name` and `Last Name` parameters."
}
]
{
"type": "banner",
"title": "This is an info",
"text": "Here is a description of info.",
"theme": "info"
}
{
"type": "banner",
"title": "This is a warning",
"text": "Here is a description of warning.",
"theme": "warning"
}
{
"type": "banner",
"title": "Headline, if needed...",
"text": "Minimum recommended length of message text. (50 characters)",
"theme": "danger"
}
[
{ // when parameter name exists
"condition": "{{parameters.name}}",
"response": {
"valid": {
"condition": false, //to throw response as error
"type": "DataError",
"message": "You can't use the parameter 'name' as it has been removed.\nPlease read the module's note message."
}
}
},
{ // when parameter name doesn't exist
"condition": "{{!parameters.name}}",
"url": "/api/users",
"method": "POST",
"body": "{{omit(parameters, 'name')}}",
"response": {
"output": "{{body}}"
}
}
]
{
"response": {
"valid": {
"condition": "{{'a' === 'b'}}",
"message": "You can't use this module anymore as it has been shut down.\nPlease read the module's note message."
}
}
}
.
Adding an additional call (chaining request).
Changing a linked connection.
.
Setting the select parameter mappable to false.
Setting the select parameter dynamic to false.
Removing or changing items in a list or dropdown.
Include an example to provide more clarity, if specific formatting is used, or if it is valuable for users.
Use the format ‘For example, code formatting’.
Image URL
URL address to a public resource of the image. For example, https://getmyimage.com/myimage.png.
Additional information
Include extra information the user must know to successfully use the field.
Output file name
Name of the generated audio file. Do not include the file extension.
What if left empty
Describe the impact of not entering a value.
Format
If left empty, default formatting is used.
Link
When linking to Make's Help Center, use ‘our Help Center’.
When linking to third-party documentation, include the name of the app/service and the name of the page/documentation.
Account
Name of the primary user’s account. For details, see our .
Voice
Voice to use in the audio. For voice samples, see the .
For details on how to obtain your [name of value], see the [app name] [page name].
For details on how to obtain your access token, see the .
Third-party account:
with link
You can obtain your [name of value] on the [page name] in your [app name] account.
You can obtain your [name of value] on the [app name] [page name].
You can obtain your refresh token on the in your Atlassian account.
You can obtain your API key on the .
Third-party account:
with instructions
*not preferred due to length
You can obtain your [name of value] by going to [item]→ [item] → [item] in your [app name] account
You can obtain your refresh token by going to Account → Profile → API in your Atlassian account.
https://help.make.com/types-of-modules#b3ZEQ
Expected input
Include a clear description of what to enter/select.
This will often be the description included in the API documentation.
If the description is not clear or is too technical, update it to be more user-friendly.
Response format
Format of the generated audio file.
Result
Include a clear description of the outcome, especially if there are various possible outcomes.
Include this information if it is useful to describe what will happen when users enter a specific value.
Temperature
Higher values generate a more random response. For example, 0.8. Lower values generate a more focused response. For example, 0.2.
Our Help Center
For details on how to obtain your [name of value], see our Help Center.
For details on how to obtain your API key, see our Help Center.
Link to apps.make.com/[your-app-slug]
Third-party resource:
API docs
For details on how to obtain your [name of value], see the [app name] API documentation.
For details on how to obtain your [client ID or secret], see the [app name] [page name].
For details on how to obtain your client ID, see the Oracle Help Center.
Polling trigger
Limit
Maximum number of results to return. For information about setting limits, see our Help Center.
https://help.make.com/types-of-modules#b3ZEQ
Search and List modules
Limit
URL
Enter the part of the URL that comes after [prefix path]}. For example, [postfix].
Enter the part of the URL that comes after https://api.openai.com. For example, /v1/models.
Example
Third-party resources:
other than API docs
Maximum number of results to return and work with during one execution cycle. For information about setting limits, see our .
There is a risk of a typo or omission of a parameter.
{ // ..."body": "
With this approach, all parameters from the modules will be sent to the API.
[{"name":"
Using an IML function or omitting a parameter
Sometimes, you don't want to map all parameters in the body. Some reasons may include:
The parameter shouldn't be sent at all (technical parameters such as selects, etc.).
The parameter should be sent somewhere else than in the body, e.g. in the url.
The parameter has to be wrapped in an IML or custom IML function.
In this example you have to map every parameter correctly.
There is a risk of a typo or omission of a parameter.
Note that "{{...}}" lists all available parameters from the module and allows adding other parameters.
The omit() function allows the removal of parameters that are used somewhere else, shouldn't be used, or require special attention.
In this case, the id parameter is already used in the url, and the registrationDate parameter is wrapped in formatDate IML function.
Handling arrays, nulls, and empty strings
Make and other third-party services transport values in many different formats. It is important to know how to handle the value types of arrays, nulls, and empty strings.
Bad practices
It isn't possible to send a null value to a service.
It isn't possible to send a null, empty string, and 0 (zero) value to a service.
It isn't possible to send an empty array to a service. E.g. User wants to remove all tags from a task.
Let users decide which parameters they want to send to the service. Make has a feature to show how to process values. This feature allows users to define exactly how Make should behave when the value is "empty".
For example, if a user defines that they want to send a specific field to a service even if the value is null , empty string, or an empty array, it will be sent to the service. In module communication, config passes parameters without any modification.
Query string (qs)
Query string parameters should be defined using the qs directive as a key-value collection, where the key is the parameter name and the value is the parameter value. Values in the qs collection are automatically encoded, so you don't need to escape them manually.
The same automatic encoding applies to the headers and body collections for request headers and body payloads, respectively.
If you provide a query string directly in the url directive, it won't be automatically encoded. You have to encode it manually. But in common cases, entering the query string in the url is not a recommended approach, especially when values are inserted dynamically. See the Special case: Query string parameters in the URL section for more details.
Special case: Query string parameters in the URL
In most cases, having the query string in the URL is not the best practice. It is better to use the qs collection, but sometimes there may be a special case when you need to use the query string directly in the URL.
The main difference is that the query string in the URL is not encoded automatically, so you have to do it manually. This can be useful when the third-party service requires a very specific format or encoding of the query string parameters. In that case, you can add a query string directly to the url directive string and manage the encoding yourself.
Example of specific query string parameters in the URL:
The most common use case for this is when a third-party service requires special symbols like brackets [] or parentheses () to be unencoded in the query string.
Important: Never mix the qs directive together with the query string in the URL. This will lead to invalid escaping of parameters specified in the url.
Using arrays in qs
You can also use an array as a value in the qs collection. In this case, the resulting query string will repeat the key for each value in the array, e.g. ?tag=one&tag=two&tag=three.
qs (and also headers) are single-level collections only, meaning that you cannot specify a nested collection in their parameters.
This example will not work.
Since there is no defined standard for how to encode nested objects in a query string, you need to implement it manually based on special requirements of the third-party service. The most common approach is to use dot notation (use a . to separate the keys in the query string) for nested properties.
This will issue the request with the query string:
Generally, PUT does not support partial updates, meaning you need to provide a full request to avoid losing the rest of the record. PATCH supports partial updates.
However, in practice, many APIs with PUT methods support partial updates.
Make expects empty fields to be ignored, not erased.
Chain of actions: Read > Write
Get record by ID
PUT the record patched by user’s input
Example
GoHighLevel > Update a Contact
If a partial update is not supported, you must execute an extra call to retrieve the current data and combine the data using an IML function.
If a value needs to be deleted, use the erase pill (available only in update modules).
Get a record after update
Some services only return an ID after a record update.
Chain of actions: Write > Read
Update the record
Get the record by ID
Example
Workday Financial Management > Update a Supplier Invoice
Upload a file
Upload in chunks
Chain of actions: Write > Write > … > Write
This is an exception to the rule that combines multiple Write actions. These requests are designed to be used in sequence.
Create an upload session
Keep sending chunks
Finalize the upload
Example
Dropbox > Upload a File
Download a file
Download by media ID
Chain of actions: Read > Read
Get the media ID
Download file by media ID
Example
WhatsApp Business Cloud > Download a Media
Telegram Bot > Download a File
Asynchronous process
Requests involving processes running asynchronously on 3rd party service.
Chain of actions: Write > Read > Read > … > Read
Start the task
Keep polling for task status
Get the result when done
Example
Microsoft Power Automate: Trigger a Desktop Flow
Responsiveness approaches
Keep in mind that there are two approaches to responsiveness in a service:
Synchronous - Upon an action request, the service returns a result that can then be processed in the following modules in a scenario.
Asynchronous - The service doesn't return anything at all, or doesn't return useful output, e.g. a processed file.
Comparison of synchronous and asynchronous approaches
Attribute/ Approach
Synchronous
Asynchronous
Advantage
The result is returned right away. The result can be processed in the following modules.
Helpful when you need to process a large amount of data, like a file conversion.
Disadvantage
The job may take too long. This might cause a timeout (default 40 sec). For example, in a file conversion. The default timeout can be prolonged depending on the valid cases.
You need to create at least two scenarios - one for triggering the job, and another one for processing the result from the first scenario. The second scenario, if possible, should start with an instant trigger that triggers once the job finishes.
Handling of asynchronous approach
When a web service doesn't support a synchronous approach and the common use case of the module requires support, it should be added on the app's side. There should be two (or more calls) executed instead of only one:
Create a call
Check the status of the call
Request the result of the call
Example
After importing a JSON file to a web service, it requires a certain period of time to process the file. In this case, continue to check if the status of the entity changed from processing to completed. When the status is completed, the result is already part of the response.
When the repeat directive is used, the condition and limit should always be provided to prevent infinite loops.
{
"url": "http://yourservice.com/api/users/{{parameters.userId}}?groups=(1,2,3,4)&specificallyEncodedParameter={{parameters.specific}}",
// qs: {} // <- Do not include the `qs` collection here
"method": "POST",
// ...
}
The Base section is used to set up authorization. Most services require the authorization key be sent either in headers or in the qs (query string). If you set the authorization in the base, all modules and Remote Procedure Calls (RPCs) will inherit it.
A mappable parameter is a variable or setting that you can change or link (map) to another value.
Types of fields
You can use mappable parameters in many types of fields:
Standard fields
Visible by default
Frequently used
Typically easy to understand
Visible on the third-party’s Web UI by default
Advanced fields
Hidden by the Advanced settings toggle
Not needed by the majority of users
Required fields
Require minimal effort to make the module work
Validate if the user has filled in all necessary fields required by the API call
Conditionally-required fields
Required based on a condition. For example:
Either field A or field B is required
Optional fields
Not necessary for the API to work, but good to have
Enrich the UX by providing flexibility to the user to send all fields the API supports
Static, dynamic, and semi-dynamic fields
When mapping parameters, there are different types of fields to choose from.
Static fields
With static fields, all parameters are manually specified in the module, so every users sees the same options. Though not ideal, some APIs require the use of static fields.
Dynamic fields
With dynamic fields, all parameters are loaded dynamically from the API, using . The options shown to a user are based on the user's account specifications. For example, a user who is a manager may have access to more files and folders in an account than another employee. Every user will have a different experience interacting with the module based on their account login. Whenever possible, using dynamic fields is the ideal approach.
Custom fields
Custom fields are user-defined fields in the third-party application. You can use custom fields with RPCs as well, for further customization.
However, if an API supports implementation of custom fields where the field name and field value may be specified by the user (the user is creating new custom fields), both of the fields should not be mandatory. There may be reasons for a value to be empty, and requiring both could cause an error. Instead, require only field value. Additionally, if the API doesn't allow empty values, the validation of an empty value should be set so the pair will not be sent.
Date parameters
Use the date and time type parameters instead of asking users to format the date and time themselves. These values should be formatted in the backend to support Make's format.
Exception: If the endpoint accepts date only or time only, use the text parameter with a clear hint and example.
Processing of date parameters
When a field is a type "date", it should be possible to use our keyword "now" as a value. The field should accept ISO-8601 date format and if the service requires only the date (no time) or a different format like timestamp, this formatting should happen inside the module.
Users of the app should never be prompted to format the date inputs the way API requires. Apps that require this will not be approved by Make.
Communication:
Parameter birthday is required to have format YYYY-MM-DD and parameter due_date is required to be a time stamp by the service, so the formatting happens inside the Communication part of the module.
Parameters:
Support of array aggregators
If the API doesn't support arrays or arrays of collection, you need to implement an IML function that enables the use of array aggregators.
Remote procedure calls (RPCs)
For every parameter where options are listed dynamically (values pulled from the API), you should implement an RPC, especially when you need to provide an ID (or raw value) instead of a label.
For example, if you have a lot of customers and you don’t remember their IDs, the RPC will display a list of names / emails and fill in the ID for you. Also, RPCs help the user to understand the behavior and outputs of the module before building the logic of their scenario.
If there are many RPCs nested to each other, you need to implement an additional select which allows users to choose whether they will map the deepest parameter from previous modules or whether they will follow every RPC to select every parameter in order to get into the deepest parameter.
Edit mode
The edit mode ("mode": "edit") is used in modules where the RPCs should be switched off by default. Those modules are - UPDATE, GET, DELETE etc.
There are two main reasons why this is used:
To reduce module load time: If you click on the module to open it, all options for all RPCs need to be loaded before it opens. By using mode:edit, the module opens right away and RPC options are loaded when you open the select field.
Imagine a module to create a donut:
RPC for the type of dough
RPC for the icing color or flavor
Edit mode is also recommended in modules that will always be working with the lowest entity, for example, an attachment for an e-mail in a module.
Mappable: false
You may want to hide the mapping toggle to help the user enter correct information in a field.
For example, in a select field type a user should select from a list of options. Having a map toggle is unnecessary and may confuse the user.
To hide the mappable toggle, use the "mappable": false parameter.
After switching on the mapping toggle, the text fields disappear.
"mappable": false
Messages (banners)
In some circumstances, you may want to give users additional information in a module.
There are three distinct message types available, each with a specific icon and guidelines for appropriate use. The recommended length of the message is 50 to 300 characters.
Information (blue)
Warning (yellow)
Danger (red)
ID finder
The ID finder allows users to identify items within a module by entering search criteria. The ID finder can either be the only search method for a field or it can be included in a list of multiple search methods.
The ID finder window can either include a single search criterion (keyword or exact match) or multiple search criteria. There are specific guidelines to follow when implementing the ID finder, both within the module and the ID finder itself.
Module guidelines for the ID finder
When implementing the ID finder within a module, it is important to consider whether it is the only available search method to identify the item, or if there are multiple search methods. Regardless of the number of search methods, the ID finder button should always be labeled ID finder.
If you are implementing the ID finder for a field that is not searching for an ID, for example the Dropbox > Watch files module with the File Path field, the button should read Finder instead of ID finder.
Single search method
ID finder guidelines
The ID finder can include either one single search criterion (keyword or exact match) or multiple search criteria. It is important to note that the number of results the ID finder will return is limited both on the Make platform side and the app side. Because of this, we do not advise users to leave the search field empty to return all results, as this information can be misleading.
The standard blue info box message should be used for all ID finders, except for in cases of Single search criterion: exact match.
ID finder results
If the API allows, the ID finder’s results should be listed in alphabetical order.
ID finder template
Support for custom query and filter options
Certain APIs provide support for custom queries or filters when searching records, such as invoices. In Make, our goal is to offer query and filter capabilities to both regular and advanced users.
Therefore we have implemented two methods of achieving this functionality, and ideally users should be able to choose between the two options.
Predefined query
We have utilized the familiar filter setup format found in Scenario Builder. With this approach, users are not required to learn the query format. Instead, they can simply set up the query in a manner similar to configuring filters.
When the module is executed, a custom IML function constructs the query, adhering to the specified format.
Custom query
Users have the option to manually compose their own queries. This feature is particularly valuable when the API supports new operators that are not yet available within the module.
To assist users in leveraging the query field effectively, the following helpful information should be provided:
Query format: The guidelines for structuring the query.
Example of a functional query: An illustrative sample query as reference.
API documentation URL: Direct access to the API documentation with query specification.
Search filters
Provide a list of fields and a list of operators.
Group operators by their data types
Labels
Labels are available for:
Array(s)
Array item(s)
Default to Item
Universal module
If possible, provide a universal module.
The prefix path of the URL should not contain the version of the API, to ensure that users can use any version of the API. Even if there is no other version, it is good practice in case there is one in the future.
The hint under the URL should contain the correct prefix path of the URL, together with an example of a postfix path of the URL.
Consider copying the UX from the third-party’s Web UI, for clarity
Limit should be the last variable
Generally more difficult to understand
Might require technical knowledge. A hint or link to documentation is necessary
Includes custom fields, if supported by the app
Hidden on the third-party’s Web UI
Placed at the bottom of all fields. This ensures that when users toggle to the advanced settings, they can easily view them without being mixed in with regular fields
Consider copying the UX from the third-party’s Web UI, for clarity
Limit should be the last variable
Guard against getting an API error from the third party due to missing fields
Ideally contain a default value
If an advanced field, must contain a default value
The field is only required to create but not update in an upsert module
A clear hint is mandatory to explain the condition
Should follow required fields and be located before optional fields
This could be an exception if the fields have to be arranged in logical blocks
Sometimes field types in third-party applications do not match types supported in Make. In this case, when defining mappable parameters using an RPC, you also need to implement a custom IML function to convert the type.
Semi-dynamic fields
It's also possible to use a combination of static and dynamic fields to customize the user experience, based on user settings and availability in the API.
Even though this will be sent correctly, it is not user-friendly.
The parameters birthday and due_date are correctly date typed and don't need to be formatted by the user who can use the now keyword.
Communication:
Parameter birthday is required to have format YYYY-MM-DD and parameter due_date is required to be a time stamp but nothing is done with the value.
Parameters:
The parameter due_date is an incorrect type and birthday is required to be formatted by the user.
RPC for the type of sprinkles
RPC for filling options
With this setup, the module will take a long time to load, especially if the API server is busy.
If we expect the user will want to map the value, not select from the list. For example, in a Watch for new orders > Mark order as received module, map the Order ID from the previous module.
hides the mapping toggle:
If a module contains only the ID finder as a search method, the name of the field should be the
[Item] ID
that is being searched for.
[Item] ID field names include:
Campaign ID - campaign to be updated
Employee ID - employee record to delete
Etc.
Multiple search methods
If a module contains multiple search methods, they should be listed in an [Item]search method dropdown. Replace [Item] with the name of item that is being searched for.
[Item] search method field names include:
Spreadsheet search method - spreadsheet to add a row to
Channel search method - channel to send a message to
Record search method - record to update
Etc.
[Item] search method dropdown options include:
Search by keyword (ID finder with keyword search)
Search by [item] (ID finder with exact match search)
Only a limited number of results can be shown. If you don’t see the item you’re looking for, try more specific search criteria.
Single search criteria
Keyword search
The name of the search field should always be [Search item] Keywords.
[Search Item] keywords examples include:
Channel name keywords
Address keywords
Include the blue info box that instructs users to use more specific search criteria. In this case, that is a more specific keyword.
Exact match required
The name of the search field should be identical to the name of the item that the user must match.
For example, if a user must enter an item’s name, the field should be Name.
Do not include the blue info box that tells users to use more specific search criteria, as there are no other criteria or way to make an exact match more specific.
In the search field hint, add the following: Must be the exact [Search item].
For example:
Field: Channel name.
Multiple search criteria
Keyword search
The name of the search field should always be [Search Item] keywords
[Search Item] keywords examples include:
Spreadsheet keywords
Employee Title keywords
Include the blue info box that instructs users to use more specific search criteria. In this case, that is either a more specific keyword or utilizing the other criteria in the ID finder to refine their search.
Do not ask users to construct the query string.
Do not share operator among all data types.
This should be consistent and related to the label of the array. For example, if the label of an array is Recipients , the label of an array item should be Recipient.
Button(s) to add an array item
Default to Add item.
The button label should be consistent and related to the label of array items. For example, if the label of an array item is Recipient , the label of the button should be Add recipient.
The example should be “ready-to-use”. We recommend using methods for retrieving a record in the example (GET).
Every connection should have a way to check if the used API key (token) is valid (a validation endpoint).
This means that each connection should have a part that uses the API key (token) against an endpoint that requires only the API key to run. For example, a user info endpoint, or any endpoint that is used to list data.
The validation endpoint is located:
OAuth1 and OAuth2 - in the info directive
API key, basic auth, digest auth, other - in the url in the Communication tab
There are APIs that don't have a validation endpoint. In this case, it is recommended to call an endpoint that will work in every case and, if possible, will return the account's data, e. g. an endpoint /about or /me, etc.
The API key is checked against the /whoami endpoint. If the API key is incorrect, this returns an error and the connection won't be created.
Select your editor
You can build a custom app in Make in a variety of ways.
Here we show two methods: through the Make web interface or with vibe coding.
Make web interface
The Make web interface lets you create and manage the custom app configuration directly within the Make platform. It offers a graphical interface, allowing you to easily build the app by setting up connections, modules, and parameters and personalizing the app behavior.
Visual Studio Code
You can get the extension from the or install it in the Extensions tab in VS Code.
An instant trigger is a webhook that starts a scenario whenever new data arrives.
Your app should implement a fully functional instant trigger as a Watch module, even if an API might have endpoints like Get a webhook, List webhooks, or Update a webhook.
Connect metadata
Always save the metadata in the connection if
the endpoint that can obtain authenticated user’s information is available, and
the information provided is able to distinguish the connection.
When naming your connection, provide as much information as possible. This provides better identification on the connection page. The following information is suggested:
Name
Email
User ID
Organization / Company / Location / Tenant
Example - Constant Contact
UID
Always save the UID in the connection if the service supports a single webhook URL per app (a shared webhook). The saved UID must match the ID that is included in the incoming webhook payload.