Public API

This page describes the API used by @happykit/flags. You usually don't need to interact with this API. You will usually use the@happykit/flags client for Next.js applications. This API documentation is useful for people building clients for other frameworks, programming languages or devices.

In case something is unclear, feel free to open an issue at or send a DM to @happykitdev.


The public API does not need an API Key. Instead, you'll pass along what we call the Flag Key. This key identifies your project and the stage for which the flags will be resolved. Stages are explained in the next paragraph.


In most software projects you'll have a local development environment, one or multiple staging environments and a production deployment.

HappyKit supports this approach to software development by natively supporting different stages. Flags share the variants across stages, but you can apply different targeting rules for each stage. You can further turn targeting on and off per stage.

HappyKit supports the following stages

  • development This stage is intended to be used during local development.
  • preview This stage is intended for preview deployments.
  • production This stage is intended for your production deployment.

When calling the Public API, you'll pass along the Flags Key which contains the project id and the stage for which the flags will be resolved. You can not resolve flags for multiple stages in the same request.


Requests need to be sent as a POST request to:<flags key> You can find the flag key for each stage in your project's settings on

Below is the simplest possible request:

curl -X "POST" "" \
-H "content-type: application/json" \
-d '{}'
The response would look something like
{ "flags": { "ads": true, "checkout": null, "discount": 5 }, "visitor": null }

Accepted body data

You can pass along information when triggering a flag evaluation, which your flags can use to decide which variant to evaluate to.


You can pass a key to identify a visitor. The visitor key is intended as a token which is stored in the browser of that device, and is intended to exist across any user sessions your application might have.

You can use this visitor key to target visitors in their current browser. Here is an example request:

curl -X "POST" "" \
-H "content-type: application/json" \
-d '{ "visitorKey": "L37IX4EmqzIu37e0BI1Ku" }'
{ "flags": { "ads": true, "checkout": "short", "discount": 5 }, "visitor": { "key": "L37IX4EmqzIu37e0BI1Ku" } }

A visitor key should always be passed along, except when you're doing static generation of pages. During static generation, the concept of a visitor does not exist. You can signal this by not providing a visitor key in the flag evaluation request body. All flags whose evaluation depends on the visitor key will then resolve to null instead. Once your visitors browser actually loads the site, you can send a second request with the visitor key present and receive the flags for an actual visitor. This mixed approach gives you full flexibility.


This field lets you specify a user object. Usually you'll use this to pass along the signed in user of your application. You can pass null or leave this field out completely in case no user is signed in. A user object may have the following fields:

  • key (string) (required): Unique key for this user
  • email (string): Email-Address
  • name (string): Full name or nickname
  • avatar (string): URL to users profile picture
  • country (string): Two-letter uppercase country-code, see ISO 3166-1

Here is an exampe request

curl -X "POST" "" \
-H "content-type: application/json" \
-d '{ "user": { "key": "jane", "email": "" } }'
{ "flags": { "ads": true, "checkout": null, "discount": 15 }, "visitor": null }

Your targeting rules can then use the passed user information. If you are looking to pass arbitrary data, try the traits feature shown below.


Traits are any information you want to pass along to the flag targeting. They can relate to the visitor, user or anything else. Traits should be a flat object.

An example would be to signal to your flags that the flags should be evaluated for a team member:

curl -X "POST" "" \
-H "content-type: application/json" \
-d '{ "traits": { "teamMember": true } }'
{ "flags": { "ads": true, "checkout": null, "discount": 15 }, "visitor": null }

visitorKey, user and traits

The examples above use the visitor, user and traits separately for clarity. In a real application, you'd probably end up using a mix of them - and thus passing a combination of those fields.


General structure

The server responds with the status code 200 in case everything went alright. The response body will generally look like this:

{ "flags": { "ads": true, "checkout": "short", "discount": 5 }, "visitor": { "key": "L37IX4EmqzIu37e0BI1Ku" } }

Flags resolving to null

In case a flag's resolution relies on information that was not provided in the request, the flag will resolve to null. This can happen when you try to do percentage rollouts based on the visitor key, but no visitorKey was present in the request.


The response contains information about the visitor. At the moment this is only the visitor.key.

{ "flags": { "ads": true, "checkout": "short", "discount": 5 }, "visitor": { "key": "L37IX4EmqzIu37e0BI1Ku" } }

The response will never set any cookies. It's your job to read the visitor key from the response and save it on the client. Provide it as the visitorKey on the next request of that visitor to ensure consistent targeting. If your initial request contained a visitorKey then the response's visitor.key will return the provided value.