Skip to content

Discovery

Find out what a key can reach, without anyone emailing you IDs.

INFO

GET /prompts and GET /skills are on-prem endpoints. GET /skills/whoami is available on SaaS and on-prem.

Three read-only calls, all using the API key you already have. A read key is enough — listing is a read.

None of them return prompt or skill content: names, kinds and version identifiers only. Content comes from Reading, so a listing cannot become a bulk export.

Which projects can this key reach?

Start here. A key carries its owner's identity, so this answers "what is in scope for me".

bash
curl -s "$IM_URL/skills/whoami?api_key=$IM_KEY"
json
{
  "user_id": "cd5c29a0-7b51-4f1f-8381-1b0c213e7131",
  "email": "integrations@example.com",
  "organizations": [
    { "id": "d7fb6107-1188-4f7c-97e2-978403f3e3be", "name": "Optisol" }
  ],
  "accessible_projects": 3,
  "projects": [
    { "id": "8112d9c4-8334-43dd-a3c0-436b5cf1f475", "name": "sample" }
  ],
  "key_id": "ak_01H…",
  "key_created_at": "2026-08-21T12:33:06Z"
}

The path lives under /skills/ for historical reasons — it is the pm-skills CLI's login call — but it is not skill-specific. It is the identity of the key.

List the prompts in a project

bash
curl -s "$IM_URL/prompts?project_id=8112d9c4-8334-43dd-a3c0-436b5cf1f475" \
  -H "X-API-Key: $IM_KEY"
json
{
  "project_id": "8112d9c4-8334-43dd-a3c0-436b5cf1f475",
  "project_name": "sample",
  "flow_mode": "ai_assisted",
  "total": 4,
  "limit": 100,
  "offset": 0,
  "prompts": [
    {
      "name": "sampleAgent",
      "kind": "instruction",
      "has_active_version": true,
      "active_version_sha": "c8aceef013a8",
      "active_version_label": "v1.0",
      "environments": ["development", "test"],
      "published_via": null,
      "updated_at": "2026-08-21T09:14:02Z"
    },
    {
      "name": "draftOnly",
      "kind": "chat",
      "has_active_version": false,
      "active_version_sha": null,
      "active_version_label": null,
      "environments": [],
      "published_via": null,
      "updated_at": "2026-08-25T11:47:03Z"
    }
  ]
}

Fields

active_version_shastring | null

The field to keep. It is exactly what expected_active_sha needs when you publish, so listing and then publishing is two calls with nothing to look up in between.

has_active_versionboolean

Whether anything is live. A prompt with no active version is listed rather than hidden — "exists but nothing is live" is a real state, and omitting it would leave you unable to explain why a name you were given is missing.

You cannot publish over one of these: there is no version to replace. Filter them out before offering a publish.

flow_modestring

What a publish will actually do in this project — review_required, direct_publish or ai_assisted. See Publishing flows.

published_viastring | null

How the live version got there. null means a human reviewed and approved it; "api" means it came through this API; "direct" means someone published it in the console without review.

environmentsstring[]

Where the active version is released. An empty list means it is active but reaches no environment.

limit (default 100, max 500) and offset page the list; total is the unpaged count.

List across a whole organisation

bash
curl -s "$IM_URL/prompts?organization_id=d7fb6107-1188-4f7c-97e2-978403f3e3be" \
  -H "X-API-Key: $IM_KEY"
json
{
  "organization_id": "d7fb6107-1188-4f7c-97e2-978403f3e3be",
  "total": 4,
  "projects": [
    {
      "project_id": "8112d9c4-8334-43dd-a3c0-436b5cf1f475",
      "project_name": "sample",
      "flow_mode": "ai_assisted",
      "prompts": [ "…" ]
    }
  ]
}

Grouped by project, not flat. A prompt name is unique only within a project, so a flat list could carry the same name twice with nothing to tell them apart.

Only projects you can open appear. An organisation you belong to but whose projects you were never added to returns 200 with an empty projects list — not a 403, so "nothing here" stays distinguishable from "you may not look".

List skills

GET /skills

Skills are tiered — project, organisation and global — so the response shape differs from prompts: a project-scoped listing returns the effective set after resolution, and organisation scope reports the promotion ladder.

Documented with the rest of the skills API: Skills Manager → HTTP API → Discovery.

The scoping and authorization rules below are identical for both endpoints.

Scope is exclusive

Pass exactly one of project_id or organization_id. Both, or neither, is a 422.

That is deliberate rather than lenient: silently preferring one would let you believe you had asked an organisation-wide question and quietly receive a single project.

Errors

StatusMeaning
401key missing, invalid or revoked
403you are not a member of that project, or that organisation
422both or neither scope parameter; or limit above 500

Putting it together

Nothing here is hardcoded. From a key alone:

bash
# 1. what can this key see?
PID=$(curl -s "$IM_URL/skills/whoami?api_key=$IM_KEY" | jq -r '.projects[0].id')

# 2. what is in it, and what will a publish do here?
curl -s "$IM_URL/prompts?project_id=$PID" -H "X-API-Key: $IM_KEY" \
  | jq '{flow: .flow_mode, prompts: [.prompts[] | select(.has_active_version) | {name, sha: .active_version_sha}]}'

# 3. publish, using only what the listing returned → see Publishing

Next

Copyright © 2026 elsai foundry.