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 github.com/happykit/flags or send a DM to @happykitdev.

API Key

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.

Stages

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.

Endpoint

Requests need to be sent as a POST request to:

https://happykit.dev/api/flags/<flags key>
You can find the flag key for each stage in your project's settings on happykit.dev.

Below is the simplest possible request:

curl -X "POST" "https://happykit.dev/api/flags/flags_pub_289861443285680649"
The response would look something like
Response
{ "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.

visitorKey

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" "https://happykit.dev/api/flags/flags_pub_289861443285680649" \
-H "content-type: application/json" \
-d '{ "visitorKey": "L37IX4EmqzIu37e0BI1Ku" }'
Response
{ "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.

user

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
  • persist (boolean): This is a special attribute which tells HappyKit to persist that user in HappyKit. When you persist a user, you can see that users profile on happykit.dev. Note that persisting users will incur additional charges in the future.

Here is an exampe request

curl -X "POST" "https://happykit.dev/api/flags/flags_pub_289861443285680649" \
-H "content-type: application/json" \
-d '{ "user": { "key": "jane", "email": "jane@example.com" } }'
Response
{ "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

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" "https://happykit.dev/api/flags/flags_pub_289861443285680649" \
-H "content-type: application/json" \
-d '{ "traits": { "teamMember": true } }'
Response
{ "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.

Responses

General structure

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

Response
{ "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.

visitor

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

Response
{ "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.