API Reference

Happo exposes a public, REST-like, API that you can use to create or enhance custom integrations. The API resides at https://happo.io, and all endpoints use the /api namespace.

OpenAPI spec for the public Happo API

Want to use Happo from Claude, ChatGPT, Cursor, or another AI assistant? Happo also runs an MCP server with OAuth so AI agents can list comparisons, inspect diffs, and approve, reject, or report flakes for them.

Authentication

All API endpoints are auth protected. To successfully issue a command, you need to provide an authentication header with your request. There are two ways to authenticate. JWT authentication is more secure but can be a little tricky to set up. HTTP Basic authentication is a less secure alternative, but is a good option if you want a simpler setup.

Basic authentication

With Basic authentication, you provide an Authorization: Basic <token> header where the token is a base64 encoded string of your apiKey:apiSecret tokens.

JWT authentication

This auth token is a JSON web token generated based on your API key and API secret. Pass { key: <your API key> } as the payload of the JWT call and the API secret as the secret, and set a kid header equal to the API key. Pass the resulting token as a Authorization: Bearer <generated token> header in all API requests.

An example of how to construct the JWT token can be found in the source code for the happo.io client.

Endpoints

Here's a full list of API paths you can call. All endpoints speak JSON. Body params are sent as a JSON blob in the body of the request. Responses are sent as JSON in the body of the HTTP response.

Reports

Create report

POST /api/reports/:sha

URL params

  • :sha String

Body params

  • snaps Array<Snapshot>
  • project optional String
  • link optional String
  • message optional String
  • partial optional Boolean

Response

Error responses

  • 400
  • 401

Get report

GET /api/reports/:sha

URL params

  • :sha String

Query params

  • project optional String

Response

Error responses

  • 401
  • 404

Get report status

GET /api/reports/:sha/status

URL params

  • :sha String

Query params

  • project optional String
  • projects optional String

Response

Error responses

  • 400
  • 401
  • 404

Complete a report

POST /api/reports/:sha/complete

URL params

  • :sha String

Body params

  • project optional String
  • projects optional Array<String>

Response

Error responses

  • 400
  • 401
  • 404

Clone report

POST /api/reports/:fromSha/clone/:toSha

URL params

  • :fromSha String
  • :toSha String

Body params

  • project optional String
  • link optional String
  • message optional String

Response

Error responses

  • 401
  • 404

POST /api/skip/:sha

URL params

  • :sha String

Body params

  • project optional String
  • label optional String

Error responses

  • 401
  • 404

Comparisons

Compare reports

POST /api/reports/:sha1/compare/:sha2

URL params

  • :sha1 String
  • :sha2 String

Body params

  • project optional String
  • projects optional Array<String>
  • link optional String
  • message optional String
  • notify optional String
  • isAsync optional Boolean
  • fallbackShas optional Array<String>
  • deepCompare optional DeepCompareSettings
  • blockApproval optional BlockApproval

Response

Error responses

  • 400
  • 401

Get comparison status

GET /api/reports/:sha1/compare/:sha2/status

URL params

  • :sha1 String
  • :sha2 String

Query params

  • project optional String

Response

Error responses

  • 401
  • 404

Get comparison statuses

GET /api/reports/:sha/comparison-statuses

URL params

  • :sha String

Query params

  • project optional String

Response

Error responses

  • 401

Get comparison results

GET /api/reports/:sha1/compare/:sha2/results

URL params

  • :sha1 String
  • :sha2 String

Query params

  • project optional String

Response

Error responses

  • 401
  • 404

Get comparisons

GET /api/comparisons

Query params

  • from optional Date
  • to optional Date
  • limit optional Number
  • project optional String

Response

Error responses

  • 401

Jobs

Create job

POST /api/jobs/:sha1/:sha2

URL params

  • :sha1 String
  • :sha2 String

Body params

  • project optional String
  • projects optional Array<String>
  • link optional String
  • message optional String

Response

Error responses

  • 401

Create orchestration job

POST /api/jobs/:sha1/:sha2/orchestrate

URL params

  • :sha1 String
  • :sha2 String

Body params

  • projects Array<String>
  • link optional String
  • message optional String

Response

Error responses

  • 400
  • 401

Cancel job

POST /api/jobs/:sha1/:sha2/cancel

URL params

  • :sha1 String
  • :sha2 String

Body params

  • project optional String
  • status optional String
  • link optional String
  • message optional String

Error responses

  • 401
  • 404
  • 409

Get jobs

GET /api/jobs

Query params

  • from optional Date
  • to optional Date
  • limit optional Number

Response

Error responses

  • 401

Get job

GET /api/jobs/:id

URL params

  • :id Number

Response

Error responses

  • 401
  • 404

Miscellaneous

Resolve comparison

POST /api/reports/:sha1/compare/:sha2/resolve

URL params

  • :sha1 String
  • :sha2 String

Body params

  • resolution String
  • project optional String

Response

Error responses

  • 400
  • 401
  • 403
  • 404
  • 409

Get flakes

GET /api/flake

Query params

  • project optional String
  • limit optional Number
  • page optional Number
  • component optional String
  • variant optional String
  • target optional String
  • sha optional String

Response

Error responses

  • 401

Ignore diff

POST /api/ignored-diffs

Body params

  • snapshot1Id String
  • snapshot2Id String
  • project optional String

Response

  • json Object

Error responses

  • 401
  • 404

Delete ignored diff

DELETE /api/ignored-diffs

Body params

  • snapshot1Id String
  • snapshot2Id String

Error responses

  • 401
  • 404

Add component subscriptions

POST /api/subscriptions/:component

URL params

  • :component String

Body params

  • emailAddresses Array<String>

Error responses

  • 400
  • 401

Remove component subscriptions

DELETE /api/subscriptions/:component

URL params

  • :component String

Body params

  • emailAddresses Array<String>

Error responses

  • 401

Get snapshot
Experimental

GET /api/components/:component/:variant/:target

URL params

  • :component String
  • :variant String
  • :target String

Query params

  • project optional String

Response

Error responses

  • 401
  • 404

Get diff counts

GET /api/diff-counts

Query params

  • project optional String
  • from optional Date
  • to optional Date

Response

  • json Array

Error responses

  • 400
  • 401

Get current usage

GET /api/billing/current-usage

Response

Error responses

  • 401
  • 404

Get projects

GET /api/projects

Response

Error responses

  • 401

Objects

These are the domain objects you can come across while communicating with the API.

Snapshot

An object describing a screenshot of a certain component variant

  • url String
  • variant String
  • target String
  • component String
  • width Number
  • height Number
  • id String

SnapshotInfo

An object with information about a screenshot image.

  • url String
  • width Number
  • height Number

ReportStatus

An object with useful properties for a report.

  • url String
  • completedAt Date
  • createdAt Date
  • snapshotCount Number

IgnoredDiffDetails

An object with details about why a diff was ignored.

  • byName String
  • byEmail String
  • createdAt Date
  • dataHappoHide optional Boolean
  • sourceComparison optional Object

Comparison

An object with useful properties describing the differences between two reports.

ComparisonStatus

An object with information about the status of a comparison.

  • sha1 String
  • sha2 String
  • status String
  • url String
  • createdAt Date
  • diffs Number
  • unchanged Number
  • added Number
  • deleted Number
  • link String
  • message String
  • project String

Flake

An object describing a reported flake.

  • project String
  • component String
  • variant String
  • target String
  • snapshots Array<SnapshotInfo>
  • comparison ComparisonStatus
  • user Object
  • createdAt Date
  • occurrenceCount Number

Job

A small object with basic properties for a job.

  • url String
  • id Number

Usage

Snapshots usage information

  • total Number
  • quota Number
  • start Date
  • end Date

ProjectInfo

A small object with basic properties for a project.

  • id Number
  • name String

JobDetails

An object with useful properties for a job.

  • id Number
  • createdAt Date
  • finishedAt Date
  • sha1 String
  • sha2 String
  • description String
  • status String
  • link optional String
  • message optional String
  • url String
  • projects Array<ProjectInfo>

DeepCompareSettings

An object with settings for deep compare.

  • diffAlgorithm String
  • compareThreshold Number
  • ignoreThreshold Number
  • ignoreWhitespace Boolean
  • applyBlur Boolean

BlockApproval

What keeps a comparison from being approved. Both attributes are optional, and leaving one out means it is not specified. Approving a blocked comparison is refused with a 409, and an approval carried over from an earlier comparison does not apply to it.

  • renderErrors Boolean
  • accessibilityViolations Boolean

AsyncComparison

An object returned when a comparison is created with `isAsync: true`. The comparison will be completed asynchronously in the background.

  • id Number
  • statusImageUrl String
  • compareUrl String

Need help?