Quickstart
From nothing to a resolved variable. This walks through the API; everything here can also be done in the management UI.
Before you start
You need an account in an organization, and that account needs to be in a group carrying at least:
TagGroupCreate,TagCreate— to define the dimensionsVariableCreate,VariableRead,VariableList— to create and read variablesProfileCreateApiKey— if you want a machine token rather than signing in
If you do not have these yet, someone holding GroupUpdate and the permissions themselves can grant them. See
Managing access.
1. Get a token
As a person
Sign in through the auth UI at your organization's login URL. Your browser receives the JWT as an
x-tagshape-auth cookie, and the management UI uses it from there.
As a machine
Create an API key from your profile page, or by API:
curl -X POST "$ACCOUNT_API/users/me/apikeys" \
-H "x-tagshape-auth: $JWT" \
-H "Content-Type: application/json" \
-d '{"description": "quickstart", "expiry": "OneDay"}'
{
"apiKey": "ts_...",
"hint": "ts_a",
"description": "quickstart",
"createdAt": "2026-08-14T09:00:00Z",
"expiresAt": "2026-08-15T09:00:00Z"
}
apiKey is returned exactly once. Only its hash is stored, so this response cannot be asked for again. If you
lose it, delete the key and make another.
Exchange it for a JWT. The key goes in a header, and the token comes back in one:
curl -i -X POST "$IDENTITY_API/apikeyjwt" \
-H "x-tagshape-api: ts_..."
HTTP/1.1 200 OK
x-tagshape-auth: eyJhbGciOiJSUzI1NiIs...
That JWT carries the same claims a signed-in person's would. Use it in x-tagshape-auth on every request below.
2. Define your dimensions
A tag group is a dimension; the tags in it are the values it can take.
curl -X POST "$LIBRARY_API/taggroups" \
-H "x-tagshape-auth: $JWT" \
-H "Content-Type: application/json" \
-d '{"name": "Environment", "description": "Where the code is running"}'
Then add tags to it:
curl -X POST "$LIBRARY_API/tags" \
-H "x-tagshape-auth: $JWT" \
-H "Content-Type: application/json" \
-d '{"name": "Production", "tagGroupId": 1}'
Repeat for Staging. Add a second group — Region, with EU and US — if you want to see multi-dimensional
resolution work.
3. Create a library set
A library set is what a consumer fetches as a unit.
curl -X POST "$LIBRARY_API/variablesets" \
-H "x-tagshape-auth: $JWT" \
-H "Content-Type: application/json" \
-d '{"name": "orders-service", "description": "Config for the orders service"}'
4. Add a variable with tagged values
One variable, three values: a default, one for production, and one for production in the EU.
curl -X POST "$LIBRARY_API/variables" \
-H "x-tagshape-auth: $JWT" \
-H "Content-Type: application/json" \
-d '{
"name": "DatabaseConnection",
"variableSetId": 1,
"values": [
{ "value": "Server=localhost;Database=orders", "tags": [] },
{ "value": "Server=prod.internal;Database=orders", "tags": ["Environment/Production"] },
{ "value": "Server=eu-prod.internal;Database=orders", "tags": ["Environment/Production", "Region/EU"] }
]
}'
5. Resolve it
Ask for the set, with the tags describing where you are:
curl "$LIBRARY_API/variablevalues?set=1&tag=Environment/Production&tag=Region/EU" \
-H "x-tagshape-auth: $JWT"
{
"total": 1,
"items": {
"DatabaseConnection": "Server=eu-prod.internal;Database=orders"
}
}
Change the tags and the answer changes:
| Tags asked for | Value returned |
|---|---|
Environment/Production, Region/EU | Server=eu-prod.internal;Database=orders |
Environment/Production, Region/US | Server=prod.internal;Database=orders |
Environment/Staging | Server=localhost;Database=orders |
| (none) | Server=localhost;Database=orders |
The exact match wins where there is one; otherwise the best partial match wins; otherwise the untagged default. Resolution sets out the rule properly.
6. See why
When a value comes back and you are not sure which one it was, ask the preview endpoint instead. It runs the same resolution and returns the whole winning value — its tags, whether it is sensitive, and its hint:
curl "$LIBRARY_API/variablevalues/preview?set=1&tag=Environment/Production&tag=Region/EU" \
-H "x-tagshape-auth: $JWT"
Next steps
- Consuming variables — wiring this into a deployment
- Importing a library — bringing a whole library in as one file
- Sensitive values — how secrets are stored and withheld
- API permissions — what each call above required