arrow-left

Only this pageAll pages
gitbookPowered by GitBook
triangle-exclamation
Couldn't generate the PDF for 196 pages, generation stopped at 100.
Extend with 50 more pages.
1 of 100

Custom Apps Documentation

Get started

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Create your first app

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Debug your app

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

App Review

Loading...

Loading...

Loading...

Loading...

Loading...

Best practices

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

App Maintenance

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

App components

Loading...

Loading...

Loading...

Loading...

Local development for Apps

Commit the changes in Git repository

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.

circle-info

Custom Apps Development Training

If you are new to custom apps, enroll in the Make Academy course Getting started with custom appsarrow-up-right.

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.

hashtag
Get started

hashtag
Step 1: Select your editor

you want to use to build your custom app:

  • ,

  • , or

  • with vibe coding (information coming soon)

hashtag
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 ).

hashtag
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.

hashtag
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 .

hashtag
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.

Select the editor
Make web interface
Visual Studio Code
create your first app
Step 3
make a test HTTP call
deploy the changes

Click Change icon.

In the file upload dialog box, select your icon to upload to Make.

The change icon view closes and the new icon appears in the left tree.

Make's app logo requirements

Visual Studio Code

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 Marketplacearrow-up-right 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.

circle-info

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.

Next, you will commit the changes in the Git repository.

Response Headers

  • Response Body

  • 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.

    hashtag
    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.

    hashtag
    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.

    hashtag
    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.

    hashtag
    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.

    hashtag
    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.

    hashtag
    Collaborative development flow

    Below is a diagram explaining how developers can collaborate on app development.

    section
    testing and production app versions
    2

    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.

    generated your API key
    configured VS Code

    App visibility

    hashtag
    Private app

    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.

    circle-info

    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.

    hashtag
    Deletion of a private app

    If your private app is not used in any of your scenarios, you can delete the private app.

    hashtag
    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.

    hashtag
    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.

    hashtag
    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).

    hashtag
    Deletion of a public app

    circle-exclamation

    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.

    hashtag
    Deletion of a module, webhook, connection, RPC, or custom IML function

    circle-exclamation

    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.

    hashtag
    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.

    hashtag
    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.

    To create a new app origin:

    1

    Clone the production app to a local workspace.

    2

    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 DevToolarrow-up-right you can debug your Make scenarios by adding an extra pane to the Chrome Developer Toolsarrow-up-right. 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.

    hashtag
    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.

    hashtag
    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

    circle-exclamation

    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:

    • Connections

    Overview

    circle-info

    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.

    The information found here corresponds with the content of the Get started with custom apps online coursearrow-up-right and serves as an additional resource.

    To create your first app, you will:

    Generate your API key

    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.

    hashtag
    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.

    hashtag
    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.

    hashtag
    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.

    hashtag
    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.

    Complete the initial setup in Make
    Set up the Create a connection component for users to connect to your app
    Specify the common directives in the Base
    Create a module
    Test your app

    150+ useful videos all about Make.

    Make Help Centerarrow-up-right

    Our documentation to help you learn more about the Make platform and the Scenario Builder.

    Stack Overflowarrow-up-right

    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.

    Regular expressions 101arrow-up-right

    A recommended tool for experimenting with regular expressions. Make sure to tick the ECMAScript (JavaScript) FLAVOR in the left panel.

    Regular expressions generatorarrow-up-right

    A regular expressions generator for those who need help with regex.

    Lunapicarrow-up-right

    A free editor to create and edit app logo files.

    Make supportarrow-up-right

    Contact us if you need help or you didn't find the information you need.

    Custom apps development trainingarrow-up-right
    Make community - custom appsarrow-up-right
    Make YouTube channelarrow-up-right
    contact our support teamarrow-up-right
    app review procedure
    request an app review
    passes our review process
    Chrome Web Storearrow-up-right
    Make DevToolarrow-up-right
    Live Stream
    Scenario Debugger
    Tools
    App visibility article
    Base
    Modules
    baseUrl - the URL to the origin's zone
  • appId - the name of the app

  • circle-exclamation

    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.

    "origins": [
        { /* --- Existing origin --- */ },
        {
            "label": "Testing",
            "baseUrl": "https://eu1.make.com/api",
            "appId": "my-first-app-test",
            "appVersion": 1,
            "apikeyFile": "../.secrets/apikey"
        }
    ]
    sdk-apps:write

    Add more API scopes to your API key as needed. You can find descriptions of the API scopes in the Make API documentationarrow-up-right.

    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.

    hashtag
    Set up Base for your Geocodify custom app

    To set up the Base for your custom app:

    1

    Remove the default code that is present.

    2

    Copy and paste the following code:

    Code
    Description
    3

    Click Save changes.

    Continue to set up the module.

    Log in to Make.
    2

    In the left navigation, click Custom Apps.

    You may need to first click More to see this option.

    The Custom Apps dashboard is where you can create a new app, see your existing apps, and see the status of your app (public or private).

    See the Create your first app section to get started.

    hashtag
    Web code editor key features

    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:

    1. Hints with links to documentation for more information.

    2. A format code button with a label showing the data format. The available data formats are:

      • jsonc

      • json

      • javascript

      • markdown

    3. 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.

    4. Hints displayed when hovering over the custom app configuration.

    5. 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.

    6. A Save changes button to save changes in all editor boxes on the page.

    1. Hovering over built-in IML functions shows detailed information.

    1. Hovering over custom IML functions provides a link to the function definition.

    1. Controls to expand and collapse the code. To view the controls, hover over the space between your code and editor line numbers.

    1. The editor highlights the IML syntax so it's distinct from the rest of the code.

    hashtag
    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 documentationarrow-up-right and the official VSCode shortcuts cards:

    • MacOSarrow-up-right

    • Windowsarrow-up-right

    circle-info

    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.

    hashtag
    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.

    circle-info

    If you don't have any tool to edit your file with the logo, you can use the Lunapicarrow-up-right free editor.

    For creating a transparent layer, you can use the Transparent Background arrow-up-righttool that is available in Lunapic.

    hashtag
    Examples of how logos are rendered

    Example of logos with one color
    Example of grayscale logos
    Example of color logos

    hashtag
    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

    hashtag
    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.

    circle-exclamation

    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.

    hashtag
    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.

    Information detailing these blocks can be found in the COMPONENT BLOCKS sectionarrow-up-right.

    When viewing module details, the tabs correspond to component blocks in the documentation.

    hashtag
    Block elements

    Block elementsarrow-up-right are like bricks for component blocks. A block doesn't exist without these elements. Multiple elements form a block.

    Pick a brick that suits your needs. You can use multiple, separated components or combine them together using the nested property.

    APP COMPONENTS sectionarrow-up-right
    Base
    Connections
    Modules
    The Make app environment main app tabs correspond to the app components in the documentation.
    hashtag
    Open module settings

    To open the module settings, double-click the module's name in the list.

    hashtag
    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.

    function formatUsername(user) {
        if (
    
    it("should format full name correctly", () => {
    
    circle-info

    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.

    circle-info

    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"

    hashtag
    Common asserts functions

    Function
    Description

    hashtag
    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.

    hashtag
    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.

    hashtag
    Development flow

    Below is a diagram explaining how a developer can develop testing and production app versions.

    hashtag
    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.

    hashtag
    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.

    hashtag
    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 .

    hashtag
    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.

    hashtag
    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.
    		]
    	}
    }
    Module names
    Module labels
    Module descriptions
  • Base

  • Connections

  • Polling triggers

  • Instant triggers (scheduled)

  • Modules

  • Remote Procedure Calls (RPCs)

  • Naming conventions
    Input parameters
    Output parameters
    Module names
  • Module labels

  • Module descriptions

  • Input parameters

    • Parameter labels

    • Parameter hints

  • Groups

  • Apps
    Modules
    circle-info

    A module name should not match any reserved word in JavaScript. See the list of reserved words in JavaScript herearrow-up-right.

    module labels
    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.

    Clone the app to the local workspace
    create a testing version of the Make app
    push the changes to the local app
    follow these steps

    "baseUrl": "https://api.geocodify.com/v2",

    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.

    "response": { "error": { // Error handling "message": "[{{body.meta.code}}] {{body.meta.error_detail}}" } },

    Instructions on how to handle errors. Note that in this case the code is the same as in the Connections component.

    "log": { "sanitize": [ "request.qs.api_key" ] }

    Instructions on the information that is saved in the logs.

    sanitize specifies what needs to be omitted.

    Note that in this case the code is the same as in the Connections component.

    Search and replace in the editor box content

    Ctrl + Space

    Show a list of code suggestions valid in the current cursor context

    Shift + Alt + F

    Format code

    Ctrl + /

    Toggle line comments

    F1

    Display web code editor command and shortcut reference

    Search and replace in the editor box content

    Ctrl + Space

    Show a list of code suggestions valid in the current cursor context

    Shift + Opt + F

    Format code

    F1

    Display web code editor command and shortcut reference

    Input parameters

    In this section, you will learn the naming conventions used for input parameters of an app.

    • Parameter labels

    • Parameter hints

    Private/Public apps

    hashtag
    Changes

    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.

    circle-exclamation

    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.

    hashtag
    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
    )
    {
    return null;
    }
    return `${user.firstName} ${user.lastName}`;
    }
    const user = { firstName: "Jane", lastName: "Doe" };
    const result = formatUsername(user);
    assert.strictEqual(result, "Jane Doe");
    });
    it("should return null if last name missing", () => {
    const user = { firstName: "Jane" };
    const result = formatUsername(user);
    assert.strictEqual(result, null);
    });

    assert.ok(value)

    Passes if value is truthy.

    assert.strictEqual(actual, expected)

    Passes if actual === expected.

    assert.deepStrictEqual(actual, expected)

    Passes if objects or arrays are deeply equal.

    assert.notStrictEqual(actual, expected)

    international time zone formatarrow-up-right
    Run IML test option

    Passes if values are not strictly equal.

    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.

    circle-info

    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.

    Read more about terms of approved app maintenance.

    App name with a custom app tag

    Mappable parameters
    Static parameters
    Processing of input parameters

    hashtag
    Edit the source code

    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.

    circle-info

    Use the shortcut CTRL+S to upload the source code back to Make.

    hashtag
    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.

    hashtag
    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.

    hashtag
    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.

    circle-exclamation

    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' visibilityarrow-up-right and the deletion of items.

    hashtag
    Generate the interface code

    Use the Interface Generator to generate an interface.

    Output labels

    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:

    • Use sentence case capitalizationarrow-up-right. Capitalize only the first word and proper nouns.

    • Use plain terms rather than API formats.

    • 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.

    circle-info

    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.

    hashtag
    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 casearrow-up-right.

    • 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.

    hashtag
    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"

    hashtag
    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"

    circle-info

    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.

    Correct group structure
    Incorrect group structure

    Configure VS Code

    To configure VS Code, first generate an API key in Make.

    Then install the Make Apps Editor. You can get the Make Apps Editor from the VS Code Marketplacearrow-up-right 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.

    circle-info

    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.

    hashtag
    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.

    hashtag
    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.

    hashtag
    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.

    circle-info

    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.

    hashtag
    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.

    hashtag
    Request app review

    After you confirm that your app complies with the prerequisites, you can .

    hashtag
    Check the review status

    The review process consists of multiple stages. You can of the review in the Flow tab.

    hashtag
    Approved app

    When Make , the app becomes available to all Make users. After approval, the process of your custom app management changes.

    hashtag
    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.

    circle-info

    When a string is stored as metadata, Make sets a limit of 512 characters.

    circle-info

    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.

    The process is different between private/public apps, and approved apps.

    hashtag
    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.

    hashtag
    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.

    You should always make sure the changes will not break existing scenarios.

    circle-info

    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:

    • Module types

    • Batch actions

    • Bulk actions

    Make a test HTTP call

    circle-info

    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.

    hashtag
    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.

    circle-info

    Track code changes

    hashtag
    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.

    circle-info

    Make sure that the base URL is a production endpoint 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 .

    hashtag
    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:

    circle-info

    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.

    hashtag
    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

    hashtag
    Rollback of changes in Make

    If you need to roll back any changes you have made so far, contact usarrow-up-right.

    best practices
    request an app review
    check the current status
    approves your app
    keep your app up to date
    approved custom app
    approval of the changes
    Search modules

    Custom IML functions

    Make DevTool or the console
    Pagination in list and search modules
    Remote Procedure Calls (RPCs)
    Interface
    Processing of output parameters

    Email address

    Email Address

    User ID

    userID or user_id

    mappable parameter labels
    Make API key
    Environment indicator
    circle-info

    In this example, the connection types are incorrectly specified.

    "headers": {
    "Authorization": "Bearer {{connection.accessToken}}"
    },
    "response": {
    "error": {
    "message": "[{{statusCode}}] {{body.error.message}} (error code: {{body.error.code}})"
    }
    },
    "log": {
    "sanitize": [
    "request.headers.authorization"
    ]
    }
    }
    module labels
    module descriptions
    ...
    "response": {
        "metadata": {
                "type": "email", //allowed values are "email" and "text"
                "value": "{{body.data.user.email}}"
            }
    },
    ...
    best practices for Base URL
    [
       {
          "name": "sandbox",
          "type": "boolean",
          "label": "Sandbox"
       },
       ...
    ]
    {
        "baseUrl": "https://{{if(connection.sandbox,'sandbox.', '')}}yourapi.com/api"
    }
    [
        {
            "name": "environment",
            "type": "select",
            "label": "Environment",
            "options": [
                {
                    "label": "EU",
                    "value": "eu"
                },
                {
                    "label": "US",
                    "value": "us"
                }
            ],
            "default": "production"
        },
        ...
    ]
    {
        "baseUrl": "https://{{connection.environment}}.yourapi.com",
        ...
    }

    X (Formerly Twitter)

    'formerly Twitter' is additional information. In this case, the additional information should be place between ( ) and the adverb should be lowercase.

    Appname

    Appname - Best tool for marketing

    An additional description or explanation should not be included in the app name. Additional information can be added to the Description field when .

    Google Ads Reports

    Google Ads reports

    'Report' is a suffix and should be capitalized.

    Instagram for Business

    Instagram For Business

    'for' is a preposition and should not be capitalized in title case.

    X (formerly Twitter)

    Ordered by RCUD logic (read, create, update, delete)
    • TRIGGERS

    • FORMS

    • TASKS

    • DEALS

    • OTHER

    FORMS

    • List forms

    • Get a form

    • Create a form

    • Update a form

    • Delete a form

    Review the Geocodify API documentation

  • Do a Postman test

  • Make an HTTP call

  • hashtag
    Get an API token

    To get your API token from Geocodify:arrow-up-right

    1

    Got to the Geocodify websitearrow-up-right 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.

    hashtag
    Review the API documentation

    To plan the HTTP call, study the Geocodify API documentationarrow-up-right, 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

    circle-info

    The documentation doesn't specify the HTTP method, but since you are retrieving coordinates, you should use the GET method.

    hashtag
    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 Postmanarrow-up-right, create a new request and add the necessary elements to make the HTTP call:

    • Method: GET

    • URL (base + endpoint): https://api.geocodify.com/v2/geocode

    • Query parameters:

      • api_key: your API key

      • q: address to search, for example Champ de Mars, 5 Avenue Anatole France, 75007 Paris, France

    2

    Click Send.

    The API responds (HTTP 200 OK successful response status code) with a JSON file containing the address information and the API key.

    If something is not working properly, use the error that the API returns to troubleshoot any issues.

    hashtag
    Make an HTTP call

    After a successful Postman test, build your call using the HTTP module in Make.

    According to the Geocodify API documentationarrow-up-right, you need to provide an API key as a query parameter.

    1

    In the Scenario Builder, add the HTTP > Make a request module.

    2

    For Authentication type, select API key.

    3

    For Credentials, click Create a keychain.

    Change the name of the new keychain if you wish, then fill in the following:

    • Key: your Geocodify API key

    • API Key placement: In the query parameters

    • API Key parameter name: api_key

    4

    Click Create.

    5

    Add the necessary information for the API call, including the address for which you want to retrieve the coordinates:

    • URL (base + endpoint): https://api.geocodify.com/v2/geocode

    • Method: GET

    6

    Click Save.

    7

    Save your scenario and click Run once.

    After a successful run, your module output can be found under Output> Data > Response > Features> 1> Geometry> Coordinates.

    You are now ready to create your custom app.

    selected the editor you want to use
    building your first app
    Get an API token from Geocodify
    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.

    hashtag
    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

    hashtag
    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.

    hashtag
    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.

    hashtag
    Correct Base URL examples

    An example from the Mailerlite app:

    {
        "baseUrl": "https://api.mailerlite.com/api/v2"
    

    An example from the Freshsales app:

    {
        "baseUrl": "https://{{connection.domain}}.freshsales.io"
    

    hashtag
    Incorrect Base URL examples

    {
        "baseUrl": "https://mydomain.freshsales.io"
    
    circle-info

    The "mydomain" should be a variable used from the Connection.

    {
        "baseUrl": "https://mailerlite.heroku.com/development"
    

    hashtag
    Using the Base URL

    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.

    circle-info

    The underlined part, which is the same for each module, should be in the Base tab.

    circle-info

    Modules "url" should start with forward slash /

    Base URL
    The solution to this varies across different platforms, but they are similar.

    One method is to use a select parameter to retrieve only the fields that you need. For example, Open Data Protocol (OData)arrow-up-right.

    GET serviceRoot/Airports?$select=Name,IcaoCode
    
    circle-info

    With Name and IcaoCode as the only output, adjust the interface to indicate to users that only these fields are available for mapping.

    Interface Generator

    Date and Time - When the activity happened.

  • Action - Name of the activity.

  • 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.

    circle-info

    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

    circle-exclamation

    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.

    hashtag
    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.

    chevron-rightLocal directoryhashtag
    1. Open Visual Studio Code and navigate to File > Open Folder.

    1. In the file manager, select the folder where the app should be cloned.

    chevron-rightGit repository using the GitHub Desktop apphashtag
    1. Navigate to the GitHub Desktop app and open the repository where you intend to store the app.

    2. Click Open in Visual Studio Code.

    hashtag
    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.

    hashtag
    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.

    circle-info

    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:

    • Custom app functionality

    • Custom app code best practices

    Review the following sections to learn more about each prerequisite.

    hashtag
    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.

    hashtag
    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.

    circle-exclamation

    The items above are mandatory for each app.

    hashtag
    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.

    circle-exclamation

    Make sure that the testing scenarios and their execution logs don't contain personal or sensitive data.

    hashtag
    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.

    hashtag
    RPC page

    Compare the tabs below to learn how to access information about your RPCs in Make.

    hashtag
    Communication tab

    After creating a new RPC, you can modify the default template in the Communications tab for your needs.

    circle-info

    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.

    hashtag
    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. .

    circle-info

    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.

    hashtag
    RPC debug tool

    The RPC debug tool works the same way modules do.

    1. Specify the connection and other fields (parameters) if needed.

    2. Click the Test button.

    3. 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.

    circle-info

    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.

    hashtag
    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 connectionsarrow-up-right 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.

    circle-info

    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.

    hashtag
    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.

    circle-info

    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).

    circle-info

    By using debug() you can understand what data you are manipulating inside a function.

    circle-info

    hashtag
    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:

    circle-info

    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.

    hashtag
    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:

    chevron-rightCommunicationhashtag

    Request app review

    Once you make sure that your app meets Make's and follows Make's , you can request an app review:

    hashtag
    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

    hashtag
    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 .

    {
    "@odata.context": "serviceRoot/$metadata#Airports(Name,IcaoCode)",
    "value": [
    {
    "@odata.id": "serviceRoot/Airports('KSFO')",
    "@odata.editLink": "serviceRoot/Airports('KSFO')",
    "Name": "San Francisco International Airport",
    "IcaoCode": "KSFO"
    },
    ......
    ]
    }

    Make updated the review status.

    App has been approved.

    Make approved your app. You app is now available to every user in Make.

    creating your app
    Avoid using APIs that don't have their own domain, or have their domain associated with service platforms like Heroku or AWS.
  • Your custom app has to use only credentials that the service requires to create a connection. Don't request any additional credentials from the user.

  • If your custom app is a scraper app, it can't include the name of a third-party service in your app or module names.

  • The connection is using a correct URL. If the user uses incorrect credentials, they get an error.
  • Modules have correct labels and descriptions.

  • The app has a universal module.

  • All modules have the correct interface depending on the output from the module.

  • All dates are formatted or parsed in the mappable parameters and interface.

  • Search modules, trigger modules, and RPCs have a limit parameter.

  • Search modules, trigger modules, and RPCs have pagination if it's supported in the service API.

  • Testing your custom app with test scenarios
    Best Practices guide
    sanitization
    error handling
    base
    follow the steps here
    Example of a test scenario
    Example of an error

    Query parameters: Parameter 1 Name: q Parameter 1 Value: Champ de Mars, 5 Avenue Anatole France, 75007 Paris, France

  • Parse response - Yes (this allows you to map the response items if needed)

  • api_key: The API key used for authentication.

    q: The address for which you want to retrieve the coordinates.

    }
    }
    }
    }

    Repeatedly the scenario increases the interval by 1, 2, 5, 10 minutes, and 1, 3, 12, and 24 hours.

    increasing time intervalsarrow-up-right
    {
      "response": {
        "error": {
          "429": {
            "type": "RateLimitError",
            "message": "{{body.message}}"
          },
          "message": "{{body.message}}"
        }
      }
    } 
    [
        {
            "help": "Your MailerLite API Key.",
            "name": "apiKey",
            "type": "password",
            "label": "API Key",
            "editable":true,
            "required": true
        }
    ]
    During the run of a module, IML functions called inside this module will also run.

    All debug messages that you specified in the IML function are available inside the developer console of your browser.

    JS Playgroundarrow-up-right
    Mozilla developer playgroundarrow-up-right
    RunJSarrow-up-right
    function add(a, b) {
        	let sum = a + b;
        
            //instead of usual console.log(), use debug().
            debug("a = " + a) 
    	debug('b = ' + b)
    	debug(`a+b = ${sum}`)
    	
    	return sum;
    }
    authorization
    sanitization
    {
    ...
        "headers": {
            "Authorization": "Token {{connection.apiKey}}"
        },
        "log": {
            "sanitize": [
                "request.headers.authorization"
            ]
        }
    ...
    }
    {
    ...
        "qs": {
            "access_token": "{{connection.accessToken}}"
        },
        "log": {
            "sanitize": [
                "request.qs.access_token"
            ]
        }
    ...
    }
    function myFunction(x) {
        x = x + 1;
        //do something
        console.log(x); // outputs the value of x at this point
        return x;
    }
    
    myFunction(1);
    {
    ...
        "headers": {
            "authorization": "Basic {{base64(connection.username + ':' + connection.password)}}"
        },
        "log": {
            "sanitize": [
                "request.headers.authorization"
            ]
        }
    ...    
    }
    {
    ...
        "body": "There is something {{parameters.secret}} hidden here.",
        "type": "raw",
        "log": {
            "sanitize": [
                "request.body<parameters.secret>"
            ]
        }
    ...
    }
  • In the pop-up window, click "Yes, I trust the authors" option.

  • The current local directory in Visual Studio is set.

    1. 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 dataarrow-up-right 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.

    Optionally, click Publish branch.
    GitHub Desktoparrow-up-right
    GUI toolarrow-up-right
    GitHub Desktoparrow-up-right
    Learn more about using RPC parameters

    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.

    chevron-rightStatic parametershashtag

    Input parameters that the user cannot map from other modules. They are only used for polling triggers, which don't have mappable parameters.

    chevron-rightMappable parametershashtag

    Input parameters in the interface that the user can either enter manually or map from the output of other modules.

    chevron-rightInterfacehashtag

    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.

    chevron-rightSampleshashtag

    Examples of data to help the users set up the module.

    hashtag
    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.

    Now you are ready to test your app.

    six different types of modules
    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.

    circle-exclamation

    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

    hashtag
    Review process

    The review process contains three phases: form submission, automatic review, and manual review.

    hashtag
    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.

    hashtag
    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.

    circle-info

    The automatic review is in beta and is still in the process of improvement. Therefore, there might be inconsistencies.

    hashtag
    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.

    requirements
    best practicesarrow-up-right

    Error handling

  • Sanitization

  • Key
    Type
    Description

    baseUrl

    String

    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",
    
    circle-info

    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.

    hashtag
    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.

    circle-info

    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):

    circle-info

    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.

    Base URL
    Authorization
    the results can be sorted or defaulted in descending order.
    circle-info

    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.

    hashtag
    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.

    circle-info

    The code is missing a limit parameter.

    circle-info

    The code includes a limit parameter.

    hashtag
    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.

    circle-info

    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.

    circle-info

    In this module example, there aren't any required From or To fields.

    circle-info

    The mapped data.lastDate IML variable is available to the user in the Choose where to start setting, defined in the .

    circle-info

    The behavior of the supported options:

    circle-info

    The List campaigns module in this example is incorrectly identified as an Action module.

    circle-info

    The List campaigns module in this example is correctly identified as a Search module.

    hashtag
    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.

    Make sure the universal module has the:

    • correct label and description,

    • correct url which starts with the base URL, and

    • correct connection.

    modules
    best practices guide to module descriptions

    Connections

    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:

    1. to get any relevant information from the user that adds the connection (credentials, API key, etc.)

    2. to process the authentication

    3. 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:

    chevron-rightRequesthashtag

    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.

    chevron-rightResponsehashtag

    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.

    chevron-rightLoghashtag

    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}}.

    hashtag
    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.

    2

    Fill in the details of your connection.

    Continue to set up the .

    Remote Procedure Calls

    Remote procedure calls (RPCs) are used to retrieve live data from a service for an input field.

    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.

    circle-info

    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.

    hashtag
    Mode edit

    hashtag
    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.

    hashtag
    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.

    hashtag
    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.

    hashtag
    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.

    hashtag
    Make an API Call parameters: non-editable connection

    {
    	"type": "banner",
    
    circle-info

    If you encounter the warning String is longer than the maximum length of 256. , wrap it in an RPC.

    hashtag
    Make an API Call parameters: editable connection

    hashtag
    Connection parameters

    hashtag
    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.

    hashtag

    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

    circle-info

    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

    • fixing bugs the users report

    {
    	"secret": "AABBCCDD"
    }
    {
    	"baseUrl": "https://www.example.com",
    	"headers": {
    		"Signature": "{{common.secret}}"
    	}
    }
    {
    	"timeout": 300000
    }
    {
    	"url": "https://www.example.com",
    	"method": "GET",
    	"timeout": "{{common.timeout}}"
    }
    submitting API checkups
  • 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.

    hashtag
    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.

    circle-exclamation

    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.

    hashtag
    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.

    hashtag
    Feature requests on Make Idea Exchange

    When Make users miss a feature in an app, they can submit a new request to the App Improvement Ideas boardarrow-up-right.

    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.

    "headers": {
    "authorization": "Basic {{base64(connection.username + ':' + connection.password)}}"
    },
    "response": {
    "valid": {
    "condition": "{{body.status != 'error'}}"
    },
    "error": {
    "200": {
    "message": "{{ifempty(errors(body.message), body.message)}}"
    },
    "message": "[{{statusCode}}]: {{body.reason}}"
    }
    },
    "log": {
    "sanitize": [
    "request.headers.authorization"
    ]
    }
    }

    qs

    Object

    Default query string parameters that every module will use.

    body

    Object

    Default request body that every module will use when issuing a POST or PUT request.

    response

    Object

    Default directives for handling response, such as error handling.

    log

    Object

    Default directive for handling logs, such as sanitization of sensitive data.

    oauth

    OAuth 1.0 Parameter Specification

    Collection of directives containing parameters for the OAuth 1 protocol.

    Dialog window requesting the confirmation of trusting the authors of the code
    make.com integrations pagearrow-up-right

    Provides longitude, latitude, and place details of a location (address, name of a place, or location).

    Parameter name displayed in the module setup.

    type

    Required. Type of the parameter.

    help

    Instructions for the user displayed in the module setup. It supports Markdown for text formatting.

    required

    Specifies if the parameter is required.

    The default method is GET, so it could have been omitted in this case.

    qs

    Query parameter containing the location to geolocate. Note that you access it by using parameters.location_info.

    response

    Defines the output returned, which in this case is the whole body of the response.

    Template

    Blank module (you will set it up from scratch)

    Type

    Search (to retrieve geolocation details)

    Connection

    Geocodify API Key (the connection you have created earlier)

    Name

    geocode

    Label

    Search geolocation

    name

    Required. Internal name of the parameter. Use it when you want to access the parameter using {{parameters.name}}.

    url

    The API endpoint. Since it starts with /, it is joined to the base URL. Note that if the URL starts with https://, it will override the base URL.

    Description

    label

    method

  • From now on - The current date will be sent.

  • Since specific date - The date provided will be sent.

  • Choose manually - The date of the chosen item will be sent.

  • All - The default date 1970-01-01 will be sent.

  • Epoch tab
    Example of a missing limit
    "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
    	}
    }
    ...
    "qs": {
             "from": "{{data.lastDate}}",
             "to": "{{now}}"
          },
    ...
    
    "mode": "edit",
    {
        "name": "userId",
        "type": "select",
        "label": "User ID",
        "options": "rpc://getUsers",
        "mode": "edit"
    }
    {
        "name": "userId",
        "type": "select",
        "label": "User ID",
        "options": "rpc://getUsers"
    }
     {
    	"url": "/contacts",
    	"method": "GET",
    	"qs": {
    		"pageSize": 25
    	},
    	"response": {
    		"limit": 75
    		"output": {
    			"label": "{{item.displayname}}",
    			"value": "{{item.id}}"
    		},
    		"iterate": "{{body.data}}"
    	},
    	"pagination": {
    		"condition": "{{pagination.page <= 3}}",
    		"qs": {
    			"page": "{{pagination.page}}"
    		}
    	}
    }
     {
    	"url": "/contacts",
    	"method": "GET",
    	"qs": {
    		"pageSize": 25
    	},
    	"response": {
    		"output": {
    			"label": "{{item.displayname}}",
    			"value": "{{item.id}}"
    		},
    		"iterate": "{{body.data}}"
    	},
    	"pagination": {
    		"qs": {
    			"page": "{{pagination.page}}"
    		}
    	}
    }
    {
    	"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
        }
    ]
    {
        "authorize": {
            "qs": {
                "scope": "{{join(distinct(merge(oauth.scope, ifempty(parameters.additionalScopes, emptyarray))), ',')}}",
                ...
            },
            "url": "...",
            "response": {
                "temp": {
                    "code": "{{query.code}}"
                }
            }
        }
    }
    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.

    8

    Copy and paste the following code:

    Code
    Description

    "url": "https://api.geocodify.com/v2/geocode", "qs": { "api_key": "{{parameters.apiKey}}" },

    Request that the apps engine makes to validate the credentials.

    • url: Absolute URL of the endpoint that is used for validation.

    • qs: Query string.

    • api_key: Key of the qs parameter as specified by the API docs. This means that it will use the apiKey that the user provides.

    "response": { "error": { "message": "[{body.meta.code}}] {body.meta.error_detail}}" } },

    9

    Click Save changes.

    Base
    hashtag
    Iteration and pagination

    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.

    hashtag
    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.

    circle-info

    The pagination directive contains "since", "until" and "limit" parameters that are already defined in query string ("qs").

    circle-info

    The pagination directive correctly contains only the "offset" parameter.

    hashtag
    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.

    hashtag
    Examples

    hashtag
    ActiveCampaign

    ActiveCampaign API pagination documentationarrow-up-right:

    Parameter
    Description

    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.

    In this case, set limit to 100 in the request.

    hashtag
    Productive

    Productive API pagination documentationarrow-up-right:

    Parameter
    Description

    current_page

    1 by default or the value you put in page[number]

    total_pages

    total_count/page_size rounded up

    total_count

    Total number of resources you have

    page_size

    In this case, set page_size to 200.

    hashtag
    Limiting output

    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.

    circle-info

    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.

    Search modules
    action modules
    {
        "url": "/users",
        },
        "response": {
            "output": "{{item}}",
            "iterate": "{{body.data}}",
            "limit": "{{parameters.limit}}"
        }
    }
    Error handling example

    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": 
    
    circle-info

    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": 
    
    circle-info

    The error object in this example contains the code and message fields, but not a text field.

    hashtag
    Common error messages

    hashtag
    4xx: Client Error

    4xx errorsarrow-up-right indicate something wrong on the client side.

    hashtag
    5xx: Server Error

    5xx errorsarrow-up-right indicate something wrong on the side of the third-party service.

    hashtag
    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.

    circle-info

    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:

    circle-info

    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:

    circle-info

    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.

    error handling
    Be descriptive, not instructional. If the selection needs more explanation, include information in the help text below the field.
  • Use sentence case capitalizationarrow-up-right. The following should be capitalized:

    • The first word of the label

    • 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.

  • hashtag
    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.

    circle-info

    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.

    hashtag
    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:

    1. End result (mandatory): Clearly describes what the module achieves.

    2. 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.

    3. 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.

    hashtag
    Watch modules

    Watch modules watch for new data in a service and return it. They are trigger and instant trigger (webhook) modules.

    circle-info

    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

    hashtag
    Action modules

    Action modules write data into a service, modify data in a service, or retrieve a single result.

    circle-info

    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

    hashtag
    Search modules

    Search modules retrieve data from a service and allow for one or more results.

    circle-info

    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

    hashtag
    Universal modules

    Universal modules are modules used to make an API call or query when a pre-built module does not exist.

    circle-info

    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

    hashtag
    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.

    hashtag
    Search modules

    hashtag
    Action modules

    hashtag
    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.

    hashtag
    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

    hashtag
    Examples

    hashtag
    Pipedrive

    Part of the response from Pipedrive API /activities :

    from Pipedrive

    Field
    Parse?
    Reason

    hashtag
    Virtuagym

    Part of the response from Virtuagym API /api/v0/activity:

    Field
    Parse?
    Reason

    hashtag
    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.

    circle-info

    Read more about error handling in the Help Center:

    circle-exclamation

    When the service returns an HTTP error, it is not possible to evaluate it as a success.

    hashtag
    Error handling: 401 error

    circle-info

    With error handling, details of the error are available and the user will know how to solve the problem.

    hashtag
    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.

    hashtag
    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.

    hashtag
    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.

    hashtag
    Available error types

    When handling an error, you can specify the type of the error.

    Error type
    Description

    hashtag
    Error handling with type

    Tools

    The Tools section of the Make DevTool has useful features that can help you build your scenario.

    hashtag
    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.

    hashtag
    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": "/clients",
        "method": "GET",
        "qs": {
            "per_page": 100
        },
        "response": {
            "limit": "{{parameters.limit}}",
            "output": "{{item}}",
            "iterate": "{{body.clients}}"
        },
        "pagination": {
            "qs": {
                "page": "{{pagination.page}}"
            },
            "condition": "{{body.next_page}}"
        }
    }
    {
            "name": "limit",
            "label": "Limit",
            "type": "uinteger",
            "help": "Number of clients to return",
            "default": 10
        }
    ]
    {
    	"url": "/items",
    	"method": "GET",
    	"qs": {
    		"id": "{{parameters.itemId}}"
    	},
    	"response": {
    		"output": "{{body.items[1]}}"
    	}
    }
    {
    	"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."
    }
    }
    {
    "message": "[{{statusCode}}] {{body.error.message}} (error code: {{body.error.code}})"
    }
    }
    {
    "message": "{{body.error.text}}"
    }
    }
    hashtag
    Find module(s) by mapping

    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.

    hashtag
    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.

    hashtag
    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.

    hashtag
    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.

    hashtag
    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.

    hashtag
    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.

    hashtag
    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.

    hashtag
    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.

    hashtag
    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.

    hashtag
    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.

    hashtag
    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.

    hashtag
    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.

    hashtag
    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.

    hashtag
    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).

    hashtag
    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.

    Parameter name as displayed in the module.

    type

    Required. Data type of the parameter.

    help

    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.

    API documentation: Date formatarrow-up-right
    implementing dynamic mappable parameters using a custom IML function

    duration

    RateLimitError

    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.

    InconsistencyError

    DataError

    Introduction to errors and warningsarrow-up-right
    Overview of error handlingarrow-up-right
    Error handlersarrow-up-right
    Error in Make DevTool
    Error with no detail message
    Error with a detail message

    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": {
        "output": "{{item}}",
        "iterate": "{{body}}"
    }
    "response": {
        "output": {
            "id": "{{item.id}}",
            "name": "{{item.name}}"
        },
        "iterate": "{{body}}"
    }
    "response": {
        "output": "{{body}}"
    }
    "response": {
        "output": {
            "id": "{{body.id}}",
            "name": "{{body.name}}"
        }
    }
    [
        {
            "id": 8,
            "due_date": "2022-06-09",
            "due_time": "10:00",
            "duration": "01:00",
            "add_time": "2020-06-08 12:37:56",
            "marked_as_done_time": "2020-08-08 08:08:38",
            "update_time": "2020-08-08 12:37:56"
        }
    ]
    {
        "act_inst_id": 25957,
        "timestamp_edit": 1319816131,
        "timestamp": 1319796000
    }
    {
        // ...
        "response": {
            "error": {
                "message": "[{{statusCode}}] {{body.error}}"
            }
        },
        // ...
    }
    {
        "response": {
            "error": {
                "type": "RuntimeError",
                "message": "[{{statusCode}}] {{body.error.message}}",
                "400": {
                    "type": "DataError",
                    "message": "[{{statusCode}}] {{body.error.message}}"
                },
                "500": {
                    "type": "ConnectionError",
                    "message": "[{{statusCode}}] {{body.error.message}}"
                }
            }
        }
    }
    {
        "response": {
                "valid": {
                    "condition": "{{body.status != 'error'}}"
                },
                "error": {
                    "200": {
                        "message": "{{ifempty(errors(body.message), body.message)}}"
                    },
                    "message": "[{{statusCode}}]: {{body.reason}}"
                }
            }
    }
    {
        "response": {
            "error": {
                "message": "Generic error message",
                "400": {
                    "message": "Your request was invalid"
                },
                "500": {
                    "message": "The server was not able to handle your request"
                }
            }
        }
    }
    {
        "response": {
            "error": {
                "type": "DataError",
                "message": "[{{statusCode}}] {{body.message}}"
            }
        }
    }
    Breaking Changes

    Base

    Any changes might break scenarios.

    Connection

    Changing the refresh call for OAuth connection.

    Module's Communication

    Changing response.output.

    Changing response.type.

    Adding response.valid for 2xx response.

    Changing response.trigger.

    Adding a condition

    Module's Parameters

    Adding a new required parameter.

    Changing required from false to true.

    Removing a parameter.

    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.

    hashtag
    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:

    1. 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.

    1. 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.

    1. 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.

    hashtag
    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.

    hashtag
    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.

    help deskarrow-up-right

    Parameter hints

    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

    hashtag
    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.

    1. Expected input

    2. Result

    3. Example

    4. Additional information

    Information type
    Description
    Example

    hashtag
    Connection field hints

    hashtag
    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

    hashtag
    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

    hashtag
    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

    hashtag
    Limit field hints

    Location
    Field
    Format
    Link
    circle-info

    The Limit field should also be the last standard field in the module. It should not be in the advanced settings.

    hashtag
    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

    hashtag
    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 casearrow-up-right. 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.

    hashtag
    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

    hashtag
    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

    hashtag
    Search modules

    Search modules retrieve data from a service and allow for one or more results.

    Module type
    Format (plural)
    Correct
    Note

    hashtag
    Bulk modules

    Bulk modules can perform an action on multiple records in a single call.

    Format (plural)
    Correct

    hashtag
    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

    hashtag
    Mapping all parameters

    circle-info

    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.

    circle-info

    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.

    RPC

    Changing parameter required from false to true.

    Changing RPCs building dynamic parameters.

    Custom Functions

    Any changes might break scenarios.

    type coercionsarrow-up-right

    Watch updated contacts

    Watch contacts updated

    Watch deleted [item]s

    Watch deleted contacts

    Watch contacts deleted

    Create or Update

    Create or update a/an [item]

    Create or update a record

    Create or update a vector

    Upsert a record

    Delete

    Delete a/an [item]

    Delete a message

    Delete a user from a list

    Download

    Download a/an [item]

    Download a message

    Download an image

    Generate

    Generate a/an [item]

    Generate an image

    Generate an audio file

    Get

    Get a/an [item]

    Get a message

    Get a user

    Invite

    Invite a/an [item]

    Invite a user

    Invite a user to a channel

    Remove

    Remove a/an [item]

    Remove a reaction

    Remove a user from a list

    Send

    Send a/an [item]

    Send a message

    Send an email to a team member

    Update

    Update a/an [item]

    Update a message

    Update a product variant

    Upload

    Upload a/an [item]

    Upload an image

    Upload a product image

    Search modules are those that have one or more filtering options.

    List folder items (BETA)

    Advanced, beta (both tags)

    Module name (advanced) (beta)

    Update a campaign (advanced) (beta)

    Update a campaign (advanced, beta)

    Deprecated

    Module name (deprecated)

    Send a message (deprecated)

    Send a message (Deprecated)

    Rebrand

    Module name (formerlyl [name])

    X (formerly Twitter)

    X (Formerly Twitter)

    Watch [item]s

    Watch contacts

    Watch a contact

    Watch new [item]s

    Watch new contacts

    Watch contacts created

    Add

    Add a/an [item]

    Add a reaction

    Add a user to a list

    Create

    Create a/an [item]

    List

    List [item]s

    List users

    List entity types

    List modules are those that have no filtering options.

    Search

    Search [item]s

    Bulk [action] [parameter] (advanced)

    Bulk upload call conversions (advanced) Bulk create folders (advanced)

    Advanced

    Module name (advanced)

    Search rows (advanced)

    Search rows (Advanced module)

    Beta

    Module name (beta)

    Watch updated [item]s

    Create a message

    Create a completion

    Search users

    Search contacts

    List folder items (beta)

    What if left empty

  • Link

  • 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.

    1. 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.

    1. What if left empty

    Describe the impact of not entering a value.

    Format

    If left empty, default formatting is used.

    1. 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

    1. 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.

    1. 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 Centerarrow-up-right. 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 API key, see the Instantly API documentationarrow-up-right.

    Our Help Center

    For details on how to obtain your [client ID or client secret], see our Help Center.

    For details on how to obtain your client secret, see our Help Centerarrow-up-right. Link to apps.make.com/[your-app-slug]

    Third-party resource:

    API docs

    For details on how to obtain your [client ID or client secret], see the [app name] API documentation.

    For details on how to obtain your client secret, see the Hotmart API documentationarrow-up-right.

    Third-party resource:

    other than API docs

    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 Centerarrow-up-right.

    Polling trigger

    Limit

    Maximum number of results to return. For information about setting limits, see our Help Centerarrow-up-right.

    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.

    1. 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": "
    
    circle-info

    With this approach, all parameters from the modules will be sent to the API.

    [
        {
            "name": "
    

    hashtag
    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.

    circle-info

    In this example you have to map every parameter correctly.

    There is a risk of a typo or omission of a parameter.

    circle-info

    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.

    hashtag
    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.

    hashtag
    Bad practices

    circle-info

    It isn't possible to send a null value to a service.

    circle-info

    It isn't possible to send a null, empty string, and 0 (zero) value to a service.

    circle-info

    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.

    hashtag
    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.

    circle-info

    The same automatic encoding applies to the headers and body collections for request headers and body payloads, respectively.

    This will issue the request to URL in this way:

    http://yourservice.com/api/items?limit=100&since=2023-01-01&until=2023-01-31

    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.

    hashtag
    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.

    circle-info

    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.

    hashtag
    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.

    circle-info

    This will issue the request to URL in this way:

    http://yourservice.com/api/items?anytag=one&anytag=two&anytag=three

    hashtag
    Using structured data in qs

    circle-info

    qs (and also headers) are single-level collections only, meaning that you cannot specify a nested collection in their parameters.

    circle-info

    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.

    circle-info

    This will issue the request with the query string:

    ?someProp.anotherOne.and-one-more=THIS%20WILL%20WORK

    {
        ...
        "body": {
            "firstName": "{{parameters.firstName}}",
            "lastName": "{{parameters.lastName}}",
            "email": "{{parameters.email}}"
        },
        // ... other directives
    }

    to avoid receiving misleading or incorrect error messages and,

  • to allow users to set up error handling for individual modules.

  • hashtag
    Exceptions

    The following are exceptions when you may want to use a batch action:

    • PUT vs PATCH behavior in update modules

    • Get a record after update

    • Upload a file

    • \

    hashtag
    PUT vs PATCH behavior in update modules

    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

    1. Get record by ID

    2. PUT the record patched by user’s input

    hashtag
    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).

    hashtag
    Get a record after update

    Some services only return an ID after a record update.

    Chain of actions: Write > Read

    1. Update the record

    2. Get the record by ID

    hashtag
    Example

    • Workday Financial Management > Update a Supplier Invoice

    hashtag
    Upload a file

    hashtag
    Upload in chunks

    Chain of actions: Write > Write > … > Write

    circle-info

    This is an exception to the rule that combines multiple Write actions. These requests are designed to be used in sequence.

    1. Create an upload session

    2. Keep sending chunks

    3. Finalize the upload

    hashtag
    Example

    • Dropbox > Upload a File

    hashtag
    Download a file

    hashtag
    Download by media ID

    Chain of actions: Read > Read

    1. Get the media ID

    2. Download file by media ID

    hashtag
    Example

    • WhatsApp Business Cloud > Download a Media

    • Telegram Bot > Download a File

    hashtag
    Asynchronous process

    Requests involving processes running asynchronously on 3rd party service.

    Chain of actions: Write > Read > Read > … > Read

    1. Start the task

    2. Keep polling for task status

    3. Get the result when done

    hashtag
    Example

    • Microsoft Power Automate: Trigger a Desktop Flow

    hashtag
    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.

    hashtag
    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.

    hashtag
    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:

    1. Create a call

    2. Check the status of the call

    3. Request the result of the call

    hashtag
    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.

    circle-info

    When the repeat directive is used, the condition and limit should always be provided to prevent infinite loops.

    {
        "url": "/contact/{{parameters.id}}",
        "method": "PUT",
        "body": {
            "email": "{{parameters.email}}",
            "firstName": "{{parameters.firstName}}",
            "lastName": "{{parameters.lastName}}",
            "registrationDate": "{{formatDate(parameters.registrationDate, 'YYYY-MM-DD')}}"
            
        },
        // ...
    }
    {
        "url": "/contact/{{parameters.id}}",
        "method": "PUT",
        "body": {
            "{{...}}": "{{omit(parameters, 'id', 'registrationDate')}}",
            "registrationDate": "{{formatDate(parameters.registrationDate, 'YYYY-MM-DD')}}"
        },
        // ...
    }
    {
        "url": "/messages.json",
        "method": "POST",
        "body": {
            "status": "active",
            "content": "{{ifempty(parameters.content, undefined)}}"
        },
        // ...
    }
    {
        "url": "/messages.json",
        "method": "POST",
        "body": {
            "status": "active",
            "content": "{{if(parameters.content, parameters.content, undefined)}}"
        },
        // ...
    }
    {
        "url": "http://yourservice.com/api/items",
        "qs": {
            "limit": 100,
            "since": "{{parameters.since}}",
            "until": "{{parameters.until}}"
        }
        // ... other directives
    }
    {
        "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",
        // ...
    }
    {
        "url": "http://yourservice.com/api/items",
        "qs": {
            "anytag": ["one", "two", "three"]
        }
    }
    {
        "qs": {
            "person": {
                "address": {
                    "street": "123 Main Street"
                }
            }
        }
    }
    {
       "qs": {    
         "person.address.street": "changethis"
        }
    }
    {
        {
        "url": "/webservice.php", 
        "method": "GET",
        "qs": {
            "id": : "{{parameters.object}}",
            "operation": retrieve"
            },
             "response": {
                 "temp": {
                     "fields": "{{body.results[]}}"
                 }
             }
        },
         {
             "url": "/webservice.php",
             "method":"POST",
             "type": "urlencoded", 
             "body": {
                 "operation": "revise",
                 "elementType": "{{parameters.elementType}}", 
                 "element": "{{stringifyFields(parameters, 'revise', temp.fields)}}
         },
         "response": {
             "output": "{{objectResponse(body.result)}}"
         }
     }
     }
             
    {
        "last_name": "Smith",
        "contact_id" : "12345",
        "first_name" : null,
        "company_name" : "Acme Company"
    }
    [
    	{
    		"url": "/v3/activities/contacts_json_import",
    		"method": "POST",
    		"body": "{{encodeParameters(parameters)}}",
    		"response": {
    			"temp": "{{parseResponse(body)}}"
    		}
    	},
    	{
    		"url": "{{temp._links.self.href}}",
    		"method": "GET",
    		"repeat": {
    			"condition": "{{body.state != 'completed'}}",
    			"delay": 1000,
    			"limit": 300
    		},
    		"response": {
    			"temp": "{{body}}"
    		}
    	},
    	{
    		"response": {
    			"valid": "{{length(temp.activity_errors) = 0}}",
    			"error": {
    				"message": "{{join(temp.activity_errors, '\n')}}"
    			},
    			"output": "{{parseResponse(temp)}}"
    		}
    	}
    ]
    {{parameters}}
    "
    ,
    // ...
    }
    email
    "
    ,
    "type": "email",
    "label": "Email address",
    "required": true
    },
    {
    "name": "firstName",
    "type": "text",
    "label": "First Name",
    "required": true
    },
    {
    "name": "lastName",
    "type": "text",
    "label": "Last Name",
    "required": true
    }
    ]
    [
        {
            "name": "id",
            "type": "string",
            "label": "Contact ID",
            "required": true
        },
        {
            "name": "email",
            "type": "email",
            "label": "Email address"
        },
        {
            "name": "firstName",
            "type": "text",
            "label": "First Name"
        },
        {
            "name": "lastName",
            "type": "text",
            "label": "Last Name"
        },
        {
            "name": "registrationDate",
            "type": "date",
            "label": "Date of Registration"
        }
    ]
    {
        "url": "/tasks.json",
        "method": "POST",
        "body": {
            "status": "active",
            "tags": "{{if(length(parameters.tags) > 0, parameters.tags, undefined)}}"
        },
        // ...
    }

    Module example

    Example scenarios

    The scenario contains module, which has the synchronous logic implemented on app's side.

    The first scenario contains module which has asynchronous approach by default. The only result is the job's ID.

    Download a file
    Asynchronous process
    OpenAI Voice options guidearrow-up-right
    Shopify App Development blogarrow-up-right
    Security pagearrow-up-right
    Anthropic Console API keys pagearrow-up-right
    Help Centerarrow-up-right
    CloudConvert > Convert a Filearrow-up-right
    CloudConvert > Create a Job (advanced)arrow-up-right
    Convert files from Google Drive in CloudConvertarrow-up-right
    Convert a Filearrow-up-right
    Create an archive job in CloudConvertarrow-up-right
    Download files from the job in CloudConvertarrow-up-right
    Create a Job (advanced)arrow-up-right

    Authorization

    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.

    hashtag
    Common methods of authorization

    hashtag
    API key in headers

    hashtag
    API key in query string

    hashtag
    OAuth 2 access token in headers

    {
        "headers": {
            "x-api-key": "{{connection.apiKey}}"
        }
    }
    {
        "qs": {
            "apikey": "{{connection.apiKey}}"
        }
    }
    {
        "headers": {
            "authorization": "Bearer {{connection.accessToken}}"
        }
    }

    Mappable parameters

    A mappable parameter is a variable or setting that you can change or link (map) to another value.

    hashtag
    Types of fields

    You can use mappable parameters in many types of fields:

    chevron-rightStandard fieldshashtag
    • Visible by default

    • Frequently used

    • Typically easy to understand

    • Visible on the third-party’s Web UI by default

    chevron-rightAdvanced fieldshashtag
    • Hidden by the Advanced settings toggle

    • Not needed by the majority of users

    chevron-rightRequired fieldshashtag
    • Require minimal effort to make the module work

    • Validate if the user has filled in all necessary fields required by the API call

    chevron-rightConditionally-required fieldshashtag
    • Required based on a condition. For example:

      • Either field A or field B is required

    chevron-rightOptional fieldshashtag
    • 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

    chevron-rightStatic, dynamic, and semi-dynamic fieldshashtag

    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.

    chevron-rightCustom fieldshashtag

    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.

    hashtag
    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.

    circle-info

    Exception: If the endpoint accepts date only or time only, use the text parameter with a clear hint and example.

    hashtag
    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.

    circle-info

    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:

    circle-info

    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:

    hashtag
    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.

    hashtag
    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.

    hashtag
    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:

    1. 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.

    hashtag
    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.

    circle-info

    After switching on the mapping toggle, the text fields disappear.

    circle-info

    "mappable": false

    hashtag
    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.

    hashtag
    Information (blue)

    hashtag
    Warning (yellow)

    hashtag
    Danger (red)

    hashtag
    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.

    chevron-rightModule guidelines for the ID finderhashtag

    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

    chevron-rightID finder guidelineshashtag

    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.

    circle-info

    chevron-rightID finder resultshashtag

    If the API allows, the ID finder’s results should be listed in alphabetical order.

    chevron-rightID finder templatehashtag

    hashtag
    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.

    hashtag
    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.

    hashtag
    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.

    hashtag
    Search filters

    circle-info

    Provide a list of fields and a list of operators.

    circle-info

    Group operators by their data types

    hashtag
    Labels

    Labels are available for:

    • Array(s)

    • Array item(s)

      • Default to Item

    hashtag
    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.

    circle-info

    Even though this will be sent correctly, it is not user-friendly.

    circle-info

    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:

    circle-info

    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:

    circle-info

    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.

    circle-info

    Do not ask users to construct the query string.

    circle-info

    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).
    dynamic fields RPCs
    {
        "url": "/api/users",
        "method": "POST",
        "body": {
            "name": "{{parameters.name}}",
            "birthday": "{{parameters.birthday}}",
            "due_date": "{{parameters.due_date}}"
        },
        "response": {
            "output": "{{body}}"
        }
    }
    [
        {
            "name": "name",
            "type": "text",
            "label": "Name"
        },
        {
            "name": "birthday",
            "type": "date",
            "label": "Birthday",
            "help": "Format YYYY-MM-DD"
        },
        {
            "name": "due_date",
            "type": "integer",
            "label": "Due Date",
            "help": "Enter a timestamp"
        }
    ]
    {
        "url": "/api/users",
        "method": "POST",
        "body": {
            "name": "{{parameters.name}}",
            "birthday": "{{formatDate(parameters.birthday, 'YYYY-MM-DD')}}",
            "due_date": "{{formatDate(parameters.due_date, 'X')}}"
        },
        "response": {
            "output": "{{body}}"
        }
    }
    [
        {
            "name": "name",
            "type": "text",
            "label": "Name"
        },
        {
            "name": "birthday",
            "type": "date",
            "label": "Birthday"
        },
        {
            "name": "due_date",
            "type": "date",
            "label": "Due Date"
        }
    ]
    [
    	{
    		"name": "array",
    		"type": "array",
    		"label": "PDF documents",
    		"required": true,
    		"spec": {
    			"type": "collection",
    			"label": "Document",
    			"spec": [
    				{
    					"name": "name",
    					"type": "filename",
    					"label": "Name",
    					"semantic": "file:name",
    					"required": true
    				},
    				{
    					"name": "data",
    					"type": "buffer",
    					"label": "Data",
    					"semantic": "file:data",
    					"required": true
    				}
    			]
    		},
    		"labels": {
    			"add": "Add document"
    		}
    	}
    ]
    {
        "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"
    }
    {
        "name": "recordId",
        "type": "text",
        "label": "Record ID",
        "rpc": {
            "label": "ID finder",
            "url": "rpc://...",
            "parameters": [
                {
                    "type": "banner",
                    "text": "If you don't see the result you're looking for, try more specific search criteria.",
                    "theme": "info"
                },
                {
                    "name": "query",
                    "type": "text",
                    "label": "Query"
                }
            ]
        }
    }
    //If the API is expecting an array of collection
    // {
    //     "recipients": [
    //         {
    //              "name": "abc"
    //         }
    //     ]
    // }
    [
    	{
    		"name": "recipients",
    		"type": "array",
    		// Label of the array
    		"label": "Recipients",
    		"spec": {
    			"type": "collection",
    			// Label of array item(s)
    			"label": "Recipient",
    			"spec": [
    				{
    					"name": "name",
    					"type": "text",
    					"label": "Name",
    					"required": true
    				}
    			]
    		},
    		"labels": {
    			// Label of the button to add an array item
    			"add": "Add recipient"
    		}
    	}
    ]
    // If the API is expecting a primitive array
    // {
    //     "recipients": [
    //         "name-abc"
    //     ]
    // }
    [
    	{
    		"name": "recipients",
    		"type": "array",
    		// Label of the array
    		"label": "Recipients",
    		"spec": {
    			"type": "text",
    			// Label of array item(s)
    			"label": "Recipient name"
    		},
    		"labels": {
    			// Label of the button to add an array item
    			"add": "Add recipient name"
    		}
    	}
    ]
    Select by file path
  • Select from list

  • Enter manually

  • Etc.

  • Hint: Must be the exact
    Channel name
    .
    Help Centerenvelope

    Connections

    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

    circle-info

    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.

    circle-info

    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.

    hashtag
    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.

    hashtag
    Visual Studio Code

    You can get the extension from the or install it in the Extensions tab in VS Code.

    hashtag
    Vibe coding

    Coming soon.

    VS Code
    VS Code Marketplacearrow-up-right

    Instant triggers (scheduled)

    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.

    hashtag
    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

    hashtag
    Example - Constant Contact

    hashtag
    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.

    hashtag
    Example - Highlevel OAuth 2.0

    {
    	"info": {
    		"url": "https://api.cc.email/v3/account/summary",
    		"method": "GET",
    		"headers": {
    			"authorization": "Bearer {{connection.accessToken}}"
    		},
    		"response": {
    			"error": {
    				"message": "[{{statusCode}}]\n{{parseError(body)}}"
    			},
    			"uid": "{{body.encoded_account_id}}",
    			"metadata": {
    				"type": "text",
    				"value": "{{body.contact_email}}"
    			}
    		},
    		"log": {
    			"sanitize": ["request.headers.authorization"]
    		}
    	}
    }
    {
    	"url": "https://services.leadconnectorhq.com/locations/{{connection.locationId}}",
    	"method": "GET",
    	"headers": {
    		"Authorization": "Bearer {{connection.accessToken}}",
    		"Version": "2021-07-28"
    	},
    	"response": {
    		"uid": "{{connection.locationId}}",
    		"metadata": {
    			"type": "text",
    			"value": "Location: {{body.location.name}}"
    		}
    	},
    	"log": {
    		"sanitize": [ "request.headers.authorization" ]
    	}
    }
    {
        "type": "ContactCreate",
        "locationId": "ve9EPM428h8vShlRW1KT",
        "id": "nmFmQEsNgz6AVpgLVUJ0",
        "address1": "3535 1st St N",
        "city": "ruDolomitebika",
        "state": "AL",
        "companyName": "Loram ipsum",
        "country": "DE",
        "source": "xyz form",
        "dateAdded": "2021-11-26T12:41:02.193Z",
        "dateOfBirth": "2000-01-05T00:00:00.000Z",
        "dnd": true,
        "email": "[email protected]",
        "name": "John Deo",
        "firstName": "John",
        "lastName": "Deo",
        "phone": "+919509597501",
        "postalCode": "452001",
        "tags": [
            "id magna sed Lorem",
            "Duis dolor commodo aliqua"
        ],
        "website": "https://www.google.com/",
        "attachments": [],
        "assignedTo": "nmFmQEsNgz6AVpgLVUJ0"
    }