API reference
Flags
Create, read, update and delete feature flags.
The object flag
Attributes
keystring- Unique, URL-safe identifier used in code.
typeenumboolean,string,numberorjson.variationsarray- Possible values, in order.
environmentsobject- Per-environment state, rules and rollout.
permanentboolean- Excluded from stale-flag reports.
JSON
{
"key": "new-checkout",
"name": "New checkout",
"type": "boolean",
"variations": [true, false],
"permanent": false,
"tags": ["payments"],
"environments": {
"production": { "on": true, "rollout": { "percent": 25 } },
"development": { "on": true }
},
"createdAt": "2026-08-02T10:14:00Z"
}List flags
GET
/projects/{project}/flagsReturns flags in a project, newest first.
Headers
AuthorizationstringrequiredBearer <token>
Path parameters
projectstringrequired- Project id, e.g.
prj_8d2kq.
Query parameters
tagstringoptional- Only flags with this tag.
stalebooleanoptional- Only stale flags.
limitintegeroptionalDefault:20- Page size, 1–100.
cursorstringoptional- Cursor from a previous response.
Request
Terminal
curl https://api.shoal.dev/v2/projects/prj_8d2kq/flags?limit=2 \
-H "Authorization: Bearer $SHOAL_TOKEN"TypeScript
import { Shoal } from "@shoal/api";
const api = new Shoal(process.env.SHOAL_TOKEN);
const { data, next } = await api.flags.list("prj_8d2kq", { limit: 2 });Python
from shoal import Shoal
api = Shoal(os.environ["SHOAL_TOKEN"])
page = api.flags.list("prj_8d2kq", limit=2)Response
JSON
{
"data": [
{ "key": "new-checkout", "type": "boolean", "permanent": false },
{ "key": "upload-limit-mb", "type": "number", "permanent": true }
],
"next": "cur_9f2a"
}JSON
{
"error": { "code": "unauthorized", "message": "Invalid API token" }
}Create a flag
POST
/projects/{project}/flagsCreates a flag in every environment, switched off.
Headers
AuthorizationstringrequiredBearer <token>
Path parameters
projectstringrequired- Project id, e.g.
prj_8d2kq.
Body parameters
keystringrequired- Lowercase letters, numbers and dashes.
typeenumrequiredboolean,string,numberorjson.variationsarrayoptional- Required for non-boolean flags.
tagsstring[]optional- Free-form labels.
Request
Terminal
curl -X POST https://api.shoal.dev/v2/projects/prj_8d2kq/flags \
-H "Authorization: Bearer $SHOAL_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "key": "new-checkout", "type": "boolean", "tags": ["payments"] }'TypeScript
const flag = await api.flags.create("prj_8d2kq", {
key: "new-checkout",
type: "boolean",
tags: ["payments"],
});Python
flag = api.flags.create("prj_8d2kq", key="new-checkout", type="boolean", tags=["payments"])Response
JSON
{
"key": "new-checkout",
"name": "New checkout",
"type": "boolean",
"variations": [true, false],
"permanent": false,
"tags": ["payments"],
"environments": {
"production": { "on": true, "rollout": { "percent": 25 } },
"development": { "on": true }
},
"createdAt": "2026-08-02T10:14:00Z"
}JSON
{
"error": { "code": "flag_exists", "message": "A flag with key new-checkout already exists" }
}Update a flag
PATCH
/projects/{project}/flags/{key}Changes state, rules or rollout in one environment. Fields you omit stay unchanged.
Headers
AuthorizationstringrequiredBearer <token>
Path parameters
projectstringrequired- Project id, e.g.
prj_8d2kq. keystringrequired- The flag key.
Body parameters
environmentstringrequired- Environment key, e.g.
production. onbooleanoptional- Turn the flag on or off.
rollout.percentnumberoptional- 0–100 share of users served the first variation.
commentstringoptional- Shown in the audit log. Required for protected environments.
Request
Terminal
curl -X PATCH https://api.shoal.dev/v2/projects/prj_8d2kq/flags/new-checkout \
-H "Authorization: Bearer $SHOAL_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "environment": "production", "rollout": { "percent": 50 }, "comment": "Ramp to 50%" }'TypeScript
await api.flags.update("prj_8d2kq", "new-checkout", {
environment: "production",
rollout: { percent: 50 },
comment: "Ramp to 50%",
});Python
api.flags.update("prj_8d2kq", "new-checkout", environment="production", rollout={"percent": 50}, comment="Ramp to 50%")Response
JSON
{
"key": "new-checkout",
"name": "New checkout",
"type": "boolean",
"variations": [true, false],
"permanent": false,
"tags": ["payments"],
"environments": {
"production": { "on": true, "rollout": { "percent": 50 } },
"development": { "on": true }
},
"createdAt": "2026-08-02T10:14:00Z"
}Delete a flag
DELETE
/projects/{project}/flags/{key}Deletes the flag in every environment. SDKs serve the fallback afterwards.
Headers
AuthorizationstringrequiredBearer <token>
Path parameters
projectstringrequired- Project id, e.g.
prj_8d2kq. keystringrequired- The flag key.
Request
Terminal
curl -X DELETE https://api.shoal.dev/v2/projects/prj_8d2kq/flags/new-checkout \
-H "Authorization: Bearer $SHOAL_TOKEN"TypeScript
await api.flags.delete("prj_8d2kq", "new-checkout");Python
api.flags.delete("prj_8d2kq", "new-checkout")Response
— No Content —