Tray Platform / Version Control / Importing / Exporting Workflows

Importing / Exporting Workflows


When building a workflow in, once you have validated it with your test service accounts and datasets, it is possible to export it and then import into another destination workflow - either in the same account or in another account.

This is very useful in that it allows you to test workflows before putting them to real-world use.

Three key features of imported workflows are:

  1. Authentications are synchronized. The feature works on the basis that you use test authentications with your original workflow and live authentications with your destination workflow - when importing to the destination workflow you only need to create a new authentication the first time a particular service is imported and all subsequent imports will automatically map the authentications

  2. Workflow settings (properties panel operations, parameters and workflow config) are also synchronized and the settings from the original workflow will always override the settings in the destination workflow properties panel.

  3. After a first import has been made, you can work on new versions by editing and testing in the imported workflow, before exporting and importing to the destination workflow - as many times as you need

Note: the feature does not currently work with workflows that have dependencies - i.e. it does not work with callable workflows.

Also note that there may be discrepancies between the service accounts you are accessing - e.g. your Google Sheets live account may not have the same sheet as your Google Sheets test account. In this case you will have to manually set the sheet in the destination workflow.

Exporting a workflow

Exporting a workflow is done by clicking on the ellipsis in the top left of the builder and choosing export:

This will then be downloaded as a json file to your local machine:

You can then import the workflow into a newly created or already existing workflow by opening that destination workflow, clicking on the ellipsis and choosing import:

You can then pick up the json file of the workflow you wish to import:

On the first import you will then be asked to create authentications for any of the services included in the workflow (i.e. you will have used 'test' accounts in the imported workflow and will be using 'live' accounts in the new workflow being imported to):

Note: when importing subsequent versions of the workflow, you will not have to create the same authentications again.

Points to note about imported workflows

Alerting Workflows

If you have an alerting workflow set in your original workflow:

  • If you are importing to a workflow in the same account, it will be linked to the same alerting workflow
  • If you are importing to a workflow in a different account, you will need to create an alerting workflow in that account and manually link to it in the destination workflow settings

Undoing imports

If you mistakenly import a workflow, or need to undo for any reason, you can do so with the Rollback Workflow History function.

Importing new workflow versions

To continue testing, editing and producing new versions of your workflow, use the following procedure:

  1. Edit and test the original workflow
  2. Export the edited version of the original workflow
  3. Import the exported json file to the same destination workflow

Be sure to bear the following points in mind when working with subsequent vesions of your workflow:

  • All configuration and details set in the destination workflow's properties panel will be overwritten - i.e. the new details you have set in the exported workflow will overwrite the details of the previous version in the destination workflow
  • Service connectors will not need to be re-authenticated in subsequent versions
  • Any new service connectors not present in the previous version will need to be authenticated

Importing and Exporting via API

It is possible to programatically Import and Export workflows with our GraphQL APIs.

Importing and Exporting via API is only available to Embedded customers at this time
If you are exporting from e.g. a dev account and importing to a production account you will need to have a master token as bearer for each account
The first import of a workflow will have to be done manually (as described above) in order to allow you to create the linked authentications in the target workflow(s).
If new services are added to any subsequent versions then you will need to run another manual import, as new authentications will need to be created

Exporting workflows

The exportWorkflows mutation can be used to export a workflow. This requires the workflowId of the workflow you wish to export (obtained from the url when editing a workflow:{workflowId}/edit )

mutation exportWorkflows {
exportWorkflows (input: {
workflowIds: ["a90f4eef-xxxx-xxxx-xxxx-xxxxxxxxfbc"]
}) {

The response to this will contain the exportedWorkflowsJson (this is the same json output as per a manual export but in stringified format).

It will also contain the targetWorkflowIds which can be used to identify the target workflow when making the import.

An example response is given below:

mutation importWorkflows {
importWorkflows (input: {
exportedWorkflowsJson: "{\n \"export_type\" : \"workflow\",\n \"projects\" : [ ],\n \"tray_export_version\" : 3,\n \"workflows\" : [ {\n \"id\" : \"a90fxxx-xxx-xxx-xxx82abfbc\",\n \"created\" : \"2020-11-23T16:44:40.233Z\",\n \"workspace_id\" : \"6c59xxx-xxx-xxx-xxxeb938eae\",\n \"creator\" : \"6c595xxx-xxx-xxx-xxx938eae\",\n \"version\" : {\n \"id\" : \"d4a6xxx-xxx-xxxx-xxxa45e791\",\n \"created\" : \"2020-11-24T11:10:08.786Z\"\n },\n \"title\" : \"Webhook demo (dev)\",\n \"enabled\" : false,\n \"tags\" : [ ],\n \"settings\" : {\n \"config\" : {\n \"slack-channel\" : \"CE3KXDFTP\",\n \"slack-message\" : \"The webhook for your solution instance has been triggered\"\n },\n \"input_schema\" : { },\n \"output_schema\" : { }\n },\n \"steps_structure\" : [ {\n \"name\" : \"trigger\",\n \"type\" : \"normal\",\n \"content\" : { }\n }, {\n \"name\" : \"slack-1\",\n \"type\" : \"normal\",\n \"content\" : { }\n } ],\n \"steps\" : {\n \"trigger\" : {\n \"title\" : \"Webhook\",\n \"connector\" : {\n \"name\" : \"webhook\",\n \"version\" : \"2.2\"\n },\n \"operation\" : \"fire_and_forget\",\n \"output_schema\" : { },\n \"error_handling\" : { },\n \"properties\" : { }\n },\n \"slack-1\" : {\n \"title\" : \"Alert slack channel\",\n \"connector\" : {\n \"name\" : \"slack\",\n \"version\" : \"6.0\"\n },\n \"operation\" : \"send_message\",\n \"output_schema\" : { },\n \"error_handling\" : { },\n \"authentication\" : {\n \"group\" : \"3e26xxx-xxx-xxx-xxx-xxx9248b4\",\n \"title\" : \"Mike Hewitt's Slack account\",\n \"service_icon\" : {\n \"icon_type\" : \"url\",\n \"value\" : \"//\"\n },\n \"service_id\" : \"aba1a078-xxxx-xxxx-xxxx-0b703b29e76d\",\n \"auth_app_id\" : \"70fce6xxx-xxx-xxx-xxx-xxxe1a4c5\",\n \"scopes\" : [ \"chat:write:bot\", \"chat:write:user\" ]\n },\n \"properties\" : {\n \"link_names\" : {\n \"type\" : \"boolean\",\n \"value\" : false\n },\n \"reply_broadcast\" : {\n \"type\" : \"boolean\",\n \"value\" : false\n },\n \"parse\" : {\n \"type\" : \"string\",\n \"value\" : \"none\"\n },\n \"username\" : {\n \"type\" : \"string\",\n \"value\" : \"Tray Embedded tester\"\n },\n \"as_user\" : {\n \"type\" : \"boolean\",\n \"value\" : false\n },\n \"token\" : {\n \"type\" : \"jsonpath\",\n \"value\" : \"$.auth.access_token\"\n },\n \"channel\" : {\n \"type\" : \"jsonpath\",\n \"value\" : \"$.config.slack-channel\"\n },\n \"text\" : {\n \"type\" : \"jsonpath\",\n \"value\" : \"$.config.slack-message\"\n }\n }\n }\n },\n \"dependencies\" : [ ]\n } ]\n}"
targetWorkflowIds: ["2607xxx-xxx-xxx-xxx-xxx6c2fd"]
}) {

Importing workflows

The importWorkflows mutation can then be used to import the workflow to e.g. your 'production' account.

targetWorkflowIds is used to specify the id of the target workflow in your production account.

Note that it is possible to import multiple workflows (you would have to ensure that the workflows and workflowIds are listed in the exact same order in exportedWorkflowsJson and targetWorkflowIds - to make sure the correct workflow is imported to the correct target workflow)

However it is generally not recommended to import more than one workflow at a time. The recommended approach is to use multiple calls:

mutation importWorkflows {
importWorkflows (input: {
exportedWorkflowsJson: "{\n \"export_type\" : \"workflow\",\n \"projects\" : [ ],\n \"tray_export_version\" : 3,\n \"workflows\" : [ {\n \"id\" : \"a90f4eef-xxxx-xxxx-xxxx-54b1d82abfbc\",\n \"created\" : \"2020-11-23T16:44:40.233Z\",\n \"workspace_id\" : \"6c595d5b-xxxx-xxxx-xxxx-959ceb938eae\",\n \"creator\" : \"6c595d5b-xxxx-xxxx-xxxx-959ceb938eae\",\n \"version\" : {\n \"id\" : \"d4a6f06b-xxxx-xxxx-xxxx-f519ca45e791\",\n \"created\" : \"2020-11-24T11:10:08.786Z\"\n },\n \"title\" : \"Webhook demo (dev)\",\n \"enabled\" : false,\n \"tags\" : [ ],\n \"settings\" : {\n \"config\" : {\n \"slack-channel\" : \"CE3KXDFTP\",\n \"slack-message\" : \"The webhook for your solution instance has been triggered\"\n },\n \"input_schema\" : { },\n \"output_schema\" : { }\n },\n \"steps_structure\" : [ {\n \"name\" : \"trigger\",\n \"type\" : \"normal\",\n \"content\" : { }\n }, {\n \"name\" : \"slack-1\",\n \"type\" : \"normal\",\n \"content\" : { }\n } ],\n \"steps\" : {\n \"trigger\" : {\n \"title\" : \"Webhook\",\n \"connector\" : {\n \"name\" : \"webhook\",\n \"version\" : \"2.2\"\n },\n \"operation\" : \"fire_and_forget\",\n \"output_schema\" : { },\n \"error_handling\" : { },\n \"properties\" : { }\n },\n \"slack-1\" : {\n \"title\" : \"Alert slack channel\",\n \"connector\" : {\n \"name\" : \"slack\",\n \"version\" : \"6.0\"\n },\n \"operation\" : \"send_message\",\n \"output_schema\" : { },\n \"error_handling\" : { },\n \"authentication\" : {\n \"group\" : \"3e268690-xxxx-xxxx-xxxx-41a14d9248b4\",\n \"title\" : \"Mike Hewitt's Slack account\",\n \"service_icon\" : {\n \"icon_type\" : \"url\",\n \"value\" : \"//\"\n },\n \"service_id\" : \"aba1a078-xxxx-xxxx-xxxx-0b703b29e76d\",\n \"auth_app_id\" : \"70fce61a-xxxx-xxxx-xxxx-c3b26fe1a4c5\",\n \"scopes\" : [ \"chat:write:bot\", \"chat:write:user\" ]\n },\n \"properties\" : {\n \"link_names\" : {\n \"type\" : \"boolean\",\n \"value\" : false\n },\n \"reply_broadcast\" : {\n \"type\" : \"boolean\",\n \"value\" : false\n },\n \"parse\" : {\n \"type\" : \"string\",\n \"value\" : \"none\"\n },\n \"username\" : {\n \"type\" : \"string\",\n \"value\" : \"Tray Embedded tester\"\n },\n \"as_user\" : {\n \"type\" : \"boolean\",\n \"value\" : false\n },\n \"token\" : {\n \"type\" : \"jsonpath\",\n \"value\" : \"$.auth.access_token\"\n },\n \"channel\" : {\n \"type\" : \"jsonpath\",\n \"value\" : \"$.config.slack-channel\"\n },\n \"text\" : {\n \"type\" : \"jsonpath\",\n \"value\" : \"$.config.slack-message\"\n }\n }\n }\n },\n \"dependencies\" : [ ]\n } ]\n}"
targetWorkflowIds: ["260767f4-xxxx-xxxx-xxxx-1c4ebf86c2fd"]
}) {

A successful import will simply return:

"data": {
"importWorkflows": {
"clientMutationId": null

Testing the APIs

Click here to download our collection for the Insomnia Http client

Once downloaded you can import the collection file:

Once imported you will see the GraphQL calls available:

Click on 'embedded tokens' followed by 'Manage Environments':

Then you can see that the base url is

You will then need to set your master tokens:

Once this is done you can test as per the instructions above