Accounts and companies by what they have used
const url = 'https://beta-api.plune.ai/v1/admin/usage?sort=results';const options = {method: 'GET', headers: {cookie: 'plune_session=<plune_session>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url 'https://beta-api.plune.ai/v1/admin/usage?sort=results' \ --cookie plune_session=<plune_session>Every account and company that has a project, heaviest first by sort (up to 100; truncated says there were more), each with its tier and its totals. A part of the address or the name in query narrows it. Each row carries its tier’s limits and nearLimit, the limits it has used 80% or more of — a limit over a project is marked from the projects before the row leaves them out. Each row also carries latest, the newest grant of its history with who granted it (grantedByEmail), or null. Owner-only and session-only, as GET /v1/admin/tiers; everyone else gets 404. Ten calls a minute.
Authorizations
Section titled “Authorizations ”Parameters
Section titled “ Parameters ”Query Parameters
Section titled “Query Parameters ”Part of an address or a company name
files sorts by bytes
Responses
Section titled “ Responses ”The scopes, heaviest first
object
object
object
The address of an account, the name of a company.
What it is on now, as GET /v1/me shows it.
object
Free and Personal are an account’s, Team and Enterprise a company’s; Free may also be a company’s, as the row that cancels its Team.
Worked out from the grants at the database’s clock, never stored. active: a paid grant covers now. grace: it ended or was cancelled less than 14 days ago, and the limits are still the tier’s. expired: the 14 days are over — Free. disabled: the operator switched it off — Free at once, and nothing is deleted for 14 days. No grant ever is plain Free, active.
What a grant carries besides its tier. A free grant carries none.
object
What the tier allows, beside usage (TIER_LIMITS, #1048). null is no limit. Whether a limit refuses yet is enforcement.
object
Projects an account may own outside a company.
People with write access. Refuses (429, quota.kind: "writeSeats") only in enforce mode; usage.writeSeats is the count.
People who only read: Free 1, Personal 3, Team 5, Enterprise none. A person who writes anywhere in the scope is a writer, once. Refuses (429, quota.kind: "readerSeats") only in enforce mode; usage.readerSeats is the count.
Bytes of files, over fileBytesPer.
Results, over resultsPer; null is by contract.
Days of history kept on Free; null is no day limit.
The results limit of this calendar month (#1441), beside usage.resultsThisMonth: Personal 5 000 000, Team 5 000 000 for each writer (usage.writeSeats). null on Free, whose results is over the account, and on Enterprise, by contract. Never refuses: ingest is not stopped by it in either enforcement.
object
People in it. On an account or a company, the distinct people across its projects (and a company’s own members), not a sum.
Cases not in the Bin.
Runs not in the Bin.
Results stored, of every run (also of a run in the Bin).
Files kept in Plune’s database: the ones that count against the files budget.
The size of those files in bytes.
Files in the customer’s own bucket (ready). Counted, not measured: they cost the database nothing.
Plune AI draft requests since the start of the calendar month (UTC).
Projects not in the Bin.
People with write access (owner, manager, member) in the scope, each once — read it beside limits.writeSeats. Open invitations are not counted.
People who only read in the scope, each once — read it beside limits.readerSeats.
Result rows of the finished runs started this calendar month (UTC), read beside limits.resultsThisMonth (#1441). A run is counted once, as it finishes (a run that crosses midnight at the end of a month counts in the month it started), with every row it holds — those a retest replaced too, as results counts rows; a result an approved Cairn proposal adds to its finished run counts as it is added. A run that is open or was terminated is not counted until it finishes; a counted run stays counted after it goes to the Bin. null only on Free, whose results limit is over the account; Enterprise has the figure and a null limit.
The limits the scope has used 80% or more of (the threshold of the AI budget); empty when none. A mark to read, not a refusal. projects, writeSeats and readerSeats compare usage.<key> with limits.<key>; projects only for an account, since a company’s projects are not limited. fileBytes and results compare the scope’s usage.fileBytes / usage.results when the limit is over the account, and each project’s figure when it is over a project — near when any one project is. writeSeats is named only when the scope has more than one writer: the owner alone always holds a seat, so one writer is never a mark, not even of the one write seat of Free and Personal, where a second writer is already over the limit (#2020). results over a month or a month-per-paid-user compares usage.resultsThisMonth with limits.resultsThisMonth (#1441); over a contract it is never named. A null limit is never named; a limit of 0 is named once anything is used, except writeSeats, named only from the second writer. One mark says less than it seems: usage.results counts the results of runs in the Bin too, which the Free results limit (#1049) does not, so results can be named before that limit is reached, until the Bin is emptied.
The newest row of its history, as in GET /v1/admin/tiers; null when it never had one.
object
object
Free and Personal are an account’s, Team and Enterprise a company’s; Free may also be a company’s, as the row that cancels its Team.
What a grant carries besides its tier. A free grant carries none.
object
The application owner who granted it; null for a payment.
The address of grantedBy; deleted account once the purge has made that account nobody; null for a payment.
More matched than the 100 listed.
Example
{ "results": [ { "subject": { "kind": "company", "id": "6f1c2b3a-0000-4000-8000-0000000000a5" }, "label": "Acme", "tier": { "tier": "team", "tierState": "active", "options": { "saml": true }, "tierValidUntil": "2099-12-31T23:59:59.000Z", "tierGraceEndsAt": null }, "limits": { "projects": null, "writeSeats": 50, "readerSeats": 5, "fileBytes": 10737418240, "fileBytesPer": "project", "results": 5000000, "resultsPer": "month-per-paid-user", "historyDays": null, "resultsThisMonth": 15000000 }, "usage": { "projects": 1, "members": 3, "cases": 214, "runs": 41, "results": 18902, "files": 37, "fileBytes": 5242880, "bucketFiles": 0, "aiDraftsThisMonth": 12, "writeSeats": 3, "readerSeats": 0, "resultsThisMonth": 2310004 }, "nearLimit": [], "latest": { "id": "6f1c2b3a-0000-4000-8000-0000000000a6", "subject": { "kind": "company", "id": "6f1c2b3a-0000-4000-8000-0000000000a5" }, "tier": "team", "options": { "saml": true }, "validFrom": "2026-09-16T09:12:04.151Z", "validUntil": "2099-12-31T23:59:59.000Z", "source": "manual", "grantedBy": "u-shop", "note": "annual invoice 2026-114", "disabled": false, "createdAt": "2026-09-16T09:12:04.151Z" } } ], "truncated": false, "enforcement": "report", "note": "Rows are counted, not measured: results, cases and runs are numbers of rows, not the bytes they take in the database. Only files are in bytes, and only those kept in the database (a file in the customer’s bucket is counted, not measured). Cases and runs in the Bin are not counted; results and files are counted as long as they are stored."}A query over 100 characters, or a sort that is not listed
object
Example
{ "error": "sort: must be one of results, files, cases, runs, projects, members"}No / invalid session
The caller does not own the application
object
Example generated
{ "error": "example"}Rate-limited: the per-route throttle, or the per-minute request limit of the plan an API token counts by (#1442; the body names the plan, #2092). Retry-After carries the seconds until the window rolls over.
object
Example generated
{ "error": "example"}Headers
Section titled “Headers ”Seconds until the window rolls over