I thought I'd share some of my experiences with the CM API. I would have loved to have a couple of pointers like this when I started integrating our service with it, so hopefully someone finds this useful. Note that this is just my personal experience with the system. I would love to get feedback on how other people chose to integrate.
Before you start, it's important to note that CampaignMonitor sees the API as an extension but not a replacement to their web interface. Certain functions, such as importing large lists of contacts are only available through the web ui - and this doesn't seem likely to change since adding large lists programmatically means less control and no "contract" to verify that the email lists are legitimate opt-in lists. Creating lists is only possible through the Web UI at this time, so create your lists in the UI ahead of time and look up the list ID's for reference.
At my company, we use CM to synchronize a local database of subscribers with CampaignMonitor. We then communicate with those users throughout their application lifecycle. Our list has been growing and for various reasons we ran into blacklisting problems. Even though our list is 100% opt-in, certain emails bounced back and raised some red flags with email providers. Sending emails through our own system, even if it's just 400 a day just wasn't an option anymore.
Users enroll through a site and move through different stages - Pending, Completed, and Cancelled. We created three lists to represent each status so that we are able to communicate with users at each stage of the enrollment process. I suppose another option would be to use custom fields but I haven't spent enough time with this feature and found that it was generally lacking documentation.
After a user signs up on our site, we call the Subscriber.Add function and pass their name, email, and list name in. Done. Easy.
Once a user changes status, i.e. moves from Pending to Complete, our communication with the user changes. We used to just query our database with certain criteria and then send out email. With CM I found it easiest to create a separate list and first unsubscribe the user from the list, then use Subscriber.AddAndResubscribe to add them to the new list.
Since all unsubscribes and bouncebacks are handled by CampaignMonitor, we set up a nightly schedule that retrieves those emails and marks them accordingly in our database. I found the API responses to be somewhat confusing. Although the UI won't show anyone in the suppression lists, the API will return any user who was ever unsubscribed in a given list. Not a big deal, but a little confusing.
Creating and Sending Campaigns
The biggest issue with campaigns is the fact that CM does not really allow you to test this functionality 100% unless you have a list of 6 subscribers and agree to pay $5 for every time you test sending a campaign. Contact their support and they say they will credit you for every test campaign. This is an inconvenience, but I understand why they do it. Without this restriction, developers could batch-send emails 6 at a time and stay under the radar. I found that you can schedule your campaign to be delivered at a future date using a list of 6 or more for testing. You won't get billed for a campaign until it gets sent out. So even though you can't test the final delivery, you can test-send the campaign through the UI to verify your custom fields are working etc.
Creating a Campaign
There seem to be two ways to go about creating and sending campaigns. In our case we have three different types of campaigns that go out every day. Option 1 is to create a new campaign every time we are about to communicate with a list. Option 2 is to create a "Pending" campaign once and resend that campaign after it's been set up. CM will treat the resend as a new campaign and it will show up with its own report. Very handy. Option 1 would require running Campaign.Create, wait for the ID to come back, and then call Campaign.Send. The draw back to this is that the HTML template and text content is defined during the Campaign.Create call which means our client can't really change the template. Option 2 allows the client to edit and save the campaign without changing the campaign id. This way, they can define a new email template or define additional lists which puts control in their hands. Option 2 is what we decided on. The tricky thing is - there is no way to create a campaign in the UI and then also find its' ID - which means you have to programmatically create the campaign, store the id and hard-code that in your app.
It's also important to note that when you create a campaign, you pass in the URL of an HTML and TEXT template. CM then ingests these files and they can no longer be changed. This means that you cannot customize the outgoing email on your end on a recipient basis. The email you specify is the email everyone on your campaign will see. Again, you can use custom fields to create some customization. It seems that CM does not currently provide conditional text blocks which would really make things flexible. Maybe in the future.
Notes on the API
The CampaignMonitor guys have done a great job at keeping the API simple and easy to understand. I ran into a couple of issues that were quickly resolved through trial and error. For example, the documentation for Campaign.Create doesn't specifically state that the reply-to field is required. When omitted, I got a cryptic error message which indicated that an object on the CM servers couldn't be instantiated. Digging a little further revealed that I should have received an error message telling me that the reply-to field was indeed required. It's also stated in the documentation in the error description, but you really have to look for it.
The other issue which we're currently trying to work out with CM staff is that every campaign that gets created and sent is scheduled for sending 14 hours in advance. Not a huge issue for us right now, but certainly not expected behavior.
We use SOAP and ColdFusion and created a CFC that is resuable across most of our projects. If anyone is interested, I'd be happy to share it.
Nice description. Here is one additional thing we have done. We send out "past due" information via email. So we only want to send the email out to those people on the list that are past due. We could have created a new list for each send. Instead we "Unsubscribe" everyone on the list and then just "readd" the ones we want. This has a tendency to time out, but we have been successful up to about 200 email addresses
Hi snowman18, I'm not sure exactly what you're saying, but it sounds like you could benefit from using segments.
And productorials, cool post! It should be very useful to people about to do things similar to what you've done.
I'd be really interested in taking a look at the CFC you've put together, if you wouldn't mind forwarding it on?
Thanks for the great post Productorials!
I am also trying to make use of the API, and will definitely keep all these things in mind. Nice to have a community of devs looking out for potential pitfalls or stumbling blocks.
Have another tip - If you want to customize your unsubscribe page based on custom fields (not supported), just pass through the [email]field.
You can then do a lookup (via API) on that subscriber for that list based on the email, then pull out the custom field you need.
I am using this to show different unsubscribe pages based on user's language.
Is there any way you could share the CFC you have created. I am new to CM and already see that I would need to use API and so far have no luck using it with ColdFusion.
Thank you very much!
Hi Masha, apologies for resurrecting this thread, but a ColdFusion library has just been released for the Campaign Monitor API. Thanks to developer Jon Joyce for so keenly developing and documenting the components available for download.