The Flagsmith API

The Flagsmith API

A plain-English tour of how applications and people talk to Flagsmith over the web: the two APIs, how keys work, what each request does, how errors and limits behave, and how to automate everything safely.

Every button you click in the Flagsmith dashboard, and every feature flag your application reads, travels through an API. The dashboard itself is only a friendly face painted on top of it. If you understand the API, you understand how Flagsmith really works, and you gain the power to automate things that would take a person hours of clicking.

This guide explains the Flagsmith API from the ground up. You will learn what an API is, why Flagsmith has more than one, how requests are proven to be allowed, what comes back, what goes wrong, and how to build safe automation around it. We use simple language, everyday comparisons, and plain descriptions rather than code, so the ideas stay clear whatever language your team writes in.

1Why a Feature Flag Platform Needs an API

A flag service is only useful if other programs can reach it quickly and safely.

What an API is

An API, short for application programming interface, is a set of agreed requests that one program can send to another, together with the replies it should expect. It is a contract. If you ask in the agreed way, you get an answer in the agreed shape. The people who built the service can change everything inside, and as long as the contract stays the same, nobody who depends on it is hurt.

Analogy

Think of a restaurant. You do not walk into the kitchen and cook your own meal. You read a menu, tell the waiter what you want, and the waiter brings your food. The menu is the contract, the waiter is the API, and the kitchen is everything hidden behind it. You do not need to know how the kitchen is arranged, only how to order.

Why Flagsmith is built API-first

Flagsmith is a service that many different programs must talk to. Your website, your phone app, your backend servers, your build pipeline, and your support tools may all need something from it. A single, well-defined API means all of them speak the same language. The dashboard is just one more customer of that API, which is why anything you can do by clicking can usually also be done by a program.

Two very different jobs

The API does two quite different jobs. One job is reading: an application asks “what should I show this user?” thousands of times a second. The other job is managing: a person or a script creates flags, changes their values, and builds rules. These jobs have different traffic, different risks, and different people involved, so Flagsmith splits them into two APIs. Understanding that split is the single most important idea in this guide, and the next chapters build on it.

2
APIs: one for reading flags, one for managing them
JSON
the format used to send and receive information
HTTPS
the secure road every request travels on
i
Tip

Most teams never call the API by hand. They use an SDK, which wraps the API in friendly functions. Even so, knowing what happens underneath helps you fix problems quickly, build tools the SDK does not cover, and judge when something is slow or wrong.

2Two APIs, Two Audiences

The SDK API serves your running applications. The Admin API serves people and automation.

The SDK API (also called the Flags API)

The SDK API is what your applications call at runtime. It is small on purpose. It answers questions such as “give me every flag for this environment” or “give me every flag for this particular user, and remember these facts about them.” It is built to be read very often and to answer very fast. It authenticates with an environment key, which identifies one environment of one project.

The Admin API

The Admin API is what the dashboard itself uses, and it is also open to you. It is large. It covers organisations, projects, environments, features, feature states, segments, identities, tags, audit logs, webhooks, and more. It is used to create, change, and delete things. It authenticates with a secret token or an organisation API key, and it can do things your applications should never be able to do, such as delete a flag in production.

Analogy

A hotel has a front desk where guests ask simple questions, such as “what time is breakfast?” Guests are many and the questions are quick. The hotel also has a back office where staff change room prices, assign rooms, and update the rules. Few people work there and their actions have big effects. The SDK API is the front desk. The Admin API is the back office, and its door is kept locked.

QuestionSDK APIAdmin API
Who calls it?Your running applicationsPeople, scripts, pipelines, the dashboard
Main purposeRead flag states and valuesCreate, change, and delete everything
CredentialEnvironment keyAdmin token or organisation API key
TrafficVery highLow to moderate
PowerRead-only for flags, plus identity dataFull control, depending on role
Where the key may liveClient keys: anywhere. Server keys: servers onlySecrets manager only
flowchart LR
    APP["Web or Mobile App"] -->|"Environment key"| SDKAPI["SDK API"]
    SRV["Backend Service"] -->|"Server key"| SDKAPI
    DASH["Dashboard"] -->|"User login"| ADMIN["Admin API"]
    CI["Pipeline or Script"] -->|"Admin credential"| ADMIN
    SDKAPI --> STORE[("Flag Data")]
    ADMIN --> STORE
    
Different callers use different APIs and different credentials, but both read and write the same underlying flag data.
!
Warn

Never mix the two worlds. An Admin credential placed in a mobile app or web page would let anyone who finds it change your production flags. Environment keys and Admin credentials are different tools for different jobs, and they must be stored differently.

3A Short Primer on Web APIs

A few ideas about how web APIs work will make everything else easier to follow.

Requests and responses

Every conversation with the API has two halves. The caller sends a request, and the service sends back a response. A request names what the caller wants and carries any information needed. A response says whether it worked and carries the answer.

The parts of a request

  • Address (URL): where the request is going, including the path that names the kind of thing you are asking about, such as flags or identities.
  • Method: the verb that says what to do. A GET reads something. A POST creates something. A PUT or PATCH changes something. A DELETE removes something.
  • Headers: small labelled notes sent along with the request. This is where the credential goes, and where the caller says what format it speaks.
  • Body: the main content, for requests that send data, written in JSON.

JSON

JSON is a simple way to write down information so that any programming language can read it. It arranges data as named fields and lists. For example, an identity might be described by a field for its ID and a list of traits, each with a name and a value. It looks a little like a form that has been filled in.

The parts of a response

  • Status code: a number that sums up the result. Numbers beginning with 2 mean success. Numbers beginning with 4 mean the caller made a mistake. Numbers beginning with 5 mean the service had a problem.
  • Headers: extra notes about the reply.
  • Body: the answer itself, usually in JSON.

REST

Flagsmith follows a style called REST. The idea is that every kind of thing, such as a project or a feature, has its own address, and a small set of verbs act on those addresses in a predictable way. Once you learn how one kind of thing is handled, the others feel familiar.

Analogy

A library has a catalogue where every book has its own shelf location. To see a book you go to its shelf. To add one, you hand it to the librarian for that section. To remove one, you ask the librarian to take it away. REST is like that: each thing has a place, and a few simple actions work the same way everywhere.

VerbPlain meaningExample in Flagsmith terms
GETRead, change nothingFetch the flags for an environment
POSTCreate or submitSend an identity with traits, or create a feature
PUTReplace the whole thingReplace a feature’s full definition
PATCHChange part of itTurn a flag on without touching anything else
DELETERemoveDelete a retired feature

4Where the API Sits in the Architecture

Following a request from the caller to the data shows how the pieces cooperate.

The hosted service

When you use the hosted Flagsmith service, the API lives at addresses run by the Flagsmith team. Applications reading flags are usually served by a globally distributed layer, often called the Edge API, which keeps a read-optimised copy of each environment close to the caller. Management requests go to the core API, which writes changes to its main database and then makes sure the serving layer receives the update.

The self-hosted service

When you host Flagsmith yourself, the API is the application server you run, usually built in Python with the Django framework and backed by a relational database. You decide the address. You place a load balancer in front, run several copies, and add caching. The same SDK API and Admin API are available, so your applications can switch between hosted and self-hosted by changing only the address and the key.

flowchart TD
    CALLER["Caller"] --> LB["Load Balancer or Gateway"]
    LB --> API1["API Instance A"]
    LB --> API2["API Instance B"]
    API1 --> CACHE["Cache"]
    API2 --> CACHE
    CACHE --> DB[("Relational Database")]
    API1 --> DB
    API2 --> DB
    API1 --> WORK["Background Worker"]
    WORK --> OUT["Webhooks and Integrations"]
    
A typical self-hosted layout: several API copies behind a load balancer, sharing a cache and a database, with slow jobs pushed to a background worker.

Why keep the layers separate

The API handles the request, the cache avoids repeating work, the database remembers everything for good, and the worker handles slow jobs such as sending webhooks so they never delay an answer. Each part can be made bigger or smaller on its own. This is the same shape you will find in almost every busy web service.

Analogy

Imagine a busy post office. A counter clerk answers customers quickly. A sorting room keeps frequently asked-for items near the front. A large warehouse stores everything permanently. A back room handles slow tasks like special deliveries. A customer talks only to the counter clerk, yet all the other rooms make that quick answer possible.

i
Note

Addresses, regions, and the exact layout of the hosted service can change over time. Always take the current base address and any regional options from the official documentation rather than from memory or an old article.

5Authentication: Proving You Are Allowed

Every request must carry a credential. Which one depends on which API you are calling.

Why authentication matters

The service must know two things before it answers: who is asking, and what that asker is permitted to do. Authentication answers the first question, and permissions answer the second. A flag platform controls how your product behaves, so these checks are not optional.

Environment keys for the SDK API

Requests to the SDK API carry an environment key in a request header. The key tells Flagsmith which project and environment to read. There are two kinds. A client-side key is safe to place in a web page or mobile app, because it can only fetch flags for an identity and cannot read the full rules. A server-side key is a secret that can read the complete environment configuration, so it must stay on servers you control.

Credentials for the Admin API

Requests to the Admin API carry a stronger credential, also in a header. There are two common kinds. A user token belongs to one person’s account and acts with that person’s permissions. An organisation API key belongs to the organisation and is meant for automation such as pipelines and scripts, so it does not depend on a specific employee staying at the company. Check the current documentation for how the header is written, since the format matters and details can change.

flowchart TD
    R["Incoming request"] --> H{"Which API?"}
    H -->|"SDK API"| E["Read environment key from header"]
    H -->|"Admin API"| T["Read admin credential from header"]
    E --> V1{"Key valid?"}
    T --> V2{"Credential valid?"}
    V1 -->|"Yes"| A1["Answer with that environment's flags"]
    V1 -->|"No"| X1["Reject with an authorisation error"]
    V2 -->|"Yes"| P{"Permission allows this action?"}
    V2 -->|"No"| X2["Reject with an authorisation error"]
    P -->|"Yes"| A2["Perform the action"]
    P -->|"No"| X3["Reject as forbidden"]
    
Two different doors, each with its own check; the Admin door adds a second permission check after the identity check.
CredentialUsed withSecret?Can do
Client-side environment keySDK APINo, public by designFetch flags for an identity
Server-side environment keySDK APIYesFetch flags and the full environment configuration
User tokenAdmin APIYesWhatever that person is allowed to do
Organisation API keyAdmin APIYesAutomation tasks within its permissions
Analogy

Think of an office building. A visitor badge opens the front door and the lobby, and many people hold one. A staff card opens the offices. A master key opens the server room, and only a handful of people carry it. Client keys are visitor badges, server keys are staff cards, and Admin credentials are master keys.

Handling keys safely

  • Store secret keys in a secrets manager, never inside source code or chat messages.
  • Use a separate key for each environment and each application, so one leak can be cut off without breaking everything.
  • Rotate secrets on a schedule and immediately after any suspected exposure or staff change.
  • Give automation the smallest permissions that let it do its job.
  • Keep keys out of logs and error messages.
!
Warn

A key committed to a public code repository should be treated as already stolen. Remove it, create a new one, and revoke the old one at once. Deleting it from the file is not enough, because the history of the repository still holds it.

6Reading Flags: The Environment-Level Request

The simplest question you can ask Flagsmith is “what are all the flags in this environment?”

What the request looks like

To read flags, the caller sends a GET request to the flags path of the SDK API and includes the environment key in a header. There is no body, because nothing is being created. The request does not say anything about a particular user, so the answer is the same for everybody: the default state and value of every feature in that environment.

What comes back

The response is a list. Each item in the list describes one feature and usually carries four kinds of information: the feature’s identifying number, the feature’s name, whether it is enabled, and its value, which may be empty if the feature is a plain on/off switch. Your application reads the list, finds the feature it cares about by name, and decides what to do.

Piece of the answerWhat it tells youHow your app uses it
Feature nameThe label you gave the featureTo find the right item in the list
EnabledTrue or falseTo decide whether the new code path runs
ValueText, number, or true/false, or emptyTo read settings such as a limit or message
Feature identifierA number unique to the featureFor logging and for matching with other data

When to use this request

The environment-level request suits situations where every user gets the same answer: a site-wide maintenance banner, a global setting, or an application that has no notion of individual users. It is the cheapest request because Flagsmith does not need to look up an identity or test any segment rules.

Analogy

It is like reading the notice board at the entrance of a school. Everyone who walks in sees the same notices. Nobody is checked against a list first, and the board does not change depending on who is looking at it.

What it does not do

Because no identity is sent, segment overrides and percentage rollouts cannot apply. If you have a rule such as “show this to twenty percent of users,” the environment-level request cannot honour it, because it does not know who is asking. For targeted behaviour you must use the identities request, described next.

i
Tip

If a flag seems to ignore your segment rules, check which request your app is sending. A common cause is an app calling the environment-level request, which has no identity, while the rules expect one.

7Reading Flags for a User: The Identities Request

When you want answers that depend on who the user is, you introduce them to Flagsmith first.

What the request carries

The identities request is a POST. It carries the environment key in a header, and in its body it carries an identifier, which is the unique ID of the user, plus an optional list of traits, which are facts about that user. Each trait has a name and a value. A POST is used, rather than a GET, because the request can change something: it may create the identity the first time it is seen and store or update its traits.

What comes back

The response contains the flags as they apply to that user, after all rules have been evaluated, and it also contains the traits now stored for the identity. Each flag looks like the ones in the environment-level answer, but with the user’s own state and value. If the user belongs to a segment with an override, the override’s answer appears. If the user was placed into one variation of a multivariate flag, that value appears.

sequenceDiagram
    participant App as Application
    participant API as SDK API
    participant Rules as Rule Engine
    participant Store as Data Store
    App->>API: Send identifier and traits with environment key
    API->>Store: Find or create the identity and save traits
    Store-->>API: Identity record
    API->>Rules: Evaluate segments and rollouts for this identity
    Rules-->>API: Final state and value for each feature
    API-->>App: Flags plus stored traits
    
The identities request combines three jobs: remember the user, evaluate the rules, and return the personalised answer.

The order of evaluation

Flagsmith starts with the environment default for each feature. It then checks whether this exact identity has a personal override, which wins over everything else. If not, it walks through the segment overrides in priority order and applies the first one whose rules match the traits. For multivariate features it assigns the identity to a variation in a repeatable way. The result is the final list sent back.

1

Authenticate

The environment key is checked and the right environment is chosen.

2

Resolve the identity

The identifier is looked up, and a new identity is created if this is the first sighting.

3

Store the traits

Traits from the request are saved or updated against the identity.

4

Evaluate

Personal overrides, segment overrides, and rollout buckets are applied in order.

5

Respond

The final flags and the stored traits are returned to the caller.

Choosing the identifier

The identifier should be stable and unique for each person, and it should be the same in every system that talks to Flagsmith. A customer number from your own database works well. Avoid anything that changes, such as an email address that a person might edit. Avoid personal data where possible, as explained in the security chapter.

Everyday use case: a plan-based feature

A user logs in. Your server sends their customer number as the identifier and their plan name as a trait. Flagsmith matches the plan against a segment, applies the override, and returns the flags. The advanced report page is on for “enterprise” plans and off for the rest. When the customer upgrades, the next request carries the new plan and the page appears.

8Traits: Sending Facts About Your Users

Traits are the raw material of targeting. How you send them decides how good your targeting can be.

What a trait is

A trait is a named fact about an identity. It has a key, such as “plan” or “country”, and a value, such as “pro” or “India”. Values can be text, whole numbers, decimal numbers, or true and false. The type matters, because rules compare values in type-aware ways. “Greater than” makes sense for numbers but not for free text.

Three ways to send traits

  • With the identities request. The most common way. Include the traits in the body, and Flagsmith saves them and evaluates rules in one step.
  • Through a separate traits request. Some SDKs and workflows update a single trait on its own, without asking for flags.
  • As one-time traits. Newer SDKs can send traits for a single evaluation without storing them. This suits short-lived data and sensitive data you prefer not to keep.

Updating and removing traits

Sending a trait with a new value replaces the old value. Sending a trait with an empty value is the usual way to remove it. Check the current documentation for the exact behaviour in your SDK, because details such as how missing traits are treated can differ between versions.

Matching rules and types

Trait typeGood rule stylesExample
TextEquals, not equals, contains, in a listCountry is one of three named countries
Whole numberEquals, greater than, less thanAge of account in days is more than thirty
Decimal numberGreater than, less thanApp version is at least five point two
True or falseEqualsIs an employee equals true
Analogy

A traits list is like the information on a passenger’s boarding pass: seat class, frequent flyer level, and special needs. The gate agent does not need the passenger’s life story. A few well-chosen facts are enough to decide who boards first.

Common trait mistakes

  • Sending numbers as text. A trait sent as the text “5” may not compare the way a number would. Send numbers as numbers.
  • Forgetting to send a trait. A rule on a missing trait simply fails to match. Decide what the safe behaviour is for such users.
  • Inconsistent names. If one service sends “Plan” and another sends “plan”, rules may match only half your users. Agree on one spelling and case.
  • Sending too much. Every extra trait is more data to protect. Send only what your rules actually use.
  • Frequently changing traits. A value that changes every minute makes users hop between segments and see unstable behaviour.
!
Warn

Do not put sensitive personal details in traits. A rule that depends on a health detail or an email address creates a privacy burden for no benefit. Use plain categories such as plan and region instead.

9The Environment Document and Local Evaluation

For very busy servers, the best request is the one you rarely have to make.

The idea

With remote evaluation, every flag check is a request to Flagsmith. With local evaluation, a server downloads the full configuration of an environment once, and then answers every flag check from memory. The download is served by a special request that returns what is called the environment document. It contains every feature, every segment, every rule, and every override for that environment.

Who is allowed to ask for it

Because the environment document holds all your targeting rules, only a server-side key may fetch it. A client-side key is refused. This is a deliberate protection: the rules of a company can reveal plans, pricing logic, and internal groupings that should never be visible in a browser.

How the SDK uses it

A server SDK in local mode fetches the document when it starts, then refreshes it on a schedule, commonly about once a minute, though you can change the interval. Between refreshes, each flag check takes the identity and traits from your code, runs the segment rules inside your own process, and returns the answer without leaving the machine.

flowchart LR
    SRV["Your Server with SDK"] -->|"Fetch once a minute with server key"| API["SDK API"]
    API -->|"Environment document"| SRV
    SRV --> MEM["In-memory rules"]
    REQ["Thousands of flag checks"] --> MEM
    MEM --> ANS["Instant answers"]
    
One download, thousands of local answers: the network is used only for the periodic refresh.
Trade-offRemote evaluationLocal evaluation
Latency per checkOne network tripIn-memory, near instant
Load on FlagsmithGrows with trafficGrows only with the number of servers
FreshnessLatest at every requestAs of the last refresh
Where rules are visibleOnly inside FlagsmithInside your server’s memory
Works if the network failsNeeds cached or default valuesKeeps working with the last document
Analogy

A traveller can phone the airline every time they need a rule about baggage, or they can print the whole baggage policy once and refresh the printout each morning. The printout is faster and works when the phone line is down, but it can be a few hours behind the latest announcement.

Practical advice

Use local evaluation for busy backend services. Protect the server key like any other secret. Watch that the refresh is actually succeeding, because a server that silently stops refreshing will keep using older rules. Track how old the in-memory document is, and raise an alert if it becomes much older than expected.

10What Comes Back: Shapes of Responses and Defaults

Reading a response correctly is as important as sending the request correctly.

Lists and lookups

Flag responses arrive as lists. Your code should convert the list into a lookup by feature name once, then read from that lookup. Looking through the list again on every check wastes time and invites mistakes.

Always handle a missing flag

A flag you ask for might not exist in the response. It may have been deleted, mistyped, or never created in that environment. Never assume it is present. When it is missing, use your safe default and, ideally, log a warning so a human can fix the mismatch.

Treat the value type carefully

A value can be text, a number, or true and false. Check its type before using it, and handle an empty value as a normal case rather than an error. A flag that is on but has no value is perfectly valid; it simply has no extra setting attached.

Safe defaults

Every flag check in your code needs a default: what to do when no answer arrives, or the answer is unusable. Choose defaults that favour safety. A new, unfinished feature should default to off. A protective kill switch should default to its protective state. Defaults are the quiet hero of reliable flag use.

flowchart TD
    CALL["Request flags"] --> OK{"Valid response received?"}
    OK -->|"Yes"| FIND{"Flag present in the list?"}
    OK -->|"No"| DEF["Use safe default"]
    FIND -->|"Yes"| USE["Use state and value"]
    FIND -->|"No"| DEF
    
Two places where the answer can be missing, and one safe place to land when it is.

Everyday use case: a deleted flag

A team removes an old flag from Flagsmith but forgets one place in the code that still reads it. Because that code has a safe default of “off”, the old behaviour simply continues, and a logged warning leads the team to the leftover check. Without a default, the same mistake could have caused an error for every user.

i
Tip

Wrap your flag checks in one small helper of your own, with the default built in. Then every part of your code handles missing or broken answers the same way, and you have a single place to improve later.

11The Admin API: Managing Everything

The Admin API is the back office. It can create, read, change, and delete every kind of thing in Flagsmith.

A family of resources

The Admin API is organised around resources, which are the kinds of things Flagsmith keeps. Each resource has its own address, and the same verbs work on each in a similar way. The main resources mirror the concepts you already know.

Resource

Organisations

The top-level container holding teams and projects.

Resource

Projects

One product or application and its list of features.

Resource

Environments

Development, Staging, Production, each with its own keys and states.

Resource

Features

The named flags and config values defined in a project.

Resource

Feature states

The on/off state and value of a feature within one environment.

Resource

Segments

Saved groups of users defined by rules over traits.

Resource

Identities

The known users, with their traits and personal overrides.

Resource

Audit logs and webhooks

History of changes and automatic notifications.

Features versus feature states

This distinction trips up many newcomers. A feature is the definition: its name, its description, its type. It exists once per project. A feature state is how that feature behaves in one environment: whether it is on, and which value it carries. If you have three environments, each feature has three feature states. To turn a flag on in Production, you change its feature state in the Production environment, not the feature itself.

flowchart TD
    ORG["Organisation"] --> PROJ["Project"]
    PROJ --> FEAT["Feature definition"]
    PROJ --> ENVD["Environment: Development"]
    PROJ --> ENVP["Environment: Production"]
    FEAT --> FSD["Feature state in Development"]
    FEAT --> FSP["Feature state in Production"]
    ENVD --> FSD
    ENVP --> FSP
    
A feature is defined once for a project; each environment keeps its own state for it.
Analogy

A restaurant menu lists a dish called “spicy noodles”. That is the feature. Each branch of the restaurant then decides whether the dish is available today and how spicy it is. Those branch decisions are the feature states. The dish is defined once, but each branch controls its own version.

Learning the resource map

Flagsmith publishes interactive documentation for its API, based on a standard description format. For a self-hosted installation, the same documentation is usually available from your own server. Browsing it is the fastest way to see every resource, every field, and every allowed action for the version you run.

12Managing Features and Feature States

The two jobs people most often automate: creating a flag, and flipping it.

Creating a feature

To create a flag, a script sends a POST to the features resource of a project, carrying the feature’s name and optional details such as a description, a type, an initial value, and tags. The service replies with the newly created feature, including its identifying number. After that, the feature exists in every environment of the project, usually off by default.

Changing a feature state

To turn a flag on or off, or to change its value, a script changes the feature state belonging to the target environment. It finds the right feature state, then sends a PATCH or PUT request with the new on/off setting or value. Changing a state in Production takes effect for applications on their next fetch or refresh.

Common workflows

1

Create on feature branch

When a developer starts a feature, a script creates the flag in the project so teammates can use it right away.

2

Enable in lower environments

After a successful build, the pipeline turns the flag on in Development and Staging for testing.

3

Release in stages

A scheduled or manual step raises the percentage in Production at agreed times.

4

Retire

After the launch, a cleanup task deletes the flag and the code that reads it.

Bulk work

When you must change many flags, a script can list the features of a project and loop through them. For example, a task may add a tag to every flag older than a chosen age, or copy a set of flag states from Staging to a new environment. Take care with bulk changes in Production. Test the script in a lower environment first and make it print what it would change before it changes anything.

!
Warn

Deleting a feature through the API removes it for the whole project, in every environment, and any code still reading it will fall back to its default. Confirm that nothing depends on the flag before a script deletes it.

Everyday use case: a creation step in the pipeline

A team agrees that every new feature needs a flag with a standard name and an owner tag. A pipeline step checks the pull request for a flag name, calls the Admin API to create it if it does not exist, and adds the author as owner. This removes a manual chore and guarantees every flag has a name and an owner from the first day.

13Segments, Overrides, and Identities in the Admin API

Targeting rules are data too, and the Admin API lets you manage them like any other resource.

Segments

A segment is created in a project with a name and a list of rules. Each rule has conditions that compare a trait to a value with an operator. Rules can be combined, so a segment can require several conditions together. A script that creates segments is helpful when many projects need the same group definitions, such as “internal staff” or “enterprise customers”.

Segment overrides

A segment override attaches a segment to a feature in one environment, with its own on/off state and value. The order of overrides matters because the first matching one wins, so the API lets you view and change the priority. Managing the order by script reduces the risk of a human accidentally putting a general rule above a restrictive one.

Identities and personal overrides

The Admin API can list identities, look up a specific one, view its traits, and set identity overrides that pin a feature for exactly that person. Support teams use this to give one customer early access or to switch off a feature for one person having trouble. Because identities hold user information, access to them should be limited, and deleting an identity is the usual way to honour a request to remove someone’s data.

TaskResource touchedWho usually does it
Create a reusable group of usersSegmentProduct or engineering
Give a group early accessSegment override on a feature stateProduct manager
Let one customer try a featureIdentity overrideSupport or customer success
Remove a person’s stored dataIdentityPrivacy or support team
Analogy

Think of the guest list for a venue. A segment is a named list such as “press” or “sponsors”. An override says what the list is allowed to do, such as entering through a side door. An identity override is a handwritten note for one person: “let Asha in, even though she is not on any list.” The manager can edit lists and notes, but should be careful, because each edit changes who gets in.

i
Tip

Record why each identity override exists, perhaps in a tag or a ticket reference. Months later, nobody remembers why one person was pinned, and unexplained overrides are a common source of confusion.

14Audit Logs, Webhooks, and Governance Through the API

Reading history and reacting to changes are as important as making them.

Audit logs

The Admin API exposes the audit log, a record of who changed what and when. A script can read recent entries to build a daily summary, feed another tool, or look for unusual activity, such as many production changes outside working hours. Because the log is data, you can search it, filter it by project or time, and keep a copy in your own long-term storage.

Webhooks

A webhook is an automatic message that Flagsmith sends to an address you provide whenever something happens, such as a flag being changed. You can create and manage webhooks through the API. The receiving side is a small web service that accepts the message and acts on it, perhaps posting to a chat channel, refreshing a cache, or opening a ticket.

sequenceDiagram
    participant Eng as Engineer
    participant Admin as Admin API
    participant Hook as Webhook Sender
    participant Recv as Your Receiver
    participant Chat as Team Chat
    Eng->>Admin: Change a flag in Production
    Admin->>Hook: Queue a change notification
    Hook->>Recv: Send message to your address
    Recv->>Chat: Post who changed what
    Recv-->>Hook: Acknowledge receipt
    
A webhook turns a flag change into a message your own systems can react to.

Verifying webhooks

Anyone who learns the address of your receiver could send it fake messages. Protect it. Flagsmith can sign webhook messages with a shared secret, so your receiver can check that the message truly came from Flagsmith and was not altered on the way. Confirm the current signing options in the documentation, and always reject messages that fail the check.

Change requests and scheduling

In plans that include them, change requests let one person propose a change and another approve it, and scheduled changes let a change happen at a future time. These can be driven through the API as well, which allows teams to build their own approval flows in the tools they already use.

Analogy

A bank keeps a statement of every transaction, and it sends you a text message when money leaves your account. The audit log is the statement, and the webhook is the text message. One lets you look back, and the other tells you the moment something happens.

15Lists, Pages, Filters, and Bulk Operations

A project with hundreds of flags cannot be returned in one reply, so list requests come in pages.

Pagination

When you ask for a list of things in the Admin API, the answer is usually split into pages. The response typically includes the total count, a link to the next page when there is one, a link to the previous page, and the items for the current page. To collect everything, your script follows the link to the next page until none remains. A common bug is to read only the first page and conclude that the rest does not exist.

Analogy

A phone book is too big to read at once, so it is split into pages. You read a page, and if the name you want is not on it, you turn to the next one. Pagination works the same way: take a page, check whether another follows, and keep going until the book ends.

flowchart TD
    S["Request first page"] --> R["Read the items"]
    R --> N{"Is there a next page link?"}
    N -->|"Yes"| G["Request the next page"]
    G --> R
    N -->|"No"| D["Done: all items collected"]
    
The standard loop for collecting a complete list from a paged API.

Filtering and searching

Many list requests accept filters, so you can ask only for features with a certain tag, or only for items matching a search word. Use filters rather than downloading everything and sorting it yourself. It is faster, kinder to the service, and less likely to hit limits.

Ordering

Lists often allow you to choose the order, such as by name or by creation date. When your script depends on the order, ask for it explicitly rather than assuming a default, so a change in the service’s behaviour cannot break your logic.

Doing many things at once

When a task touches many items, there are three common approaches. You can send requests one after another, which is simple and gentle. You can send a few at the same time, which is faster but must stay within rate limits. Or you can use a bulk request if the resource offers one. Whatever you choose, make the script safe to run twice: if it stops halfway, running it again should finish the job without creating duplicates.

i
Tip

Build every script with a “dry run” mode that only prints what it would do. Review that output before running for real. This one habit prevents most expensive automation accidents.

16Status Codes and Handling Errors

Things go wrong. A good caller reads the status code and responds sensibly to each kind of failure.

The families of status codes

Every response begins with a three-digit number. The first digit tells the family. Numbers starting with 2 mean the request succeeded. Numbers starting with 4 mean the request itself was faulty, so repeating it unchanged will fail again. Numbers starting with 5 mean the service had trouble, so trying again later may work.

CodePlain meaningWhat your code should do
200 or 201Success or createdUse the result
204Success with nothing to returnCarry on, typical after a delete
400The request was malformed or invalidFix the request; do not retry unchanged
401Credential missing or not validCheck the key; alert a human
403Valid credential, but not allowedReview permissions; do not retry
404Thing not foundCheck names and identifiers
409Conflict with current stateReload, merge, then try again
429Too many requestsSlow down and retry after a wait
500, 502, 503, 504The service had a problemRetry with backoff; use defaults meanwhile

Reading the error message

Error responses usually include a short explanation in the body that names the field or rule that caused the problem. Log it. A message such as “this field is required” saves hours of guessing. For SDK calls, remember that an error from Flagsmith should never become an error for your user. Fall back to the safe default and report the problem quietly.

Analogy

If a shop assistant says “we do not stock that item,” asking again will not help. That is a 4 type answer. If they say “the till is broken, please come back in ten minutes,” trying again later is sensible. That is a 5 type answer. Reading the difference prevents both wasted effort and needless giving up.

Do not hide failures

An automation that fails silently is worse than one that fails loudly. If a pipeline step could not turn on a flag, the pipeline should fail, not carry on as if everything were fine. Raise an alert, include the status code and message, and make it easy for a person to see what was not done.

17Rate Limits, Retries, and Backoff

Shared services protect themselves from overload. A polite caller slows down when asked and never hammers a struggling service.

Why limits exist

A service shared by many customers must stop any single caller from using more than a fair share. Limits protect everyone from accidents, such as a script stuck in a loop, and from abuse. The exact limits depend on the plan, the endpoint, and whether you host the service yourself, so check the current documentation and your own plan rather than assuming a number.

What happens when you hit one

When you ask too often, the service answers with the status code meaning “too many requests”. Many services also include a hint about how long to wait. A good client reads that hint, waits at least that long, and then tries again.

Retrying wisely

Retrying is useful for temporary problems and harmful for permanent ones. Retry on server errors, on timeouts, and on “too many requests”. Do not retry on mistakes such as an invalid request or a rejected credential, because the outcome will not change.

Exponential backoff with jitter

Exponential backoff means waiting longer after each failed attempt: for example one second, then two, then four, then eight. Jitter means adding a small random amount to each wait. Without jitter, a thousand clients that all failed at the same moment will all retry at the same moment, and the struggling service is hit by a second wave. With jitter, the retries spread out and the service can recover.

flowchart TD
    A["Send request"] --> B{"Success?"}
    B -->|"Yes"| OK["Use the answer"]
    B -->|"No, temporary problem"| C{"Attempts left?"}
    B -->|"No, permanent problem"| F["Stop and report"]
    C -->|"Yes"| W["Wait longer, plus a random amount"]
    W --> A
    C -->|"No"| D["Use safe default and report"]
    
A patient retry loop: grow the wait, add randomness, and stop after a limited number of tries.
Analogy

Imagine a crowd trying to leave a stadium through a single gate that has jammed. If everyone pushes at once, the jam gets worse. If people step back and try again at slightly different moments, the gate clears. Backoff with jitter is the polite step back.

Setting a budget

Retries must have a limit, both in number and in total time. A flag lookup in the middle of a web request cannot wait thirty seconds. For runtime reads, use a very short timeout and few or no retries, and rely on defaults and caches. Save the patient retry loops for background jobs and automation, where waiting costs little.

!
Warn

Retrying a request that creates something can create it twice. Before retrying a create, check whether the first attempt actually succeeded, or design the request so repeating it is harmless.

18Performance and Scalability of the API

Flag reads sit on the hot path of your product, so the API must be fast and must stay fast as you grow.

Read-heavy by nature

Flags are written rarely and read constantly. A flag may change once a week and be read a hundred million times. Systems with this shape reward caching and copying data close to the reader, and nearly all of the performance story for the SDK API is about making reads cheap.

Where speed comes from

  • A serving layer near the caller. The hosted service keeps a read-optimised copy of each environment in a store at the edge, which shortens the journey.
  • Caching. Repeated reads are answered from a fast cache rather than the main database.
  • Small answers. A list of flags is a compact reply that travels quickly.
  • Local evaluation. The fastest request is the one that never leaves your server.
  • Persistent connections. Reusing one secure connection for many requests saves the cost of setting it up each time.

An example with simple numbers

These numbers are made up to show the idea. Suppose a backend of fifty servers handles ten thousand page views a second, and each page checks four flags. If each check were its own request, the flag service would see forty thousand requests a second. If each page fetched all flags in one call, it would see ten thousand a second. With local evaluation, each of the fifty servers refreshes about once a minute, so the service sees under one request a second. The checks still happen forty thousand times a second, but they are answered from memory.

40,000
checks a second, one request each
10,000
requests a second, one per page
Under 1
requests a second, with local evaluation

Scaling the Admin API

The Admin API sees far less traffic, but heavy automation can still strain it. Spread bulk jobs over time, use filters, and avoid asking for the entire list of identities when you only need one. If you host the service yourself, add more API instances behind a load balancer, add read replicas for the database, and push slow work to background workers.

Usage analytics and its cost

SDKs can report how often each flag is evaluated, which helps you find unused flags. That reporting is sent in batches rather than on every check, so its load is small. If you build your own client on the raw API, you may choose to batch such reports in the same way.

Analogy

A town library with one reference desk gets overwhelmed if every visitor asks the librarian each question. Handing out a printed guide, refreshed every morning, removes nearly all the questions. The librarian can then focus on the rare question that truly needs a fresh answer.

19Reliability: Timeouts, Fallbacks, and Circuit Breakers

The flag service must never become the thing that takes your product down.

Assume it will fail someday

Every network service has bad moments. A well-built application plans for the day when a flag request is slow or fails, and makes sure the effect on users is small or invisible.

Timeouts

Give every flag request a short timeout, often well under a second for runtime reads. A request that waits forever ties up resources and can drag your whole application down with it.

The layers of fallback

  1. Use the live answer if it arrives in time.
  2. If not, use the last good answer from a cache in your own process.
  3. If there is no cached answer, use the safe default written in your code.

Circuit breakers

A circuit breaker is a small piece of logic that stops calling a failing service for a while. After a number of failures, the breaker opens, and calls skip the service and go straight to the fallback. After a pause, the breaker allows a trial request. If it succeeds, normal service resumes. This protects both your application, which stops wasting time, and the flag service, which gets a chance to recover.

stateDiagram-v2
    [*] --> Closed
    Closed --> Open: "Too many failures"
    Open --> HalfOpen: "Wait period ends"
    HalfOpen --> Closed: "Trial request succeeds"
    HalfOpen --> Open: "Trial request fails"
    
A circuit breaker moves between three states so that a failing service gets time to recover.
Analogy

It is exactly like the circuit breaker in a house. When too much current flows, the breaker trips and cuts the power so the wiring does not catch fire. After you fix the cause, you switch it back on and test it. An API circuit breaker cuts off calls to a failing service for the same protective reason.

High availability when self-hosting

If you run the service yourself, make the API highly available. Run several instances in separate zones, put a load balancer with health checks in front, use a database with automatic failover and tested backups, and monitor the whole chain. Because many applications depend on the flag service, it deserves the same care as your most important systems.

i
Tip

Practice the failure. In a staging environment, block the network path to the flag service and watch how your application behaves. If the result surprises you, fix the defaults and fallbacks before production teaches the same lesson.

20Security of the API

An API that controls product behaviour deserves the care you would give to any production control panel.

Use encrypted connections only

Every request must travel over HTTPS, which encrypts the content so that eavesdroppers cannot read keys or data. Refuse any configuration that allows plain, unencrypted requests, especially for the Admin API.

Least privilege

Give each credential only the power it needs. A pipeline that only turns flags on and off in Staging should not be able to delete projects. Use separate credentials for separate jobs, so that a leak in one place has a limited effect.

Protect secrets throughout their lives

  • Keep secrets in a dedicated secrets manager and inject them when the program starts.
  • Never print keys in logs, error messages, or chat messages.
  • Rotate credentials on a schedule and when people leave.
  • Scan your code repositories automatically for accidentally committed keys.
  • Revoke any key you cannot account for.

Client-side keys are public

A client-side environment key can be read by anyone who opens your web page or inspects your app. It is designed for that. It is safe only because it cannot read your full rules or change anything. Never place a server-side key or an Admin credential in front-end code, mobile apps, or public repositories.

Flags are not permissions

A flag fetched through the API tells your application what to show. It does not stop a determined person from calling your own back-end directly. Any action that must be restricted needs a permission check on the server. Use flags to decide what is shown, and use authorisation to decide what is allowed.

API-SEC-01Anti-pattern
The mistake

A team puts a server-side key into a mobile app because “it is easier than building a small back-end service”.

Why it fails

Anyone can unpack the app and read the key. With it they can download your complete targeting rules, including plans, internal groups, and unreleased feature names.

The fix

Use the client-side key in apps, and keep the server-side key on your own servers. If you need server-side power for an app, route the request through a small service you control.

Data minimisation

Send only the traits your rules need. Prefer internal numeric identifiers over email addresses. Remember that anything stored against an identity is data you must be able to delete on request.

Control and review access

Limit who can change Production, use approval workflows for sensitive flags where your plan supports them, and review the list of users and API keys regularly. Keep the audit log enabled and watch it for surprises.

21Monitoring, Logging, and Observability

You cannot fix what you cannot see. Make your use of the API visible.

Measure your calls

For every call to Flagsmith, record how long it took and whether it succeeded. Graph the speed and the failure rate. A creeping increase in response time often warns of trouble long before users notice. Track fallbacks too: every time your code falls back to a default, count it. A sudden rise in fallbacks means something is wrong with the API path.

Measure staleness

If you use local evaluation, record the age of the environment document held in memory. A server that has silently stopped refreshing will serve old rules, and only an age graph will reveal that.

Log what matters, and no more

  • Log: the endpoint, the status code, the duration, and the name of the flag or resource involved.
  • Do not log: keys, tokens, or personal details from traits.
  • Add context: a request identifier that ties a Flagsmith call to the user request that caused it.

Mark changes on your graphs

A flag change is a production change. Use webhooks or integrations to send flag changes to your monitoring tool, so a vertical line appears on your error graph at the moment the flag was flipped. When something breaks, the first question is always “what changed?”, and this makes the answer instant.

What to watchWhy it mattersTypical signal of trouble
Call durationFlag reads sit on the hot pathSlow growth in response time
Failure rateShows service or network problemsRising errors or timeouts
Fallback countShows how often defaults are usedA sudden jump
Document ageShows whether local evaluation refreshesAge far above the refresh interval
Admin changesShows who changed productionChanges at odd hours or by unknown users
Analogy

A car dashboard has a speedometer, a fuel gauge, and a warning light for the engine. You do not wait for the car to stop moving to find out something was wrong. Good monitoring gives your API usage the same kind of dashboard, so problems show up as small warning lights instead of big breakdowns.

22Versions, Documentation, and Staying Compatible

APIs evolve. Knowing how to read the docs and stay compatible keeps your integrations from breaking quietly.

Versions in the address

Web APIs commonly include a version in the path, so that the service can improve without breaking existing callers. Flagsmith’s current main version appears in its paths. When a new version appears, the old one is normally kept for a time, so you can migrate calmly. Always read the release notes of the version you run, especially for a self-hosted installation, where you decide when to upgrade.

Interactive documentation

The API is described in a standard machine-readable format, and the documentation lets you browse every resource, field, and allowed action, and often try requests from the page. For a self-hosted server, the same documentation for your exact version is usually served by the server itself. When you doubt what a field does, the documentation for your version is the authority, ahead of any article, including this one.

Write tolerant clients

Services add new fields to responses over time. A tolerant client ignores fields it does not recognise instead of failing. A strict client that rejects unknown fields will break the day a harmless field is added. Likewise, do not depend on the order of fields or on undocumented behaviour.

Test against upgrades

Before upgrading a self-hosted Flagsmith, run your automated tests and scripts against a staging copy of the new version. Pay attention to changes in authentication, pagination, and the shape of responses. After the upgrade, watch your error rates and fallback counts for unusual changes.

flowchart LR
    R["Read release notes"] --> S["Upgrade a staging copy"]
    S --> T["Run tests and scripts"]
    T --> D{"All healthy?"}
    D -->|"Yes"| P["Upgrade production"]
    D -->|"No"| F["Fix and test again"]
    F --> T
    P --> W["Watch errors and fallbacks"]
    
A safe upgrade path: read, rehearse, verify, then upgrade, and keep watching afterwards.
i
Note

Details in this guide, such as exact paths, header formats, and field names, can change between versions. Treat the documentation for your own version as the final word, and use this guide to understand the ideas.

23The API or an SDK? Making the Choice

Most of the time an SDK is the right tool. Sometimes calling the API directly is better.

What an SDK adds

An SDK, or software development kit, wraps the API in friendly functions for a particular language. It handles building requests, reading responses, caching, default values, local evaluation, and sometimes background refreshing and retries. It saves effort and avoids many mistakes.

When the raw API is the better choice

  • No SDK exists for your language or platform.
  • You are writing a small script, such as a one-off report or a cleanup task.
  • You need an Admin API feature that the SDK does not expose, which is the usual case, since SDKs focus on reading flags.
  • You are building your own tool, such as a chat bot that flips flags or a dashboard that shows flag status.
SituationBest choiceReason
Application reading flags at runtimeSDKCaching, defaults, and local evaluation built in
Busy backend serviceSDK in local modeNear-instant checks with minimal load
Pipeline creating and flipping flagsAdmin APISDKs do not manage resources
Language without an SDKSDK API directlyNothing else is available
Reporting and cleanup scriptsAdmin APINeeds lists, filters, and audit data

Keep your own thin layer

Whatever you choose, put a small layer of your own between your application code and Flagsmith, with a simple method such as “is this feature enabled for this user”. This keeps defaults, logging, and error handling in one place. It also makes it easier to change tools later, or to adopt the OpenFeature standard, which defines a vendor-neutral way to ask for flags and has providers that connect it to Flagsmith.

Analogy

You could build a table from raw wood using only a saw and nails, or use a ready-made kit with all the parts cut and labelled. The kit is quicker and safer for the usual table. But if you want a very unusual shape, you go back to the saw. SDKs are the kit, and the raw API is the saw.

24Automating with the Admin API

The real prize of the Admin API is doing automatically what would otherwise be slow, repetitive, and easy to get wrong.

Pipelines

A delivery pipeline can call the Admin API at several points. It can create the flag a new feature needs, enable it in test environments after a build passes, and check that production flags have owners before a release. Because the pipeline records what it did, you gain an automatic history alongside the audit log.

Infrastructure as code

Some teams describe their flags, segments, and environments in files kept under version control and apply them with a tool, so that the setup can be reviewed, repeated, and rebuilt. A community or vendor-supported provider for popular infrastructure tools exists for Flagsmith, which lets you manage resources this way. Check the current documentation for what is supported. The benefit is that changes go through code review, like any other change.

Chat-based operations

A small chat bot can call the Admin API to answer questions such as “is the new checkout on in production?” or to flip a flag after the right person confirms. This puts the controls where the team already talks. Keep it safe by requiring approval for production changes, restricting who may use it, and logging every command.

Hygiene jobs

Scheduled jobs can keep the flag list tidy. One job lists flags older than a chosen age and posts them to the owning team. Another finds flags that are on for everybody and have been for months, which are candidates for removal. Another reports identity overrides that were created long ago. These small jobs prevent the slow build-up of clutter.

flowchart LR
    SCHED["Scheduler"] --> JOB["Hygiene job"]
    JOB -->|"List features and ages"| ADMIN["Admin API"]
    ADMIN --> JOB
    JOB --> REP["Report of old or unowned flags"]
    REP --> CHAT["Team chat or ticket"]
    
A scheduled job that reads from the Admin API and tells people which flags need attention.

Rules for safe automation

  • Use a dedicated credential with the least power needed, never a person’s token.
  • Provide a dry-run mode and read its output before the first real run.
  • Make scripts safe to run twice.
  • Fail loudly and alert a human on errors.
  • Respect rate limits and use backoff.
  • Keep scripts in version control and review changes to them.
  • Record what was changed and why, in the tool’s own log or in a ticket.

Everyday use case: the Monday flag report

Every Monday a scheduled job reads the list of features, finds those older than ninety days with no recent changes, and posts them to the team chat grouped by owner. Owners reply with “keep” or “remove”. Within a quarter, the number of stale flags falls sharply, and nobody had to remember to check.

25Design Patterns for Using the API

A handful of proven shapes cover most real integrations.

Pattern 1: Decide at the edge, pass it along

In a system of many small services, the first service to receive a request asks for the flags once and passes the decision to the others in the request context. This keeps every service consistent for the same user, and saves repeated calls. Analogy: a relay race where one baton is handed from runner to runner, rather than each runner picking up a new one.

Pattern 2: A flag service wrapper

All application code asks one small internal module, “is this enabled for this user”, and only that module talks to Flagsmith. Defaults, logging, caching, and error handling live there. Analogy: a hotel concierge who deals with every outside company so that guests never have to.

Pattern 3: Local evaluation for busy servers

High-traffic backends download the environment document, refresh it on a schedule, and answer every check from memory. Analogy: a printed rulebook refreshed each morning rather than a phone call for every question.

Pattern 4: A backend-for-frontend

For web and mobile apps, a small back-end service asks Flagsmith with a server-side key and returns only the flags the app needs. The app never holds a powerful key and never sees the full rules. Analogy: a waiter who reads the kitchen’s rulebook and tells you only what you may order.

Pattern 5: Server-side rendering with flags

A web server fetches the flags before drawing a page and sends them with the page, so the user never sees a flicker between the old and new designs. Analogy: setting the stage before the curtain opens, instead of rearranging furniture while the audience watches.

Pattern 6: Reconcile on a schedule

A scheduled job compares the flags in the project with the flags actually referenced in your code and reports any that exist in only one of them. Analogy: a stock-take that compares the shelf with the inventory list.

flowchart LR
    APP["Mobile or Web App"] -->|"Ask for needed flags"| BFF["Your Back-End Service"]
    BFF -->|"Server key, local evaluation"| FS["Flagsmith"]
    BFF --> APP
    
The app talks to your own service, which holds the powerful key and returns only what the app needs.

Choosing a pattern

Start with the simplest pattern that fits: an SDK with a wrapper. Add local evaluation when traffic grows. Add a back-end-for-frontend when you need to protect rules or reduce what apps hold. Add edge decisions when many services must agree. Complexity should arrive only when a real need arrives.

26Anti-Patterns and Common Mistakes

These are the traps that catch teams over and over. Learn them once and save yourself the pain.

API-01Anti-pattern
One request per flag check

Code that sends a separate request for each flag, on each page, creates enormous traffic and slows every page.

The fix

Fetch all flags once per request or use local evaluation, then read from memory.

API-02Anti-pattern
No timeout and no default

A flag request with no time limit and no fallback turns a small service delay into a full application outage.

The fix

Always set a short timeout and a safe default, and test the failure path on purpose.

API-03Anti-pattern
Admin credentials in the wrong place

A powerful token pasted into a build file, a chat, or a public repository can let a stranger change production.

The fix

Use a secrets manager, narrow permissions, and rotation. Revoke anything that has been exposed.

API-04Anti-pattern
Reading only the first page

A script that does not follow the next-page link sees only part of the list and makes wrong decisions, such as deleting flags it believes are unused.

The fix

Always loop until there is no next page, and compare totals.

API-05Anti-pattern
Retrying blindly

Retrying immediately and forever, or retrying errors that cannot succeed, adds load to a struggling service and delays real fixes.

The fix

Retry only temporary failures, with growing waits, random jitter, and a limit.

More mistakes to avoid

  • Using the wrong key kind. A client-side key cannot fetch the environment document, and a server-side key must never be public.
  • Mixing up environments. Pointing a test app at the Production key is a classic way to flip real flags by accident.
  • Trusting a flag for security. A flag hides a button. It does not lock the door behind it.
  • Letting local evaluation go stale unnoticed. Track the age of the document and alert on it.
  • Running scripts without a dry run. A bulk change that runs for the first time in Production is a gamble.
  • Hard-coding addresses. The base address belongs in configuration, so you can switch between hosted and self-hosted or between regions.
  • Ignoring unknown fields. Strict parsing that fails on new fields breaks on harmless upgrades.

27Best Practices Checklist

If you remember only a few pages of this guide, make them these.

Keys

Right key, right place

Client keys in apps, server keys on servers, Admin credentials only in secrets managers.

Keys

One key per use

Separate credentials per environment and per application, so a leak has a small reach.

Reliability

Timeout plus default

Every runtime flag read has a short timeout and a safe fallback.

Speed

Read once, use many times

Fetch all flags together, or use local evaluation on busy servers.

Errors

React to the code

Retry temporary failures with backoff and jitter. Fix and report permanent ones.

Lists

Follow every page

Loop until there is no next page, and use filters to ask for less.

Automation

Dry run first

Print what would change, review it, then apply, and make scripts safe to repeat.

Visibility

Watch and mark

Graph call speed, failures, and fallbacks, and mark flag changes on your charts.

Privacy

Send the minimum

Use internal IDs and simple categories, never sensitive personal details.

Structure

One thin wrapper

Keep all Flagsmith calls behind a small module of your own.

Upgrades

Rehearse in staging

Test scripts and apps against a new version before upgrading production.

Hygiene

Automate the clean-up

Scheduled reports on old flags and old overrides keep clutter from growing.

The best API call is the one you did not need to make, and the second best is the one you can safely repeat.

A starter routine

If you are new to the Flagsmith API, begin in a test project. Read flags with an environment key, then send an identity with a trait and watch the answer change. Next, use an Admin credential to create a flag and flip it, and read the audit log entry that appears. Finally, write a small dry-run script that lists your features and their ages. In an afternoon you will have touched every important idea in this guide.

28Real-World Usage Scenarios

Common ways teams use the two APIs together. These are general practices, not claims about any named customer.

A safe payment-provider switch

An online store replaces its payment provider. A pipeline creates a flag through the Admin API, and the checkout code reads it through the SDK API. Staff go first, then one percent of customers, then more, with the rollout steps applied by a script at agreed times. When error graphs stay flat, the last step turns the flag on for everyone, and a cleanup job later removes the flag.

Support tools that unlock features

A support agent uses an internal tool to give one customer early access to a feature. Behind the tool, a small service calls the Admin API to create an identity override for that customer. Each use is logged, and a weekly job lists overrides older than thirty days for review.

Mobile apps and old versions

A travel app sends its version number as a trait on every identities request. A segment matches version six and above, and the new booking screen is attached to that segment. Users on older versions never see a screen their app cannot draw.

A busy backend with local evaluation

A video service runs hundreds of servers. Each downloads the environment document once a minute and answers all flag checks in memory. During a traffic spike, an engineer turns off a heavy recommendation row with one Admin API call from a chat bot, and within a minute every server has the new rules, while the rest of the experience carries on.

Compliance reporting

A regulated company copies the audit log through the Admin API into its own long-term storage every night. Auditors can see who changed which flag, and when, without needing access to the Flagsmith dashboard.

Environment cloning for new teams

When a new team joins, a script creates a project with the standard environments, copies the agreed segments, and creates the common flags with default states. What took half a day of clicking now takes minutes and is the same every time.

Analogy

In all of these stories there are two sets of people. Visitors come and ask quick questions at the front desk, and staff work in the back office changing the rules. The two APIs let both groups do their jobs at once, without getting in each other’s way.

29Advantages, Disadvantages, and Trade-offs

A fair look at what the API design gives you and what it asks of you.

Advantages

  • Everything the dashboard does can be automated.
  • A clear split between a fast read API and a powerful management API.
  • Two kinds of environment keys, so apps hold safe, limited credentials.
  • Local evaluation removes nearly all runtime network traffic on servers.
  • Standard REST and JSON work from any language.
  • Interactive documentation for the exact version you run.
  • Audit logs and webhooks give visibility into changes.
  • Open source, so self-hosting keeps data and traffic in your control.

Disadvantages

  • Two APIs and several credentials to learn and protect.
  • Powerful credentials are a serious risk if mishandled.
  • Local evaluation trades freshness for speed.
  • Rate limits and retries need careful handling in automation.
  • Self-hosting makes you responsible for uptime, scaling, and upgrades.
  • Details can change between versions, so scripts need testing on upgrades.
  • Raw API use means writing your own caching, defaults, and error handling.

The main trade-offs, in plain words

ChoiceYou gainYou give up
Local evaluationSpeed and tiny loadInstant freshness; rules sit in server memory
Remote evaluationLatest answers, rules stay privateA network trip for each check
SDKConvenience and safetySome control and Admin features
Raw APIFull controlYou build caching and error handling
Hosted serviceLittle operating effortSome control over hosting details
Self-hostedFull control of data and networkYou run and secure it

30Troubleshooting Guide

When something looks wrong, work through the cause by symptom.

SymptomLikely causeWhat to check
Every request is rejected as unauthorisedWrong, missing, or revoked credentialHeader name and spelling, key for the right environment, whether the key was rotated
Request is refused as forbiddenValid credential without permissionRole of the user or key, and the action attempted
Flags return but segment rules never applyNo identity was sentUse the identities request, not the environment-level one
Segment rule does not matchTrait missing, misspelled, or wrong typeTrait name and case, and number versus text
Change in dashboard not visible in the appCaching or refresh intervalLocal evaluation refresh time, app caches, and the environment used
Fetching the environment document failsClient-side key in useUse a server-side key for that request
List seems incompleteOnly the first page was readFollow next-page links to the end
Requests suddenly rejected for volumeRate limit reachedRequest rate, retry loops, and batching; add backoff with jitter
Slow flag lookupsNetwork trip per check or no connection reuseUse local evaluation, caching, and persistent connections
Flag exists but code gets the defaultName mismatch or wrong environmentExact name, environment key, and logs of fallbacks
Webhook receiver not triggeredWrong address or blocked network pathWebhook address, firewall rules, and delivery history

A calm routine for any problem

1

Check what changed

Read the audit log and recent deployments before looking anywhere else.

2

Read the status code

The first digit tells you whether the fault is with the request or with the service.

3

Confirm the basics

Right address, right key, right environment, right identity.

4

Reproduce in isolation

Make the same request from a simple tool, outside your application, to see if it behaves the same way.

5

Fix, then add a guard

Once fixed, add a log, an alert, or a test so the same problem is caught earlier next time.

31A Worked Walkthrough: One Feature from Idea to Launch

Let us follow a single feature through both APIs, step by step, to see how all the pieces fit together.

Imagine a team building a new “saved carts” feature for an online store. The team wants to release it safely, to a few customers first. Here is how the two APIs help at each stage.

Step 1: Create the flag with the Admin API

When the developer opens the pull request, a pipeline step calls the Admin API with a pipeline credential. It asks for the features of the project, finds that no flag called “saved-carts” exists, and creates one with a description, an owner tag, and an initial state of off. The reply carries the new feature’s identifying number, which the pipeline records in the pull request comments.

Step 2: Read the flag with the SDK API

The new code reads the flag through the SDK, using the server-side key and local evaluation. The code asks “is saved carts enabled for this customer?” and, if the answer is missing for any reason, defaults to off. Because the flag is off everywhere, merging the code changes nothing for customers.

Step 3: Turn it on for testing

After the build passes, the pipeline calls the Admin API to change the feature state of “saved-carts” to on in the Development and Staging environments. Testers now see the feature. Production is untouched, since it has its own feature state.

Step 4: Target staff and a beta group

A product manager creates a segment for staff using a trait that marks employees, and a second segment for customers who joined the beta programme. Segment overrides turn the flag on for both groups in Production. The application already sends the customer number and these traits with the identities request, so the rules apply at once.

Step 5: A gradual rollout

The team adds a percentage rule, starting at one percent of all customers. Each time they widen the audience, they update the rule through the Admin API, on a schedule agreed in advance. A webhook posts each change to the team chat, and the monitoring tool marks each change on the error graph.

Step 6: A problem appears, and is solved quickly

At ten percent, the error graph rises for customers using a certain older app version. The on-call engineer uses the chat bot, which calls the Admin API, to turn the flag off in Production. Within about a minute, every server has refreshed its document and the errors stop. The team adds a rule using the app version trait so that only versions able to handle the feature receive it, and resumes the rollout.

Step 7: Launch and clean up

At one hundred percent, the team waits a week. Then a cleanup task confirms through the audit log and the usage reports that the flag is on for everyone, and removes the flag and the old code path. The code ends up simpler than before.

sequenceDiagram
    participant Dev as Developer Pipeline
    participant Admin as Admin API
    participant App as Application Servers
    participant SDK as SDK API
    participant Team as Team Chat
    Dev->>Admin: Create flag and add owner
    App->>SDK: Download environment document
    Dev->>Admin: Enable in Development and Staging
    Dev->>Admin: Add segment overrides and one percent rule
    Admin->>Team: Webhook announces each change
    App->>SDK: Refresh document each minute
    Dev->>Admin: Widen rollout, or switch off if needed
    Dev->>Admin: Delete flag after launch
    
One feature’s life: the Admin API changes the rules, and the SDK API delivers them to running applications.
Analogy

Think of opening a new ride at a theme park. Engineers prepare it behind a fence, staff test it, a small group of guests try it, and the queue is opened slowly to everyone. If a fault appears, the operator presses a stop button and the ride halts at once. The Admin API is the control room with the buttons, and the SDK API is the loudspeaker that tells every gate what to do.

32A Production-Readiness Checklist for API Use

Before you depend on the Flagsmith API in production, walk through these questions with your team.

AreaQuestion to answerA good answer sounds like
KeysWhere does each key live, and who can read it?Secrets are in a manager, and client-side keys are the only ones in front-end code
EnvironmentsCould a test app reach production flags?Each environment has its own keys, and apps load the right one from configuration
DefaultsWhat does every flag do when no answer arrives?Each flag has a safe default, tested by cutting the network on purpose
TimeoutsHow long may a flag read wait?A short, deliberate timeout with a cached fallback
SpeedHow many requests will we send at peak?We read once per request or use local evaluation, and we have estimated the numbers
FreshnessHow old may our answers get?We know the refresh interval, and critical flags refresh faster
ErrorsWhich failures do we retry?Only temporary ones, with backoff, jitter, and a limit
AutomationCan a script harm production?Narrow credentials, dry runs, safe repeats, and loud failures
VisibilityWill we notice a problem quickly?We graph call speed, failures, fallbacks, and document age, and mark flag changes
PrivacyWhat personal data do we send?Only internal IDs and simple categories, with a way to delete an identity
GovernanceWho may change production flags?A named small group, with approvals for sensitive flags and the audit log enabled
RecoveryIf we self-host, can we restore it?Backups exist, and the restore has been tested
UpgradesHow will we test a new version?We rehearse scripts and apps against a staging copy first

How to use the checklist

Hold a short review meeting before your first production launch, and again each time your use grows in a major way. Go through each row and ask for a real answer, not a hope. Any row where the team shrugs is a row where something will eventually go wrong. Write down the gaps, give each an owner, and fix the most dangerous first.

i
Tip

Turn the checklist into a standing agenda item for your regular flag review. Teams that look at their API usage together every few months catch drifting keys, forgotten overrides, and silent refresh failures before any of them cause an incident.

33Glossary of Terms

Every important word in this guide, in one place.

TermMeaning
APIAn agreed set of requests and replies that lets one program talk to another.
SDK APIThe Flagsmith API your applications call to read flags and identity data.
Admin APIThe Flagsmith API used to create, change, and delete resources; used by the dashboard and by automation.
Edge APIA globally distributed serving layer that answers flag reads near the caller.
RESTA style of web API in which each kind of thing has its own address and a few verbs act on it.
JSONA simple text format for sending structured data.
HeaderA labelled note sent along with a request or response, such as the one that carries a credential.
Status codeA three-digit number summarising the result of a request.
Environment keyThe credential used with the SDK API to identify one environment.
Client-side keyA public environment key safe to place in browsers and apps.
Server-side keyA secret environment key that can read full rules; for servers only.
User tokenAn Admin API credential that acts with one person’s permissions.
Organisation API keyAn Admin API credential meant for automation, not tied to one person.
IdentityA unique ID representing one user, device, or account.
TraitA fact about an identity, used by segment rules.
SegmentA saved group of identities defined by rules over traits.
FeatureThe definition of a flag or config value, shared by all environments of a project.
Feature stateHow a feature behaves in one environment: its on/off setting and value.
Environment documentThe full configuration of an environment, downloaded for local evaluation.
Local evaluationAnswering flag checks inside your own server from a downloaded document.
PaginationSplitting a long list into pages that are fetched one at a time.
Rate limitA cap on how many requests a caller may make in a period.
Exponential backoffWaiting longer after each failed attempt before retrying.
JitterA small random amount added to waits so that many clients do not retry together.
Circuit breakerLogic that stops calling a failing service for a while to let it recover.
WebhookAn automatic message sent to an address you choose when something happens.
Audit logA record of who changed what and when.
OpenFeatureAn open standard that defines a vendor-neutral way to ask for flags.

34Frequently Asked Questions

Q1Is the Flagsmith API free to use?
The core platform is open source, so self-hosting has no license fee for the core. On the hosted service, limits and pricing depend on your plan. Check the current plan details, because they change.
Q2What is the difference between the SDK API and the Admin API?
The SDK API is for your running applications to read flags. The Admin API is for people and automation to create and manage flags, segments, and more. They use different credentials and have very different levels of power.
Q3Which key should I put in my website or mobile app?
The client-side environment key. It is designed to be public and cannot read your full rules or change anything. Never place a server-side key or an Admin credential there.
Q4Do I need an SDK, or can I call the API directly?
For application code, an SDK is usually best because it brings caching, defaults, and local evaluation. For automation, scripts, and unusual languages, calling the API directly is perfectly reasonable.
Q5Why do my segment rules not apply?
The usual causes are that no identity was sent, a trait is missing or misspelled, or a number was sent as text. Use the identities request and check trait names, case, and types.
Q6How quickly do changes reach my application?
With remote evaluation, the next request sees the change, subject to any caches. With local evaluation, the change appears at the next refresh of the document, commonly within about a minute by default. Check your SDK for options.
Q7What happens if Flagsmith is unreachable?
Your application should use the last cached answer, or the safe default written in your code. With local evaluation, the last downloaded rules keep working until the network returns.
Q8Can I change flags from a script or pipeline?
Yes. Use the Admin API with a dedicated, narrowly scoped credential. Add a dry-run mode, make the script safe to repeat, and alert on failures.
Q9How do I handle rate limits?
Read the status code for too many requests, wait at least as long as any hint says, then retry with growing waits and random jitter. Reduce your request volume with batching, filters, and local evaluation.
Q10Why did my script see only some of my flags?
List requests are paged. Follow the link to the next page until there is none, and compare the total count with what you collected.
Q11Is it safe to store traits about my users?
It is safe if you send only what you need, use internal identifiers instead of emails or names, avoid sensitive details, and have a way to delete an identity on request.
Q12How do I find the exact paths and fields for my version?
Use the interactive API documentation. For a self-hosted server, it is usually served by the server itself, matching the exact version you run. It is the final authority on paths, headers, and fields.
Q13Can I switch from the hosted service to self-hosting later?
Yes, because the API shape is the same. Keep the base address and keys in configuration, and keep your Flagsmith calls behind a thin wrapper, and the move becomes mostly a configuration change plus a data migration.
Q14Should I use flags to protect sensitive features?
Use flags to decide what is shown, but enforce real permissions on the server. A flag controls display, not access.

35Summary and Key Takeaways

The Flagsmith API is the foundation under every flag, every rule, and every dashboard click. It is split into two parts with two audiences: a fast, read-focused SDK API for your running applications, and a broad, powerful Admin API for people and automation. Learn the split, keep the keys in the right places, plan for failure, and automate carefully, and the API becomes one of your strongest tools for shipping safely.

Key Takeaways

  • Two APIs: the SDK API reads flags for applications; the Admin API manages everything and is used by the dashboard and by automation.
  • Keys decide power: client-side keys are public and limited, server-side keys are secret and read full rules, and Admin credentials can change production.
  • Identities unlock targeting: send a stable identifier and a few well-chosen traits to get personalised answers; without an identity, everyone gets the same default.
  • Speed comes from not asking: fetch flags together, cache, and use local evaluation on busy servers, accepting a short refresh delay.
  • Plan for failure: use short timeouts, layered fallbacks, safe defaults, circuit breakers, and retries with backoff and jitter.
  • Automate safely: least-privilege credentials, dry runs, safe repeats, loud failures, and respect for rate limits and pagination.
  • Stay secure and visible: use HTTPS, protect and rotate secrets, send minimal data, watch call speed and fallbacks, and mark every flag change on your graphs.