Cloud 2 Cloud

📘

Enterprise Feature

The EVRYTHNG Cloud 2 Cloud (C2C) Connector Framework is an extensible capability to integrate other third party cloud services with the EVRYTHNG Platform. Users can interact with devices/products/things that are connected to another cloud (e.g. Nest) from the EVRYTHNG Platform and vice versa. EVRYTHNG becomes the glue between different third party clouds and applications can leverage this to easily combine in their logical things from different platforms in a homogeneous way, and further enrich the end-user experience.


API Status
Stable:
/projects/:projectId/applications/:applicationId/connectors
/connectors
/connectors/:connectorName
/connectors/:connectorName/auth


Overview

To integrate a third party cloud with your EVRYTHNG account you have to:

  • Define the basic connector information (using the API defined below)
  • Define the authentication parameters for the third party cloud. This usually requires credentials for an OAuth authentication and authorization process that enables the connector instance to access your third party cloud account. The connector will provide a common endpoint to launch the authentication process from any application.
  • Create and manage a model that maps the properties of the "devices" in the third party cloud to the Thngs in the EVRYTHNG platform. The connector uses this mapping for various operations such as creation of Thngs, synchronization, monitoring and more.

Supported Third Party Clouds

Currently, the following clouds are supported:

  • Nest - Integrate with Nest smart devices to exchange data and trigger actions.

ConnectorDocument Data Model

.name (string, read-only, one of 'nest')
    The unique name of the connector.

.model (NestModelDocument)

.auth (OAuthDocument)

.displayName (string, read-only)
    Friendly name of the connector.

.url (string, read-only)
    The url of the 3rd party service.

.image (string, read-only)
    The location of an image associated with the 3rd party 
    service.

.authUrl (string, read-only)
    The authentication url for the 3rd party service.

.status (string, read-only, one of 'connected', 'disconnected')
    The status of the connector.
{
  "type": "object",
  "description": "An object describing a Cloud 2 Cloud Connector Framework connector.",
  "properties": {
    "name": {
      "type": "string",
      "description": "The unique name of the connector.",
      "readOnly": true,
      "enum": [ "nest" ]
    },
    "model": { "$ref": "NestModelDocument" },
    "auth": { "$ref": "OAuthDocument" },
    "displayName": {
      "type": "string",
      "description": "Friendly name of the connector.",
      "readOnly": true
    },
    "url": {
      "type": "string",
      "description": "The url of the 3rd party service.",
      "readOnly": true
    },
    "image": {
      "type": "string",
      "description": "The location of an image associated with the 3rd party service.",
      "readOnly": true
    },
    "authUrl": {
      "type": "string",
      "description": "The authentication url for the 3rd party service.",
      "readOnly": true
    },
    "status": {
      "type": "string",
      "description": "The status of the connector.",
      "enum": [ "connected", "disconnected" ],
      "readOnly": true
    }
  }
}
{
  "name": "nest",
  "displayName": "Nest",
  "url": "http://www.nest.com",
  "image": "http://file.answcdn.com/answ-cld/image/upload/v1/tk/brand_image/c7d3fadd/c71c29fef0dd6c56a9b2777906bcf3245960c403.png",
  "authUrl": "https://api.evrythng.com/connectors/nest/auth",
  "model": {
    "structures": {
      "name": "Structure Name"
    },
    "devices": {
      "thermostats": {
        "name": "Thermostat Name"
      },
      "smoke_co_alarms": {
        "name": "Smoke Alarm Name"
      }
    }
  },
  "auth": {
    "type": "oauth",
    "oAuthUrl": "https://home.nest.com/login/oauth2",
    "tokenUrl": "https://api.home.nest.com/oauth2/access_token",
    "clientId": "6b5adf3d-4434-443b-b43a-756a9a7e58c6",
    "clientSecret": "27BCDgGp493BaB8GFHVmACBCB"
  }
}

See also: OAuthDocument, NestModelDocument


OAuthDocument Data Model

.clientId (string)
    The OAuth client ID for the 3rd party service.

.clientSecret (string)
    The OAuth client secret for the 3rd party service.

.type (string, one of 'oauth')
    The authentication type.

.oAuthUrl (string)
    The URL of the OAuth service.

.tokenUrl (string)
    The URL of the OAuth service access token.
{
  "type": "object",
  "description": "OAuth connector credentials",
  "properties": {
    "clientId": {
      "type": "string",
      "description": "The OAuth client ID for the 3rd party service.",
      "minLength": 36,
      "maxLength": 36
    },
    "clientSecret": {
      "type": "string",
      "description": "The OAuth client secret for the 3rd party service.",
      "minLength": 25,
      "maxLength": 25
    },
    "type": {
      "type": "string",
      "description": "The authentication type.",
      "enum": [ "oauth" ]
    },
    "oAuthUrl": {
      "type": "string",
      "description": "The URL of the OAuth service."
    },
    "tokenUrl": {
      "type": "string",
      "description": "The URL of the OAuth service access token."
    }
  }
}

Create a Connector

To enable a third party integration for a specific application, we need to POST a connector model describing the configuration of the connection with the third party cloud. Only the Operator can enable connectors in an application. For Nest connectors, the auth credentials can be found in the Nest Developers console.

📘

Note

To use the default connector model for a given name connector, specify model as 'default'. See Nest Model Example for an example.

POST /projects/:projectId/applications/:applicationId/connectors
Content-Type: application/json
Authorization: $OPERATOR_API_KEY

{
  "name": "nest",
  "model": "default",
  "auth": {
    "clientId": "6b5adf3d-4434-443b-b43a-756a9a7e58c6",
    "clientSecret": "27BCDgGp493BaB8GFHVmACBCB"
  }
}
curl -i -H "Content-Type: application/json" \
  -H "Authorization: $OPERATOR_API_KEY" \
  -X POST 'https://api.evrythng.com/projects/U2meqbNWegsaQKRRaDUmpssr/applications/UF3Vqb7D6G8EhMwaRYgQ2pFc/connectors'
  -d '{
    "name": "nest",
    "model": "default",
    "auth": {
      "clientId": "6b5adf3d-4434-443b-b43a-756a9a7e58c6",
      "clientSecret": "27BCDgGp493BaB8GFHVmACBCB"
    }
  }'
const projectId = 'U3fAq5MDBgswQpwawXgK2pSr';
const applicationId = 'UmH2xEfGMGsEEqRaREtn3eCq';

const payload = {
  name: 'nest',
  model: 'default',
  auth: {
    clientId: '6b5adf3d-4434-443b-b43a-756a9a7e58c6',
    clientSecret: '27BCDgGp493BaB8GFHVmACBCB'
  }
};

evrythng.api({
  url: `/projects/${projectId}/applications/${applicationId}/connectors`,
  apiKey: operatorApiKey,
  method: 'post',
  data: payload,
}).then(console.log);
HTTP/1.1 201 Created
Content-type: application/json

{
  "name": "nest",
  "displayName": "Nest",
  "url": "https://www.nest.com",
  "image": "https://file.answcdn.com/answ-cld/image/upload/v1/tk/brand_image/c7d3fadd/c71c29fef0dd6c56a9b2777906bcf3245960c403.png",
  "authUrl": "https://api.evrythng.com/connectors/nest/auth",
  "model": {
    "structures": {
      "tags": [
        "Nest",
        "Nest-structure"
      ],
      "name": "{name}",
      "description": "{name}",
      "properties": {
        "away": "{away}",
        "time_zone": "{time_zone}",
        "country_code": "{country_code}",
        "postal_code": "{postal_code}",
        "rhr_enrollment": "{rhr_enrollment}",
        "peak_period_start_time": "{peak_period_start_time}",
        "peak_period_end_time": "{peak_period_end_time}",
        "eta": "{eta}"
      },
      "actions": [
        "_nestUpdate"
      ]
    },
    "devices": {
      "thermostats": {
        "tags": [
          "Nest",
          "Nest-thermostat"
        ],
        "name": "{name}",
        "description": "{name_long}",
        "properties": {
          "locale": "{locale}",
          "device_id": "{device_id}",
          "software_version": "{software_version}",
          "structure_id": "{structure_id}",
          "last_connection": "{last_connection}",
          "is_online": "{is_online}",
          "can_cool": "{can_cool}",
          "can_heat": "{can_heat}",
          "is_using_emergency_heat": "{is_using_emergency_heat}",
          "has_fan": "{has_fan}",
          "fan_timer_active": "{fan_timer_active}",
          "fan_timer_timeout": "{fan_timer_timeout}",
          "has_leaf": "{has_leaf}",
          "temperature_scale": "{temperature_scale}",
          "target_temperature_f": "{target_temperature_f}",
          "target_temperature_c": "{target_temperature_c}",
          "target_temperature_high_f": "{target_temperature_high_f}",
          "target_temperature_high_c": "{target_temperature_high_c}",
          "target_temperature_low_f": "{target_temperature_low_f}",
          "target_temperature_low_c": "{target_temperature_low_c}",
          "away_temperature_high_f": "{away_temperature_high_f}",
          "away_temperature_high_c": "{away_temperature_high_c}",
          "away_temperature_low_f": "{away_temperature_low_f}",
          "away_temperature_low_c": "{away_temperature_low_c}",
          "hvac_mode": "{hvac_mode}",
          "ambient_temperature_f": "{ambient_temperature_f}",
          "ambient_temperature_c": "{ambient_temperature_c}",
          "humidity": "{humidity}",
          "hvac_state": "{hvac_state}",
          "where_id": "{where_id}",
          "is_locked": "{is_locked}",
          "locked_temp_min_f": "{locked_temp_min_f}",
          "locked_temp_max_f": "{locked_temp_max_f}",
          "locked_temp_min_c": "{locked_temp_min_c}",
          "locked_temp_max_c": "{locked_temp_max_c}",
          "label": "{label}"
        },
        "actions": [
          "_nestUpdate"
        ]
      },
      "smoke_co_alarms": {
        "tags": [
          "Nest",
          "Nest-protect"
        ],
        "name": "{name}",
        "description": "{name_long}",
        "properties": {
          "locale": "{locale}",
          "software_version": "{software_version}",
          "structure_id": "{structure_id}",
          "last_connection": "{last_connection}",
          "is_online": "{is_online}",
          "battery_health": "{battery_health}",
          "co_alarm_state": "{co_alarm_state}",
          "smoke_alarm_state": "{smoke_alarm_state}",
          "is_manual_test_active": "{is_manual_test_active}",
          "last_manual_test_time": "{last_manual_test_time}",
          "ui_color_state": "{ui_color_state}",
          "where_id": "{where_id}"
        },
        "actions": [
          "_nestUpdate"
        ]
      },
      "cameras": {
        "tags": [
          "Nest",
          "Nest-cam"
        ],
        "name": "{name}",
        "description": "{name_long}",
        "properties": {
          "software_version": "{software_version}",
          "structure_id": "{structure_id}",
          "where_id": "{where_id}",
          "is_online": "{is_online}",
          "is_streaming": "{is_streaming}",
          "is_audio_input_enabled": "{is_audio_input_enabled}",
          "last_is_online_change": "{last_is_online_change}",
          "is_video_history_enabled": "{is_video_history_enabled}",
          "web_url": "{web_url}",
          "app_url": "{app_url}",
          "is_public_share_enabled": "{is_public_share_enabled}",
          "activity_zones": "{activity_zones}",
          "public_share_url": "{public_share_url}",
          "snapshot_url": "{snapshot_url}",
          "last_event": "{last_event}"
        },
        "actions": [
          "_nestUpdate"
        ]
      }
    }
  },
  "auth": {
    "type": "oauth",
    "oAuthUrl": "https://home.nest.com/login/oauth2",
    "tokenUrl": "https://api.home.nest.com/oauth2/access_token",
    "clientId": "6b5adf3d-4434-443b-2h2f-756a9a7e58c6",
    "clientSecret": "27BC2Dg5Gp1aB83GFHVmACBCB"
  }
}

Possible Error Codes Returned

CodeDescriptionMeaning
404Not foundThe application was not found;
No supported connector was found.
400Bad requestNo name was provided;
No model was provided;
No auth was provided;
The model provided is invalid;
The auth provided is invalid.
409ConflictThe connector has already been enabled.

Read all Connectors

Returns a list of all connectors. The result may be paginated if there are more than 30 items.

GET /projects/:projectId/applications/:applicationId/connectors
Authorization: $OPERATOR_API_KEY
curl -H "Authorization: $OPERATOR_API_KEY" \
  -X GET 'https://api.evrythng.com/projects/U2meqbNWegsaQKRRaDUmpssr/applications/UF3Vqb7D6G8EhMwaRYgQ2pFc/connectors'
const projectId = 'U3fAq5MDBgswQpwawXgK2pSr';
const applicationId = 'UmH2xEfGMGsEEqRaREtn3eCq';

evrythng.api({
  url: `/projects/${projectId}/applications/${applicationId}/connectors`,
  apiKey: operatorApiKey,
}).then(console.log);
HTTP/1.1 200 Ok
Content-type: application/json

[
  {
    "name": "nest",
    "displayName": "Nest",
    "url": "https://www.nest.com",
    "image": "https://file.answcdn.com/answ-cld/image/upload/v1/tk/brand_image/c7d3fadd/c71c29fef0dd6c56a9b2777906bcf3245960c403.png",
    "authUrl": "https://api.evrythng.com/connectors/nest/auth",
    "model": {
      "structures": {
        "name": "Structure Name"
      },
      "devices": {
        "thermostats": {
          "name": "Thermostat Name"
        },
        "smoke_co_alarms": {
          "name": "Smoke Alarm Name"
        }
      }
    },
    "auth": {
      "type": "oauth",
      "oAuthUrl": "https://home.nest.com/login/oauth2",
      "tokenUrl": "https://api.home.nest.com/oauth2/access_token",
      "clientId": "6b5adf3d-4434-443b-2h2f-756a9a7e58c6",
    	"clientSecret": "27BC2Dg5Gp1aB83GFHVmACBCB"
    }
  }
]

Read a Connector

Returns the connector description when specified by ID.

GET /projects/:projectId/applications/:applicationId/connectors/:connectorName
Authorization: $OPERATOR_API_KEY
curl -H "Authorization: $OPERATOR_API_KEY" \
  -X GET 'https://api.evrythng.com/projects/U2meqbNWegsaQKRRaDUmpssr/applications/UF3Vqb7D6G8EhMwaRYgQ2pFc/connectors/nest'
const projectId = 'U3fAq5MDBgswQpwawXgK2pSr';
const applicationId = 'UmH2xEfGMGsEEqRaREtn3eCq';
const connectorName = 'nest';

evrythng.api({
  url: `/projects/${projectId}/applications/${applicationId}/connectors/$connectorName}`,
  apiKey: operatorApiKey,
}).then(console.log);
HTTP/1.1 200 Ok
Content-type: application/json

{
  "name": "nest",
  "displayName": "Nest",
  "url": "https://www.nest.com",
  "image": "https://file.answcdn.com/answ-cld/image/upload/v1/tk/brand_image/c7d3fadd/c71c29fef0dd6c56a9b2777906bcf3245960c403.png",
  "authUrl": "https://api.evrythng.com/connectors/nest/auth",
  "model": {
    "structures": {
      "name": "Structure Name"
    },
    "devices": {
      "thermostats": {
        "name": "Thermostat Name"
      },
      "smoke_co_alarms": {
        "name": "Smoke Alarm Name"
      }
    }
  },
  "auth": {
    "type": "oauth",
    "oAuthUrl": "https://home.nest.com/login/oauth2",
    "tokenUrl": "https://api.home.nest.com/oauth2/access_token",
    "clientId": "6b5adf3d-4434-443b-2h2f-756a9a7e58c6",
    "clientSecret": "27BC2Dg5Gp1aB83GFHVmACBCB"
  }
}

Possible Error Codes Returned

CodeDescriptionMeaning
404Not foundThe connector has not been enabled

Update a Connector

Update a connector with new data.

🚧

Note

Not all the fields of a connector can be updated. If the authentication parameters changed, this is considered to be a new connector and it must to be created separately as a new resource. Only the Operator can modify the connector information.

PUT /projects/:projectId/applications/:applicationId/connectors/:connectorName
Content-Type: application/json
Authorization: $OPERATOR_API_KEY

ConnectorDocument (subset)
curl i -H "Content-Type: application/json" \
  -H "Authorization: $OPERATOR_API_KEY" \
  -X PUT 'https://api.evrytng.com/projects/U2meqbNWegsaQKRRaDUmpssr/applications/UF3Vqb7D6G8EhMwaRYgQ2pFc/connectors/nest'
  -d '{
    "model": {
      "structures": {
        "name": "New Structure Name"
      }
    }
  }'
const projectId = 'U3fAq5MDBgswQpwawXgK2pSr';
const applicationId = 'UmH2xEfGMGsEEqRaREtn3eCq';
const connectorName = 'nest';

const payload = {
  model: {
    structures: { name: 'New Structure Name' },
  }
};

evrythng.api({
  url: `/projects/${projectId}/applications/${applicationId}/connectors/${connectorName}`,
  apiKey: operatorApiKey,
  method: 'put',
  data: payload,
}).then(console.log);
HTTP/1.1 200 Ok
Content-type: application/json

{
  "name": "nest",
  "displayName": "Nest",
  "url": "https://www.nest.com",
  "image": "https://file.answcdn.com/answ-cld/image/upload/v1/tk/brand_image/c7d3fadd/c71c29fef0dd6c56a9b2777906bcf3245960c403.png",
  "authUrl": "https://api.evrythng.com/connectors/pest/auth",
  "model": {
    "structures": {
      "name": "New Structure Name"
    }
  },
  "auth": {
    "type": "oauth",
    "oAuthUrl": "https://home.nest.com/login/oauth2",
    "tokenUrl": "https://api.home.nest.com/oauth2/access_token",
    "clientId": "6b5adf3d-4434-443b-2h2f-756a9a7e58c6",
    "clientSecret": "27BC2Dg5Gp1aB83GFHVmACBCB"
  }
}

Possible Error Codes

CodeDescriptionMeaning
400Bad requestOne or more fields provided in the payload cannot be updated;
The model provided is invalid.
404Not foundThe connector has not been enabled

Delete a Connector

Deletes a connector for an application.

🚧

Warning

Deleting a connector for an application will delete all the Thngs that were imported from the third party cloud.

DELETE /projects/:projectId/applications/:applicationId/connectors/:connectorName
Authorization: $OPERATOR_API_KEY
curl -H "Authorization: $OPERATOR_API_KEY" \
  -X DELETE 'https://api.evrythng.com/projects/U2meqbNWegsaQKRRaDUmpssr/applications/UF3Vqb7D6G8EhMwaRYgQ2pFc/connectors/nest'
const projectId = 'U3fAq5MDBgswQpwawXgK2pSr';
const applicationId = 'UmH2xEfGMGsEEqRaREtn3eCq';
const connectorName = 'nest';

evrythng.api({
  url: `/projects/${projectId}/applications/${applicationId}/connectors/${connectorName}`,
  apiKey: operatorApiKey,
  method: 'delete',
}).then(console.log);
HTTP/1.1 200 Ok

Possible Error Codes Returned

CodeDescriptionMeaning
404Not foundThe connector has not been created, or is not enabled

Read Connectors Available for User

Returns list of connectors that are enabled for a specific Application User whose API key authenticates the request.

GET /connectors
Authorization: $APPLICATION_USER_API_KEY
curl -H "Authorization: $APPLICATION_USER_API_KEY" \
  -X GET 'https://api.evrythng.com/connectors'
const projectId = 'U3fAq5MDBgswQpwawXgK2pSr';
const applicationId = 'UmH2xEfGMGsEEqRaREtn3eCq';

evrythng.api({
  url: '/connectors',
  apiKey: applicationUserApiKey,
}).then(console.log);
HTTP/1.1 200 Ok
Content-type: application/json

[
  {
    "name": "nest",
    "displayName": "Nest",
    "url": "https://www.nest.com",
    "image": "https://file.answcdn.com/answ-cld/image/upload/v1/tk/brand_image/c7d3fadd/c71c29fef0dd6c56a9b2777906bcf3245960c403.png",
    "authUrl": "https://api.evrythng.com/connectors/nest/auth",
    "status": "disconnected"
  }
]

Read a Connector as an Application User

Returns the connector description for the connector with name connectorName.

GET /connectors/:connectorName
Authorization: $APPLICATION_USER_API_KEY
curl -H "Authorization: $APPLICATION_USER_API_KEY" \
  -X GET 'https://api.evrythng.com/connectors/nest'
const projectId = 'U3fAq5MDBgswQpwawXgK2pSr';
const applicationId = 'UmH2xEfGMGsEEqRaREtn3eCq';
const connectorName = 'nest';

evrythng.api({
  url: `/connectors/${connectorName}`,
  apiKey: applicationUserApiKey,
}).then(console.log);
HTTP/1.1 200 Ok
Content-type: application/json

{
  "name": "nest",
  "displayName": "Nest",
  "url": "https://www.nest.com",
  "image": "https://file.answcdn.com/answ-cld/image/upload/v1/tk/brand_image/c7d3fadd/c71c29fef0dd6c56a9b2777906bcf3245960c403.png",
  "authUrl": "https://api.evrythng.com/connectors/nest/auth",
  "status": "disconnected"
}

Possible Error Codes Returned

CodeDescriptionMeaning
404Not foundThe connector is not available

Authenticate With the 3rd Party Service

This endpoint is provided as a generic access to the authentication process. A successful request is redirected to the 3rd party service authentication mechanism. The URL is provided as well in the connector resource as authUrl, and should be opened in a web browser to allow the user to sign into the 3rd party service and allow EVRYTHNG to access the relevant data.

https://api.evrythng.com/connectors/:connectorName/auth?access_token=$APPLICATION_USER_API_KEY

Possible Error Codes Returned

CodeDescriptionMeaning
404Not foundThe connector has not been enabled

Authenticate with an Existing Token

If an OAuth token for the 3rd party service has already been obtained, it can be used to shorten the authentication process.

POST /connectors/:connectorName/auth/token
Authorization: $APPLICATION_USER_API_KEY

{
  "access_token": "c.Kd7ahAwGn9wcZfRKEFqKlTpNU3ouQ...",
  "expires_in": 315360000
}
curl -H "Content-Type: application/json" \
  -H "Authorization: $APPLICATION_USER_API_KEY" \
  -X POST 'https://api.evrythng.com/connectors/nest/auth/token' \
  -d '{
    "access_token": "c.Kd7ahAwGn9wcZfRKEFqKlTpNU3ouQAwuujhJAGkVOBvlXCpOIyWacgi1zzsdjFeGbZivn6tVlSn856UpVMdTh8llKJLM8taMO4Hwr7YZB0Cm85uvOy0jQ7SOTnWJLEf5pFif51iGVJ8SKSBM",
    "expires_in": 315360000
  }'
HTTP/1.1 202 Accepted

Unlink User From a Connector

Application Users who want to revoke access to their third party cloud connector and remove all the information from EVRYTHNG can do so by invoking this endpoint.

🚧

Important

This will delete the connection between the clouds and remove any information and history from the users' Thngs that was imported from the third party cloud.

GET /connectors/:connectorName/auth
Authorization: $APPLICATION_USER_API_KEY
curl -H "Authorization: application/json" \
  -X GET 'https://api.evrythng.com/connectors/nest/auth'
HTTP/1.1 200 OK

Possible Error Codes Returned

CodeDescriptionMeaning
404Not foundThe connector has not been enabled;
Connector is not found for this user.