Skip to content

9Login API: requests and errors#

How to call the 9Login API: the address, the key, the shape of every answer, the error codes and the limits. The endpoints are listed by group on the pages that follow.

Quick start#

Every endpoint lives under http://127.0.0.1:37286 and needs the key shown on the API & MCP screen of 9Login in an Authorization header: Authorization: Bearer <key>. Reads are GET with parameters in the query; writes are POST with a JSON body.

9Login must be open and signed in, on a paid plan. Calls run with the permissions of the account signed in to this app.

The examples use curl in a POSIX shell (macOS, Linux, Git Bash). In Windows PowerShell call curl.exe, and put the JSON body in a file passed with -d @body.json.

curl -H "Authorization: Bearer YOUR_API_KEY" "http://127.0.0.1:37286/v1/status"

Key and safety#

The key is 32 hex characters, one key for the endpoints below, the events WebSocket and MCP.

Send it in the Authorization header of every request: Authorization: Bearer <key>. A key in the URL is refused, except on the WebSocket, where browsers cannot set headers: there ?key= works too. A missing or wrong key answers 401 badKey.

With Require Auth off, every request runs without a key. Requests sent from a web page are always refused, so a site you visit cannot call the API. With Local only on, only 127.0.0.1 and localhost are accepted as the Host as well; with it off (the default), any host or IP is accepted, so a firewall rule or port forward can expose the port to other machines, and the key is then the only lock: keep Require Auth on.

Anyone holding the key can create, start and (when allowed) delete profiles of this account on this machine. Do not paste it anywhere public; if it leaks, make a new key.

The settings and the key belong to the 9Login account that turned the API on. When another account signs in on this computer, the API turns off and the key is cleared; turning it on again makes a new key.

Responses and errors#

Success is { "ok": true, "data": ... } with HTTP 200. A refusal of the whole request is { "ok": false, "code", "message", "details"? } with the status below. code never changes meaning; message is for people.

Endpoints that work on many profiles answer 200 and list per-profile refusals in failed, each with id, code and message (second table).

A call that succeeded can also carry warnings: [{ code, message, ids }], present only when there is something to point out. scriptOnRestore (create and update): the profiles have a script and onStartup "restore", so the browser reopens the last session first and the script starts on a restored tab. Use "custom" with a url when the run depends on the script. earlierRunLogs (exec): an earlier run on the profile passed its timeoutSec and was still going, so logs may include lines it printed; a run that fails carries it in details.warnings. noSetResult (add-script, proxy update, test-script): the proxy script never calls SetResult, so every start that uses it fails once its time runs out.

Code HTTP Meaning
badKey 401 The key is missing or wrong. Send it as Authorization: Bearer <key>.
badHost 403 Local only is on and the request was not sent to 127.0.0.1 or localhost.
planRequired 403 The plan does not include the API (or a field asked for a feature the plan lacks).
notSignedIn 403 9Login is not signed in.
permissionDenied 403 This sub-user may not do this.
toolsetOff 403 A switch on the API & MCP screen is off (Allow changes, Allow deleting, Allow automation).
invalidParams 400 A field is wrong; details lists each one with its path.
invalidJson 400 The body is not valid JSON.
unsupportedMediaType 415 A POST body was sent without Content-Type: application/json.
notFound 404 No such endpoint, or nothing with this id (profile, proxy, extension, script, task, task run or job).
methodNotAllowed 405 Wrong HTTP method for this endpoint.
profileRunning 409 The profile is not fully stopped.
fpBudget 409 Not enough new fingerprints left for the last 30 days; details has left and freesAt.
quota 409 The plan has no room for more (profiles, proxies, extensions, scripts or tasks).
conflict 409 The same data was changed elsewhere first. For a script, details.server has the account's version: get it again and retry, or pass overwrite true. For the proxy list and the task list, call again with onConflict "reload".
notRunning 409 The profile has no running browser.
noWindow 409 The browser has no visible window yet, or it runs hidden.
inSync 409 The profile is in a Sync control session, which fixes its window size.
busy 429 Too many requests or jobs at once, or the task already has a run going.
unsupportedPlatform 501 This feature does not exist on this operating system.
macroError 422 The macro failed in the browser: it threw, its tab closed, or it did not finish in time. message has the error, details.logs what it logged.
browserError 502 The browser did not answer, or refused the request. The message says why.
serverUnreachable 502 The 9Hits server could not be reached.
serverError 502 The 9Hits server refused the write.
internal 500 9Login hit an error.

Per-profile results#

Codes found in failed[] of the commands and jobs that work on many items: profiles, proxies, cookies, cloud data, extensions, scripts and windows. Each entry carries its id (or the install source) and a message that says more.

Code Meaning
notFound Nothing with this id: profile, proxy, extension, script or install source.
profileRunning The profile is not fully stopped. Stop it first.
fpUnavailable The fingerprint of this profile could not be loaded from the server. Try again.
lockedElsewhere The profile is open on another machine or by another member.
permissionDenied This sub-user may not do this to this item.
planExpired This sub-user account is suspended.
planRequired The current plan does not include this.
overLimit The profile is outside the number of profiles the plan can run.
serverUnreachable The 9Hits server could not be reached.
serverError The 9Hits server refused the request.
updateNeeded This app needs an update before it can open profiles.
notAuthorised The server did not authorise this launch.
cloudNewer The cloud has newer browser data than this computer. Start: pass cloudNewer; upload: pass overwriteNewer.
launchFailed The browser could not be launched.
quota The plan has no room for more: profiles, list entries, or cloud storage. The message says which.
fpBudget The limit of new fingerprints for the last 30 days is reached.
conflict Another machine changed it first. Read it again and retry.
identityChange This change gives the profile a new fingerprint and it already has browsing data. Pass confirmNewIdentity true to do it anyway.
failed It could not be done. The message says why.
refused This item was refused. The message says why.
inUse It is still in use. The message says by what.
duplicate Another entry already has the same endpoint and credentials.
exists It is already installed. Pass replace true to install over it.
notRunning The profile has no running browser.
noWindow The browser has no visible window yet, or it runs hidden.
tooBig It is larger than allowed. The message says which limit.
noLocalData This profile has no browser data on this computer.
noCloudData The cloud has no browser data for this profile.
undecryptable The cloud copy could not be decrypted with this account's key.
dataBusy An upload or download of this profile's data is already queued or running.
localNewer This computer has browser data newer than the cloud copy. Pass overwriteLocalNewer true to replace it anyway.
badSource The source is not a Chrome Web Store id or URL, nor an absolute local path.
downloadFailed The download from the Chrome Web Store failed.
noStoreBuild The Chrome Web Store has no build of this extension for this browser version.
badPackage The file is not a valid Chrome extension package.
writeFailed The extension could not be written to disk.

Limits#

What Limit
HTTP HTTP/1.1; a body needs a Content-Length header (chunked bodies are not supported)
Request body 4 MB
Requests running at once 64 (more answer busy)
Start jobs running at once 5 (more answer busy; one start takes up to 500 ids)
Upload and download jobs running at once 2 together (more answer busy)
Proxy check, proxy script test and extension install jobs 1 of each at a time (more answer busy)
Proxy script 16 KB (UTF-8); a start waits 120 seconds for it to call SetResult
Profile ids per call 500 (download: 250)
Profiles per create, copies per duplicate 100
Proxy ids per call 1000
Script or extension ids per delete 200
wait on jobs 100 seconds
Finished jobs kept 30 minutes
WebSocket connections 32
MCP messages per request 1 (a batch only from clients on 2025-03-26)
Macro run (exec) timeoutSec 60 by default, at most 110; code up to 512 KB
Automation calls per profile 1 at a time; a call that arrives meanwhile waits up to 15 seconds, then answers busy
Task runs at once 3 on this computer (more wait their turn); 1 per task
Task run history the last 50 runs of each task, on this computer only
Task list stored in the account as one list, like proxies: 1000 tasks on a paid plan, up to 2000 hand-picked profiles per task, 512 KB compressed in all