Skip to content

9Login API: extensions#

Read, install and remove the extensions of the account's library. See Extensions.

GET /v1/extensions#

The extension library: what is installed on this computer, what is only in the account, and how many profiles use each. Profiles refer to extensions by id (extensionIds). installed false means the extension is in the account but not on this computer. storeId is a Chrome Web Store id when source is "store"; for a crx install it can be the package's own id. max is how many extensions the plan stores in the account; canInstall says whether this session may install.

MCP tool: list_extensions. Access: read only.

Field Type Required Description
rescan boolean no Read the extensions folder again first, as opening the Extensions screen does, to pick up folders added by hand. Skipped while an install or delete is running. Default false.
search string no Only extensions whose name, id, store id, version or notes contain this text, case-insensitive.
Request
curl -H "Authorization: Bearer YOUR_API_KEY" "http://127.0.0.1:37286/v1/extensions?search=block"
Response
{
  "ok": true,
  "data": {
    "total": 1,
    "max": 100,
    "canInstall": true,
    "items": [
      {
        "id": "ublock-origin",
        "name": "uBlock Origin",
        "version": "1.62.0",
        "manifestVersion": 2,
        "source": "store",
        "storeId": "cjpalhdlnbpafiamejdnhcphjbkeiagm",
        "installed": true,
        "external": false,
        "sync": "ok",
        "canRestore": false,
        "usedBy": 12,
        "notes": "",
        "notesTruncated": false,
        "error": null
      }
    ]
  }
}

POST /v1/extensions/install#

Install extensions from the Chrome Web Store, a .crx or .zip file, or an unpacked folder, as the Install button does. Returns a job. Pass 1 to 20 sources in total across store, files and folders. Files and folders are copied into the 9Login extensions folder; the originals are not changed. An extension that is in the account but not on this computer is installed into its place. The job result lists each source with its new id or the reason it failed; catalogue says whether the account took the new list (over the plan's limit the extension stays on this computer only). A download can take up to 2 minutes, longer than waitSec allows: when the job is still running, poll GET /v1/jobs/{id}. One install job runs at a time.

MCP tool: install_extensions. Access: needs "Allow changes", needs the sub-user permission "manageExt", needs a plan with extensions.

Field Type Required Description
store string[] no Chrome Web Store ids (32 letters a-p) or Web Store page URLs.
files string[] no Absolute paths of .crx or .zip files on this computer. Network paths are refused.
folders string[] no Absolute paths of unpacked extensions on this computer: manifest.json at the top, or in its only subfolder. Network paths are refused.
replace boolean no Install over an extension already installed on this computer with the same identity, keeping its id, so every profile using it gets the new files. When false such a source fails with exists. Default false.
wait boolean no Wait for the job to finish, at most waitSec, before answering. false answers at once with the job, to follow with GET /v1/jobs/{id}. Default true.
waitSec integer no How long wait may hold the request. Min 1, max 100. Default 60.
Request
curl -X POST "http://127.0.0.1:37286/v1/extensions/install" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "store": [
    "https://chromewebstore.google.com/detail/ublock-origin/cjpalhdlnbpafiamejdnhcphjbkeiagm"
  ],
  "files": [
    "C:\\Users\\me\\Downloads\\my-extension.crx"
  ],
  "wait": true
}'
Response
{
  "ok": true,
  "data": {
    "id": "j0123456789abcdef",
    "kind": "extensionInstall",
    "state": "done",
    "createdAt": 1760000000000,
    "finishedAt": 1760000006000,
    "progress": {
      "done": 2,
      "total": 2
    },
    "error": null,
    "result": {
      "installed": [
        {
          "source": "https://chromewebstore.google.com/detail/ublock-origin/cjpalhdlnbpafiamejdnhcphjbkeiagm",
          "id": "ublock-origin",
          "name": "uBlock Origin",
          "version": "1.62.0",
          "manifestVersion": 2,
          "replaced": false
        }
      ],
      "failed": [
        {
          "source": "C:\\Users\\me\\Downloads\\my-extension.crx",
          "code": "badPackage",
          "message": "Unsupported CRX version. Only CRX3 is accepted."
        }
      ],
      "catalogue": {
        "status": "ok",
        "code": null,
        "message": null
      }
    }
  }
}

POST /v1/extensions/delete#

Remove extensions from the library and from every profile that uses them, as the Delete button does. Needs "Allow deleting" on the API & MCP screen. Deletes the files 9Login installed on this computer; an extension that points at a folder of your own leaves the list but the folder stays (filesKept). There is no undo. catalogue says whether the account took the new list; profiles lists the profiles that dropped the extensions. Answers busy while the extension list is being changed in 9Login or by an install job. Works on a plan without extensions, so an account can still clean up.

MCP tool: delete_extensions. Access: needs "Allow deleting", needs the sub-user permission "manageExt".

Field Type Required Description
ids string[] yes Extension ids from GET /v1/extensions. An extension that points at a folder of your own has that folder's path as its id.
Request
curl -X POST "http://127.0.0.1:37286/v1/extensions/delete" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "ids": [
    "ublock-origin"
  ]
}'
Response
{
  "ok": true,
  "data": {
    "deleted": [
      "ublock-origin"
    ],
    "filesKept": [],
    "failed": [],
    "catalogue": {
      "status": "ok",
      "code": null,
      "message": null
    },
    "profiles": {
      "updated": [
        "a1b2c3"
      ],
      "failed": [],
      "error": null
    }
  }
}