Provide API endpoint for license settings modification

My company would like to be able to modify the license count via API, instead of the web interface. Currently there does not seem to be an endpoint for that. Would it be possible to create one?

Background: When the license count is increased automatically, an invoice for each new user is created. This is a management overhead for our accounting team. Hence they have requested to increase/decrease the license count once a month so one big invoice is created. We would like to automate this process.

Feature name

Provide API endpoint for license settings modification

Feature function

  • GET /public/license
{
  "object": "license",
  "data": {
      "seats": 150,
      "limit": 170,
      "limited": true,
      "object": "license",
    }
}
  • PUT /public/license
 {
  "object": "license",
  "data": {
      "seats": 150,
      "limit": 170,
      "limited": true,
      "object": "license",
    }
}

Hi @thincheek the team is looking into this functionality.

There’s an undocumented API endpoint, /organizations/{id}/seat using POST with a model that looks like this:

{ “SeatAdjustment”: 20 }

where SeatAdjustment is the number of seats to add (positive) or subtract (negative). This will also use the auto-scaling if configured to cap the seats. To update the max autoscale seats itself requires a more complex Organization PUT that may be a bit more challenging (need to use a GET then modify max seats, then PUT ).

And then use openssl + curl for login. Only thing to keep in mind for the private API is you can’t use an API Key, it has to be username/password and it has to be tied to an individual’s account (not the org itself).

1 Like

Hi @bw-admin,
thanks for your reply. I cannot seem to figure out the API call you are describing. Could you provide a full curl command for the following calls?

/organizations/{id}/seat Method GET
/organizations/{id}/seat Method POST
/organizations/{id}/seat Method PUT

Also is there any documentation how to handle authentication against the private API with username / password?

Cheers,
Dominik

Can you try the following?

Perform the regular oauth request, using PERSONAL Client Credentials with the scope api (via your settings, not the orgs)

For the /seat endpoint, should be expecting a json blob of

{ “seatAdjustment”: < number > }

It’s also POST only, to fetch seat number, need to access another endpoint which should be the seat request i.e. /organizations/{id}.

Please keep in mind these are undocumented APIs and may change at any time.

My struggle is to which URI I perform the authentication and seats request. Since I couldn’t find documentation on that I tried to mimic a browser request but to no avail. Please find my PowerShell code below. Perhaps you can point me where I’m going wrong. Do I use the password of my credentials or my personal API key?

$Params = @{
    UseBasicParsing = $true
    Uri             = "https://vault.bitwarden.com/api/accounts/prelogin"
    Method          = "POST"
    ContentType     = "application/json; charset=utf-8"
    Session         = "Session"
    Body            = @{email = "[email protected]" }  | ConvertTo-Json -Compress
}
Invoke-RestMethod @Params

kdf kdfIterations
-- - ------------ -
0        100000


$Params = @{
    UseBasicParsing = $true
    Uri             = "https://vault.bitwarden.com/identity/connect/token"
    Method          = "POST"
    ContentType     = "application/x-www-form-urlencoded; charset=utf-8"
    WebSession      = $Session
    Body            = @{
        scope             = "api offline_access"
        client_id         = "web"
        grant_type        = "password"
        username          = "[email protected]"
        password          = "password"
    }  | ConvertTo-Json -Compress
}
Invoke-RestMethod @Params

The remote server returned an error: (400) Bad Request.

Try the following:

The curl request should work using the api tokens and there is no need for a prelogin.

curl --request POST \
  --url https://identity.bitwarden.com/connect/token \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/x-www-form-urlencoded; charset=utf-8' \
  --header 'Device-Type: 6' \
  --header 'User-Agent: Bitwarden_CLI/1.20.0 (WINDOWS)' \
  --data scope=api \
  --data grant_type=client_credentials \
  --data 'client_id=<client_id>' \
  --data client_secret=<client_secret> \
  --data deviceType=6 \
  --data deviceIdentifier=<random GUID> \
  --data deviceName=windows

Many thanks, got it working based on this information. Much appreciated!

1 Like

I’ve got one follow up question: It seems my automation user whos API credentials I use, is removed from my organization after some requests. When I re-add the user to my org, everything works for a couple of requests, then the user is removed again.

Is there any rate limit I need to honor or policy I need to modify? I make about 9 requests per hour against the private API.

Hi @thincheek, are you using Directory Connector?

Hi again,
to complete my last request: This was related to script we had running in the background and we solved it.

Today I have another request related to the original question: I am collecting the total number and the used number of license seats with the following request:

$Params = @{
    Uri             = "https://api.bitwarden.com/organizations/<org-id>/subscription"
    Headers         = @{Authorization = ("Bearer " + $Token) }
    UseBasicParsing = $true
}
Invoke-RestMethod @Params

Invoke-RestMethod : The remote server returned an error: (404) Not Found

This stopped working yesterday and is now answering with a 404. As a test a made the same request with a bearer token from my Bitwarden web session which returns the desired data correctly. I am aware this is a private API so things can change. However is there an alternative to retrieve the total number and used number of license seats with an API access token?

Hi @bw-admin, do you have any knowledge about whether the API endpoint has been made unavailable to requests with API credentials? Is there an alternative to fetch the number of license seats in a scripted way?

Background: We want to monitor our (unused) license seats in order to be notified of a shortage of licenses seats. The auto-increment is not an option for us, as it creates lots of invoices which causes too much processing time by out accounting department.

Sorry, I missed this one. I’ll get back to you shortly on this one! :+1:

Hey @bw-admin, do you have any news on this topic?

Hey @thincheek

Due to recent changes, the Org API key would not work for this because Bitwarden explicitly checking user-level permissions now.
and just need to ensure the user API key that’s being used is for a user that has access, the same user-level API key auth that would be used in the bw CLI.

Let me know if that helps!

Hi @bw-admin, thanks for getting back to me. I do perform this request with an admin user API key and not with an org API key, still receive a 404. Any other ideas?

Hi @bw-admin, any news on this front? Being able to monitor the number of free license seats would make our lives a lot easier.

Ah, it looks like this one will need to be run as owner rather than admin, if you need any additional support, please feel free to send your script to the team at Get in Touch | Bitwarden for a review :slight_smile:

That was it! User was admin only. As owner everything works again. Many thanks @bw-admin!

2 Likes