             iex> ExampleApi.#{unquote(method)}("/users", %{name: "Jon"}, query: [scope: "admin"])
         """
         @spec unquote(method)(Tesla.Env.client, Tesla.Env.url, Tesla.Env.body) :: Tesla.Env.t
-      else
-        @doc false
-      end
-      def unquote(method)(client, url, body) when is_function(client) do
+      end
+      dynamic_def unquote(private), unquote(method)(client, url, body) when is_function(client) do
         request(client, method: unquote(method), url: url, body: body)
       end
-      if unquote(docs) do
+      unless unquote(private) do
         @spec unquote(method)(Tesla.Env.url, Tesla.Env.body, [option]) :: Tesla.Env.t
-      else
-        @doc false
-      end
-      def unquote(method)(url, body, options) do
+      end
+      dynamic_def unquote(private), unquote(method)(url, body, options) do
         request([method: unquote(method), url: url, body: body] ++ options)
       end
 
-      if unquote(docs) do
+      unless unquote(private) do
         @doc """
         Perform a #{unquote(method |> to_string |> String.upcase)} request.
         See `request/1` or `request/2` for options definition.

            iex> ExampleApi.#{unquote(method)}("/users", %{name: "Jon"})
        """
        @spec unquote(method)(Tesla.Env.url, Tesla.Env.body) :: Tesla.Env.t
      else
        @doc false
      end
      def unquote(method)(url, body) do
        request(method: unquote(method), url: url, body: body)
      end
    end
  end

  defp generate_api(method, docs) when method in [:head, :get, :delete, :trace, :options] do
    quote do
      if unquote(docs) do
        @doc """
        Perform a #{unquote(method |> to_string |> String.upcase)} request.
        See `request/1` or `request/2` for options definition.

            __client__: nil
end

defmodule Tesla.DynamicDef do
  defmacro dynamic_def(true, definition, do: body) do
    quote do
      defp unquote(definition) do
        unquote(body)
      end
    end
  end

  defmacro dynamic_def(_, definition, do: body) do
    quote do
      def unquote(definition) do
        unquote(body)
      end
    end
  end
end

defmodule Tesla.Builder do
  @http_verbs ~w(head get delete trace options post put patch)a

  defmacro __using__(opts \\ []) do
    opts = Macro.prewalk(opts, &Macro.expand(&1, __CALLER__))
    private = Keyword.get(opts, :private)

    quote do
      import Tesla.DynamicDef

      Module.register_attribute(__MODULE__, :__middleware__, accumulate: true)
      Module.register_attribute(__MODULE__, :__adapter__, [])

      unless unquote(private) do
        @type option :: {:method,   Tesla.Env.method}  |
                        {:url,      Tesla.Env.url}     |
                        {:query,    Tesla.Env.query}   |
