> ## Documentation Index
> Fetch the complete documentation index at: https://docs.appsignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# HTTPoison

export const VersionRequirements = ({versions = []}) => {
  if (!Array.isArray(versions) || versions.length === 0) {
    return null;
  }
  const boundaries = {
    upper: " or lower",
    exact: "",
    lower: " or higher"
  };
  const containerStyle = {
    marginTop: "0.5rem",
    marginBottom: "1.5rem"
  };
  const lineStyle = {
    display: "block",
    margin: "0 0 0.35rem 0",
    fontSize: "0.875rem",
    lineHeight: "1.4"
  };
  const pillBaseStyle = {
    display: "inline-block",
    padding: "0.1em 0.4em",
    borderRadius: "0.25rem",
    border: "1px solid",
    fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
    fontSize: "0.85em",
    fontWeight: 500
  };
  const pillColors = {
    "AppSignal for Elixir": {
      background: "#f3e8ff",
      borderColor: "#e9d5ff",
      color: "#9333ea"
    },
    "AppSignal for Front-end": {
      background: "#fef9c3",
      borderColor: "#fde68a",
      color: "#ca8a04"
    },
    "AppSignal for Go": {
      background: "#ccfbf1",
      borderColor: "#99f6e4",
      color: "#0d9488"
    },
    "AppSignal for JavaScript": {
      background: "#fef9c3",
      borderColor: "#fde68a",
      color: "#ca8a04"
    },
    "AppSignal for Node.js": {
      background: "#dcfce7",
      borderColor: "#bbf7d0",
      color: "#16a34a"
    },
    "AppSignal for Python": {
      background: "#dbeafe",
      borderColor: "#bfdbfe",
      color: "#2563eb"
    },
    "AppSignal for Ruby": {
      background: "#fee2e2",
      borderColor: "#fecaca",
      color: "#dc2626"
    },
    "AppSignal for Rust": {
      background: "#ffedd5",
      borderColor: "#fed7aa",
      color: "#ea580c"
    }
  };
  const defaultPillColor = {
    background: "#f4f4f5",
    borderColor: "#e4e4e7",
    color: "#52525b"
  };
  const getPillStyle = name => ({
    ...pillBaseStyle,
    ...pillColors[name] || defaultPillColor
  });
  const getBoundText = bound => {
    return boundaries[bound] || boundaries.lower;
  };
  return <div style={containerStyle}>
      {versions.map((v, i) => <p key={`${v.name}-${v.version}-${v.bound || "lower"}-${i}`} style={lineStyle}>
          This feature requires{" "}
          <code style={getPillStyle(v.name)}>{v.name}</code> version {v.version}
          {getBoundText(v.bound)}.
        </p>)}
    </div>;
};

<VersionRequirements
  versions={[
{ name: "AppSignal for Elixir", version: "2.17.0" },
{ name: "HTTPoison", version: "2.0.0" }
]}
/>

The AppSignal for Elixir package instruments HTTP requests performed by [HTTPoison](https://github.com/edgurgel/httpoison).

HTTPoison is a popular HTTP client for Elixir. Unlike Finch and Tesla, HTTPoison does not emit telemetry events, so AppSignal cannot automatically instrument it. Instead, AppSignal provides wrapper modules that you opt into: `Appsignal.HTTPoison` as a drop-in client, and `Appsignal.HTTPoison.Base` for custom client modules. The response and error structs (`%HTTPoison.Response{}`, `%HTTPoison.Error{}`, ...) are HTTPoison's own types and are returned unchanged.

AppSignal will wrap requests executed via `Appsignal.HTTPoison` as `request.httpoison` events on your performance samples' event timeline, allowing you to see how much time HTTPoison spends making external API requests. This data may help inform you to move the API requests to a background job, or to introduce caching to help speed up performance and limit unnecessary API requests.

## Configuration

HTTPoison instrumentation is opt-in. Choose the approach that best fits your application.

### Using Appsignal.HTTPoison directly

Call `Appsignal.HTTPoison` instead of `HTTPoison` to make instrumented requests. Pattern-match on `%HTTPoison.Response{...}` and `%HTTPoison.Error{...}` as normal — these are HTTPoison's own struct types, returned unchanged:

<Warning>
  Do not use `alias Appsignal.HTTPoison`. This would shadow the `HTTPoison`
  module name, causing `%HTTPoison.Response{}` and `%HTTPoison.Error{}` pattern
  matches to fail.
</Warning>

<CodeGroup>
  ```elixir Elixir theme={null}
  defmodule MyAppWeb.PageController do
    use MyAppWeb, :controller

    def index(conn, _params) do
      case Appsignal.HTTPoison.get("https://api.example.com/users") do
        {:ok, %HTTPoison.Response{status_code: 200, body: body}} ->
          render(conn, :index, users: body)

        {:ok, %HTTPoison.Response{status_code: status}} ->
          conn |> put_status(status) |> text("Error")

        {:error, %HTTPoison.Error{reason: reason}} ->
          conn |> put_status(500) |> text("Error: #{reason}")
      end
    end
  end
  ```
</CodeGroup>

### Custom client modules

If you use a custom HTTP client module based on `HTTPoison.Base`, replace `use HTTPoison.Base` with `use Appsignal.HTTPoison.Base`. No further changes are needed — inside the module, you can call methods like `get/1` and `post/3`, and match on HTTPoison's response and error structs as normal:

<CodeGroup>
  ```elixir Elixir theme={null}
  defmodule MyApp.ApiClient do
    # replace `use HTTPoison.Base` with `use Appsignal.HTTPoison.Base`
    use Appsignal.HTTPoison.Base

    def process_url(url) do
      "https://api.example.com" <> url
    end

    def users do
      case get("/users") do
        {:ok, %HTTPoison.Response{status_code: 200, body: body}} -> {:ok, body}
        {:ok, %HTTPoison.Response{status_code: status}} -> {:error, status}
        {:error, %HTTPoison.Error{reason: reason}} -> {:error, reason}
      end
    end
  end
  ```
</CodeGroup>

All requests made through your custom client will then be instrumented automatically. If your module overrides `request/5`, make sure to call `super` to preserve the instrumentation:

<CodeGroup>
  ```elixir Elixir theme={null}
  defmodule MyApp.ApiClient do
    use Appsignal.HTTPoison.Base

    def request(method, url, body, headers, options) do
      # ... custom logic here ...
      super(method, url, body, headers, options)
    end
  end
  ```
</CodeGroup>
