Exceptions API

Your JSON payload should be submitted as the body of a POST request to https://api.honeybadger.io/v1/notices, with the following headers:

  • X-API-Key: The API key from your project settings page
  • Content-Type: application/json
  • Accept: application/json
  • User-Agent: "{{ Client name }} {{ client version }}; {{ language version }}; {{ platform }}"

Regarding the format of the User-Agent header, you can see an example of how that's generated in our Ruby implementation here, which generates a string like this: HB-Ruby 2.1.1; 2.2.7; x86_64-linux-gnu. If you don't have all this information available to send, that's OK, but the more the merrier. :)

If all went well with your POST, you'll get a response with the status code 201 and information about the just-logged error as a JSON hash.

If all didn't go well, you could get a response with one of these status codes:

  • 403: Either the API key is incorrect or the account has been deactivated.
  • 422: The payload couldn't be processed. Please note that we only do minimal checking of the payload when it hits our API. It's entirely possible to get a 201 response, only to have the payload end up not being able to processed later in the pipeline and thus not show up in the UI.
  • 429: The API key was valid, but the payload was not accepted because you hit a rate limit (i.e., we have received too much traffic for this API key).
  • 500: Our bad! :)

Sample Payload

Your JSON will probably vary most from the example in the request key of the hash, which supplies info about the request made by the user, the web server environment, and so on. The context key of the request hash should have information about the logged-in user, if any, so that we can report on the users effected by application errors.

The backtrace key of the error hash is essential, as that is used for grouping similar errors together in the Honeybadger UI. The class and message keys of the error hash are displayed in the Honeybadger UI and used for posting errors to other services, like Github issues.

Here's an annotated payload for your enjoyment:

{
  // Please use relevant values for the name, url, and version keys of the
  // `notifier` key that point back to your code/package.
  "notifier":{
    "name":"Honeybadger Notifier",
    "url":"https://github.com/honeybadger-io/honeybadger-ruby",
    "version":"1.0.0"
  },
  // Here's where you're exception's class, message tags and backtrace go.
  // The `class` and `message` attributes are what make up the error's "title" that we display in the UI.
  // The `fingerprint` attribute is an optional string that is used to force errors with the same fingerprint (regardless of error class, message, or location) to be grouped together.
  // The `backtrace` is a ruby-style backtrace.  If the `source` attribute is included for a backtrace line, it will be displayed as a snippet in the UI,
  // Last but not least, `causes` is an optional list of causes for the error.
  // Honeybadger displays causes in the order they are listed here.
  "error":{
    "class":"RuntimeError",
    "message":"RuntimeError: This is a runtime error, generated by the crywolf app",
    "tags":["wubba"],
    "fingerprint":"optional string to force errors with the same fingerprint to be grouped together",
    "backtrace":[
      {
        "number":"4",
        "file":"/crywolf/app/controllers/pages_controller.rb",
        "method":"runtime_error",
        "source":{
          "2":"",
          "3":"  def runtime_error",
          "4":"    raise RuntimeError.new(\"This is a runtime error, generated by the crywolf app\")",
          "5":"  end",
          "6":""
        }
      },
      {
        "number":"4",
        "file":"/gems/1.9.3-p194/lib/ruby/gems/1.9.1/gems/actionpack-3.2.8/lib/action_controller/metal/implicit_render.rb",
        "method":"send_action"
      }
    ],
    "causes": [
      {
        "class":"StandardError",
        "message":"StandardError: This is the first cause",
        "backtrace":[
          {
            "number":"8",
            "file":"/crywolf/app/models/page.rb",
            "method":"find"
          },
          {
            "number":"13",
            "file":"/crywolf/app/services/find.rb",
            "method":"call"
          }
        ]
      }
    ]
  },

  // `request` contains information about the HTTP request that caused this exception.
  "request":{

    // We display this data on the error's details page.
    // `user_id` and `user_email` are special keys that are used to generate the "affected users" list in the UI.
    "context":{
      "user_id":123,
      "user_email":"test@example.com"
    },

    // In rails this is the Controller.
    "component":"pages",

    // In rails this is the Action.
    "action":"runtime_error",

    // The URL where the error occurred
    "url":"http://crywolf.dev/pages/runtime_error?a=1&b=2",

    // These are displayed under "params" on the error detail page
    "params":{
      "_method":"post",
      "authenticity_token":"tuZ7y1PUEMadgKevSzgSUK6T0p267I1+NL0+rnR7xrI=",
      "a":"1",
      "b":"2",
      "controller":"pages",
      "action":"runtime_error"
    },

    // These are displayed under "session" on the error detail page
    "session":{
      "session_id":"57fb796258046e92b3201ece44531320",
      "_csrf_token":"tuZ7y1PUEMadgKevSzgSUK6T0p267I1+NL0+rnR7xrI="
    },

    // These are displayed under "web environment" on the error detail page.
    // Normally you'll just include the environment variables set by your web server.
    "cgi_data":{
      "REQUEST_METHOD":"POST",
      "PATH_INFO":"/pages/runtime_error",
      "QUERY_STRING":"a=1&b=2",
      "SCRIPT_NAME":"",
      "REMOTE_ADDR":"127.0.0.1",
      "SERVER_ADDR":"0.0.0.0",
      "SERVER_NAME":"crywolf.dev",
      "SERVER_PORT":"80",
      "HTTP_HOST":"crywolf.dev",
      "HTTP_CONNECTION":"keep-alive",
      "CONTENT_LENGTH":"82",
      "HTTP_CACHE_CONTROL":"max-age=0",
      "HTTP_ORIGIN":"http://crywolf.dev",
      "HTTP_USER_AGENT":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/537.4",
      "CONTENT_TYPE":"application/x-www-form-urlencoded",
      "HTTP_ACCEPT":"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
      "HTTP_REFERER":"http://crywolf.dev/",
      "HTTP_ACCEPT_ENCODING":"gzip,deflate,sdch",
      "HTTP_ACCEPT_LANGUAGE":"en-US,en;q=0.8",
      "HTTP_ACCEPT_CHARSET":"ISO-8859-1,utf-8;q=0.7,*;q=0.3",
      "HTTP_COOKIE":"_crywolf_session=BAh7B0kiD3Nlc3Npb25faWQGOgZFRkkiJTU3ZmI3OTYy",
      "REMOTE_PORT":"52509",
      "ORIGINAL_FULLPATH":"/pages/runtime_error?a=1&b=2"
    }
  },
  "server":{

    // The directory where your code lives. This helps us to display more concise paths.
    "project_root":"/Users/josh/code/crywolf",

    // Your environment name
    "environment_name":"development",

    // The server's hostname
    "hostname":"Josh-MacBook-Air.local",

    // Optional: Git sha for the deployed version of the code, for linking to GitHub, Gitlab, and BitBucket
    "revision":"920201a",

    // Optional: ID of the process that raised the error
    "pid":1138
  }
}

Payload Tester

While you're developing an error collector in your language of choice that talks to our API, you can use our payload tester to see how your payloads will be rendered in our UI.