Documentation

  • Getting started

    Getting started

    Things You Should Know

    Critsend is a SMTP relay. The service is simple to implement.
    We go further than our competitors by giving you a clear vision on your deliverability rate.
    We track your sendings and provide you with solutions to eventual deliverability issues.
    We go from large campaigns to newsletters, and transactional emails.
    We refuse spams, and they are monitored by our tools. We tolerate up to 10Mo per email.
    Our servers are made to keep persistent connexion.
    We give you the possibility to add any header starting by X-***.
    We process encoding along with your campaigns.

  • Tags

    Tags

    Things You Should Know

    You can add “Tags” to your emails, this will allow you to segment your sending, as for exemple separate an confirmation email from a registering email, or even men from women recipient…
    If you would like to use several tags, you just need to separate them with a comma.
    You have 2 possibilities:
        1. Add contents to your email (please note subject and tag content can’t go up to 245 character): Add a [tag:xxxxxxx] to your subject, example: welcome [tag: register, men]
        2. Add a header to your email, as a X-Tag: Add a new header to your email: X-Tag: register, men
    Our system will then detect your tags and will compile them for you, you will find them in our services: webhooks, log and analytics.

  • SMTP Setup

    SMTP (Simple Mail Transfer Protocol) Setup

    Things You Should Know

    CritSend is a SMTP relay. To send emails, you only need to point to our globally secure SMTP servers.
    server: smtp.critsend.com
    ports: 25, 2525, 587
    SSL port: 465
    We support ESMTP so with TLS encryption. You can connect to the port 25 and use ESMTP in TLS instead of encrypting all the connection in SSL.
    That’s it. We told you it was simple!
    If you want to send emails you can have a look at our code samples (https://github.com/critsend/smtp-relay-snippets)

    ASP.net

    Sending API

    Simply start by downloading our .Net Connector: .Net Connector.
    You’ll find a compiled version of this code here: .Net compiled Connector

    SMTP Relay

    Here is a code sample showing how you can use ASP.NET to send emails through our SMTP Relay. You can also fork it on github.
    MailMessage message = new MailMessage();
    message.From = new MailAddress("[email protected]");
    message.To.Add(new MailAddress("[email protected]"));
    message.To.Add(new MailAddress("[email protected]"));
    message.To.Add(new MailAddress("[email protected]"));
    message.Subject = "Subject goes here";
    message.Body = "The message goes here";
    SmtpClient client = new SmtpClient();
    client.Send(message);


    System.Net.Mail reads SMTP configuration data out of the “web.config” file. Here is a way to configure it:

    <system.net>
    <mailSettings>
    <smtp from="[email protected]">
    <network host="smtp.critsend.com" port="587" userName="YourCritSendUsername"
    password="YourCritSendPassword" defaultCredentials="false" />
    </smtp>
    </mailSettings>
    </system.net>

  •     JAVA

    SMTP Setup

    Java

    Sending API
    Simply start by downloading our Java Connector: Java Connector.
    In case you need it, here’s the .Net Compiled Connector.
    Here is a code sample showing how you can make it work. You can also fork it on github.

    /*
    * This class is just here for demo purposes.
    */
    package net.mxm.connector.test;

    import java.util.logging.Level;
    import java.util.logging.Logger;
    import net.mxm.connector.ArrayEmail;
    import net.mxm.connector.CampaignParameters;
    import net.mxm.connector.Content;
    import net.mxm.connector.Email;
    import net.mxm.connector.MxmConnect;
    import net.mxm.connector.MxmConnectConfigurationException;
    import net.mxm.connector.MxmConnectException;

    /**
    * @author nico toper
    * @date 2010-10-20
    */
    public class MxmTest extends Thread {
        public MxmConnect mxm = null;
        public int res[] = new int[20];
        public MxmTest() throws MxmConnectException {
        //mxm = new MxmConnect();
        for (int i = 0; i < res.length; i++) {
            res[i] = 0;
        }
    }

    @Override
    public void run() {
        for (int i = 0; i < 2000; i++) {
            try {
                try {
                    long fStart = System.currentTimeMillis();
                    this.sendEmail();
                    //System.out.println("Time for this mail: " + ( System.currentTimeMillis() - fStart) );
                    } catch (MxmConnectException ex) {
                        Logger.getLogger(MxmTest.class.getName()).log(Level.SEVERE, null, ex);
                    }
                } catch (MxmConnectConfigurationException ex) {
                    Logger.getLogger(MxmTest.class.getName()).log(Level.SEVERE, null, ex);
                }
        }
    }

    void testOthers() throws MxmConnectException, MxmConnectConfigurationException {
        MxmConnect mxm2 = new MxmConnect("", "");
        //  mxm2.createTag("test");
        // mxm2.createTag("test2");
        String[] t = mxm2.listAllTags();
        for (int i = 0; i < t.length; i++) {
            System.out.println(t[i]);
        }
        // System.out.println(mxm2.deleteTag("test2"));
    }

    private String makeRandom() {
        Double r = new Double(Math.random() * 1000000);
        return r.toString(r);
    }

    protected void sendEmail() throws MxmConnectConfigurationException, MxmConnectException {
        MxmConnect mxm2 = new MxmConnect("", "");
        //MxmConnect mxm2 = mxm ;
        // mxm2.setFastDelivery(true);
        CampaignParameters cp = new CampaignParameters();
        cp.setMailFrom("[email protected]");
        cp.setMailFromFriendly("FriendlyName");
        cp.setReplyTo(this.makeRandom());
        cp.setReplyToFiltered(false);
        String tags[] = { "test" };
        cp.setTags(tags);
        Content c = new Content();
        //c.setSubject(this.makeRandom());
        //c.setText(this.makeRandom());
        c.setSubject("Your Subject");
        c.setText("test");
        StringBuffer sb = new StringBuffer();
        String r = this.makeRandom();
        for (int i = 0; i < 2000; i++) {
            sb.append(r);
        }

        c.setHtml(sb.toString());
        Email e = new Email();
        e.setEmail("[email protected]");
        ArrayEmail ae = new ArrayEmail();
        ae.addEmail(e);
        String host = mxm2.getHost();
        System.out.println(host);
        System.out.println(mxm2.sendCampaign(c, cp, ae));
        //System.gc();
    }

    //This is the entry point for test.
    public static void main(String[] args) throws MxmConnectException, MxmConnectConfigurationException {
        //HeapMonitor h = new HeapMonitor();
        //h.start();
        for (int i = 0; i < 1; i++) {
            MxmTest mxm = new MxmTest();
            for (int j = 0; j < 100000; j++) {
                mxm.sendEmail();
                System.out.println("ok");
                for (int x = 0; x < mxm.res.length; x++) {
                    System.out.println(x + ": " + mxm.res[x]);
                }
            }
        }
    }

    Here’s another example, that teach you how to use our SMTP services:

    import java.io.*;
    import java.net.InetAddress;
    import java.util.Properties;
    import java.util.Date;
    import javax.mail.*;
    import javax.mail.internet.*;
    import com.sun.mail.smtp.*;

    public class Distribution {
        public static void main(String args[]) throws Exception {
            Properties props = System.getProperties();
            props.put("mail.smtps.host","smtp.critsend.com");
            props.put("mail.smtps.auth","true");
            Session session = Session.getInstance(props, null);
            Message msg = new MimeMessage(session);
            msg.setFrom(new InternetAddress("[email protected]"));
            msg.setRecipients(Message.RecipientType.TO,InternetAddress.parse("[email protected]", false));
            msg.setSubject("Your subject here "+System.currentTimeMillis());
            msg.setText("Your content here");
            msg.setHeader("X-Mailer", "Header");
            msg.setSentDate(new Date());
            SMTPTransport t = (SMTPTransport)session.getTransport("smtps");
            t.connect("smtp.critsend.com", "YourCritSendUsername", "YourCritSendPassword");
            t.sendMessage(msg, msg.getAllRecipients());
            System.out.println("Response: " + t.getLastServerResponse());
            t.close();
        }
    }
  •     PHP

    SMTP Setup

    PHP

    Sending API
    Simply start by downloading our PHP Connector: PHP Connector.
    Here is a code sample showing how you can make it work. You can also fork it on github.

    $content = array('subject'=> 'My subject', 'html'=> 'my html' , 'text' =>'my test');
    $param = array('tag'=>array('invoice1'), 'mailfrom'=> '[email protected]', 'mailfrom_friendly'=> 'Nicolas Toper', 'replyto'=>'[email protected]', 'replyto_filtered'=> 'true');
    $emails[0] = array('email'=>'[email protected]', 'field1'=> 'test');

    try {
        echo $j;
        print_r($mxm->sendCampaign($content, $param, $emails));
    } catch (MxmException $e) {
        echo $e->getMessage();
    }
  •     Python

    SMTP Setup

    Python

    Sending API
    You can simply download our Python Connector: Python Connector.
    SMTP Relay
    Here is a code sample showing how you can use Python to send email through our SMTP Relay. You can also fork it on github.

    import smtplib

    #your critsend's credentials
    critsend_user = 'YOUR CRITSEND USERNAME'
    critsend_password = 'YOUR CRITSEND PASSWORD'

    sender = "YOUR NAME "
    recipients = ['RECIPIENT EMAIL']
    subject = "My subject"content = """My email message"""

    message = ("From: %s\r\nTo: %s\r\nSubject: %s\r\n%s" % (sender, ", ".join(recipients), subject, content))

    try:
        server = smtplib.SMTP("smtp.critsend.com", 587)
        server.ehlo()
        server.starttls()
        server.ehlo
        server.login(critsend_user, critsend_password)
        server.sendmail(sender, recipients, message)
        print "Successfully sent email"
    except SMTPException:
        print "Error: unable to send email"
  •     Ruby

    SMTP Setup

    Ruby

    Sending API
    You can simply download our Ruby Gem here: http://rubygems.org/gems/MxmConnect
  •     SMTP Relay

    SMTP Setup

    SMTP Relay

    Here is a code sample showing how you can use Ruby to send emails through our SMTP Relay.

    #Put in a file like config/initializers/critsend.rb

    ActionMailer::Base.smtp_settings = {
        :address => "smtp.critsend.com",
        :port => 587,
        :authentication => :plain,
        :user_name => "YOUR_CRITSEND_USERNAME",
        :password => "YOUR_CRITSEND_PASSWORD",
        :enable_starttls_auto => false
    }

    ActionMailer::Base.delivery_method = :smtp
  • DNS Setup

    DNS Setup

    DKIM Setup

    Setting up your DKIM is strongly recommended to improve your deliverability. You can read more about it. This operation is a simple two-step process that will take no time at all.
    Let’s say you are using 'example.com' as a domain.

    1) Start by adding a CNAME record with the following Name and Value.
    Address, Name or Host: critsend2._domainkey.example.com
    Value: dkim.critsend.com.
    Please note that sometimes your domain name might be automatically added to this field. In such cases you will have to take off 'example.com' in the address field.
    If your DNS client doesn’t support CNAME’s with underscores, you will need to add a TXT record instead:
    Address, Name or Host: critsend2._domainkey.example.com
    Value: k=rsa\; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCvEpIr9ILg7iXsdMlMst5sCK+MDc4GQDaZDmgLLHHVNn952Jh4zmB1Qp+fBSUzVfcU/qW4hicOMJKRe0bo8nIB/Gvh3CtJuyAFizXCUjDtn2V4t5rg2OEpVkEXHkwUoW43Z5753Q62flW2wb3zuEqoO5fWLUt4rcIqatE+O8zmSwIDAQAB

    2) In your Critsend account, go to 'Account -> Mail Settings' and find the 'Signed-by Domain' line.

    The corresponding value will be used by email providers to check for an appropriate DKIM record. For instance, if you’ve used 'example.com' in step 1, then you would need to enter 'example.com' in this field.
    Warning: Hotmail’s DKIM verifying procedure needs the 'From' address domain to be the same as the DKIM signing domain. So, if your signing domain is 'example.com', your 'From' address should be something like '[email protected]'.
    That’s it. If you haven’t set up your SPF yet, we recommend that you do it immediately.

    3) Test your settings

    Once you’ve set up your DKIM, you can test it here. Use 'critsend2' as Selector and your own domain name as Domain Name (Wait 4 hours for DNS propagation though.)

  •     DKIM Setup

    DNS Setup

    DKIM Setup

    Setting up your DKIM is strongly recommended to improve your deliverability. You can read more about it. This operation is a simple two-step process that will take no time at all.
    Let’s say you are using 'example.com' as a domain.

    1) Start by adding a CNAME record with the following Name and Value.
    Address, Name or Host: critsend2._domainkey.example.com
    Value: DKIM.critsend.com
    Please note that sometimes your domain name might be automatically added to this field. In such cases you will have to take off 'example.com' in the address field.
    If your DNS client doesn’t support CNAME’s with underscores, you will need to add a TXT record instead:
    Address, Name or Host: critsend2._domainkey.example.com
    Value: k=rsa\; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCvEpIr9ILg7iXsdMlMst5sCK+MDc4GQDaZDmgLLHHVNn952Jh4zmB1Qp+fBSUzVfcU/qW4hicOMJKRe0bo8nIB/Gvh3CtJuyAFizXCUjDtn2V4t5rg2OEpVkEXHkwUoW43Z5753Q62flW2wb3zuEqoO5fWLUt4rcIqatE+O8zmSwIDAQAB

    2) In your Critsend account, go to 'Account -> Mail Settings' and find the 'Signed-by Domain' line.

    The corresponding value will be used by email providers to check for an appropriate DKIM record. For instance, if you’ve used 'example.com' in step 1, then you would need to enter 'example.com' in this field.
    Warning: Hotmail’s DKIM verifying procedure needs the 'From' address domain to be the same as the DKIM signing domain. So, if your signing domain is 'example.com', your 'From' address should be something like '[email protected]'.
    That’s it. If you haven’t set up your SPF yet, we recommend that you do it immediately.

    3) Test your settings

    Once you’ve set up your DKIM, you can test it here. Use 'critsend2' as Selector and your own domain name as Domain Name (Wait 4 hours for DNS propagation though.)

  •     SPF Setup

    DNS Setup

    SPF Setup

    Setting up your SPF is strongly recommended to improve your deliverability. This operation is a simple two step process that will take no time at all.
    Let’s say you are using 'example.com' as a domain.

    1) Add the following TXT record to your domain: Address, Name or Host: example.com
    TXT value: v=spf1 mx include:messaging-master.com ~all
    If you already have SPF records set up for your domain, just add: 'include:messaging-master.com' to your existing entry.

    2) In your Critsend account, go to 'Account -> Mail Settings' and find the 'On Behalf of Addresses' line.
    Enter a default email address from the domain you’ve just updated in step 1, for instance '[email protected]'. Important: You may have several domains in this field but you can only add ONE 'On Behalf of' address per domain. Separate each address from different domains with a comma.
    Please also note that this is not the same as your Mail-From: or From: address and that it does not affect your Mail-From: or From: address in any way. It will only be used by email providers to check for an appropriate SPF TXT record.

    3) Test your settings
    Once you’ve set up your SPF, you can test your domain here. When clicking 'Get SPF record', you should see 'messaging-master.com' in the results. (Wait 4 hours for DNS propagation.)

  • Sending Emails

    Sending Emails

    With Python:

    import smtplib
    server = smtplib.SMTP('smtp.critsend.com')
    server.login(‘MYLOGIN’, MyPass) server.sendmail(‘[email protected]’, ‘[email protected]’, ‘Hello there’)
  •     Sending at scale to us

    Sending Emails

    Sending at scale to us

    CritSend is able to receive more than 3 million emails per hour. We can increase or decrease this capacity as quickly as necessary as our system is fully distributed and spread out all around the globe. We are able to send your emails within two minutes provided your reputation with ISP is good enough.
    If you want to send at scale and fast, here are some tips:
    SMTP is very verbose and slow. This is because the protocol requires a lot of round trips between the client and the server. To speed up things, the obvious and working solution is to use multithreading and multiprocessing.
    Ideally try to hit a different server each time (by resolving again and again 'smtp.critsend.com'; be careful- some frameworks will cache it and will resolve to the same servers).
    Reuse connections where possible to avoid a round trip for authentication.
    Sometimes preparing emails to send (eg; generating content, encoding) can take a meaningful time. It helps to prepare them well in advance before sending.
    Feel free to contact us on [email protected] if you need any help.

  • Statistics And Big Data

    Statistics And Big Data

    We collect statistics about your deliveries which you can access at any time:
    Analytics https://account.critsend.com/analytics/delivery presents you an aggregated view of your statistics. This allows you to pinpoint and fix any issues.
    Logs https://account.critsend.com/logs/index are a detailed view of your deliveries. If you pass us a X-uid or some tags, we will put them here. We keep data for 15 days.
    Webhooks API is the same as logs except we push all these data into a push HTTP Request. https://account.critsend.com/delivery/event_api
    This is the complete list of events we track with their definition.
    We track any events by:
    Recipient of your email
    ISP: Domain of your recipient. For instance, our corporate domain mxmtech resolves to gmail.
    Time of delivery: We timestamp each incoming email.
    Hostname: The name of the machine that delivered your email.
    X-UID: This is any string of characters (< 755 characters) that you passed in your emails as a X-Uid header.
    Tags: Passed in X-Tags (or in [Tags:…] in the subjet. It’s a comma separated lists.
    Additional String: This is where we put additional information such as the SMTP error code and message.
    Events we keep track of:
    Open: We record all atomic opens, only when a user displays the images. Usually we record less open than our competition, due to our systems being configured to record the open once the whole query is completed.
    Spam Report: Happens when a subscriber marks your email as spam, in which case we add it to our suppression database. We are notified when that happens with Outlook, Yahoo (if you have asked us to authenticate your DKIM), AOL and all FBL operated by Return Path.
    Bouncing: When an email bounces, we will try resending it for up to 12 hours. All the error codes are logged during that event with the answer of the SMTP server. The SMTP error code is of 4XX which usually indicates temporary errors.
    Permanent Failure: Happens when we know that the SMTP code is of the form 5XX. We don’t flag at this step, addresses as invalid addresses.
    Sent: We have sent the email to the SMTP server.
    Filtered: The email is in our suppression database (todo put link) and we filtered it out. The email was not sent.
    Blocked: The SMTP server rejected the email. Usually this happens because the IP is blacklisted or because the content is seen as spam. When you see this event, you can contact us on [email protected] for some additional explanations.#Email landed in spambox.
    Received: This event means we received a request to send from you.
    Error: We were unable to deliver your email. Because we love transparency, you will see the Python stacktrace. If you see these, please contact us as it’s very uncommon.
    Click: A subscriber clicked on your link. The additional string will contain the link clicked.
    DT_ATOMIC_OPEN = 24 => First open event
    #Isp accepted with response code
    DT_ISP_ACCEPTED = 29 => ISP acceptation confirmation (With information)
    #Isp deferred code
    DT_ISP_DEFERRED = 30 => Email deferred by ISP
    #Temp new arrival replace code 12 using on production
    DT_ARRIVED = 31 => Critsend input confirmation

  • Suppression Database

    Suppression Database

    When a user reports your email as spam, unsubscribes, or the email bounces too many times, we will add it to our suppression list. This way, you don’t have to do anything. The next email deliveries will be seen as filtered in your analytics.
    Here is a description of the specific cases where we will add an address to that list:
    User marks your email as spam: We are notified by the ISPs.
    We mark it as such in our suppression DB.
    These users are automatically filtered.
    User unsubscribes: when the user unsubscribes from your deliveries, he is automatically added to that database.
    Email is blacklisted: We can blacklist an email for you following a complaint we have received, or an email you have added.
    Email bounces: When an email bounces we add it to a shared pool of bounced addresses. These addresses will stay for 6 months and they are then randomly removed. We wait for consistent bounces for three weeks and no successful deliveries. This part is above the state of the art. We ran some studies and found out that it offers a better deliverability for our customers.
    By default, tagging is enabled on a per account basis. If you use tagging, you can activate an option that will filter these emails on a per tag basis instead of a per account basis.
    You can check the status of a given address here https://account.critsend.com/delivery/filters, and you can remove/add addresses.

  • Deliverability

    Deliverability

    Deliverability is the action of making sure your emails end up in an inbox. We monitor your deliveries on the fly duplicating some of the contents to some of our test addresses (this is called seed address; the exact algorithm is part of our secret sauce). When we detect a specific stream is landing in spambox, we usually contact you (sometimes we don’t if we think things will go back to normal by themselves; if in doubt, get in touch; we love interacting with our customers).
    Usually, a spam landing has three sources:
    IP reputation: This still happens even though it’s becoming less and less important in recent times. When a specific IP sends spam, some SMTP servers will block the spam source at the IP level. Blocklists are the same. Usually we are notified of such an issue, but you can get in touch with us on [email protected]. We have tools by our side to detect blocks and act on them. If you’re on a dedicated cluster, let us know if you want access.
    Content: For some reasons, your email will trigger a spam filter. For instance, if you’re a legitimate pharmacy sending a receipt order for Viagra from Nigeria you’ll have a very hard time landing in inbox.
    Spam Report: When too many users (> 0.1%) mark your email as spam, then your deliveries will land in spam. Usually spam filters use some element of your delivery and add it to their block list.

  •     Event API

    Event API

    Overview
    The Event API allows users to setup web services to receive event notifications about their emails and their recipients from CritSend.
    You can enable the Event API by specifying a target URL in the ‘Event API’ section under the ‘Mail Settings’ tab. In the same section, you will be able to choose which categories you wish to enable (see the categories below).
    A HTTP POST will be issued to the URL you’ve specified at a fixed interval (e.g. 5 minutes) with all the events we received in the meantime. The POST request payload describes the collection of events using the Webhooks model, and consists of a UTF8-encoded JSON array of JSON objects (events) in the following format:
    [{
    "category": "hard_bounce",
    "date": "2011-09-02T14:39:53",
    "recipient": "[email protected]",
    "mx": "example.com",
    "tags": ["default", "tag1"],
    "uid": "CC27F483098347ECB693EC7A1CAF45E9"
    },
    {
    "category": "blocked",
    "date": "2011-09-02T14:55:53",
    "recipient": "[email protected]",
    "mx": "example.com",
    "tags": ["default", "tag2"],
    "uid": "A5DA637119D041BABAE316D3E908FF0A"
    },
    ... ]


    While we will make a best effort to promptly deliver all Webhooks events, messages may not arrive in order of commit. If we fail to reach the specified URL, we will retry several times over a 7-days period. This allows your services to be down for short maintenance windows and still receive all messages. Web services should respond to the POST request with a 2XX response code to indicate successful delivery. Redirects (3XX response codes) are not followed, and no further delivery attempts will be made. Server errors (5xx response codes) are treated as failures and will be retried. All other response codes will be ignored.

    Event API format
    The payload’s event JSON object contains the following items:
    The list of event categories is:

    • open: When the recipient opens an email. Counted only for HTML emails and image-view-enabled recipients.
    • click: When the recipient clicks a link in your email.
    • unsubscribed: When the recipient unsubscribed from your email traffic.
    • bounce: When we receive a bounce (either soft or hard) for an email. Future emails to that address *will be* delivered.
    • hard_bounce: Deprecated in favour of ‘bounce’.
    • soft_bounce: Deprecated in favour of ‘bounce’.
    • blocked: When we receive a notification from a recipient’s servers that an email of yours has been blocked for spam or content reasons. Future emails to that address *will be* delivered.
    • spam_report: When a user has reported an email of yours as Spam to an ISP within our Feedback Loop. Future emails to that address will *not* be delivered.
    • filtered: When we filter an email of yours and it is not sent out (due to various reasons, for example; we have received too many permanent failures for the address or it has been unsubscribed or it has sent a spam report etc).
    • error: When there is an email’s structure or other internal error.
    • new_failed_address: When we filter an email address after receiving too many permanent failures for it. Future emails to that address will *not* be delivered.
    • filtered_address: Deprecated in favour of ‘new_failed_address’
    • blacklisted_address: When a user blacklists an address from here. Future emails to that address will *not* be delivered.
    • unblacklisted_address: When a user removes an address from their blacklist. Future emails to that address *will be* delivered.
    • freed_address: When we remove an email address during our periodic failed addresses’ assessment and cleanup procedure (failed addresses are those we have received too many permanent failures for). Future emails to that address *will be* delivered.
    Note 1: The event’s JSON representation fields should not be considered as fixed. Later on, new JSON fields may be added.
    Note 2: All deprecated events will stop being sent by 1st March 2013. Until then, we will send both the old (deprecated) and the new events.
    Errors: If there are errors decoding your tags or other you have returned you will recieve the following error in the form of JSON:
    [{
    "error": "Invalid Character",
    },
    ... ]


    Authentication
    You will find your unique Webhooks ‘secret key’, in the ‘Event API’ section under the ‘Mail Settings’ tab. This key is used to seed the HMAC-SHA256 algorithm. Each POST request contains header called X-Critsend-Webhooks-Signature used to authenticate the payload. This header’s value is a 64-character hexadecimal string. To verify the Webhook request is originating from CritSend you encode the payload with the HMAC-SHA256 algorithm (using your Webhooks ‘secret key’ as a key and SHA256 digest mode) and compare the resulting hexdigest to the X-Critsend-Webhooks-Signature header’s value (signature).

    Authentication in Python
    import hmac, hashlib
    def is_authenticated(your_webhooks_key, your_request_json_payload, x_critsend_webhooks_signature):
        my_signature = hmac.new(key=your_webhooks_key, msg=your_request_json_payload, digestmod=hashlib.sha256).hexdigest()
        return x_critsend_webhooks_signature == my_signature


    Authentication in PHP:
    function is_authenticated($your_webhooks_key, $your_request_json_payload, $x_critsend_webhooks_signature) {
        $my_signature = hash_hmac("sha256", $your_request_json_payload, $your_webhooks_key);
        return $x_critsend_webhooks_signature == $my_signature;
    }


    Example in PHP:
    $our_webhooks_key = "xxxxxxxxxxxxxxx";
    $critsend_signature = $_SERVER["HTTP_X_CRITSEND_WEBHOOKS_SIGNATURE"];
    $json_payload = file_get_contents('php://input');
    # Check if payload is valid
    if($critsend_signature != hash_hmac("sha256", $json_payload, $our_webhooks_key)) {
        throw exception("Invalid payload according to our webhooks key");
    }
    $events = json_decode($json_payload);
    foreach($events as $event) {
        switch($event["category"]) {
            case "open":
                event_open($event);
                break;
            case "click":
                event_click($event);
                break;
            case "unsubscribed":             event_unsubscribe($event);
                break;
            case "hard_bounce":
                event_hard_bounce($event);
                break;
            case "soft_bounce":
                event_soft_bounce($event);
                break;
            case "blocked":
                event_blocked($event);
                break;
            case "spam_report":
                event_spam_report($event);
                break;
            case "filtered":
                event_filtered($event);
                break;
            case "error":
                event_error($event);
                break;
            default:
                throw exception("Invalid category");
            }
    }