Profiles API
Steering profile management at /api/profiles. Profiles store a named steering configuration (feature → strength map) plus the model/SAE context it was built for. See Profiles for concepts and the per-request usage pattern.
List / get
curl http://localhost:8000/api/profiles # all profiles
curl http://localhost:8000/api/profiles/active # currently active profile (or null)
curl http://localhost:8000/api/profiles/prof_1a2b3c
{
"id": "prof_1a2b3c4d5e6f",
"name": "dogs-40",
"description": "GemmaScope L12/16k feature 12082 @ 40",
"model_id": "google/gemma-2-2b",
"sae_id": "sae_a1b2c3...",
"layer": 12,
"steering": {"12082": 40.0},
"is_active": false,
"created_at": "2026-07-11T12:40:00Z",
"updated_at": "2026-07-11T12:40:00Z"
}
Note: steering keys are stringified feature indices (JSON object keys are strings).
Create
curl -X POST http://localhost:8000/api/profiles \
-H "Content-Type: application/json" \
-d '{
"name": "dogs-40",
"description": "dogs feature at moderate strength",
"steering": {"12082": 40.0, "4517": -10.0},
"sae_id": null, "model_id": null, "layer": null
}'
Names must be unique (409 PROFILE_ALREADY_EXISTS). An empty steering map is valid — activating such a profile is a supported way to switch to a clean unsteered state.
Save the current steering as a profile
curl -X POST http://localhost:8000/api/profiles/save-current \
-H "Content-Type: application/json" \
-d '{"name": "session-2026-07-11", "description": "whatever is dialed in right now"}'
Captures the live steering values plus the attached SAE/layer context. Requires an attached SAE.
Update
curl -X PATCH http://localhost:8000/api/profiles/prof_1a2b3c \
-H "Content-Type: application/json" \
-d '{"steering": {"12082": 55.0}}'
Partial updates (PATCH); steering, when provided, replaces the map.
Activate / deactivate
curl -X POST http://localhost:8000/api/profiles/prof_1a2b3c/activate
curl -X POST http://localhost:8000/api/profiles/prof_1a2b3c/deactivate
Activation replaces the current steering values with the profile's and enables steering:
- Requires an attached SAE when the profile has steering values (
400 SAE_NOT_ATTACHEDotherwise) - Indices are validated against the attached SAE first — out-of-range indices fail with
400BEFORE any live steering is touched (nothing is partially applied). Values are scaled by the profile's intensity (λ) and clamped to ±200 at apply time - Activating an empty-steering profile clears existing steering
- Deactivation (optionally
?clear_steering=false) clears the steering values by default
Per-request activation
Any saved profile can be applied for a single chat-completion request via the profile parameter on POST /v1/chat/completions — no global state change, previous steering restored afterwards.
Export / import
curl http://localhost:8000/api/profiles/prof_1a2b3c/export > dogs-40.json
curl -X POST http://localhost:8000/api/profiles/import \
-H "Content-Type: application/json" \
--data-binary @dogs-40.json
The export format includes model/SAE provenance (see Profiles). Imports are validated — steering entries that can't convert to int→float return VALIDATION_ERROR (in the envelope, details.invalid_keys names them) rather than being silently dropped. Posting a cluster definition/bundle here returns IS_CLUSTER_DOCUMENT pointing at /api/clusters/import (see the Management API index) — the flat profile format has no member/budget semantics. Feature indices are only meaningful with the same SAE the profile was built for.
Delete
curl -X DELETE http://localhost:8000/api/profiles/prof_1a2b3c
Deleting the active profile deactivates it first.
Common errors
| Code | Status | When |
|---|---|---|
PROFILE_NOT_FOUND | 404 | Unknown ID or (for per-request use) unknown name |
PROFILE_ALREADY_EXISTS | 409 | Duplicate name on create/rename |
VALIDATION_ERROR | 200* | Malformed import payload — steering entries that can't convert to int→float (envelope, details.invalid_keys) |
IS_CLUSTER_DOCUMENT | 200* | A cluster definition/bundle was posted to /api/profiles/import — use /api/clusters/import |
SAE_NOT_ATTACHED | 400 | Activate/save-current without an attached SAE |
INVALID_FEATURE_INDEX | 400 | Profile steering doesn't fit the attached SAE |
* Returned in the {success:false, error} envelope with HTTP 200 — see the 200-envelope house style.