List actions
https://api.granska.cloud/v1/actionsLists the follow-up actions this tenant may run against a finished analysis.
What an action is
An action takes a finished audit and writes something from it — the grounds for an appeal, a plain-language summary of the findings, a letter. Like profiles, actions are tenant configuration rather than a fixed feature list, so this endpoint is the only authority on what your organisation can run.
Each entry carries an id, a name, a one-line tagline and a longer description. The id is
the actionType you send to POST /v1/action; the other three are written to be
shown to a person choosing between them.
Naming an actionType that is not in this list answers 403 — and, because the metering middleware
runs first, that rejection has already spent a run. Read the list rather than guessing.
curl "https://api.granska.cloud/v1/actions?profileId=lss_utredning" \
-H "Authorization: Bearer $TOKEN"{
"actions": [
{
"id": "action_overklagande",
"name": "Överklagandeunderlag",
"tagline": "Skriv fram grunderna för ett överklagande",
"description": "Sammanställer utredningens brister till ett underlag för överklagande.",
"longDesc": "Skriver fram grunderna för ett överklagande ur de brister granskningen hittat, och yrkandet de leder till.",
"warningMessage": "Läses igenom av jurist innan den lämnas in.",
"fitsProfileIds": [
"lss_utredning"
]
},
{
"id": "action_sammanfattning",
"name": "Sammanfattning",
"tagline": "Utredningen i klarspråk",
"description": "Skriver om utredningens slutsatser så att den de gäller kan läsa dem."
}
]
}The actions for one profile
An action is often written for one kind of audit. Pass profileId — the same id you passed to
POST /v1/analyze, and the one
POST /v1/action requires — and the list comes back narrowed to the actions
written for that profile. A profileId your organisation is not licensed for is a 403, not an
empty list: an empty list would read as "this profile has no actions", which is a different fact.
Omit the parameter and nothing changes: the whole list comes back, exactly as it did before this parameter existed.
Each entry also carries fitsProfileIds, the binding itself, so a client that caches the list once
can narrow it locally instead of calling this endpoint per profile. Three cases are listed for
every profile, and they are deliberate rather than accidental:
- an action with no
fitsProfileIdsat all, or an empty one — nobody has decided which profiles it is for, so it is offered everywhere; - an action naming the reserved id
generell— decided, and decided for everybody; - an action whose named profiles your organisation no longer has — a binding that resolves to nothing hides the action from every list rather than from the wrong ones, so it is shown.
A list that is short because a binding could not be resolved is indistinguishable, to whoever reads it, from a list that is short because something is broken. So the narrowing only ever removes an action that certainly belongs to a different profile you actually have.
| Parameter | Description |
|---|---|
profileIdstring·query | Lists only the actions written for this profile — the same id you pass to POST /v1/analyze, a bundle profile included. Omit it and the whole list comes back, exactly as before this parameter existed.A bundle profile is expanded here: name it and the answer is the union of what fits either profile in it, each action once — an action written for only one of the two is still offered. The parameter is not repeatable and does not need to be, because a bundle's members are not licensed separately and you hold the bundle's id alone. Every action listed for a bundle can also be run for it: POST /v1/action takes the bundle's id and expands it the same way, so a bundle's menu is both readable here and runnable there. Otherwise the rule is fail-open: an action with no profiles named, one naming the reserved id "generell", and one whose named profiles this workspace no longer has are all listed for every profile, because a list that is short because a binding could not be resolved is indistinguishable from a broken one. |
A bundle profile: one id, one list
Some profiles are bundles — a single profile that reviews a document under two others at once.
profileId takes a bundle's id, the same one you pass to POST /v1/analyze,
and the answer is the union of what fits either profile in it: every action offered under one of
them is offered here, once, in the same order as the full list.
There is no repeated profileId parameter and there is deliberately no need for one. A bundle's
members are not licensed separately, so you hold the bundle's id and nothing else — the expansion is
this endpoint's job, not yours. Naming a member profile directly answers for that member alone,
exactly as for any other profile, but only if your tenant happens to be licensed for that member
separately; otherwise the member has no profile of its own to name and you get a 403.
An action written for only one of the two profiles is still offered. Reviewing a document under two profiles adds angles to it; it does not narrow what you may then write from it.
This endpoint is the only one of the two that takes a bundle's id. POST /v1/action
refuses one with a 400: a bundle has no reviewers of its own, so there is no legal text for it to
write an action from. A bundle's menu is therefore something you can read and show today, and not
yet something you can run.
The bundle's members are readable from GET /v1/config, on the profile's
memberProfileIds, if you want to show a person which profiles are behind a name.
Errors
| Error | When |
|---|---|
401UNAUTHORIZED | The Authorization header is missing, is not a readable bearer token, or names no tenant. |
401TOKEN_EXPIRED | The access token was issued by this gateway and has since expired. Not probed: it needs a token older than its own lifetime. |
403FORBIDDEN | The profileId named is not one this tenant is licensed for. Refused rather than answered with an empty list, so a typo cannot read as "this profile has no actions". |
500INTERNAL_ERROR | An unexpected server-side failure. Not probable from outside — reaching it means something is wrong. |
Send it without writing a client
If your organisation already has an account, an administrator can list the licensed actions from the
API tester at /admin/api-tester.