0

I am trying to add a subscriber to my mailing list from my Swift 5 iOS app. I am seeing the following error when trying to do this:

{
    detail = "Your request did not include an API key.";
    instance = "3f4cb654-c674-4a97-adb8-b4eb6d86053a";
    status = 401;
    title = "API Key Missing";
    type = "http://developer.mailchimp.com/documentation/mailchimp/guides/error-glossary/";
}

Of course this indicates that I am missing my API Key, however I am specifying it in the Authorization header (see below code). I have tried a mix of the answer here and the guide here but I'm not having much luck so far. Here's my current code for setting up the request:

let mailchimpAPIURL = "https://us3.api.mailchimp.com/3.0"
let requestURL = NSURL(string: mailchimpAPIURL)!

let apiCredentials = "anystring:<API_KEY>"
let loginData = apiCredentials.data(using: String.Encoding.utf8)!.base64EncodedString()

let params = [
    "list_id": "<LIST_ID>",
    "email_address": email,
    "status": "subscribed",
    "merge_vars": [
         "FNAME": firstName,
         "LNAME": lastName
    ]
] as [String: Any]

let request = NSMutableURLRequest(url: requestURL as URL)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.setValue("Basic \(loginData)", forHTTPHeaderField: "Authorization")
do {
    request.httpBody = try JSONSerialization.data(withJSONObject: params, options: [])
} catch {
    return
}
podomunro
  • 495
  • 4
  • 16

2 Answers2

1

You need to send api key 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] {

    }
}
Samir Shaikh
  • 547
  • 3
  • 9
  • What if I can’t use Alamofire? – podomunro Aug 06 '19 at 06:02
  • Your header also look fine try changing setValue to addValue. or try with alamofire it's may be encoding issue because you are getting 401 you are sending API key but not read properly on server side. – Samir Shaikh Aug 06 '19 at 06:22
0

Okay, I got it. @Sam's answer helped me realise that the URL I was using was wrong, and I needed to add the ListID into that URL. I also changed setValue to addValue, and changed NSMutableURLRequest to URLRequest. I also added request.httpMethod = "POST" Here is my updated, working code:

let subscribeUserURL = "https://us3.api.mailchimp.com/3.0/lists/<LISTID>/members/"
let requestURL = NSURL(string: subscribeUserURL)!

let apiCredentials = "anystring:<APIKEY>"
let loginData = apiCredentials.data(using: String.Encoding.utf8)!.base64EncodedString()

let params = [
    "email_address": email,
    "status": "subscribed",
    "merge_fields": [
        "FNAME": firstName,
        "LNAME": lastName
    ]
] as [String: Any]

var request = URLRequest(url: requestURL as URL)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.addValue("Basic \(loginData)", forHTTPHeaderField: "Authorization")
request.httpMethod = "POST"
do {
    request.httpBody = try JSONSerialization.data(withJSONObject: params, options: [])
} catch {
    return
}
podomunro
  • 495
  • 4
  • 16