BokaMera.API.Host

<back to all web services

SuperAdminAssistantUsageQuery

Requires Authentication
Requires the role:superadmin
The following routes are available for this service:
GET/superadmin/assistant/usageList AI assistant and MCP token usage per companyReturns, for a page of companies, how many tokens each has consumed in the current rolling window against its configured limit — separately for the admin AI assistant and for the public MCP server. Usage is read from the rolling-window store, so only the current window is available; there is no history. Ordering is by company name, because usage is not stored in a queryable form and cannot be sorted across pages.
import 'package:servicestack/servicestack.dart';

class AssistantUsageMeter implements IConvertible
{
    /**
    * Tokens consumed within the current rolling window.
    */
    // @ApiMember(Description="Tokens consumed within the current rolling window.")
    int TokensUsed = 0;

    /**
    * The company's token limit for the window. Zero or less means no cap is applied.
    */
    // @ApiMember(Description="The company's token limit for the window. Zero or less means no cap is applied.")
    int TokenLimit = 0;

    /**
    * Tokens remaining before the limit is reached (never negative).
    */
    // @ApiMember(Description="Tokens remaining before the limit is reached (never negative).")
    int TokensRemaining = 0;

    /**
    * Share of the limit consumed, as a percentage. Zero when no cap is applied.
    */
    // @ApiMember(Description="Share of the limit consumed, as a percentage. Zero when no cap is applied.")
    double PercentUsed = 0;

    /**
    * True while the company is still below its token limit.
    */
    // @ApiMember(Description="True while the company is still below its token limit.")
    bool IsWithinBudget;

    AssistantUsageMeter({this.TokensUsed,this.TokenLimit,this.TokensRemaining,this.PercentUsed,this.IsWithinBudget});
    AssistantUsageMeter.fromJson(Map<String, dynamic> json) { fromMap(json); }

    fromMap(Map<String, dynamic> json) {
        TokensUsed = json['TokensUsed'];
        TokenLimit = json['TokenLimit'];
        TokensRemaining = json['TokensRemaining'];
        PercentUsed = JsonConverters.toDouble(json['PercentUsed']);
        IsWithinBudget = json['IsWithinBudget'];
        return this;
    }

    Map<String, dynamic> toJson() => {
        'TokensUsed': TokensUsed,
        'TokenLimit': TokenLimit,
        'TokensRemaining': TokensRemaining,
        'PercentUsed': PercentUsed,
        'IsWithinBudget': IsWithinBudget
    };

    getTypeName() => "AssistantUsageMeter";
    TypeContext? context = _ctx;
}

class SuperAdminAssistantUsage implements IConvertible
{
    /**
    * The company the usage applies to.
    */
    // @ApiMember(Description="The company the usage applies to.")
    String CompanyId = "";

    /**
    * The company's name.
    */
    // @ApiMember(Description="The company's name.")
    String CompanyName = "";

    /**
    * Token budget for the admin portal AI assistant. Null when it could not be read.
    */
    // @ApiMember(Description="Token budget for the admin portal AI assistant. Null when it could not be read.")
    AssistantUsageMeter? AiChat;

    /**
    * Token budget for the public MCP server. Null when it could not be read.
    */
    // @ApiMember(Description="Token budget for the public MCP server. Null when it could not be read.")
    AssistantUsageMeter? Mcp;

    SuperAdminAssistantUsage({this.CompanyId,this.CompanyName,this.AiChat,this.Mcp});
    SuperAdminAssistantUsage.fromJson(Map<String, dynamic> json) { fromMap(json); }

    fromMap(Map<String, dynamic> json) {
        CompanyId = json['CompanyId'];
        CompanyName = json['CompanyName'];
        AiChat = JsonConverters.fromJson(json['AiChat'],'AssistantUsageMeter',context!);
        Mcp = JsonConverters.fromJson(json['Mcp'],'AssistantUsageMeter',context!);
        return this;
    }

    Map<String, dynamic> toJson() => {
        'CompanyId': CompanyId,
        'CompanyName': CompanyName,
        'AiChat': JsonConverters.toJson(AiChat,'AssistantUsageMeter',context!),
        'Mcp': JsonConverters.toJson(Mcp,'AssistantUsageMeter',context!)
    };

    getTypeName() => "SuperAdminAssistantUsage";
    TypeContext? context = _ctx;
}

class SuperAdminAssistantUsageQueryResponse implements IConvertible
{
    /**
    * Number of companies skipped.
    */
    // @ApiMember(Description="Number of companies skipped.")
    int Offset = 0;

    /**
    * Total number of companies matching the filter.
    */
    // @ApiMember(Description="Total number of companies matching the filter.")
    int Total = 0;

    /**
    * Length of the rolling usage window, in days.
    */
    // @ApiMember(Description="Length of the rolling usage window, in days.")
    int WindowDays = 0;

    /**
    * Usage for the requested page of companies.
    */
    // @ApiMember(Description="Usage for the requested page of companies.")
    List<SuperAdminAssistantUsage> Results = [];

    ResponseStatus ResponseStatus;

    SuperAdminAssistantUsageQueryResponse({this.Offset,this.Total,this.WindowDays,this.Results,this.ResponseStatus});
    SuperAdminAssistantUsageQueryResponse.fromJson(Map<String, dynamic> json) { fromMap(json); }

    fromMap(Map<String, dynamic> json) {
        Offset = json['Offset'];
        Total = json['Total'];
        WindowDays = json['WindowDays'];
        Results = JsonConverters.fromJson(json['Results'],'List<SuperAdminAssistantUsage>',context!);
        ResponseStatus = JsonConverters.fromJson(json['ResponseStatus'],'ResponseStatus',context!);
        return this;
    }

    Map<String, dynamic> toJson() => {
        'Offset': Offset,
        'Total': Total,
        'WindowDays': WindowDays,
        'Results': JsonConverters.toJson(Results,'List<SuperAdminAssistantUsage>',context!),
        'ResponseStatus': JsonConverters.toJson(ResponseStatus,'ResponseStatus',context!)
    };

    getTypeName() => "SuperAdminAssistantUsageQueryResponse";
    TypeContext? context = _ctx;
}

// @ApiResponse(Description="You were unauthorized to call this service", StatusCode=401)
// @ApiResponse(Description="You have too low privileges to call this service", StatusCode=403)
// @ValidateRequest(Validator="IsAuthenticated")
class SuperAdminAssistantUsageQuery implements IConvertible
{
    /**
    * Filter on company name. Case-insensitive substring match.
    */
    // @ApiMember(DataType="string", Description="Filter on company name. Case-insensitive substring match.", ParameterType="query")
    String? Search;

    /**
    * Return only this company. Takes precedence over Search when both are set.
    */
    // @ApiMember(DataType="string", Description="Return only this company. Takes precedence over Search when both are set.", ParameterType="query")
    String? CompanyId;

    /**
    * Number of companies to skip.
    */
    // @ApiMember(DataType="integer", Description="Number of companies to skip.", ParameterType="query")
    int? Skip;

    /**
    * Number of companies to return. Capped server-side.
    */
    // @ApiMember(DataType="integer", Description="Number of companies to return. Capped server-side.", ParameterType="query")
    int? Take;

    SuperAdminAssistantUsageQuery({this.Search,this.CompanyId,this.Skip,this.Take});
    SuperAdminAssistantUsageQuery.fromJson(Map<String, dynamic> json) { fromMap(json); }

    fromMap(Map<String, dynamic> json) {
        Search = json['Search'];
        CompanyId = json['CompanyId'];
        Skip = json['Skip'];
        Take = json['Take'];
        return this;
    }

    Map<String, dynamic> toJson() => {
        'Search': Search,
        'CompanyId': CompanyId,
        'Skip': Skip,
        'Take': Take
    };

    getTypeName() => "SuperAdminAssistantUsageQuery";
    TypeContext? context = _ctx;
}

TypeContext _ctx = TypeContext(library: 'testapi.bokamera.se', types: <String, TypeInfo> {
    'AssistantUsageMeter': TypeInfo(TypeOf.Class, create:() => AssistantUsageMeter()),
    'SuperAdminAssistantUsage': TypeInfo(TypeOf.Class, create:() => SuperAdminAssistantUsage()),
    'SuperAdminAssistantUsageQueryResponse': TypeInfo(TypeOf.Class, create:() => SuperAdminAssistantUsageQueryResponse()),
    'List<SuperAdminAssistantUsage>': TypeInfo(TypeOf.Class, create:() => <SuperAdminAssistantUsage>[]),
    'SuperAdminAssistantUsageQuery': TypeInfo(TypeOf.Class, create:() => SuperAdminAssistantUsageQuery()),
});

Dart SuperAdminAssistantUsageQuery DTOs

To override the Content-type in your clients, use the HTTP Accept Header, append the .csv suffix or ?format=csv

HTTP + CSV

The following are sample HTTP requests and responses. The placeholders shown need to be replaced with actual values.

GET /superadmin/assistant/usage HTTP/1.1 
Host: testapi.bokamera.se 
Accept: text/csv
HTTP/1.1 200 OK
Content-Type: text/csv
Content-Length: length

{"Offset":0,"Total":0,"WindowDays":0,"Results":[{"CompanyName":"String","AiChat":{"TokensUsed":0,"TokenLimit":0,"TokensRemaining":0,"PercentUsed":0,"IsWithinBudget":false},"Mcp":{"TokensUsed":0,"TokenLimit":0,"TokensRemaining":0,"PercentUsed":0,"IsWithinBudget":false}}],"ResponseStatus":{"ErrorCode":"String","Message":"String","StackTrace":"String","Errors":[{"ErrorCode":"String","FieldName":"String","Message":"String","Meta":{"String":"String"}}],"Meta":{"String":"String"}}}