openapi: 3.2.0 info: title: APImetrics Account API description: API for the APImetrics platform termsOfService: http://apimetrics.io/tos/ contact: name: APIContext Support url: https://apicontext.io/ email: support@apicontext.com license: name: Apache 2.0 url: https://www.apache.org/licenses/LICENSE-2.0.html version: v2026-09-02 tags: - name: Account description: View and update the caller's own Auth0 account profile. paths: /api/2/account/: get: tags: - Account summary: Get-Account description: Return the caller's Auth0 profile fields. operationId: get-account responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/AccountProfileResponse' security: - OAuth2: [] - ApiKey: [] put: tags: - Account summary: Update-Account-Put description: Update the caller's Auth0 profile via the Management API. operationId: update-account-put requestBody: content: application/json: schema: $ref: '#/components/schemas/UpdateAccountBody' required: true responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/AccountProfileResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' security: - OAuth2: [] - ApiKey: [] /api/2/account/billing: get: tags: - Account summary: Get-Account-Billing description: Billing summary for every org/project the caller can bill for. operationId: get-account-billing deprecated: true security: - OAuth2: [] - ApiKey: [] parameters: - name: apimetrics-project-id in: header required: false schema: anyOf: - type: string - type: 'null' title: Apimetrics-Project-Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/BillingResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/2/account/quota: get: tags: - Account summary: Get-Account-Quota description: Quota and current usage for the caller's active project. operationId: get-account-quota deprecated: true security: - OAuth2: [] - ApiKey: [] parameters: - name: clear_cache in: query required: false schema: anyOf: - type: string - type: 'null' title: Clear Cache - name: apimetrics-project-id in: header required: false schema: anyOf: - type: string - type: 'null' title: Apimetrics-Project-Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/api2__account__billing__QuotaResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/2/account/verify: post: tags: - Account summary: Verify-Account-Email description: (Re)send the caller's email-verification message if not yet verified. operationId: verify-account-email responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/StatusResponse' security: - OAuth2: [] - ApiKey: [] /api/2/account/reset_password: post: tags: - Account summary: Reset-Account-Password description: Send a password-reset email (own address, or another if authorised). operationId: reset-account-password security: - OAuth2: [] - ApiKey: [] parameters: - name: Apimetrics-Project-Id in: header required: false schema: anyOf: - type: string - type: 'null' title: Apimetrics-Project-Id requestBody: content: application/json: schema: anyOf: - $ref: '#/components/schemas/ResetPasswordBody' - type: 'null' title: Body responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/StatusResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/2/account/projects: get: tags: - Account summary: List-Account-Projects description: 'List the projects and organizations the caller can access. Returns the ``{meta, projects, organizations}`` envelope: ``meta`` carries the caller''s account id, org roles, and permissions; ``projects`` lists each reachable project (direct grants and org-role grants merged, highest access kept); ``organizations`` maps each relevant org id to its details. The project the frontend is currently viewing (the stateless replacement for the legacy session value) lets a site-level caller see that project even when they hold no explicit grant on it. The frontend does not always send the ``Apimetrics-Project-Id`` header on this call -- notably the site-admin project picker selects a non-member project without setting it -- but it always sets the same-origin ``current-project-id`` cookie, so fall back to that (legacy read the equivalent value from its server-side session).' operationId: list-account-projects security: - OAuth2: [] - ApiKey: [] parameters: - name: apimetrics-project-id in: header required: false schema: anyOf: - type: string - type: 'null' title: Apimetrics-Project-Id - name: current-project-id in: cookie required: false schema: anyOf: - type: string - type: 'null' title: Current-Project-Id responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/AccountProjectsResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' post: tags: - Account summary: Create-Account-Project description: Create a new personal project owned by the caller. operationId: create-account-project security: - OAuth2: [] - ApiKey: [] requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateAccountProjectBody' responses: '200': description: Successful Response content: application/json: schema: $ref: '#/components/schemas/AccountProjectAccessResponse' '422': description: Validation Error content: application/json: schema: $ref: '#/components/schemas/HTTPValidationError' /api/2/account/subscription/proj/{sub_id}: get: operationId: get-project-subscription summary: Get subscription for a project tags: - Account security: - OAuth2: [] parameters: - $ref: '#/components/parameters/subId' responses: '200': description: Subscription details post: operationId: update-project-subscription summary: Update subscription for a project tags: - Account security: - OAuth2: [] parameters: - $ref: '#/components/parameters/subId' requestBody: required: true content: application/json: schema: type: object responses: '200': description: Updated subscription /api/2/account/subscription/proj/{sub_id}/usage: get: operationId: get-project-usage summary: Get usage statistics for a project subscription tags: - Account security: - OAuth2: [] parameters: - $ref: '#/components/parameters/subId' responses: '200': description: Usage statistics /api/2/account/subscription/org/{sub_id}: get: operationId: get-org-subscription summary: Get subscription for an organisation tags: - Account security: - OAuth2: [] parameters: - $ref: '#/components/parameters/subId' responses: '200': description: Subscription details post: operationId: update-org-subscription summary: Update subscription for an organisation tags: - Account security: - OAuth2: [] parameters: - $ref: '#/components/parameters/subId' requestBody: required: true content: application/json: schema: type: object responses: '200': description: Updated subscription /api/2/account/subscription/org/{sub_id}/usage: get: operationId: get-org-usage summary: Get usage statistics for an organisation subscription tags: - Account security: - OAuth2: [] parameters: - $ref: '#/components/parameters/subId' responses: '200': description: Usage statistics components: schemas: KeyStr: type: string description: URL-safe base64 Datastore key minLength: 3 maxLength: 400 pattern: ^[-A-Za-z0-9_]*={0,3}$ ProjectResponse: properties: id: type: string title: Id name: type: string title: Name org_id: type: string title: Org Id tags: items: type: string type: array title: Tags system_tags: items: type: string type: array title: System Tags last_update: anyOf: - type: string format: date-time - type: 'null' title: Last Update created: anyOf: - type: string format: date-time - type: 'null' title: Created security_profile: anyOf: - type: string - type: 'null' title: Security Profile email: anyOf: - type: string - type: 'null' title: Email sub_info: anyOf: - additionalProperties: true type: object - type: 'null' title: Sub Info type: object required: - id - name - org_id - tags - system_tags - last_update - created - security_profile title: ProjectResponse examples: - created: '2026-06-19T09:06:47.046143Z' id: ahFkZXZ-YXBpbWV0cmljcy1xY3ILCxIEVXNlchieQgw last_update: '2026-06-19T09:06:47.046170Z' name: Project 1 org_id: apicontext sub_info: counts: org_test_run_count: 0 public_report_count: 0 scheduled_test_count: 288 test_setup_count: 4 user_test_run_count: 0 month_progress: 0.814 quotas: public_report_quota: 10 test_run_quota: 1000000 test_setup_quota: 1000 sub: backend: azure level: CONTRACT name: Enterprise org_id: apicontext plan: enterprise tags: [] api2__account__billing__QuotaResponse: properties: sub: $ref: '#/components/schemas/SubDetail' quotas: $ref: '#/components/schemas/QuotaLimits' counts: $ref: '#/components/schemas/QuotaCounts' has_trial_expired: anyOf: - type: boolean - type: 'null' title: Has Trial Expired trial_expiry_date: anyOf: - type: string format: date-time - type: 'null' title: Trial Expiry Date month_progress: type: number title: Month Progress billing_admin_id: anyOf: - type: string - type: 'null' title: Billing Admin Id type: object required: - sub - quotas - counts - month_progress title: QuotaResponse description: '``GET /api/2/account/quota`` -- the caller''s project quota/usage. Identical to :class:`SubInfo` with the legacy top-level ``billing_admin_id`` the quota handler injects when the project bills through an org admin.' UpdateAccountBody: properties: given_name: anyOf: - type: string - type: 'null' title: Given Name family_name: anyOf: - type: string - type: 'null' title: Family Name name: anyOf: - type: string - type: 'null' title: Name nickname: anyOf: - type: string - type: 'null' title: Nickname picture: anyOf: - type: string - type: 'null' title: Picture use_mfa: anyOf: - type: boolean - type: 'null' title: Use Mfa fav_orgs: anyOf: - items: type: string type: array - type: 'null' title: Fav Orgs fav_projects: anyOf: - items: type: string type: array - type: 'null' title: Fav Projects type: object title: UpdateAccountBody ResetPasswordBody: properties: email: anyOf: - type: string - type: 'null' title: Email description: Address to send the reset email to. Only honoured for site admins and admins of the project named in the ``Apimetrics-Project-Id`` header; otherwise the caller's own address is always used. type: object title: ResetPasswordBody examples: - email: colleague@example.com BillingMeta: properties: account_id: type: string title: Account Id roles: additionalProperties: items: type: string type: array type: object title: Roles permissions: items: type: string type: array title: Permissions current_project_id: anyOf: - type: string - type: 'null' title: Current Project Id type: object required: - account_id title: BillingMeta BillingResponse: properties: meta: $ref: '#/components/schemas/BillingMeta' results: items: $ref: '#/components/schemas/BillingResult' type: array title: Results type: object required: - meta title: BillingResponse description: '``GET /api/2/account/billing`` -- everything the caller can bill for.' AccountProjectAccessResponse: properties: id: type: string title: Id project: anyOf: - $ref: '#/components/schemas/ProjectResponse' - type: 'null' access_level: type: string title: Access Level account_id: anyOf: - type: string - type: 'null' title: Account Id account_email: anyOf: - type: string - type: 'null' title: Account Email role_id: anyOf: - type: string - type: 'null' title: Role Id last_update: anyOf: - type: string format: date-time - type: 'null' title: Last Update created: anyOf: - type: string format: date-time - type: 'null' title: Created type: object required: - id - access_level title: AccountProjectAccessResponse description: 'A single project the account can reach. Direct grants (``AccountProject``) carry ``account_id``/``account_email``; org-role grants (``ProjectRole``) carry ``role_id`` instead.' examples: - access_level: OWNER account_email: user@example.com account_id: auth0|abc123 created: '2026-06-19T09:06:47.046143Z' id: ahFkZXZ-YXBpbWV0cmljcy1xY3ILCxIHQWNjb3VudBiAgIDg6 last_update: '2026-06-19T09:06:47.046170Z' project: created: '2026-06-19T09:06:47.046143Z' id: ahFkZXZ-YXBpbWV0cmljcy1xY3ILCxIEVXNlchieQgw last_update: '2026-06-19T09:06:47.046170Z' name: Project 1 org_id: apicontext sub_info: counts: org_test_run_count: 0 public_report_count: 0 scheduled_test_count: 288 test_setup_count: 4 user_test_run_count: 0 month_progress: 0.814 quotas: public_report_quota: 10 test_run_quota: 1000000 test_setup_quota: 1000 sub: backend: azure level: CONTRACT name: Enterprise org_id: apicontext plan: enterprise tags: [] AccountProjectsResponse: properties: meta: $ref: '#/components/schemas/AccountProjectsMeta' projects: items: $ref: '#/components/schemas/AccountProjectAccessResponse' type: array title: Projects organizations: additionalProperties: $ref: '#/components/schemas/OrgResponse' type: object title: Organizations type: object required: - meta - projects - organizations title: AccountProjectsResponse QuotaCounts: properties: user_test_run_count: type: integer title: User Test Run Count org_test_run_count: type: integer title: Org Test Run Count test_setup_count: type: integer title: Test Setup Count public_report_count: type: integer title: Public Report Count scheduled_test_count: type: integer title: Scheduled Test Count type: object required: - user_test_run_count - org_test_run_count - test_setup_count - public_report_count - scheduled_test_count title: QuotaCounts description: The current usage counts (``QuotaInfo.counts``). AccountInviteResponse: properties: id: type: string title: Id invited_by: type: string title: Invited By invited_email: anyOf: - type: string - type: 'null' title: Invited Email email: type: string title: Email org_id: anyOf: - type: string - type: 'null' title: Org Id project_id: anyOf: - type: string - type: 'null' title: Project Id name: anyOf: - type: string - type: 'null' title: Name access_level: type: string title: Access Level roles: items: type: string type: array title: Roles last_update: anyOf: - type: string format: date-time - type: 'null' title: Last Update created: anyOf: - type: string format: date-time - type: 'null' title: Created type: object required: - id - invited_by - email - access_level title: AccountInviteResponse CreateAccountProjectBody: properties: name: anyOf: - type: string - type: 'null' title: Name type: object title: CreateAccountProjectBody examples: - name: New Project StatusResponse: properties: status: type: string title: Status type: object required: - status title: StatusResponse ValidationError: properties: loc: items: anyOf: - type: string - type: integer type: array title: Location msg: type: string title: Message type: type: string title: Error Type input: title: Input ctx: type: object title: Context type: object required: - loc - msg - type title: ValidationError BillingResult: properties: id: type: string title: Id org_id: type: string title: Org Id name: type: string title: Name system_tags: items: type: string type: array title: System Tags subscription_level: type: string title: Subscription Level sub_info: $ref: '#/components/schemas/api2__account__billing__SubInfo' type: object required: - id - org_id - name - subscription_level - sub_info title: BillingResult description: One billable entity (an org the caller can bill, or an owned project). api2__account__billing__SubInfo: properties: sub: $ref: '#/components/schemas/SubDetail' quotas: $ref: '#/components/schemas/QuotaLimits' counts: $ref: '#/components/schemas/QuotaCounts' has_trial_expired: anyOf: - type: boolean - type: 'null' title: Has Trial Expired trial_expiry_date: anyOf: - type: string format: date-time - type: 'null' title: Trial Expiry Date month_progress: type: number title: Month Progress type: object required: - sub - quotas - counts - month_progress title: SubInfo description: The ``SubLevelManager.to_json`` payload, shared by quota and billing. AccountProjectsMeta: properties: account_id: type: string title: Account Id roles: additionalProperties: items: type: string type: array type: object title: Roles permissions: items: type: string type: array title: Permissions current_project_id: anyOf: - type: string - type: 'null' title: Current Project Id invites: items: $ref: '#/components/schemas/AccountInviteResponse' type: array title: Invites new_project: type: boolean title: New Project default: false verify_needed: type: boolean title: Verify Needed default: false type: object required: - account_id title: AccountProjectsMeta HTTPValidationError: properties: detail: items: $ref: '#/components/schemas/ValidationError' type: array title: Detail type: object title: HTTPValidationError QuotaLimits: properties: test_run_quota: type: integer title: Test Run Quota test_setup_quota: type: integer title: Test Setup Quota public_report_quota: type: integer title: Public Report Quota type: object required: - test_run_quota - test_setup_quota - public_report_quota title: QuotaLimits description: The per-plan quota limits (``QuotaInfo.quotas``). OrgResponse: properties: id: type: string title: Id name: type: string title: Name subscription_level: type: string title: Subscription Level billing_admin_id: anyOf: - type: string - type: 'null' title: Billing Admin Id enforce_2fa: type: boolean title: Enforce 2Fa default: false kms_enabled: type: boolean title: Kms Enabled default: false password_expiry_days: type: integer title: Password Expiry Days default: 0 tags: items: type: string type: array title: Tags system_tags: items: type: string type: array title: System Tags last_update: anyOf: - type: string format: date-time - type: 'null' title: Last Update created: anyOf: - type: string format: date-time - type: 'null' title: Created sub_info: anyOf: - additionalProperties: true type: object - type: 'null' title: Sub Info type: object required: - id - name - subscription_level title: OrgResponse AccountProfileResponse: properties: given_name: anyOf: - type: string - type: 'null' title: Given Name family_name: anyOf: - type: string - type: 'null' title: Family Name name: anyOf: - type: string - type: 'null' title: Name nickname: anyOf: - type: string - type: 'null' title: Nickname picture: anyOf: - type: string - type: 'null' title: Picture type: object title: AccountProfileResponse SubDetail: properties: level: type: string title: Level name: type: string title: Name plan: type: string title: Plan start: anyOf: - type: string - type: 'null' title: Start end: anyOf: - type: string - type: 'null' title: End state: anyOf: - type: string - type: 'null' title: State org_id: anyOf: - type: string - type: 'null' title: Org Id backend: anyOf: - type: string - type: 'null' title: Backend type: object required: - level - name - plan title: SubDetail description: The subscription summary (``QuotaInfo.sub``). parameters: subId: name: sub_id in: path required: true description: Project or organisation subscription ID schema: $ref: '#/components/schemas/KeyStr' securitySchemes: OAuth2: type: oauth2 flows: authorizationCode: scopes: openid: OpenID Connect identity profile: User profile email: User email address authorizationUrl: https://auth.apimetrics.io/authorize?audience=https://client.apimetrics.io tokenUrl: https://auth.apimetrics.io/oauth/token ApiKey: type: apiKey in: header name: X-Api-Key