NAV Navbar
  • Introduction
  • Authentication
  • Errors
  • v2
  • v1
  • Webhook
  • Changelog
  • Introduction

    The Saleswhale API allows you to:

    Authentication

    Getting an API Key

    To access the API, you will need an API Key. The Key can be found in the Saleswhale App under Settings.

    settings

    Authentication Methods

    The API Key should be included in each request, either as a query parameter or as a property in the JSON body of the request.

    Query Parameter

    curl https://engage-api.saleswhale.com/api/{version}/{api_endpoint}/?token=<API_KEY>
    

    In the URL of each request, include a token query parameter, with your API key as the value.

    Request Body

    curl https://engage-api.saleswhale.com/api/{version}/{api_endpoint} -X POST -H "Content-Type: application/json" -d "{\"token\":\"<API_KEY>\"}"
    

    In the JSON body of each request, include the token property, with your API key as the value.

    Errors

    Example Response:

    {
      "errors": [
        {
          "id": "ffcf2b4c1076be36ba841535103503",
          "detail": "Lead 41552 does not exist.",
          "status": "unprocessable_entity"
        }
      ]
    }
    

    Our API returns standard HTTP success or error status codes. The various HTTP status codes we might return are listed below.

    Code Title Description
    200 OK The request was successful.
    201 Created The resource was successfully created.
    400 Bad Request Bad request e.g. missing properties.
    401 Unauthorized Your API key is invalid
    409 Time out Error Your session timed out.
    422 Unprocessable Entity Validation error e.g. duplicated record.
    429 Too Many Requests Rate limit is exceeded. Limit is 5 requests per second.
    500 Internal Server Error An error occured with our API.
    Returns

    For most errors, we will also return a JSON object with more details. If you have any issues resolving the error, please contact our Customer Success Team, including the error object in your communications.

    v2

    Leads

    Create a Lead

    Example Request:

    POST https://engage-api.saleswhale.com/api/v2/leads

    {
      "lead": {
        "first_name": "Myah",
        "last_name": "Harber",
        "email": "myah.harber@kihn.info",
        "job_title": "Internal Marketing Manager",
        "lead_owner": {
          "id": 4421,
          "type": "sales_rep"
        },
        "account_name": "Kihn Pte. Ltd.",
        "custom_attribute_values": [
          {
            "custom_attribute_id": 51662,
            "value": "Email Marketing"
          }
        ]
      }
    }
    

    Example Response:

    {
      "lead": {
        "id": 21248461,
        "first_name": "Myah",
        "last_name": "Harber",
        "email": "myah.harber@kihn.info",
        "job_title": "Internal Marketing Manager",
        "follow_up_at": "2018-08-29T06:20:58.909Z",
        "do_not_contact": false,
        "lead_owner": {
          "id": 4421,
          "type": "sales_rep"
        },
        "account_name": "Kihn Pte. Ltd.",
        "custom_attribute_values": [
          {
            "custom_attribute_id": 51662,
            "custom_attribute_name": "lead_source",
            "value": "Email Marketing"
          }
        ]
      }
    }
    

    To create a Lead, the request should contain the following JSON object:

    Property Type Description Required
    lead object The Lead object Yes


    The Lead object accepts the following properties:

    Property Type Description Required
    first_name string The first name of your lead. Yes
    last_name string The last name of your lead. No
    email string The email of your lead. Yes
    job_title string The job title or role of your lead. No
    lead_owner object The Lead Owner object. No
    account_name string The name of the account or company that your lead belongs to. No
    custom_attribute_values array An array of Custom Attribute Value objects to assign to the lead. No


    The Lead Owner object accepts the following properties:

    Property Type Description Required
    id number The ID of the Sales Rep, retrieved via the Sales Rep endpoint. Yes
    type string The type of Lead Owner object (e.g. "sales_rep") Yes


    The Custom Attribute Value object accepts the following properties:

    Property Type Description Required
    custom_attribute_id number The ID of the Custom Attribute, retrieved via the Custom Attribute endpoint. Yes
    value string The value to assign to the Custom Attribute. Yes
    Returns

    A Lead object.

    Delete a Lead

    Example Request:

    DELETE https://engage-api.saleswhale.com/api/v2/leads/{lead_id}

    {
      "force": false
    }
    

    By default, the API prevents you from deleting a Lead that has an ongoing Conversation. You can override this behaviour (delete the Lead and cancel his/her ongoing Conversation) by including the force property in the JSON body.

    Property Type Description Required
    force boolean Force delete a Lead, canceling his/her ongoing Conversation. No
    Returns

    A successful delete operation will return a 204 HTTP status with no object. Any errors will be returned as an object.

    Retrieve a Lead

    Example Request:

    GET https://engage-api.saleswhale.com/api/v2/leads/{lead_id}

    Example Response:

    {
      "lead": {
        "id": 21248461,
        "first_name": "Myah",
        "last_name": "Harber",
        "email": "myah.harber@kihn.info",
        "job_title": "Internal Marketing Manager",
        "follow_up_at": "2018-08-29T06:20:58.909Z",
        "do_not_contact": false,
        "lead_owner": {
          "id": 4421,
          "type": "sales_rep"
        },
        "account_name": "Kihn Pte. Ltd.",
        "custom_attribute_values": [
          {
            "custom_attribute_id": 51662,
            "custom_attribute_name": "lead_source",
            "value": "Email Marketing"
          }
        ]
      }
    }
    
    Returns

    A Lead object.

    Campaigns

    List all Campaigns

    Example Request:

    GET https://engage-api.saleswhale.com/api/v2/campaigns

    Example Response:

    {
      "campaigns": [
        {
          "id": 41223,
          "name": "Inbound Lead Engagement"
        }
      ]
    }
    

    Returns

    An array of Campaign objects.

    Sales Reps

    List all Sales Reps

    Example Request:

    GET https://engage-api.saleswhale.com/api/v2/sales_reps

    Example Response:

    {
      "sales_reps": [
        {
          "id": 91233,
          "type": "sales_rep",
          "email": "jermaine@example.co",
          "first_name": "Jermaine",
          "last_name": "Clement"
        }
      ]
    }
    

    Returns

    An array of Sales Rep objects.

    Custom Attributes

    List all Custom Attributes

    Example Request:

    GET https://engage-api.saleswhale.com/api/v2/custom_attributes

    Example Response:

    {
      "custom_attributes": [
        {
          "id": 98221,
          "name": "lead_source",
          "fallback_value": "",
          "attr_type": "lead"
        }
      ]
    }
    

    Returns

    An array of Custom Attribute objects.

    Enrolments

    Create an Enrolment

    Example Request:

    POST https://engage-api.saleswhale.com/api/v2/enrolments

    {
      "enrolment": {
        "lead_id": 155169,
        "campaign_id": 12375
      }
    }
    

    Example Response:

    // Successful Enrolment
    {
      "enrolment": {
        "id": 512562,
        "status": "processed",
        "campaign_id": 12375,
        "lead_id": 155169,
        "errors": null,
        "conversation_id": 13512266
      }
    }
    
    // Errors in Enrolment
    {
        "enrolment": {
            "id": 512563,
            "status": "error",
            "campaign_id": 12375,
            "lead_id": 155169,
            "errors": [
                "Lead already engaged",
                "Lead was in this campaign"
            ],
            "conversation_id": null
        }
    }
    

    To create an Enrolment to enrol a Lead into a Campaign, the request should contain the following JSON object:

    Property Type Description Required
    enrolment object The Enrolment object Yes


    The Enrolment object accepts the following properties:

    Property Type Description Required
    campaign_id string The ID of the Campaign to enrol the Lead to. Yes
    lead_id string The ID of the Lead to enrol into the Campaign. Yes

    Returns

    An Enrolment object.

    Conversations

    Show a Conversation

    Example Request:

    GET https://engage-api.saleswhale.com/api/v2/conversation/{conversation_id}

    Example Response:

    {
      "conversation": {
        "id": 12513522,
        "started_at": "2018-08-16T06:32:00.000Z",
        "handover_rep": {
          "id": 95233,
          "type": "sales_rep"
        },
        "leads": [
          {
            "id": 32244
          }
        ],
        "status": "qualified",
        "enrolment": {
          "id": 2214225,
          "status": "processed",
          "campaign_id": 2245,
          "lead_id": 32244,
          "errors": null,
          "conversation_id": 12513522
        }
      }
    }
    

    Returns

    A Conversation object.

    The possible statuses for a Conversation are listed below. Some are Terminal States, where the bot has stopped attempting engage the lead, and a new Conversation can be initiated with the lead.

    Status Is Terminal State? Description
    pending_lead_response No The Conversation is ongoing - our bot is awaiting a response from the lead.
    pending_bot_response No The Conversation is ongoing - the lead is awaiting a response from our bot.
    bounced Yes The Conversation could not be started because the Lead's email address is invalid.
    human_review Yes The Conversation has gone out of scope of the Topic Template and human involvement is required.
    not_interested Yes The Lead has explicitly stated he or she is not interested in furthering the conversation.
    qualified Yes The sales and marketing goal of the Topic Template was achieved.
    stop_responding Yes The Lead replied at least once, but thereafter stopped responding.
    unresponsive Yes The Lead did not reply to the Main Sequence.
    canceled Yes The Conversation was canceled.

    Cancel a Conversation

    Example Request:

    POST https://engage-api.saleswhale.com/api/v2/conversations/{conversation_id}/cancel

    Example Response:

    {
      "conversation": {
        "id": 446461,
        "started_at": "2018-08-16T03:40:00.000Z",
        "handover_rep": null,
        "leads": [
          {
            "id": 446461
          }
        ],
        "status": "canceled",
        "enrolment": {
          "id": 355253,
          "status": "processed",
          "campaign_id": 4145,
          "lead_id": 446461,
          "errors": null,
          "conversation_id": 446461
        }
      }
    }
    

    Returns

    A Conversation object.

    v1

    The Saleswhale Import API lets you add individual leads into the Saleswhale platform and initiate automated conversations on them. If you need help after reading this, please contact our Customer Success Team.

    Import leads

    Example Request:

    POST https://engage-api.saleswhale.com/api/v1/leads

    {
      "token": "example-api-key",
      "campaign_id": "i-am-a-campaign-id",
      "allow_existing_lead": false,
      "lead": {
        "first_name":"Ahab",
        "last_name":"Pequod",
        "email" : "whale.hunter@saleswhale.com",
        "job_title": "Captain",
        "account_name": "Saleswhale",
        "number": "+1 541 000 0011011",
        "custom_attribute_1": "custom_attribute_value"
      }
    }
    

    You can pass the following parameters along when importing a lead:

    Parameter Type Description Required
    token string Your API key. Yes
    campaign_id string The ID of the Campaign to enrol leads into. Yes
    allow_existing_lead boolean Whether to allow enrolment of an existing Lead into a campaign. Note that this will not update the Lead's properties. No
    lead object The Lead object. Yes

    The lead object accepts the following parameters:

    Parameter Type Description Required
    first_name string The first name of your lead. Yes
    email string The email of your lead. Yes
    last_name string The last name of your lead. No
    job_title string The job title or role of your lead. No
    account_name string The name of the account that your lead belongs to. No
    number string The phone number of your lead. No
    <custom_attribute> string Any custom attributes added when customising the bot assistant. Use the Import Column Header. No

    topic id

    Webhook

    Saleswhale can notify your application of events via a webhook.

    Setup

    First, setup the webhook Target URL in your Account Settings

    walk account settings

    Receiving a Webhook

    Checking Signature

    # Computing the signatures for comparison
    # Python 3
    expected_signature = hmac.new(
      "your_api_key".encode(),
      f"{timestamp}.{body}".encode(),
      digestmod=hashlib.sha256
    ).hexdigest()
    
    # Ruby
    expected_signature = OpenSSL::HMAC.hexdigest(
      OpenSSL::Digest.new('sha256'),
      your_api_key,
      "#{timestamp}.#{body}"
    )
    

    We recommend you verify that each webhook request is from Saleswhale. Each Webhook request we send includes signature and timestamp query parameters for this purpose e.g. we would POST the webhook to <your_webhook_url>?signature=<signature>&timestamp=<timestamp>.

    Steps to verify a Saleswhale signature:

    1. Compute a SHA256 HMAC hexdigest of your own using your Saleswhale API Key together with the timestamp parameter and the webhook request body. Be sure to add a period punctuation mark when concatenating the timestamp and body of the webhook request, and to use the raw body as is (e.g. via request.raw_post in Rails). Refer to the example code on the right.
    2. Compare your generated signature against the signature provided with our webhook POST request. The two signatures should be identical. It is recommended to use a "constant time" string comparison (such as secure_compare in Rails) to protect against timing attacks.
    3. If the signature is valid, check if the difference between the current timestamp and the timestamp parameter (when we send the webhook) is within your tolerance.

    Webhook Request Format

    {
      "event_name": "conversation.ended",
      "event_time": "2017-05-19T12:11:03.321+08:00",
      "event_payload": { ... }
    }
    

    Each webhook request includes a JSON object formatted as follows:

    Attribute Type Description
    event_name string Name of event that triggers the webhook request to your provided URL.
    event_time string Timestamp of when webhook is triggered.
    event_payload hash Data relating to the event.

    Acknowledging a Webhook

    You should acknowledge receipt of a webhook by returning a HTTP 200 status code. All other HTTP codes will be interpreted as a failed webhook delivery. We will attempt to re-deliver the webhook up to 4 more times, with an exponential backoff.

    Events

    conversation.ended

    {
      "event_name": "conversation.ended",
      "event_time": "2017-05-19T12:11:03.321+08:00",
      "event_payload": {
        "conversation": {
          "id": 12513522,
          "started_at": "2018-08-16T06:32:00.000Z",
          "handover_rep": {
            "id": 95233,
            "type": "sales_rep"
          },
          "leads": [
            {
              "id": 32244
            }
          ],
          "status": "qualified",
          "enrolment": {
            "id": 2214225,
            "status": "processed",
            "campaign_id": 2245,
            "lead_id": 32244,
            "errors": null,
            "conversation_id": 12513522
          }
        }
      }
    }
    

    This event is triggered when a Conversation reaches a Terminal State (indicated by conversation["status"]). Possible Terminal States are detailed in Show a Conversation. The event_payload will include a Conversation object.

    Changelog

    2018-09-13

    2018-08-29

    2018-08-01