Dynamic options RPC
You can use the dynamic options RPC to display dynamic options for a specific select field or use a search button to help the users find a specific item and map it to the field.
Syntax of RPC output
The output of the RPC must be an array of objects, each with a label and a value.
The label is what the user sees when selecting items from the select dropdown/search button, while the value is what is sent to the API once the module is executed.
You must define a limit to the output if the API endpoint returns a large number of items (>500)
You can optionally use "default": true to automatically pre-select the first item from the RPC response. This works for select parameters, but should not be used for search buttons.
"response": {
"limit": 500,
"iterate": "{{body.users}}",
"output": {
"label": "{{item.name}}",
"value": "{{item.id}}",
"default": true
}
}"response": {
"iterate": "{{body.users}}",
"output": "{{item}}"
}Select parameter
Select parameter with dynamic options
You can customize labels and values by combining multiple properties together. For example:
"label": "{{item.name}}"or"label": "{{item.firstname + ' ' + item.lastname}}"
Both are accepted.


[
{
"name": "status",
"type": "select",
"options": "rpc://NameOfMyRemoteProcedure",
"label": "Status"
}
]{
"url": "/status",
"method": "GET",
"response": {
"iterate": "{{body.data}}",
"output": {
"label": "{{item.optionName}}",
"value": "{{item.optionID}}"
}
}
}Filtering options in an RPC
If your RPC returns unwanted items, you can filter them out by using the iterate directive together with the container and condition objects.
This approach is only recommended when the filtering of unwanted items is not supported on the API side.
...
"response": {
"iterate":{
"container": "{{body.data}}",
"condition": "{{item.type = 'contact'}}"
},
"output": {
"label": "{{item.name}}",
"value": "{{item.id}}"
}
...Select parameter with nested RPCs
Sometimes, you may have a value that depends on another, for example, selecting a file inside a folder in an account. In this case, you'd have three API calls, and so three RPCs, each depending on the selected value from the previous one:
List accounts
List folders in the selected account
List files inside the selected folder
It is possible to nest RPCs under each other in Make. Here is an example of how it would look inside a module's mappable parameters and an RPC's communication.

[
{
"name": "parameter_1",
"type": "select",
"label": "Parameter 1",
"required": true,
"mappable": false,
"options": {
"store": "rpc://exampleRpc1", //proper usage of options in this case
"nested": [
{
"name": "parameter_2",
"type": "select",
"label": "Parameter 2",
"required": true,
"mappable": false,
"options": {
"store": "rpc://exampleRpc2", //don't forget to store your options
"nested": [
{
"name": "parameter_3",
"type": "select",
"label": "Parameter 3",
"required": true,
"mappable": false,
"options": "rpc://exampleRpc3"
//you are not using "nested" after it
//-> there's no need to "store" options
}
]
}
}
]
}
}
]{
"url": "/example1",
"type": "GET",
"response": {
"output": {
"value": "{{item.value}}",
"label": "{{item.label}}"
},
"iterate": "{{body.examples}}"
}
}{
"url": "/example2",
"type": "GET",
"qs": {
"needed_parameter": "{{parameters.parameter_1}}"
},
"response": {
"output": {
"value": "{{item.value}}",
"label": "{{item.label}}"
},
"iterate": "{{body.examples}}"
}
}{
"url": "/example3",
"type": "GET",
"qs": {
"needed_parameter": "{{parameters.parameter_2}}"
},
"response": {
"output": {
"value": "{{item.value}}",
"label": "{{item.label}}"
},
"iterate": "{{body.examples}}"
}
}You're not restricted from using inherited parameters in qs only. In this example, the nested RPCs obtain a value from the parent's RPC and it is passed to the nested RPC in the URL.

[
{
"name": "workspace_id",
"label": "Workspace",
"type": "select",
"required": true,
"mappable": false,
"options": {
"store": "rpc://getWorkspaces",
"nested": [
{
"name": "space_id",
"type": "select",
"label": "Space",
"mappable": false,
"required": true,
"options": {
"store": "rpc://getSpaces",
"nested": [
{
"name": "folder_id",
"label": "Folder",
"type": "select",
"options": "rpc://getfolders",
"required": true
}
]
}
}
]
}
}
]{
"url": "/workspace",
"method": "GET",
"response": {
"iterate": "{{body.workspaces}}",
"output": {
"label": "{{item.name}}",
"value": "{{item.id}}"
}
}
}{
"url": "/workspace/{{parameters.workspace_id}}/space",
"method": "GET",
"response": {
"iterate": "{{body.spaces}}",
"output": {
"label": "{{item.name}}",
"value": "{{item.id}}"
}
}
}{
"url": "workspace/{{parameters.workspace_id}}/space/{{parameters.space_id}}/folder",
"method": "GET",
"response": {
"output": {
"label": "{{item.name}}",
"value": "{{item.id}}"
}
}
}Search button
Sometimes, a select parameter may not be the best option. If you're dealing with a lot of items and the API allows you to filter/search results, a search button may provide a better user experience than a select, which may not have all values listed.
However, there's an important UI difference between these two:
When using a select parameter, the user will always see a
labeleven though thevalueis mapped. This makes it easier to identify the mapped values.When using the search button, the user sees the
labelwhen choosing which item to map. But once an item is selected, thevalueis shown in the field.
Search button for a query

{
"name": "authorID",
"type": "text",
"rpc": {
"label": "Search Author",
"url": "rpc://getUser",
"parameters": [
{
"name": "email",
"label": "Author Email",
"help": "Enter author's email on whose behalf the comment should be created. E.g. yours.",
"type": "text"
}
]
},
"label": "Author ID",
"required": true
}
]{
"url": "/users/retrieve",
"method": "GET",
"qs": {
"email": "{{parameters.email}}"
},
"response": {
"output": {
"label": "{{body.name}}",
"value": "{{body.id}}"
}
}
}Search button with nested RPCs


[
{
"label": "Comment ID",
"name": "id",
"type": "text",
"required": true,
"rpc": {
"label": "Search Comments",
"url": "rpc://getComments",
"parameters": [
{
"name": "id",
"label": "Board ID",
"type": "select",
"mode": "edit",
"options": {
"store": "rpc://listBoards"
},
"nested": [
{
"name": "postId",
"label": "Post ID",
"type": "select",
"options": {
"store": "rpc://listPostsbyBoard"
},
"required": true
}
]
}
]
}
}
]Advanced search button
Some services have a lot of records, like mailboxes, task-tracking platforms, and CRMs. In these cases, it may be worth implementing a more advanced search, as long as the API supports that.
You may even want to nest one or more search buttons inside your first search button popup.
In this example for Freshdesk, users can filter results to find exactly what they're looking for.

{
"name": "ticket",
"label": "Ticket ID",
"type": "text",
"required": true,
"rpc": {
"url": "rpc://listTickets",
"label": "Search Tickets",
"parameters": [
{
"name": "filter",
"type": "select",
"label": "Predefined Filter",
"options": [
{
"label": "New and my open",
"value": "new_and_my_open"
},
{
"label": "Watching",
"value": "watching"
},
{
"label": "Spam",
"value": "spam"
},
{
"label": "Deleted",
"value": "deleted"
}
]
},
{
"name": "requester_id",
"type": "text",
"label": "Requester(Agent) ID",
"rpc": {
"label": "Search Agents",
"url": "rpc://listAgents",
"parameters": [
{
"name": "term",
"label": "Term",
"type": "text",
"required": true,
"help": "◉ The search is case insensitive.\n◉ You cannot search with a substring. For example, an agent \"John Jonz\" can be looked up using \"john\", \"Joh\", \"Jonz\" and \"jon\". But it will not be returned when you search for \"hn\" or \"th\"."
}
]
}
},
{
"name": "company_id",
"type": "text",
"label": "Company ID",
"rpc": {
"label": "Search Companies",
"parameters": [
{
"name": "term",
"label": "Keyword Name",
"type": "text",
"help": "◉ It is case insensitive.\n◉ You cannot search with a substring. For example, a company \"Acme Corporation\" can be looked up using \"acme\", \"Ac\", \"Corporation\" and \"Co\". But it will not be returned when you search for \"cme\" or \"orporation\"."
}
],
"url": "rpc://listCompanies"
}
},
{
"name": "updated_since",
"type": "date",
"label": "Updated Since"
}
]
}
},
...
]{
"url": "/tickets",
"method": "GET",
"qs": {
"per_page": 100,
"order_by": "updated_at",
"order_type": "desc",
"company_id": "{{ifempty(parameters.company_id, undefined)}}",
"requester_id": "{{ifempty(parameters.requester_id, undefined)}}",
"updated_since": "{{ifempty(parameters.updated_since, undefined)}}",
"filter": "{{ifempty(parameters.filter, undefined)}}"
},
"response": {
"output": {
"label": "{{item.subject}}",
"value": "{{item.id}}"
},
"iterate": "{{body}}",
"limit": 500
},
"pagination": {
"qs": {
"page": "{{pagination.page}}"
},
"condition": "{{headers.link}}"
}
}Reusable options in a select
Sometimes it is better to keep the list of available options outside of mappable parameters code, to keep the code cleaner or to reuse the same piece of code in multiple places.
In this case, we can create a request-less RPC, where we manually define the list of available options that will be returned in the RPC's output.

[
{
"label": "Status",
"name": "status",
"type": "select",
"options": "rpc://reusableOptions"
}
]{
"response": {
"output": [
{
"label": "Option A",
"value": "a"
},
{
"label": "Option B",
"value": "b"
},
{
"label": "Option C",
"value": "c"
}
]
}
}Send query to RPC
You might create an RPC and realize that some other module needs an RPC that does almost the same thing.
Instead of creating a new RPC with small differences, in some cases you can modify the first RPC and use a query string parameter with different values depending on the module.
For example, you have one general search endpoint that requires you to specify the items for which to search: companies or contacts.
Instead of creating rpc://searchCompanies and rpc://searchContacts, use rpc://search?type=companies&active=true
[
{
"label": "Option",
"name": "option",
"type": "select",
"options": "rpc://yourRPC?type=contact&active=true"
}
]{
"url": "/search/{{parameters.type}}",
"qs": {
"active": "{{parameters.active}}"
},
"response": {
"output": {
"label": "{{item.name}}",
"value": "{{item.id}}"
}
}
}Send array to RPC
You can send an array to an RPC.
[
{
"name": "options",
"type": "select",
"label": "Options",
"options": "rpc://passArrayToRPC?buttonTypes=a&buttonTypes=b&buttonTypes=c",
"required": true
}
][
{
"name": "buttonTypes",
"type": "array",
"label": "Button Types",
"spec": {
"type": "text"
}
}
]Last updated

