Chamaileon offers a REST API for email HTML exchange. As an alternative, you can develop an integration connector for Chamaileon if your ESP, CRM or custom tool is not listed on Chamaileon’s official integration list.

, Chamaileon Integration API

3rd party partners are able to list, sync, update emails between their own tool and Chamaileon. This is a 2-way synchronization and allows you to sync the email’s workflow status back to Chamaileon platform. It’s useful when an email is sent or scheduled, and edits shouldn’t be made.

The following documentation includes every detail 3rd party developers might need to create a custom integration to Chamaileon.

Availability of your integration to Chamaileon users
Bear in mind, that Chamaileon’s support team can enable a 3rd party integration for all OR specific Chamaileon users. Enabling for all users is a good way to promote your solution that has email sending capabilities. If you wish to do so, please drop an email to hello@chamaileon.io about you and your plans.

We recommend to check out how existing integrations work for Chamaileon users with a test Chamaileon account before you start developing a new integration.

Integration API documentation

Email fields and data that can be synchronized with this API:

  • emailHTML: the generated email HTML output of Chamaileon,
  • emailText: plain text version of the generated HTML email,
  • previewText: the email’s preview text, useful when you sync campaigns,
  • subject: the subject line for the planned campaign/email,

To perform the synchronization, we require several data from the integration side:

  • pre: auxiliary information about where and how to sync the email in your system (account or folder id, username, etc), that are requested prior to the synchronization
  • id: id of the email in your system after sychronization is created. This id serves for identification during the update of the email. Useful to keep things tidy,
  • status: the status of the email in your system such as “sent” or “synced”,
  • webUrl: an URL where Chamaileon users can be redirected to check or open the email/campaign/template in your system.

Every request for our side contains all user-specific credentials:

https://chamaileon.io/integrations/: API keys, tokens, and/or other connection requirements

Security and authorization

Data is encrypted with HTTPS, both endpoints must use that. Moreover, a Jason Web Token (JWT) with the signed body has to be sent in the authedPayload field.

On GET requests, authedPayload has to be inserted to the query params.
For other methods add the authedPayload to the body.

Example:

const body = { … }
body.authedPayload = jwt.sign(body, apiSecret)
post(url, method, body);

Responses
All responses are JSON objects with standard fields.

If the query was unsuccessful the error contains an error object, otherwise, error has to be null. The result of the query is encapsulated in the result object.

The content of the error object can be useful for debugging or informing users.
Please use the following error pattern when you want to show a meaningful error notification to Chamaileon users on the interface:

result: null,
error: {
    notification: “String displaying on the front-end, it is propagated until another notification overwrites it”,
    message: “String, a message used for debugging or logging”,
    code: “SHORT_ERROR_CODE”,
    originalError: Object
}

originalError might be an empty Object ({}), or might contain another level of the same pattern.

Client-side endpoints

The following endpoints must be implemented on the integration’s connector (your) side.
Integration setup post-hook call
This is a one-time test call when a Chamaileon user sets a new connection up. Regardless of the response, the integration will be saved in Chamaileon’s database.
If the response contains an error notification, it will be shown for the user.

POST: <>/v1/integration/create

Body:

{
    connectionData: Object, described below (link),
    authedPayload: Object, described above (link)
}

Example:

{
    connectionData: {
        user: “username”,
        apiKey: “sssdfmdspovksdlvm”,
},
    authedPayload: “dslfkmsdlfkmf”
}

ConnectionData is an object with all necessary connection credentials that are needed for communication. If you choose to create a predefined integration, the keys of the connectionData are saved to offer for the client when creating the integration.

The response does not influence the save process of the integration in the Chamaileon database, however, if the error contains a notification field, it is shown for the user.

Pre-hook

Listing preconditions and requirements of adding a new email/campaign/template.

How it works: When a client wants to synchronize an email with a given integration (clicks Sync), some information might be needed from the integration side, eg. the folder where to save the mail, the name, or the subject, etc. On the integration connector side, these data might be required or might be overridden as well.

After the below-described data is pre-fetched a form displayed on the front-end based on the hook answer to fill the missing information by the user. Once the user fills out the form, the e-mail can be synced (next route).

Note that connectionData and authedPayload (carry only the connectionData) has to be sent as a query param. These objects are sent as a stringified and URL-encoded JSON format.

GET: <>/v1/email/pre

The response is directly used to display the user-filled form and results are sent back during sync.

Response:

{
error,
result: [fieldSet]
}

a fieldSet is

{
id: an identifier of the field,
name: a human-readable name of the field,
type: the type of the field (text, select or logical),
required: a boolean value that tells whether it is required to answer,
values: if the type is select, this is an array of choices.
}

an element of the values can be:

{
  value: the value to send,
  name: a human-readable text of the value,
  default: boolean, true for the default value
}

Example response:

{
  "success": true,
  "result": [
    {
      "id": "folder",
      "name": "Folder",
      "type": "select",
      "values": [
        {
          "value": "0bdb03ef0000000000000000000000006a2b",
          "name": "Messages",
          "default": true
        },
        {
          "value": "0bdb03ef0000000000000000000000006a2d",
          "name": "Drafts",
          "default": false
        },
        {
          "value": "0bdb03ef0000000000000000000000006a47",
          "name": "newFolder",
          "default": false
        }
      ],
      "required": true
    },
    {
      "id": "messageName",
      "name": "Message name (default: the subject)",
      "type": "text",
      "required": false
    }
  ]
}

Sync an email

Action: Once the user filled out the form with preconditions, then clicked the Sync button, email, text-version and all other details are generated and sent to the sync route.

POST: <>/v1/email/sync

Body:

{
    "authedPayload": String, the signed payload,
    "emailHTML": String, the email in html,
    "emailText": String, the email as text,
    "previewText": String, the email preview text,
    "subject": String, The subject of the e-mail,
    "connectionData": Object, connection keys and credentials,
      "pre": Object, the filled preconditions
}

Example:

{
    "authedPayload": "sdasld.asdmasld.sadfksdfdf",
    "emailHTML": "<html>The content as a html</html>",
    "emailText": "The content as a text",
    "subject": "The subject of the e-mail",
    "connectionData": {
        "apiToken": "72kg358mcjsn"
    },
     "pre": [{
         "id": "folder",
         "value": "0bdb03ef0000000000000000000000006a2c"
     }, {
         "id": "messageName",
         "value": "Name to be saved in the ESP"
     }]
}

The “pre” object contains the response from the previous, pre, request.

Response:

{
    error: error object, if any, otherwise null,
    result: {
    id: the id of the email on the integration side
    status: String, optional, the status of the email (synced or sent),
        webUrl: String, optional, a URL where the email can be opened.
}
}

Update sync

When an email/campaign/template has been already synchronized, it’s content can be updated. It can be done using the following method:

PUT: <>/v1/email/sync/:id

Where “:id” = a key to identify the email/campaign/template on the integrator side returned from the created endpoint.

Body:

{
    "authedPayload": String, the signed payload,
    "emailHTML": String, the email in html,
    "emailText": String, the email as text,
    "previewText": String, the email preview text,
    "subject": String, The subject of the e-mail,
    "connectionData": Object, connection keys and credentials
}

The structure is the same as for the sync without pre fields.

Workflow connector webhooks

To report back to CHamaileon about the email//campaigntemplate status, a webhook can be configured on the integrator side.

Email status update webhook

Fired when the status of the email is changed from “synced” to “sent” or back.

Target:

POST https://folders.chamaileon.io/sync/webhook/v1/

For development purposes use

POST https://folders-staging.chamaileon.io/sync/webhook/v1/

Body:

{
    syncId: The id of the email on the integration side,
    status: String, the new status of the e-mail
    authedPayload: The signed payload
}