GRANSKA

List profiles

GEThttps://api.granska.cloud/v1/profiles

Lists the analysis profiles this tenant is licensed for — who owns each one, whether it is published, and the workers it runs.

Bearer tokenSpends no quota

What a profile is

A profile is one kind of audit: which reviewers run, which legal sources they may cite, which document type it expects, and what language it answers in. None of that is in the API — it is tenant configuration resolved when a job runs, which is why this endpoint exists rather than a fixed list in this documentation.

The id of a profile is the profileId you send to POST /v1/analyze and, strongly preferably, to POST /v1/action. It is also what addresses the profile for PATCH /v1/profiles/:id, and what POST /v1/profiles hands back when you create one — one string, every route. Only profiles your tenant is licensed for are returned; naming one that is not in this list answers 403.

The reviewer ids inside a profile are spelled differently — longer, and carrying your organisation's own identifier. That is not something to correct or trim: send each one back exactly as it appears here.

If you hold an older id for a reviewer, it still runs. Every route that takes a reviewer id matches on the reviewer it names, not on the characters you sent, so a spelling this endpoint published before a configuration change reaches the same reviewer as the one it publishes today. What it will not do is guess: a dynamicContext.workerContext key naming a reviewer the analysis does not run is refused rather than quietly applied to nothing, and so is a second key naming a reviewer the first one already named.

Request
curl https://api.granska.cloud/v1/profiles \
  -H "Authorization: Bearer $TOKEN"
Response
{
  "profiles": [
    {
      "id": "lss_utredning",
      "name": "LSS-utredning",
      "documentType": "LSS",
      "userHelpText": "För utredningar om insatser enligt LSS.",
      "urlSlug": "lss-utredning",
      "tenantId": "SYSTEM",
      "status": "PUBLISHED",
      "updatedAt": "2026-08-04T09:12:44.000Z",
      "workers": [
        {
          "id": "worker_objectivity",
          "name": "Objektivitetsgranskare",
          "shared": true
        },
        {
          "id": "worker_legal",
          "name": "Rättslig grund",
          "shared": false
        }
      ]
    },
    {
      "id": "lss_utredning_intern",
      "name": "LSS-utredning (intern)",
      "documentType": "LSS",
      "tenantId": "tenant_kommunen",
      "status": "DRAFT",
      "updatedAt": "2026-08-09T15:01:02.000Z",
      "workers": [
        {
          "id": "worker_objectivity",
          "name": "Objektivitetsgranskare",
          "shared": true
        }
      ]
    }
  ]
}

Why the worker ids matter

Each profile lists its workers — the individual reviewers the audit runs, each with an id and a name.

Those ids are the keys of dynamicContext.workerContext on POST /v1/analyze, which is how you aim a local rule at one reviewer for one run. An id that matches no reviewer in the profile fails the job, so read them from here rather than writing them by hand or caching them across a configuration change.

This endpoint takes no parameters, spends no quota, and is cheap enough to call before each run if you would rather not cache.

A reviewer marked shared belongs to more than one profile

A reviewer carries "shared": true when another of your profiles names the same one. Editing it through PATCH /v1/profiles/:id changes what those other profiles run too, and they will not be mentioned anywhere in the request or the response. Check this flag before editing a profile you did not build.

Which profiles are ours, and which are finished

Two fields answer the questions a picker has to answer, and neither is readable from the id.

tenantId says who owns the profile. SYSTEM is a profile we build and maintain — the official audit, the same for every customer. Anything else is a profile owned by your own organisation or by the template it was provisioned from. The id cannot tell you this: an organisation may hold its own version of an audit under the same name, in which case that version is what your credential runs, and the two are spelled identically.

status says whether the profile is finished. PUBLISHED means it is built, reviewed and runnable. DRAFT means it is mid-construction — and your credential is shown drafts deliberately, so that you can create a profile and read it back before publishing it. Filter on status before offering a profile to an end user. A draft will run, and answer with whatever it has been given so far. When the profile is ready, PATCH /v1/profiles/:id with {"status": "PUBLISHED"} is what moves it.

unlisted is a third, narrower thing: a profile that is finished and runnable but deliberately kept out of pickers, because it is advertised somewhere else. Skip it in a list; keep honouring it when a caller names it.

updatedAt is when the owning record was last written, in ISO 8601, and is there for caching. It is a hint, not a guarantee — it stamps the record tenantId names, so where your own profile overrides one of ours and inherits a field it does not itself set, a later change of ours does not move it. It is absent on profiles written before we started stamping.

PUBLISHED is not "for sale"

status is about whether the audit works, and nothing else. Whether an audit may be sold — priced, targeted, packaged — is a separate decision, made where the commercial terms live and not in this API. A profile can be finished here and not offered anywhere.

Errors

ErrorWhen
401
UNAUTHORIZED
The Authorization header is missing, is not a readable bearer token, or names no tenant.
401
TOKEN_EXPIRED
The access token was issued by this gateway and has since expired. Not probed: it needs a token older than its own lifetime.
500
INTERNAL_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 profiles from the API tester at /admin/api-tester.