Pass Parameters

The HTTP protocol allows to carry additional data either by using the request URI, or by using the HTTP body, for which there are a few already widely used standards. HTTPX aims at solving the majority.


Using the :params option will encode the parameters in the URI query in the x-www-form-urlencoded format:

HTTPX.get("", params: { "q" => "john" })


Using the :body option will pass the raw data to the request body. You can pass:

  • raw strings;
  • an IO object (i.e. a File, or a StringIO object);
  • an object which implements #each and yields strings (such as ["a", "b", "c"]);

The content type will be set to application/octet-stream, unless stated explicitly otherwise.

# body as a string"", body: "thiswillbethebody")

# body as IO object"", body:"large-file.txt"))"", body:"largetext"))

# As an object implementing each"", body: %w[this will be the body])
# or
fib = do |y|
  a = b = 1
  loop do
    y << a.to_s
    a, b = b, a + b
    break if a > (2 ** 32)
end"", body: fib)

# Note: The `content-length` header won't be sent in this case, and chunks will be immediately sent to the server when yielded.


Using the :json option will encode the parameters in the application/json format:

# POSTed as '{"foo":"bar"}'"", json: { "foo" => "bar" })


Using the :form option will encode the parameters in the request body encoded in the x-www-form-urlencoded format:

# POSTed as "foo=bar""", form: { "foo" => "bar" })


If the :form param contains files or pathnames (or parameters with a given specification explained below), the request will be encoded as multipart/form-data:

path = "path/to/image.jpg"
# with pathnames
response ="", form: { image: })

# or with files
response ="", form: { image: })

# ...
# Content-Type: multipart/form-data; boundary=---------------------a324a748aade297ac4ffc87108bee9ecd8cb2c2fea ...
# "-----------------------2a6965a264bbf67e519ad96cbc970800cac79dd240
# ...
# Content-Disposition: form-data; name="image"; filename="image.jpg"
# Content-Type: image/jpeg
# \xFF\xD8\xFF\xE0\x00\x10JFIF\x00\x01\x01\x00\x00\x01\x00\x01\x00\x00\xFF\xDB\x00\x84\x00\x02\x02\x02

Content Types

In multipart payloads, the content type of String values will be set as “text/plain”.

For files, the type will be inferred using one of the following strategies:

  • using the filemagic gem (if available);
  • using the marcel gem (if available);
  • using the mime-magic gem (if available);
  • shelling out to the file cli tool (if installed in the system);
  • application/octet-stream as fallback;"", form: { image: })

caveat: the integrations above are oriented towards media files which typically contain information about its first bytes, such as photos and videos, but may not work as well with text-based mime-types (such as “text/csv”).

You can override passing the file (or string) inside an hash with the following options:"", form: {
  image: {
    content_type: "image/png",
    filename: "image.jpg",
  metadata: {
    content_type: "application/json",
    body: JSON.dump({ location: "Japan", frame_number: 2 })

you can also pass your own object responding to those fields as methods, and implementing #read(?Integer bytesize, ?String buffer):

class AwesomeVideo
  def content_type

  def filename

  def read(*)
   # .....
   # .....

  # optionally, you can implement
  # def close ; end
  # and
  # def rewind ; end
end"", form: {


If using “HTTP/1.1”, you can set the header, and httpx will encode it using the chunked transfer encoding immediately:

HTTPX.with(headers: { "transfer-encoding" => "chunked" })
     .post("", body: %w[this will be the body])

Expect: 100-continue

If you want to give the server the opportunity to validate the HTTP request headers before the body is sent, you can just add the expect header, and the client will seamlessly respect it:"", headers: { "expect" => "100-continue" }, body:"body.txt"))

However, if you aren’t sure if the server you’re requesting from does not handle it, you are strongly recommended to use the expect plugin instead, which gracefully degrades to sending the body anyway after a timeout if the server doesn’t.

Next: Pass Headers