Abbey Jackson Abbey Jackson - 2 months ago 15
Swift Question

Receiving MailChimp error "Your request did not include an API key." even though the API key is included using Alamofire

I am using Alamofire to send a request to MailChimp to add a user to a list

MailChimp's docs say:


There are 2 authentication methods for the API: HTTP Basic authentication and OAuth2. The easiest way to authenticate is using HTTP Basic authentication. Enter any string as your username and supply your API Key as the password.


The request I wrote for Alamofire:

let params: [String : AnyObject] = ["email_address": email, "status": "subscribed", "merge_fields": [ "FNAME": name]]

guard let url = "https://us10.api.mailchimp.com/3.0/lists/<listID>/members/".stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding) else { return }

Alamofire.request(.POST, url, parameters: params, encoding: .URL)
.authenticate(user: "apiKey", password: "<apikey>")
.responseJSON { response in

if response.result.isFailure {

}
else if let responseJSON = response.result.value as? [String: AnyObject] {

}
}


I checked that the API key is correct by using it to access their playground:
https://us1.api.mailchimp.com/playground/

The response I get back states that the API key was not included:


Your request did not include an API key.


Where have I gone wrong?

Answer

So MailChimp actually needs the api key sent in the authorization header like this:

        let params: [String: AnyObject] = ["email_address": email, "status": "subscribed"]

    guard let url = "https://us10.api.mailchimp.com/3.0/lists/<listID>/members/".stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding) else { return }

    let credentialData = "user:<apikey>".dataUsingEncoding(NSUTF8StringEncoding)!
    let base64Credentials = credentialData.base64EncodedStringWithOptions([])

    let headers = ["Authorization": "Basic \(base64Credentials)"]

    Alamofire.request(.POST, url, headers: headers, parameters: params, encoding: .URL)
        .responseJSON { response in

        if response.result.isFailure {

        }
        else if let responseJSON = response.result.value as? [String: AnyObject] {

        }
    }