Skip to content
Shoal
Shoal

API reference

Flags

Create, read, update and delete feature flags.

The object flag

Attributes

keystring
Unique, URL-safe identifier used in code.
typeenum
boolean, string, number or json.
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}/flags

Returns flags in a project, newest first.

Headers

Authorizationstringrequired
Bearer <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}/flags

Creates a flag in every environment, switched off.

Headers

Authorizationstringrequired
Bearer <token>

Path parameters

projectstringrequired
Project id, e.g. prj_8d2kq.

Body parameters

keystringrequired
Lowercase letters, numbers and dashes.
typeenumrequired
boolean, string, number or json.
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

Authorizationstringrequired
Bearer <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

Authorizationstringrequired
Bearer <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 —

Type to search. Results come from a local index — nothing leaves your browser.

↑ ↓ to navigate↵ to openMiniSearch · local