Cbas Cbas - 2 years ago 180
Ruby Question

Ruby POST with custom headers and body?

I'm trying to POST to Mailchimp in Ruby but I can't get any code working which has custom headers and a body. This is the request I am trying to replicate:

curl --request GET \
--url 'https://<dc>' \
--user 'anystring:<your_apikey>'

but I also have to add a JSON body.

If I run this code:

postData = Net::HTTP.post_form(URI.parse(''), { ... }})
puts postData.body

I get a response from Mailchimp that the apikey is missing. How do I add the API key?

Based on these posts:
Ruby request to https - "in `read_nonblock': Connection reset by peer (Errno::ECONNRESET)"

Ruby send JSON request

I tried this:

uri = URI('')
req =, initheader = {'Content-Type' =>'application/json'})
req.basic_auth 'anystring', 'xxxx'
req.body = URI.encode_www_form({ ... }})
response =, uri.port, :use_ssl => uri.scheme == 'https').start {|http| http.request(req) }
puts "Response #{response.code} #{response.message}:#{response.body}"

but I get the error
TypeError (no implicit of Hash into String)
on the
response = ...
line. What is the error referring to and how do I fix it?


instead of

response = Net::HTTP.start(uri.hostname, uri.port, :use_ssl => uri.scheme == 'https') {|http| http.request(req) }

I am able to send the request, but I get a 400 response: "We encountered an unspecified JSON parsing error"

I get the same response with the posted answer. here is my JSON:

{'email_address' => '', 'status' => 'subscribed', 'merge_fields' => {'FNAME' => 'xxx', 'LNAME' => 'xxx' }

I also tried adding the data like this:

req.set_form_data('email_address' => '', 'status' => 'subscribed', 'merge_fields' => {'FNAME' => 'xxx', 'LNAME' => 'xxx' } )

but I get the same JSON parse error

Answer Source

Try this, if it works for you

uri = URI('')

Net::HTTP.start(, uri.port, :use_ssl => uri.scheme == 'https') do |http|
  req =
  req['Content-Type'] = 'application/json'
  req.basic_auth 'username', 'password'
  req.set_form_data('from' => '2005-01-01', 'to' => '2005-03-31')

  response = http.request req # Net::HTTPResponse object

You need to set form data in post request like

req.set_form_data('from' => '2005-01-01', 'to' => '2005-03-31')


Try posting raw data like

json_data = {'from' => '2005-01-01', 'to' => '2005-03-31'}.to_json
req.body = json_data
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download