# Elixir - HTML to Image Example

Generate PNG, JPG, WebP, and PDF output with Elixir, using HTML/CSS or reusable templates rendered in Google Chrome.

## Generating images with Elixir

1.  Send your HTML/CSS to the API.
2.  The API renders it in Google Chrome.
3.  Read the generated image URL from the JSON response.

See [Creating an image](/getting-started/using-the-api/#creating-an-image) for request parameters. A response includes the image's `url` and `id`.

![Example image generated from HTML with Elixir](/assets/images/dog-rates-example.png)

## Authentication with Elixir

Use HTTP Basic authentication with your API ID as the username and API key as the password. Find both in the [dashboard](https://htmlcsstoimage.com/dashboard). Keep credentials in server-side configuration or environment variables.

## Elixir example code

The example sends a POST request to `https://hcti.io/v1/image`. Image creation requires `images:create`. See [authentication and API keys](/getting-started/using-the-api/api-keys/) for scoped credentials and access errors.

This example sends JSON using [`Jason`](https://hexdocs.pm/jason/) for encoding and Erlang/OTP’s built-in `:httpc` client for the HTTP request.

Add `Jason` to your `mix.exs` dependencies:

```elixir
defp deps do
  [
    {:jason, "~> 1.4"}
  ]
end
```

```elixir
:inets.start()
:ssl.start()


user_id = "your-user-id"
api_key = "your-api-key"


payload = %{
  html: "<div class='box'>Elixir ✅</div>",
  css: ".box { border: 4px solid #03B875; padding: 20px; font-family: Roboto, sans-serif; }",
  google_fonts: "Roboto"
}


body = Jason.encode!(payload)


auth = Base.encode64("#{user_id}:#{api_key}")


headers = [
  {'authorization', String.to_charlist("Basic #{auth}")},
  {'accept', 'application/json'}
]


request = {
  'https://hcti.io/v1/image',
  headers,
  'application/json',
  String.to_charlist(body)
}


case :httpc.request(:post, request, [], []) do
  {:ok, {{_, status, _}, _headers, response_body}} when status in 200..299 ->
    IO.puts(response_body)


  {:ok, {{_, status, _}, _headers, response_body}} ->
    raise "Request failed with status #{status}: #{to_string(response_body)}"


  {:error, reason} ->
    raise "Request failed: #{inspect(reason)}"
end


# {"url":"https://hcti.io/v1/image/1113184e-419f-49f1-b231-2069942a186f"}
```

## Phoenix example with Req

For Phoenix applications, [`Req`](https://hexdocs.pm/req/) is a popular HTTP client that keeps the request code compact and uses `Jason` for JSON encoding.

Add `Req` and `Jason` to your `mix.exs` dependencies:

```elixir
defp deps do
  [
    {:jason, "~> 1.4"},
    {:req, "~> 0.5"}
  ]
end
```

Store your credentials in config or environment variables, then call the API from a context or service module.

```elixir
defmodule MyApp.Images.HtmlCssToImage do
  @endpoint "https://hcti.io/v1/image"


  def create_image do
    user_id = System.fetch_env!("HCTI_USER_ID")
    api_key = System.fetch_env!("HCTI_API_KEY")


    payload = %{
      html: "<div class='box'>Phoenix ✅</div>",
      css: ".box { border: 4px solid #03B875; padding: 20px; font-family: Roboto, sans-serif; }",
      google_fonts: "Roboto"
    }


    case Req.post(@endpoint, auth: {:basic, "#{user_id}:#{api_key}"}, json: payload) do
      {:ok, %{status: status, body: %{"url" => url}}} when status in 200..299 ->
        {:ok, url}


      {:ok, %{status: status, body: body}} ->
        {:error, {status, body}}


      {:error, reason} ->
        {:error, reason}
    end
  end
end
```

## Need help?

Talk to a human. Email [support@htmlcsstoimage.com](mailto:support@htmlcsstoimage.com) and we’ll help you get started.
