Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time


Build Status Coverage Status license Deps Status

BlueBird is an api documentation builder for the Phoenix framework. The documentation is generated in the API Blueprint format from annotations in your controllers and from automated tests.


  1. Add BlueBird to your mix.exs dependencies:
defp deps do
  [{:blue_bird, "~> 0.4.0"}]
  1. Run mix deps.get to fetch the dependencies:
$ mix deps.get
  1. In test/test_helper.exs, start the BlueBird logger with BlueBird.start() and configure ExUnit as follows:
ExUnit.start(formatters: [ExUnit.CLIFormatter, BlueBird.Formatter])
  1. Add the following lines to config.exs:
config :blue_bird,
  docs_path: "priv/static/docs",
  theme: "triple",
  router: AppWeb.Router
  1. Add blue_bird_info to your mix.exs to add global information:
def blue_bird_info do
    host: "",
    title: "ACME API",
    description: """
                 API requires authorization. All requests must have valid
  1. Add BlueBird.Controller to your web.ex controller function:
def controller do
  quote do
    use BlueBird.Controller
  1. Install aglio:
$ npm install aglio -g



By default, documentation is only generated for routes that use the :api pipeline. You can configure which pipelines to use in the configuration.

config :blue_bird,
  pipelines: [:something_else]


Use the api/3 macro to annotate your controller functions.

defmodule AppWeb.CommentController do
  use AppWeb, :controller

  api :GET, "/posts/:post_id/comments" do
    title "List comments"
    description "Optional description"
    note "Optional note"
    warning "Optional warning"
    parameter :post_id, :integer, [description: "Post ID or slug"]
  def index(conn, %{"post_id" => post_id}) do

BlueBird groups routes by controller. By default, it uses the controller names as group names in the headings. You can change the group name of a controller by adding the apigroup macro to your controller modules. The macro can also be used to add a group description.

defmodule AppWeb.CommentController do
  use AppWeb, :controller

  apigroup "Blog Comments", "some description"


In your tests, select which requests and responses you want to include in the documentation by saving conn to BlueBird.ConnLogger:

test "list comments for post", %{conn: conn} do

  conn = conn
  |> get(comments_path(conn, :index))
  |> "Without params")

  assert json_response(conn, 200)

Generating the documentation

First, run your tests:

$ mix test

All conns that were saved to the ConnLogger will be processed. The documentation will be written to the file api.apib in the directory specified in the configuration. The file uses the API Blueprint format.

There are several tools that can render apib files to html. BlueBird has a mix task which uses Aglio renderer to generate an html document from the generated apib file.

$ mix

If you use BlueBird in an umbrella app, you must run the command from within the folder of the child app (e.g. apps/myapp_web).



The configuration options can be setup in config.exs:

config :blue_bird,
  docs_path: "priv/static/docs",
  theme: "triple",
  router: YourAppWeb.Router,
  pipelines: [:api],
  ignore_headers: ["not-wanted"]


  • docs_path: Specify the path where the documentation will be generated. If you want to serve the documentation directly from the phoenix app, you can specify priv/static/docs. If you use BlueBird within an umbrella app, the path is relative to the root folder of the umbrella app.
  • theme: The Aglio theme to be used for the html documentation.
  • router: The router module of your application.
  • pipelines (optional): Only routes that use the specified router pipelines will be included in the documentation. Defaults to [:api] if not set.
  • ignore_headers (optional): You can hide certain headers from the documentation with this option. This can be helpful if you serve your application behind a proxy. If the value is a list of strings as above, the specified headers will be hidden from both requests and responses. If you want to hide different headers from requests and responses, you can use a map instead: ignore_headers: %{request: ["ignore-me"], response: ["and-me"]}.
  • trim_path (optional): Allows you to remove a path prefix from the docs. For example, if all your routes start with /api and you don't want to display this prefix in the documentation, set trim_path to "/api".



  • host: API host.
  • title: Documentation title (can use Blueprint format).
  • description: Documentation description (can use Blueprint format).
  • terms_of_service (optional): Terms of service, string.
  • contact (optional)
    • name (optional)
    • url (optional)
    • email (optional)
  • license (optional)
    • name (optional)
    • url (optional)


Route is not generated after adding API annotations to the controller

Please make sure that the route you are using in the annotation matches the route from the phoenix router (including params) exactly. Run mix phoenix.routes (or mix phx.routes if Phoenix >= 1.3) and compare the routes.

Also note that only routes that use the api pipeline (or the pipelines you configured in config.exs) will be added to the documentation.

Body Parameters are not rendered

BlueBird reads the body_params from %Plug.Conn{}. This map is only set if body_params is a binary.


post build_conn(), "/", Poison.encode! %{my: data}  # recommended
post build_conn(), "/", "my=data"