Tray Embedded APIs (1.0.0)

Overview

Reference documentation for the Tray.io Embedded GraphQL APIs

Please visit our Tray Embedded Documentation to familiarize yourself with Tray Embedded and learn how it can help you put the automation power of Tray.io in the hands of your End Users.

Use the examples with queries and mutations and the associated code samples to test out scripts using different input/filter criteria (e.g. 'Get User by Id' or 'Get Solution Instances by owner')

You can also click 'Run in Postman' button below to import and run the collection in your local Postman app. You can also try out our Insomnia Http Client collection as a local testing environment.

Note: The Tray GraphQL API is a backend API only and calls must be invoked server-side. Client-side Javascript calls to the API should not be made as they will be blocked by CORS.

Our demo app (built using Apollo GraphQL) is a good illustration of how you can create a UI which presents an End User with their available Solutions while making all API calls server-side - using a button to hand over the Solution Instance configuration to our End User Config Wizard in a pop-up or iframe.

How to Authenticate

When interacting with GraphQL APIs, depending on the call, you will need to use

  1. A master token obtained from the Tray Embedded UI (required for calls such as 'Get Users')
  2. A user token obtained with Create user token (required for calls such as 'Get Soluton Instances')

Some calls like Get Authentications support both master and user token where using a master token gives all auths in your orgnaziation workspace while a user token only gives auths owned by that end user.

Pagination

The Tray Embedded APIs use standard conventions for pagination, compatible with the Relay Pagination Container specification . Note that in our demo app all mutations make use of clientMutationId - if this parameter is specified in the input to the mutation, it will be returned unchanged in the payload. It is not necessary to use clientMutationId but it is used in Relay and Apollo.

Two very helpful articles on pagination with GraphQL can be found at https://www.howtographql.com/react-relay/8-pagination and https://blog.apollographql.com/tutorial-pagination-d1c3b3ee2823

Using a query such as Get Users it is possible to specify the cursor and page information that you need for pagination of results:

query {
    users(first: 2, after:"OGRiNDY2YzAtYTA0MS00OTM0LWFmMzUtMTU4YzcwNGM1OWRl") {
    edges {
        node {
            id
            name
            externalUserId
        }
            cursor
        }
        pageInfo {
            hasPreviousPage
            hasNextPage
            startCursor
            endCursor
        }
    }
}

pageInfo is what GraphQL calls a connection. A connection stores additional data about the context of each item (edge/node), i.e. about the position of the item in the list as well as the items in the list that come directly before and after it.

Note that after in the above query specifies a particular cursor to begin the list from.

From the results you can see that the necessary page and cursor information is returned, as needed for pagination of results:

{
    "data": {
        "users": {
            "edges": [
            {
                "node": {
                    "id": "d9b7302f-xxx-xxx-xxx-b403242e3f26",
                    "name": "Danton Black",
                    "externalUserId": "96fxxxx85cd7"
                },
                "cursor": "ZDliNzMwMmYtxxxxxxxxxxxZmUtYjQwMzI0MmUzZjI2"
            },
            {
                "node": {
                    "id": "8db466c0-xxx-xxx-xxx-158c704c59de",
                    "name": "Miguel Rangel",
                    "externalUserId": "96b9327xxxxxxx-xxx86ce-b79e66872daa"
                },
                "cursor": "OGRiNDY2YxxxxxxxxLWFmMzUtMTU4YzcwNGM1OWRl"
            }
            ],
        "pageInfo": {
            "hasPreviousPage": true,
            "hasNextPage": true,
            "startCursor": "ZDliNzxxxxxxxxxxxxxxxxxxxUtYjQwMzI0MmUzZjI2",
            "endCursor": "OGRiNDY2YzAxxxxxxxxxxxxxMTU4YzcwNGM1OWRl"
        }
        }
    }
}

Rate Limiting

All endpoints are limited at a rate of 30 requests per second

There is limited burst capacity to allow for momentary spikes in usage, as long as the overall rate is not broken in a set window.

If you exceed a certain rate of requests, you will receive a response similar to the following:

{
    "data": null,
    "errors": [
        {
            "message": "Rate limit exceeded",
            "path": [
                "users"
            ],
            "locations": [
                {
                    "line": 2,
                    "column": 3
                }
            ],
            "extensions": {
                "name": "PreconditionError",
                "time_thrown": "2023-06-29T14:55:54.518Z",
                "code": "access_not_allowed"
            }
        }
    ]
}

The path property will tell you the query or the mutation that exceeded the threshold.

Tips and best practices to avoid being rate-limited

For the Get Users query, we recommend not using the externalUserIdas a means of looking up or retrieving Tray users in a high-throughput production environment.

In this case, you should consider storing the Tray user id in your own application or data store, in order to facilitate creation of user tokens / deletion of users without making repeated calls to the Get Users query.

Similary, you should consider storing Tray Ids for other resources such as Solution Instances or Authentications.

Exactly how you will manage this will depend on your usecase and setup.

However these are the considerations that you need to be aware of.

Use our Postman collection

Click here to download the Postman collection. Or Fork the collection using the button below:
Run in
Postman

You can set environment variables on the Postman Collection to manage base_url, master_token, user_token across different regions.

Use our Insomnia collection

Click here to download our collection for the Insomnia Http client

This will provide you with a local testing environment which allows you to very quickly run queries and mutations on your live data, before inspecting the results.

Refer this page for detailed instructions on using the insomnia collection effectively.

Regionality

Tray.io supports multiple regions to manage your end users.

The base_url for all requests would change depending on the region your Tray account is in. This is indicated in the URL of the Tray app. For US (default), your Tray app URL is app.tray.io, for EU app.eu1.tray.io and for APAC, it is app.ap1.tray.io.

Here is the list of base_url for the Embedded APIs:

Tray operates in 3 segregated AWS regions:

Region Base URL
US (AWS-West) https://tray.io/graphql
EU (AWS-Ireland) https://eu1.tray.io/graphql
APAC (AWS-Sydney) https://ap1.tray.io/graphql

Users

Users are the end users of your integrations

Queries

Queries affecting Users of your application

Get users (master token)

post/

Get all users including their name, id, and externalUserId.

Required Token Notes
Master Obtained from the Tray app UI. Refer this.

The query accepts a filter key criteria which can take in following fields:

field Notes
id This is generated by Tray when you create a end user using Mutations/Users/Create New User
externalUserId This will be provided by you upon the time of creation. It is the unique Id of the user in your own app and hence a mapping is created between your end user and their corresponding Tray user
name This will be provided by you upon the time of creation. It is the name of the end user in your own app
isTestUser This will be provided by you upon the time of creation. This is a boolean flag that tells whether the user is billable or not

Here are some sample queries:

Get all users
query {
    users {
        edges {
            node {
                name
                id
                externalUserId
                isTestUser
            }
            cursor
        }
        pageInfo {
          hasNextPage
          endCursor
          hasPreviousPage
          startCursor
        }
    }
}
Get user by ID
query {
    users (criteria: {userId: "13b3ab9c-XXXX-XXXX-XXXX-c4dd07fbbfa4"}){
        edges {
            node {
                name
                id
                externalUserId
            }
            cursor
        }
        pageInfo {
          hasNextPage
          endCursor
          hasPreviousPage
          startCursor
        }
    }
}
Get user by externalID
query {
    users ( criteria: { externalUserId: "my-external-user-id" } ){
        edges {
            node {
                name
                id
                externalUserId
            }
            cursor
        }
        pageInfo {
          hasNextPage
          endCursor
          hasPreviousPage
          startCursor
        }
    }
}
Get user by name
query {
    users ( criteria: { name: "Billy Bluehat" } ){
        edges {
            node {
                name
                id
                externalUserId
            }
            cursor
        }
        pageInfo {
          hasNextPage
          endCursor
          hasPreviousPage
          startCursor
        }
    }
}
Get test users
query {
    users ( criteria: { isTestUser: true } ){
        edges {
            node {
                name
                id
                externalUserId
            }
            cursor
        }
        pageInfo {
          hasNextPage
          endCursor
          hasPreviousPage
          startCursor
        }
    }
}
Get test user by name
query {
    users ( criteria: { isTestUser: true, name: "Billy Bluehat" } ){
        edges {
            node {
                name
                id
                externalUserId
            }
            cursor
        }
        pageInfo {
          hasNextPage
          endCursor
          hasPreviousPage
          startCursor
        }
    }
}

The query also accepts following pagination parameters:

parameter Notes
first number to filter the first n users from response
last number to filter the last n users from response
before pagination parameter to go to previous page of response
after pagination parameter to go to next page of repsonse

Here are some sample queries:

Get users after cursor
query {
    users (after: "MTNiM2FiOWMtZTIyMi00NzM5LWE2OWItYzRkZDA3ZmJiZmE0"){
        edges {
            node {
                name
                id
                externalUserId
            }
            cursor
        }
        pageInfo {
          hasNextPage
          endCursor
          hasPreviousPage
          startCursor
        }
    }
}
Get first 2 users
query {
    users (first: 2){
        edges {
            node {
                name
                id
                externalUserId
            }
            cursor
        }
        pageInfo {
          hasNextPage
          endCursor
          hasPreviousPage
          startCursor
        }
    }
}
Get first 5 users after cursor
query {
    users (first: 5, after: "MTNiM2FiOWMtZTIyMi00NzM5LWE2OWItYzRkZDA3ZmJiZmE0"){
        edges {
            node {
                name
                id
                externalUserId
            }
            cursor
        }
        pageInfo {
          hasNextPage
          endCursor
          hasPreviousPage
          startCursor
        }
    }
}

It can return the following data:

Returned Data subfields Notes
name
id Tray ID of the user
externalUserId unique id for the user in your database
cursor used for pagination
pageinfo hasNextPage, endCursor, hasPreviousPage, startCursor used for pagination
SecuritybearerAuth
Request
Responses
Request samples
curl -i -X POST \
  https://tray.io/graphql \
  -H 'Authorization: Bearer <MASTER_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": "query {\n    users {\n        edges {\n            node {\n                name\n                id\n                externalUserId\n            }\n            cursor\n        }\n        pageInfo {\n          hasNextPage\n          endCursor\n          hasPreviousPage\n          startCursor\n        }\n    }\n}",
    "variables": {}
  }'
Response samples
application/json
{
  • "data": {
    }
}

Mutations

Mutations affecting Users of your application

Create new user (master token)

post/

Create a new external user of your Embedded application.

To exclude users from billing you can mark them as test users (see our Billing page for more info).

Required Token Notes
Master Obtained from the Tray app UI. Refer this.

The mutation accepts the following as inputs:

Input Required Note
name Yes
externalUserId Yes can be used to link the End User to an ID you already have for them in your external database.
It's important to be able to access key info, such as contact email, you may have stored in your external system. Example: dealing with Expired Auths
isTestUser No Boolean value that defaults to true (billable user) if you don't pass it. A test user allows you to create Solution Instances and run test data for a user without incurring any charges. This is useful for end to end testing. Please read our billing page here.
clientMutationId No Only relevant if using the Relay GraphQL client

Here is an example mutation:

Create new user
mutation {
  createExternalUser(input: { 
    name: "Dwight Schrute",
    externalUserId: "my-apps-user-id-for-dwight"
  }) {
    userId
  }
}
Create new user with clientMutationId
mutation {
  createExternalUser(input: { 
    name: "Dwight Schrute",
    externalUserId: "my-apps-user-id-for-dwight",
    clientMutationId: "some-mutation-id" #OPTIONAL - only needed for legacy Relay & Apollo clients
  }) {
    userId
    clientMutationId #OPTIONAL
  }
}

It can return the following data:

Returned Data Notes
userId Tray Id of the user
clientMutationId Only relevant if using the Relay GraphQL client
SecuritybearerAuth
Request
Responses
Request samples
curl -i -X POST \
  https://tray.io/graphql \
  -H 'Authorization: Bearer <MASTER_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": "mutation($name: String!, $externalUserId: String!) {\n  createExternalUser(input: { \n      name: $name, \n      externalUserId: $externalUserId  \n    }) {\n      userId\n  }\n}",
    "variables": {
      "name": "Dwight Schrute",
      "externalUserId": "my-apps-user-id-for-dwight"
    }
  }'
Response samples
application/json
{
  • "data": {
    }
}

Create user token (master token)

post/

Create an accessToken for a given userId

A user token allows access to the APIs which require a user token (Create Solution Instance, Get Solution Instances, Create User Auth etc.) and should be passed as a Bearer in the Authorization header when calling those APIs.

Note: This access token expires after 2 days

Required Token Notes
Master Obtained from the Tray app UI. Refer this.

The mutation accepts the following as inputs:

Input Required Notes
userId Yes obtained when creating a user (Mutations/Users/Create New User) or getting users (Queries/Users/Get Users)
clientMutationId No Only relevant if using the Relay GraphQL client

Here is an example mutation:

Create user token
mutation {
  authorize(input: {
      userId: "d869ec65-XXXX-XXXX-XXXX-ac5c1a3958b6"
  }) {
    accessToken
  }
}
Create user token with clientMutationId
mutation {
  authorize(input: {
      userId: "d869ec65-XXXX-XXXX-XXXX-ac5c1a3958b6",
      clientMutationId: "my-mutation-id" #OPTIONAL - only needed for legacy Relay & Apollo clients
  }) {
    accessToken
    clientMutationId #OPTIONAL
  }
}

It can return the following data:

Returned Data Notes
accessToken a persistent token (valid for 2 days) that should be securely stored in your application.
Allows access to the APIs which require a user token (e.g. createSolutionInstance)
clientMutationId Only relevant if using the Relay GraphQL client
SecuritybearerAuth
Request
Responses
Request samples
curl -i -X POST \
  https://tray.io/graphql \
  -H 'Authorization: Bearer <MASTER_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": "mutation ($userId: ID!) {\n  authorize(input: {\n      userId: $userId\n  }) {\n    accessToken\n  }\n}",
    "variables": {
      "userId": "d869ec65-XXXX-XXXX-XXXX-ac5c1a3958b6"
    }
  }'
Response samples
application/json
{
  • "data": {
    }
}

Create Auth/Config dialog Authorization Code (master token)

post/

Creates an authorization code that is used to configure config wizard URL or auth-only dialog URL. Refer this page on how it's used.

Note: This is a one-time use code which expires after 5 minutes

Required Token Notes
Master Obtained from the Tray app UI. Refer this.

The mutation accepts the following as inputs:

Input Required Notes
userId Yes obtained when creating a user (Mutations/Users/Create New User) or getting users (Queries/Users/Get Users)
clientMutationId No Only relevant if using the Relay GraphQL client

Here is an example mutation:

Create Config Wizard Auth Code
mutation {
  generateAuthorizationCode( input: {
    userId: "d869ec65-XXXX-XXXX-XXXX-ac5c1a3958b6"
  }) {
    authorizationCode
  }
}
Create Config Wizard Auth Code with clientMutationId
mutation {
  generateAuthorizationCode( input: {
    userId: "d869ec65-XXXX-XXXX-XXXX-ac5c1a3958b6",
    clientMutationId: "my-mutation-id" #OPTIONAL - only needed for legacy Relay & Apollo clients
  }) {
    authorizationCode
    clientMutationId #OPTIONAL
  }
}

It can return the following data:

Returned Data Notes
authorizationCode this is required to activate the Configuration Wizard
clientMutationId Only relevant if using the Relay GraphQL client
SecuritybearerAuth
Request
Responses
Request samples
curl -i -X POST \
  https://tray.io/graphql \
  -H 'Authorization: Bearer <MASTER_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": "mutation ($userId: ID!) {\n  generateAuthorizationCode( input: {\n    userId: $userId\n  }) {\n    authorizationCode\n  }\n}",
    "variables": {
      "userId": "d869ec65-XXXX-XXXX-XXXX-ac5c1a3958b6"
    }
  }'
Response samples
application/json
{
  • "data": {
    }
}

Update user (master token)

post/

Can be used to mark a user as a test user allowing you to create Solution Instances and run test data for a user without incurring any charges (see our Billing page for more info)

Required Token Notes
Master Obtained from the Tray app UI. Refer this.

The mutation accepts the following as inputs:

Input Required Note
id Yes
isTestUser Yes Booelan value. A test user allows you to create Solution Instances and run test data for a user without incurring any charges

Here is an example mutation:

Update to test user
mutation {
   updateExternalUser(input: {
      userId: "53824943-XXXX-XXXX-XXXX-088aee14038e",
      isTestUser: true
  }) {
    user{
            name
            id
            externalUserId
            isTestUser
        }
  }
}
Update to test user with clientMutationId
mutation {
   updateExternalUser(input: {
      userId: "53824943-XXXX-XXXX-XXXX-088aee14038e",
      isTestUser: "true",
      clientMutationId: "some-mutation-id" #OPTIONAL - only needed for legacy Relay & Apollo clients
  }) {
    user{
            name
            id
            externalUserId
            isTestUser
      clientMutationId #OPTIONAL
        }
  }
}

It can return the following data:

Returned Data Notes
name
id
externalUserId
isTestUser
SecuritybearerAuth
Request
Responses
Request samples
curl -i -X POST \
  https://tray.io/graphql \
  -H 'Authorization: Bearer <MASTER_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": "mutation  ($userId: ID!, $isTestUser: Boolean ){\n   updateExternalUser(input: {\n      userId: $userId,\n      isTestUser: $isTestUser\n  }) {\n    user{\n\t\t\tname\n\t\t\tid\n\t\t\texternalUserId\n\t\t\tisTestUser\n\t\t}\n  }\n}",
    "variables": {
      "userId": "53824943-XXXX-XXXX-XXXX-088aee14038e",
      "isTestUser": true
    }
  }'
Response samples
application/json
{
  • "data": {
    }
}

Delete user (master token)

post/

This mutation is used to delete a user from your Embedded application.

Note: Deleting a user will also disable and delete all Solution Instances associated with that user.

Required Token Notes
Master Obtained from the Tray app UI. Refer this.

The mutation accepts the following as inputs:

Input Required Notes
userId Yes obtained with Queries/Users/Get Users
clientMutationId No Only relevant if using the Relay GraphQL client

Here is an example mutation:

Delete user
mutation {
  removeExternalUser(input: {
      userId: "53824943-XXXX-XXXX-XXXX-088aee14038e"
    }) {
      clientMutationId # REQUIRED - must specify as return field, not required to provide this in mutation function
  }
}
Delete user with clientMutationId
mutation {
  removeExternalUser(input: {
      userId: "53824943-XXXX-XXXX-XXXX-088aee14038e", 
      clientMutationId: "someClientMutationId"
  }) {
      clientMutationId # REQUIRED - must specify as return field
  }
}

It can return the following data:

Returned Data Notes
clientMutationId while this data is only relevant if using the Relay GraphQL client, it is actually required here as currently this mutation does not return any other data
SecuritybearerAuth
Request
Responses
Request samples
curl -i -X POST \
  https://tray.io/graphql \
  -H 'Authorization: Bearer <MASTER_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": "mutation {\n  removeExternalUser(input: {userId: $userId}) {\n      clientMutationId # REQUIRED - must specify as return field, not required to provide this in mutation function\n  }\n}",
    "variables": {
      "userId": "53824943-XXXX-XXXX-XXXX-088aee14038e"
    }
  }'
Response samples
application/json
{
  • "data": {
    }
}

Authentications

Authentications represent the auth data used for authenticating to all the services that you would be integrating with Tray.

Queries

Query for retrieving the authentications used by your end users. You can also retrieve the auths created within your main embedded org by passing the Master token in the headers.

Get user authentications (user/master token)

post/

This query can be used to retrieve the authentications for a particular user.

Please also see our guide to Mapping and Editing Auths

Required Token Notes
User obtained after creating a user token (Users/Mutations/Create User Token)
the user token is a persistent token (valid for 2 days) that should be securely stored in your application
If Master token is used will return all the authentications from the Embedded Organization including all the auths created by owner/admin/contributors and NOT including your end user auths.

Here is an example query:

Get Authentications
query {
  viewer {
    authentications {
      edges {
        node {
          id
          name
          customFields
          service {
            id,
            name,
            icon,
            title,
            version
          }
          serviceEnvironment {
              id
              title
          }
        }
      }
      pageInfo{
        hasNextPage
        hasPreviousPage
      }
    }
  }
}
Returned Data Subfields Notes
id the authentication id
name the arbitrary name the end user has given to the authentication
service id, name, icon, title, version details of the service the authentication is for
serviceEnvironment id, title relevant when Importing Authentications
pageInfo hasNextPage, hasPreviousPage can be used for pagination
SecuritybearerAuth
Request
Responses
Request samples
curl -i -X POST \
  https://tray.io/graphql \
  -H 'Authorization: Bearer <USER_OR_MASTER_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": "query {\n  viewer {\n    authentications {\n      edges {\n        node {\n          id\n          name\n          customFields\n          service {\n            id,\n            name,\n            icon,\n            title,\n            version\n          }\n        }\n      }\n      pageInfo{\n        hasNextPage\n        hasPreviousPage\n      }\n    }\n  }\n}",
    "variables": {}
  }'
Response samples
application/json
{}

Mutations

Mutations for modifying the authentications used by your end users. You can also modify the auths created within your main embedded org by passing the Master token in the headers.

Create user Auth (user/master token)

post/

Create a user authentication for a service (e.g. Dropbox or Airtable) that is used in your Embedded application.

For full instructions on using this mutation please see Importing Authentications

To generate the inputs needed, navigate to your Tray and scroll down to the section titled 'Authentication import generator'

Required Token Notes
User obtained after creating a user token (Users/Mutations/Create User Token)
the user token is a persistent token (valid for 2 days) that should be securely stored in your application
Argument Required Note
name Yes Arbitrary. Can help you categorize authentications according to service and End User
serviceId Yes See Importing Authentications
serviceEnvironmentId Yes See Importing Authentications
data Yes Used to specify auth data such as api key and domain. See Importing Auths
formData No Data that may be seen in the authentication dialog in the workflow builder, e.g. 'subdomain'
scopes Yes Can be empty array as below example. For setting scopes of access (read/write access to components)
hidden no Controls if authentication should be hidden in UI. Default is False

Here is an example mutation:

Create Authentication
mutation { 
  createUserAuthentication (input:{
    name: "my-test-sqs-authentication-1",
    serviceId: "e73d8e91-XXXX-XXXX-XXXX-37df289242",
    serviceEnvironmentId: "a84eu2880-XXXX-XXXX-XXXX-7edd82904d",
    data: "{\"region\":\"us-east-1\",\"account_id\":\"1234\",\"access_key\":\"accesskey\",\"secret_key\":\"secretkey\"}",
    scopes: [],
    hidden: true
  }) {
    authenticationId
  }
}
Create Authentication with clientMutationId
mutation { 
  createUserAuthentication (input:{
    name: "my-test-sqs-authentication-1",
    serviceId: "e73d8e91-XXXX-XXXX-XXXX-37df289242",
    serviceEnvironmentId: "a84eu2880-XXXX-XXXX-XXXX-7edd82904d",
    data: "{\"region\":\"us-east-1\",\"account_id\":\"1234\",\"access_key\":\"accesskey\",\"secret_key\":\"secretkey\"}",
    scopes: [],
    hidden: true,
    clientMutationId: "some-mutation-id" #OPTIONAL - only needed for legacy Relay & Apollo clients
  }) {
    authenticationId
    clientMutationId #OPTIONAL
  }
}
Returned Data Notes
authenticationId This will be needed when using createSolutionInstance as detailed in Importing Authentications
clientMutationId Only relevant if using the Relay GraphQL client
SecuritybearerAuth
Request
Responses
Request samples
curl -i -X POST \
  https://tray.io/graphql \
  -H 'Authorization: Bearer <USER_OR_MASTER_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": "mutation (\n    $authenticationName: String!,\n    $serviceId: String!,\n    $serviceEnvironmentId: String!,\n    $authenticationData: Json!,\n    $hidden: Boolean!\n    ){ createUserAuthentication (input:{\n            name: $authenticationName,\n            serviceId: $serviceId,\n            serviceEnvironmentId: $serviceEnvironmentId,\n            data: $authenticationData,\n            scopes: [],\n            hidden: $hidden\n      }) {\n    authenticationId\n  }\n}",
    "variables": {
      "authenticationName": "my-test-sqs-authentication-1",
      "serviceId": "e73d8e91-XXXX-XXXX-XXXX-37df289242",
      "serviceEnvironmentId": "a84eu2880-XXXX-XXXX-XXXX-7edd82904d",
      "authenticationData": "{\"region\":\"us-east-1\",\"account_id\":\"1234\",\"access_key\":\"accesskey\",\"secret_key\":\"secretkey\"}",
      "hidden": true
    }
  }'
Response samples
application/json
{
  • "data": {
    }
}

Delete user Auth (user/master token)

post/

Delete a user authentication

Required token Notes
User obtained after creating a user token (Users/Mutations/Create User Token)
the user token is a persistent token (valid for 2 days) that should be securely stored in your application

The mutation accepts the following as inputs:

Input Required Notes
authenticationId Yes obtained with Queries/Users/Get User Authentications
also see our guide to Mapping and Editing Auths
clientMutationId No Only relevant if using the Relay GraphQL client

Here is an example mutation:

Delete Authentication
mutation {
  removeAuthentication(input: { 
    authenticationId: "dd36c246-XXXX-XXXX-XXXX-a600be2b39fe"
  }) {
    clientMutationId # REQUIRED - must specify as return field, it will be returned as NULL as it's not passed
  }
}
Delete Authentication with clientMutationId
mutation {
  removeAuthentication(input: { 
    authenticationId: "dd36c246-XXXX-XXXX-XXXX-a600be2b39fe", 
    clientMutationId: "some-mutaion-id"
  }) {
    clientMutationId # REQUIRED - must specify as return field
  }
}

It can return the following data:

Returned Data Notes
clientMutationId while this data is only relevant if using the Relay GraphQL client, it is actually required here as currently this mutation does not return any other data
SecuritybearerAuth
Request
Responses
Request samples
curl -i -X POST \
  https://tray.io/graphql \
  -H 'Authorization: Bearer <USER_OR_MASTER_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": "mutation ($authenticationId: ID!){\n  removeAuthentication(input: { authenticationId: $authenticationId }) {\n    clientMutationId\n  }\n}",
    "variables": {
      "authenticationId": "dd36c246-XXXX-XXXX-XXXX-a600be2b39fe"
    }
  }'
Response samples
application/json
{
  • "data": {
    }
}

Solutions

Solutions represent the integrations you have built with Tray.

Queries

Query for retrieving the solutions published by you.

Get solutions (master token)

post/

Retrive a list of solutions using various filters and pagination parameters.

Click 'Examples' to see different types of queries you can make when listing solutions

Required Token Notes
Master Obtained from the Tray app UI. Refer this.

The query accepts the following criteria:

Criteria Notes
tags If you have created tags in the Solution Editor, this field can be used to filter Solutions in your external application

Here are some example queries:

Get all solutions
query {
  viewer {
    solutions {
      edges {
        node {
          id
          title
          description
          tags
          customFields {
            key
            value
          }
          configSlots {
            externalId
            title
            defaultValue
          }
          authSlots {
            externalId
            title
          }
        }
        cursor
      }
      pageInfo {
          hasNextPage
          endCursor
          hasPreviousPage
          startCursor
      }
    }
  }
}
Get solutions by tag(s)
query {
  viewer {
    solutions (criteria: { tags: [
        "marketing",
    "marketo"
    ] }) {
      edges {
        node {
          id
          title
          description
          tags
          customFields {
            key
            value
          }
          configSlots {
            externalId
            title
            defaultValue
          }
          authSlots {
            externalId
            title
          }
        }
        cursor
      }
      pageInfo {
          hasNextPage
          endCursor
          hasPreviousPage
          startCursor
      }
    }
  }
}
Get first 5 solutions
query {
  viewer {
    solutions(first: 5) {
      edges {
        node {
          id
          title
          description
          tags
          customFields {
            key
            value
          }
          configSlots {
            externalId
            title
            defaultValue
          }
          authSlots {
            externalId
            title
          }
        }
        cursor
      }
      pageInfo {
          hasNextPage
          endCursor
          hasPreviousPage
          startCursor
      }
    }
  }
}
Get first solution after cursor
query {
  viewer {
    solutions(first: 1, after: "MTNiM2FiOWMtZTIyMi00NzM5LWE2OWItYzRkZDA3ZmJiZmE0") {
      edges {
        node {
          id
          title
          description
          tags
          customFields {
            key
            value
          }
          configSlots {
            externalId
            title
            defaultValue
          }
          authSlots {
            externalId
            title
          }
        }
        cursor
      }
      pageInfo {
          hasNextPage
          endCursor
          hasPreviousPage
          startCursor
      }
    }
  }
}
Returned Data Subfields Notes
id The solution id which needs to be passed when using the createSolutionInstance mutation.
title
description
configSlots externalId
title
defaultValue
This can be used to expose the externalId of Config Data which is required when Importing External Data
authSlots externalId
title
Array of all the auths required by your solution
tags If you have created tags in the Solution Editor, this field can be used to filter Solutions in your external application
custom fields You can set these on the solution settings page.

Pagination

You can paginate the results of this query using the methods discussed in Pagination

SecuritybearerAuth
Request
Responses
Request samples
curl -i -X POST \
  https://tray.io/graphql \
  -H 'Authorization: Bearer <MASTER_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": "query {\n  viewer {\n    solutions {\n      edges {\n        node {\n          id\n          title\n          description\n          tags\n          customFields {\n            key\n            value\n          }\n          configSlots {\n            externalId\n            title\n            defaultValue\n          }\n          authSlots {\n            title\n            externalId\n          }\n        }\n        cursor\n      }\n      pageInfo {\n          hasNextPage\n          endCursor\n          hasPreviousPage\n          startCursor\n      }\n    }\n  }\n}",
    "variables": {}
  }'
Response samples
application/json
{
  • "data": {
    }
}

Solution Instances

Solution Instances are the end user's configuration of your Solutions. Instances contain their own auths and config data.

Queries

Query for retrieving the solution instances used by your end users.

Get solution instances (user/master token)

post/

Return the Solution Instances associated with a particular user.

Pay particular attention to solutionVersionFlags as a piece of returned data, which indicates if the Instance needs upgrading due to new information being required from the End User. For more information, refer the decision table.

Required token Notes
Master Obtained from the Tray app UI. Refer this.
If using a Master token it is possible to filter Solution Instances by the owner of the Solution Instance, or by the ID of the Solution which it came from
User obtained after creating a user token (Users/Mutations/Create User Token)
the user token is a persistent token (valid for 2 days) that should be securely stored in your application
If a User token is used, the Solution Instances displayed will only be those owned by that End User

The query accepts the following filter criteria:

Criteria Notes
solutionId Can be used to filter based on the Solution which the Instance came from. If used with a User Token it will only return instances owned by that user
owner This is the userId of an End User. Can only be used with a Master Token, in order to filter Solution Instances of a particular user

Note that it is possible to filter by both owner and solutionId at the same time.

Returned Data Subfields Notes
totalCount Note this is a top-level field, so is specified before 'edge' as per example query below
The results returned by the totalCount will depend on the filter criteria specified:
If solutionId is specified the total count will refer to the solution instances for that particular solution
If owner (userId) is specified (when using a Master Token) the total count will refer to the solution instances for that end user
If owner and solutionId are both specified the total count will refer to the solution instances for that user and for that solution
id the solutionInstance id
name the name (derived from the parent Solution)
enabled boolean to indicate whether the solutionInstance has been activated using Update Solution Instance
created the date and time the solutionInstance was created
solutionVersionFlags hasNewerVersion
requiresUserInputToUpdateVersion
requiresSystemInputToUpdateVersion
boolean flags used to indicate if an underlying Solution has a newer version which might need upgrading as explained in Updating / Upgrading Solution Instances
solution id
title
description
customFields
configSlots
authSlots
details of the parent Solution
workflows id
triggerUrl
sourceWorkflowId
sourceWorkflowName
triggerUrl is the webhook url for the End User's version of that workflow (see Retrieving Webhook URLs)
configValues externalId
value
any config data that has been set for the End User of the solutionInstance
authValues externalId
authId
authentications associated with this solutionInstance

Pagination

You can paginate the results of this query using the methods discussed in Pagination

Here are some example queries:

Get solution instance(s) by owner - Master Token
query {
    viewer {
        solutionInstances(criteria: { owner: "13b3ab9c-XXXX-XXXX-XXXX-c4dd07fbbfa4" }) {
            edges {
                node {
                    id
                    name
                    enabled
                    owner
                    created
                    solutionVersionFlags {
                        hasNewerVersion
                        requiresUserInputToUpdateVersion
                        requiresSystemInputToUpdateVersion
                    }
                    workflows {
                        edges {
                            node {
                                triggerUrl
                                id
                                sourceWorkflowId
                sourceWorkflowName
                            }
                        }
                    }
                    authValues {
                        externalId
                        authId
                    }
                    configValues {
                        externalId
                        value
                    }
                }
                cursor
            }
            pageInfo {
                startCursor
                endCursor
                hasNextPage
                hasPreviousPage
            }
        }
    }
}
Get solution instance(s) by owner and solution ID - Master Token
query {
    viewer {
        solutionInstances(criteria: { 
                solutionId: "b73d4e07xxx-xxx-xxx-xxx-xxxafad23d94",
                owner: "13b3ab9c-XXXX-XXXX-XXXX-c4dd07fbbfa4" 
            }) {
            edges {
                node {
                    id
                    name
                    enabled
                    owner
                    created
                    solutionVersionFlags {
                        hasNewerVersion
                        requiresUserInputToUpdateVersion
                        requiresSystemInputToUpdateVersion
                    }
                    workflows {
                        edges {
                            node {
                                triggerUrl
                                id
                                sourceWorkflowId
                                sourceWorkflowName
                            }
                        }
                    }
                    authValues {
                        externalId
                        authId
                    }
                    configValues {
                        externalId
                        value
                    }
                }
                cursor
            }
            pageInfo {
                startCursor
                endCursor
                hasNextPage
                hasPreviousPage
            }
        }
    }
}
SecuritybearerAuth
Request
Responses
Request samples
curl -i -X POST \
  https://tray.io/graphql \
  -H 'Authorization: Bearer <USER_OR_MASTER_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": "query ($ownerId: String!){\n\tviewer {\n\t\tsolutionInstances(criteria: { owner: $ownerId }) {\n\t\t\tedges {\n\t\t\t\tnode {\n\t\t\t\t\tid\n\t\t\t\t\tname\n\t\t\t\t\tenabled\n\t\t\t\t\towner\n\t\t\t\t\tcreated\n\t\t\t\t\tsolutionVersionFlags {\n\t\t\t\t\t\thasNewerVersion\n\t\t\t\t\t\trequiresUserInputToUpdateVersion\n\t\t\t\t\t\trequiresSystemInputToUpdateVersion\n\t\t\t\t\t}\n\t\t\t\t\tworkflows {\n\t\t\t\t\t\tedges {\n\t\t\t\t\t\t\tnode {\n\t\t\t\t\t\t\t\ttriggerUrl\n\t\t\t\t\t\t\t\tid\n\t\t\t\t\t\t\t\tsourceWorkflowId\n                                sourceWorkflowName\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tauthValues {\n\t\t\t\t\t\texternalId\n\t\t\t\t\t\tauthId\n\t\t\t\t\t}\n\t\t\t\t\tconfigValues {\n\t\t\t\t\t\texternalId\n\t\t\t\t\t\tvalue\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcursor\n\t\t\t}\n\t\t\tpageInfo {\n\t\t\t\tstartCursor\n\t\t\t\tendCursor\n\t\t\t\thasNextPage\n\t\t\t\thasPreviousPage\n\t\t\t}\n\t\t}\n\t}\n}",
    "variables": {
      "ownerId": "13b3ab9c-XXXX-XXXX-XXXX-c4dd07fbbfa4"
    }
  }'
Response samples
application/json
{
  • "data": {
    }
}

Mutations

Mutations for modifying the solution instances used by your end users.

Create solution instance (user token)

post/

This mutation is used to create a Solution Instance for an End User who has chosen to activate a particular Solution for their own use.

The steps involved in activating a Solution Instance for an End User are:

  1. Use this mutation to create a Solution Instance which returns a id

  2. Generate a Config Wizard authorization code with Users/Mutations/Create Config Wizard Authorization Code

  3. Use the id from step 1 and the auth code from step 2 to activate the pop-up Configuration Wizard for the End User with the following url:

     https://embedded.tray.io/external/solutions/${partnerId}/configure/${solutionInstanceId}?code=${authorizationCode}
    
  4. Your app will receive a tray.configPopup.finish PostMessage as explained in Dealing with the Config Wizard

  5. Once the Solution Instance is configured for the End User, use Solution Instances/Mutations/Update Solution Instance to set the status to 'enabled'

Required token Notes
User obtained after creating a user token (Users/Mutations/Create User Token)
the user token is a persistent token (valid for 2 days) that should be securely stored in your application

The mutation accepts the following arguments:

Argument Required Note
solutionId Yes obtained with Solutions/Queries/Get Solutions
instanceName Yes
authValues No can be used to import end user authentications.
see Importing Auths
configValues No can be used to import external data
see Importing External Data

Here is an example mutation:

Create Solution Instance
mutation {
   createSolutionInstance(input: {
       solutionId: "b3422397-XXXX-XXXX-XXXX-57e7e66771b3"
       instanceName: "PetersGraphQLInstance"
   }) {
     solutionInstance {
       id
       name
       enabled
       created
       authValues {
           authId
           externalId
       }
       configValues {
           value
           externalId
       }
       solution {
           id
           title
           description
           tags
           customFields
           configSlots
       }
       workflows {
           edges {
               node {
                   id
                   sourceWorkflowId
                   sourceWorkflowName
                   triggerUrl
               }
           }
       }
       solutionVersionFlags {
           hasNewerVersion
           requiresUserInputToUpdateVersion
           requiresSystemInputToUpdateVersion
       }
     }
   }
}

It can return the following data:

Returned Data Subfields Notes
id
name
created
enabled defaults to False so must be set to True with Mutations/Solution Instances/Update Solution Instance - Enable
solution id, title, description, tags, customFields, configSlots details of the parent solution
workflows id, sourceWorkflowId, sourceWorkflowName, triggerUrl details of the source workflows, including webhook url (triggerUrl)
authValues authId, externalId details of the auths associated with the instance
configValues value, externalId details of config values associated with the user
solutionVersionFlags hasNewerVersion, requiresUserInputToUpdateVersion, requiresSystemInputToUpdateVersion boolean flags used to indicate if an underlying Solution has a newer version which might need upgrading as explained in Updating / Upgrading Solution Instances
SecuritybearerAuth
Request
Responses
Request samples
curl -i -X POST \
  https://tray.io/graphql \
  -H 'Authorization: Bearer <USER_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": "mutation ($solutionId: ID!, $instanceName: String!){\n   createSolutionInstance(input: {\n       solutionId: $solutionId\n       instanceName: $instanceName\n   }) {\n     solutionInstance {\n       id\n       name\n       enabled\n       created\n       workflows {\n           edges {\n               node {\n                   id\n                   triggerUrl\n                   sourceWorkflowId\n               }\n           }\n       }\n     }\n   }\n }",
    "variables": {
      "solutionId": "b3422397-XXXX-XXXX-XXXX-57e7e66771b3",
      "instanceName": "Gene Slack star instance 2"
    }
  }'
Response samples
application/json
{
  • "data": {
    }
}

Update solution instance (user token)

post/

The primary use of this mutation is to 'enable' the solution instance. This is a required step after creating and configuring the solution instance.

If you are auto enabling the instances for your end users after they complete the config wizard, your code should be configured to delay this enable mutation by least 2 seconds after createSolutionInstance is complete.
This mutation can also be used to update existing auth and config values that were attached after the user ran the config wizard.

If you are dealing with new auth/config settings, the parent solution will be on a new version, and the instance must be upgraded by the end user re-running the Config Wizard or using Solution Instances/Mutations/Upgrade Solution Instance. This is explained in detail in Updating/Upgrading Solution Instances

Required token Notes
User Obtained after using Users/Mutations/Create User Token.
The User Token is a persistent token that should be securely stored in your application for future use (expires after 2 days)

The mutation accepts the following arguments:

Argument Required Note
solutionInstanceId Yes obtained with Solution Instances/Queries/Get Solution Instances
instanceName No
enabled No set to True to enable the Solution Instance after it is created
authValues No accepts an array of objects. Each object has two keys: externalId and authId. Check an example mutation below to see how it will be passed
configValues No accepts an array of objects. Each object has two keys: externalId and value. Note that value is always a string. So it must be stringified if it is of any other type (object/array, boolean, number). Check an example mutation below to see how it will be passed

Here is an example mutation:

Update Solution Instance - Enable
mutation {
  updateSolutionInstance(input: {
      solutionInstanceId: "2d38b2ec-xxxx-xxx-xxxx-b4ec68084266",
      instanceName: "test-instance", 
      enabled: true
  }) {
    solutionInstance {
      id
      name
      enabled
      created
    }
  }
}
Update Solution Instance - Update config and auth values
mutation {
  updateSolutionInstance(input: {
      solutionInstanceId: "2d38b2ec-xxxx-xxx-xxxx-b4ec68084266",
      configValues: [
        {
          "externalId": "external_limit",
          "value": "10"
        },
        {
                "externalId": "external_datamappings",
                "value": "{\"location\":\"**********\",\"email\":\"**********\"}"
            }
      ]
      authValues: [
        { 
          "externalId": "external_slack_authentication", 
          "authId": "aaa67786-XXXX-XXXX-XXXX-97dedd1519b3"
        }
        ]
  }) {
    solutionInstance {
      id
      name
      enabled
      created
    }
  }
}
Returned Data Subfields Notes
id
name
created
enabled defaults to False so must be set to True with this mutation
solution id, title, description, tags, customFields, configSlots, authSlots details of the parent solution
workflows id, sourceWorkflowId, sourceWorkflowName, triggerUrl details of the source workflows, including webhook url (triggerUrl)
authValues authId, externalId details of the auths associated with the instance
configValues value, externalId details of config values associated with the user
solutionVersionFlags hasNewerVersion, requiresUserInputToUpdateVersion, requiresSystemInputToUpdateVersion boolean flags used to indicate if an underlying Solution has a newer version which might need upgrading as explained in Updating / Upgrading Solution Instances
SecuritybearerAuth
Request
Responses
Request samples
curl -i -X POST \
  https://tray.io/graphql \
  -H 'Authorization: Bearer <USER_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": "mutation ($solutionInstanceId: ID!, $instanceName: String!, $enabled: Boolean!) {\n  updateSolutionInstance(input: {\n      solutionInstanceId: $solutionInstanceId,\n      instanceName: $instanceName, \n      enabled: $enabled\n  }) {\n    solutionInstance {\n      id\n      name\n      enabled\n      created\n    }\n  }\n}",
    "variables": {
      "solutionInstanceId": "2d38b2ec-xxxx-xxx-xxxx-b4ec68084266",
      "instanceName": "myCustomersSolutionInstanceName",
      "enabled": true
    }
  }'
Response samples
application/json
{
  • "data": {
    }
}

Upgrade solution instance (user token)

post/

This mutation is used when a new version of a Solution has been published which contains new Config Data (which doesn't require user input) and you wish to upgrade an End User's Instance with the new Config Data, without asking them to use the Configuration Wizard again.

Please see our page on Updating / Upgrading Solution Instances for a full explanation of how to manage changes to your Workflows and Solutions.

Required token Notes
User Obtained after using Users/Mutations/Create User Token.
The User Token is a persistent token that should be securely stored in your application for future use (expires after 2 days)

The mutation accepts the following arguments:

Argument Required Note
solutionInstanceId Yes obtained with Solution Instances/Queries/Get Solution Instances
instanceName No
authValues No Can be used to import End User authentications. See Importing Auths
configValues No Can be used to import external data. See Importing External Data
clientMutationId No Only relevant if using the Relay GraphQL client

Here is an example mutation:

Update Solution Instance - Enable
mutation {
  upgradeSolutionInstance (input: {
    solutionInstanceId: "5f85b697-XXXX-XXXX-XXXX-5d7dabe22634", 
    configValues: [
      { 
        "externalId": "external_support-email", 
        "value": "support@example.com"  
      }
      ],
    authValues: [
      { 
        "externalId": "external_slack_authentication", 
        "authId": "aaa67786-XXXX-XXXX-XXXX-97dedd1519b3"
      }
      ]
  }) { 
    solutionInstance  {
      id
      configValues{
        externalId
        value
      }
      authValues{
        authId
        externalId
      }
      enabled
      owner
      created
    }
  }
}
SecuritybearerAuth
Request
Responses
Request samples
curl -i -X POST \
  https://tray.io/graphql \
  -H 'Authorization: Bearer <USER_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": "mutation ($solutionInstanceId: ID!, $configValues: [ConfigValue!], $authValues: [AuthValue!] ){\n  upgradeSolutionInstance (input: {\n    solutionInstanceId: $solutionInstanceId, \n    configValues: $configValues,\n    authValues: $authValues\n  }) \n    { \n solutionInstance  {\n  id\n  configValues{\n    externalId\n    value\n  }\n  authValues{\n    authId\n    externalId\n  }\n  enabled\n  created\n  }\n }\n}",
    "variables": {
      "solutionInstanceId": "625xxx-xxx-xxx-xxx-xxx111f",
      "configValues": [
        {
          "externalId": "external_support-email",
          "value": "support@example.com"
        }
      ],
      "authValues": [
        {
          "externalId": "external_slack_authentication",
          "authId": "aaa67786-XXXX-XXXX-XXXX-97dedd1519b3"
        }
      ]
    }
  }'
Response samples
application/json
{
  • "data": {
    }
}

Delete Solution Instance (user token)

post/

Used to delete a Solution Instance.

Please also see our page on Deleting Solutions and Projects

Required token Notes
User obtained after creating a user token (Users/Mutations/Create User Token)
the user token is a persistent token (valid for 2 days) that should be securely stored in your application

The mutation accepts the following as inputs:

Input Required Notes
solutionInstanceId Yes obtained with Solution Instances/Queries/Get Solution Instances
clientMutationId No Only relevant if using the Relay GraphQL client

Here are some example mutations:

Delete Solution Instance
mutation {
  removeSolutionInstance(input: {solutionInstanceId: "2d38b2ec-xxxx-xxx-xxxx-b4ec68084266"}) {
   clientMutationId
 }
}
Delete Solution Instance with clientMutationId
mutation {
  removeSolutionInstance(input: {solutionInstanceId: "2d38b2ec-xxxx-xxx-xxxx-b4ec68084266", clientMutationId: "some-mutation-id"}) {
   clientMutationId
 }
}

It can return the following data:

Returned Data Notes
clientMutationId while this data is Only relevant if using the Relay GraphQL client, it is actually required here as currently this mutation does not return any other data
SecuritybearerAuth
Request
Responses
Request samples
curl -i -X POST \
  https://tray.io/graphql \
  -H 'Authorization: Bearer <USER_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": "mutation ($solutionInstanceId: ID!){\n  removeSolutionInstance(input: {solutionInstanceId: $solutionInstanceId}) {\n   clientMutationId\n }\n}",
    "variables": {
      "solutionInstanceId": "2d38b2ec-xxxx-xxx-xxxx-b4ec68084266"
    }
  }'
Response samples
application/json
{
  • "data": {
    }
}

Projects

Project represents a collection of workflows that make up the integration.

Mutations

Mutations for importing and exporting projects in your Tray org.

Import Project (master token)

post/

The importProject mutation can be used to import and overwrite an existing project in your embedded account. This is handy when you want to import projects to your 'production' account from 'staging'.

If the project you are importing has a solution associated with it, the solution will be imported as draft

That means before you start creating instances for this solution, it has to be published manually through UI.

Required token Notes
Master Obtained from the Tray app UI. Refer this.

The mutation accepts the following arguments:

Argument Required Note
exportedProjectJson Yes Can be obtained either by exporting project json from UI or using the exportProject mutation (refer below)
The JSON must be stringified.
targetProjectId Yes obtained from the url of target Project page: https://app.tray.io/workspaces/{workspaceId}/projects/{projectId}
clientMutationId No Only relevant if using the Relay GraphQL client

Here is an example mutation:

Import Project
mutation {
  importProject (input: {
    exportedProjectJson: "{}",
    targetProjectId: "944dxxx-xxx-xxx-xxx-xxx222eb99"
  }) {
    clientMutationId
  }
}
Import Project with clientMutationId
mutation {
  importProject (input: {
    exportedProjectJson: "{}",
    targetProjectId: "944dxxx-xxx-xxx-xxx-xxx222eb99",
    clientMutationId: "some-mutation-id"
  }) {
    clientMutationId
  }
}

It can return the following data:

Returned Data Notes
clientMutationId while this data is only relevant if using the Relay GraphQL client, it is actually required here as currently this mutation does not return any other data
SecuritybearerAuth
Request
Responses
Request samples
curl -i -X POST \
  https://tray.io/graphql \
  -H 'Authorization: Bearer <MASTER_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": "mutation ($exportedProjectJson: String!, $targetProjectId: ID!) {\n  importProject (input: {\n    exportedProjectJson: $exportedProjectJson,\n    targetProjectId: $targetProjectId\n  }) {\n    clientMutationId\n  }\n}",
    "variables": {
      "exportedProjectJson": "{}",
      "targetProjectId": "944dxxx-xxx-xxx-xxx-xxx222eb99"
    }
  }'
Response samples
application/json
{
  • "data": {
    }
}

Export Project (master token)

post/

The exportProject mutation can be used to export the projects from your embedded account. This is handy when you want to import project to your 'production' account from 'staging'.

Required token Notes
Master Obtained from the Tray app UI. Refer this.

The mutation accepts the following arguments:

Argument Required Note
projectId Yes obtained from the url of the Project page: https://app.tray.io/workspaces/{workspaceId}/projects/{projectId}
exportSolution Yes Boolean value.
If set to true, the solution associated with the workflow is exported as part of the JSON structure.
clientMutationId No Only relevant if using the Relay GraphQL client

Here is an example mutation:

Export Project
mutation {
  exportProject (input: {
    projectId: "944dxxx-xxx-xxx-xxx-xxx222eb99",
    exportSolution: true
  }) {
    exportedProjectJson
  }
}

It can return the following data:

Returned Data Notes
exportedProjectJson Stringified JSON of the project
SecuritybearerAuth
Request
Responses
Request samples
curl -i -X POST \
  https://tray.io/graphql \
  -H 'Authorization: Bearer <MASTER_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": "mutation ($projectId: ID!) {\n  exportProject (input: {\n    projectId: $projectId,\n    exportSolution: true\n  }) {\n    exportedProjectJson\n  }\n}",
    "variables": {
      "projectId": "944dxxx-xxx-xxx-xxx-xxx222eb99"
    }
  }'
Response samples
application/json
{
  • "data": {
    }
}

Workflows

Workflow represent a set of connector steps in Tray that perform a task.

Mutations

Mutations for importing and exporting workflows in your Tray org.

Import Workflows (master token)

post/

The importWorkflows mutation can be used to import the workflow to your embedded account. This is handy when you want to import workflows to your 'production' account from 'staging'.

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 if you are working with multiple workflows, it is more likely that you will be importing a project.

Required token Notes
Master Obtained from the Tray app UI. Refer this.

The mutation accepts the following arguments:

Argument Required Note
exportedWorkflowsJson Yes Can be obtained either by exporting workflow json from UI or using the exportWorkflows mutation (refer below)
The JSON must be stringified.
targetWorkflowIds Yes Array of workflow IDs
Workflow ID can be obtained from the url of target workflow page: https://app.tray.io/workflow/{workflowId}
clientMutationId No Only relevant if using the Relay GraphQL client

Here is an example mutation:

Import Project
mutation {
    importWorkflows (input: {
        exportedWorkflowsJson: "{\"tray_export_version\":4,\"export_type\":\"workflow\",\"workflows\":[{\"id\":\"ea3c20f5-xxxx-xxxx-xxxx-0ce2b7bb9f29\",\"created\":\"2023-05-15T11:26:14.794686Z\",\"workspace_id\":\"6c595d5b-xxxx-xxxx-xxxx-959ceb938eae\",\"creator\":\"6a4e56d9-xxxx-xxxx-xxxx-2429f79b40ff\",\"version\":{\"id\":\"018cc858-xxxx-xxxx-xxxx-2c8cfe0a7886\",\"created\":\"2023-05-16T22:25:42.413825Z\"},\"title\":\"webhook slack\",\"enabled\":false,\"tags\":[],\"settings\":{\"config\":{},\"input_schema\":{},\"output_schema\":{}},\"steps_structure\":[{\"name\":\"trigger\",\"type\":\"normal\",\"content\":{}}],\"steps\":{\"trigger\":{\"title\":\"Webhook\",\"connector\":{\"name\":\"webhook\",\"version\":\"2.3\"},\"operation\":\"fire_and_forget\",\"output_schema\":{},\"error_handling\":{},\"properties\":{}}},\"dependencies\":[]}],\"projects\":[]}",
        targetWorkflowIds: ["e5dc0748-xxxx-xxxx-xxxx-dfcc33795f12"]
        }) {
      clientMutationId
    }
}
Import Project with clientMutationId
mutation {
    importWorkflows (input: {
        exportedWorkflowsJson: "{\"tray_export_version\":4,\"export_type\":\"workflow\",\"workflows\":[{\"id\":\"ea3c20f5-xxxx-xxxx-xxxx-0ce2b7bb9f29\",\"created\":\"2023-05-15T11:26:14.794686Z\",\"workspace_id\":\"6c595d5b-xxxx-xxxx-xxxx-959ceb938eae\",\"creator\":\"6a4e56d9-xxxx-xxxx-xxxx-2429f79b40ff\",\"version\":{\"id\":\"018cc858-xxxx-xxxx-xxxx-2c8cfe0a7886\",\"created\":\"2023-05-16T22:25:42.413825Z\"},\"title\":\"webhook slack\",\"enabled\":false,\"tags\":[],\"settings\":{\"config\":{},\"input_schema\":{},\"output_schema\":{}},\"steps_structure\":[{\"name\":\"trigger\",\"type\":\"normal\",\"content\":{}}],\"steps\":{\"trigger\":{\"title\":\"Webhook\",\"connector\":{\"name\":\"webhook\",\"version\":\"2.3\"},\"operation\":\"fire_and_forget\",\"output_schema\":{},\"error_handling\":{},\"properties\":{}}},\"dependencies\":[]}],\"projects\":[]}",
        targetWorkflowIds: ["e5dc0748-xxxx-xxxx-xxxx-dfcc33795f12"],
        clientMutationId: "some-mutation-id"
        }) {
      clientMutationId
    }
}

It can return the following data:

Returned Data Notes
clientMutationId while this data is only relevant if using the Relay GraphQL client, it is actually required here as currently this mutation does not return any other data
SecuritybearerAuth
Request
Responses
Request samples
curl -i -X POST \
  https://tray.io/graphql \
  -H 'Authorization: Bearer <MASTER_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": "mutation ($exportedProjectJson: String!, $targetProjectId: ID!) {\n  importProject (input: {\n    exportedProjectJson: $exportedProjectJson,\n    targetProjectId: $targetProjectId\n  }) {\n    clientMutationId\n  }\n}",
    "variables": {
      "exportedProjectJson": "{}",
      "targetProjectId": "944dxxx-xxx-xxx-xxx-xxx222eb99"
    }
  }'
Response samples
application/json
{
  • "data": {
    }
}

Export Workflows (master token)

post/

The exportWorkflows mutation can be used to export the workflows from your embedded account. This is handy when you want to import workflows to your 'production' account from 'staging'.

Note that it is possible to export multiple workflows

Required token Notes
Master Obtained from the Tray app UI. Refer this.

The mutation accepts the following arguments:

Argument Required Note
workflowIds Yes Array of workflow IDs.
Workflow ID can be obtained from the url of target workflow page: https://app.tray.io/workflow/{workflowId}

Here is an example mutation:

Export Workflows
mutation {
  exportWorkflows (input: {
    workflowIds: ["ea3c20f5-xxxx-xxxx-xxxx-0ce2b7bb9f29", "a6af4264-xxxx-xxxx-xxxx-70a1e59d72b2"]
  }) {
    exportedWorkflowsJson
  }
}

It can return the following data:

Returned Data Notes
exportedWorkflowsJson Stringified JSON of the array of workflows
SecuritybearerAuth
Request
Responses
Request samples
curl -i -X POST \
  https://tray.io/graphql \
  -H 'Authorization: Bearer <MASTER_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": "mutation ($projectId: ID!) {\n  exportProject (input: {\n    projectId: $projectId,\n    exportSolution: true\n  }) {\n    exportedProjectJson\n  }\n}",
    "variables": {
      "projectId": "944dxxx-xxx-xxx-xxx-xxx222eb99"
    }
  }'
Response samples
application/json
{
  • "data": {
    }
}

Call Connector

Mutations for importing and exporting workflows in your Tray org.

Mutations

Mutation for calling a Tray connector.

Call a Tray connector

post/

This mutation can be used to call a specific connector operation.

This powerful feature is used in combination with a User Token and Authentication Id, to pull data from a particular service connector operation and display it in your app.

As an example, for a particular End User of your Embedded application, you could use it to display all of the 'Warm' Salesforce Leads assigned to them, or display all the customers with overdue payments.

Check out the Operations explorer app which will help you to figure out the input for any connector/any operation.

The tool also gives insight into the output schema for those operations, which will help you process the result.

Please see full instructions for using this endpoint at [https://tray.io/documentation/embedded/advanced-topics/call-connector/](https://tray.io/documentation/embedded/adva nced-topics/call-connector/)

Required token Notes
User or Master Obtained after using Users/Mutations/Create User Token.
The User Token is a persistent token that should be securely stored in your application for future use (expires after 2 days)

The mutation accepts the following arguments:

Input Required Note
connector Yes The programatic connector name. Obtained from the workflow builder, see example below
version Yes The version of the connector being used. Obtained from inspecting the Advanced settings of the input panel in the workflow builder, see example below
operation Yes The programmatic name of the operation. This is usually the name of the operation visible in the workflow builder input panel, converted to snake case. Please reach out to support@tray.io if you get the error message The connector operation ### was not found
authId Yes see prerequisites below on obtaining an authId
input Yes The stringified JSON body representing the input parameters to the operation. You can explore the input schema for all connectors and their operations' in the Operations explorer app.
clientMutationId No Only relevant if using the Relay GraphQL client

Here is a sample mutation:

Call connector - Get all leads in Salesforce
mutation {
    callConnector(input: {
        connector: "salesforce",
        version: "8.1",
        operation: "get_records",
        authId: "########-####-####-####-############",
        input: "{\\"limit\\":10,\\"conditions_type\\":\\"Match all conditions\\",\\"fields\\":[\\"Id\\",\\"Name\\"],\\"object\\":\\"Lead\\"}"
        }) 
    {
        output
    }
}

It returns the following data:

Returned Data Notes
output The stringified JSON body representing the data returned from the connector
clientMutationId Only relevant if using the Relay GraphQL client

Named requests (Aliases)

GraphQL provides the capability to send multiple mutations at once. If you need to use the same mutation multiple times, you can use aliases (avoid any duplicate names).

Here is an example mutation with two mutations merged into one using aliases listAllLeads and listWarmLeads.

Multiple connector calls in one
mutation callSalesforce {
    listAllLeads: callConnector(input: {
        connector: "salesforce",
        version: "4.0",
        operation: "find_records",
        authId: "########-####-####-####-############",
        input: "{\\"limit\\":10,\\"conditions_type\\":\\"Match all conditions\\",\\"fields\\":[\\"Id\\",\\"Name\\"],\\"object\\":\\"Lead\\"}"
        }) {
        output
    },
    listWarmLeads: callConnector(input: {
        connector: "salesforce",
        version: "4.0",
        operation: "find_records",
        authId: "########-####-####-####-############",
        input: "{\\"conditions_type\\":\\"Match all conditions\\",\\"fields\\":[\\"Id\\",\\"Name\\"],\\"conditions\\":[{\\"field\\":\\"Rating\\",\\"operator\\":\\"Equal to\\",\\"value\\":\\"Warm\\"}],\\"object\\":\\"Lead\\"}"
        }) {
        output
    }
}
SecuritybearerAuth
Request
Responses
Request samples
curl -i -X POST \
  https://tray.io/graphql \
  -H 'Authorization: Bearer <MASTER_TOKEN>' \
  -H 'Content-Type: application/json' \
  -d '{
    "query": "mutation listLeads(\n  $connector: String!, \n  $version: String!, \n  $operation: String!, \n  $authId: String, \n){ listAllLeads: callConnector(input: {\n    connector: $connector,\n    version: $version,\n    operation: $operation,\n    authId: $authId,\n    input: \"{\\\"limit\\\":10,\\\"conditions_type\\\":\\\"Match all conditions\\\",\\\"fields\\\":[\\\"Id\\\",\\\"Name\\\"],\\\"object\\\":\\\"Lead\\\"}\"\n  }) {\n    output\n  }\n}",
    "variables": {
      "connector": "salesforce",
      "version": "8.7",
      "operation": "find_records",
      "authId": "062af7e2-b5xxx-xxx-xxx-xxx-xxxxx46d912"
    }
  }'
Response samples
application/json
{
  • "data": {
    }
}