{
  "components": {
    "securitySchemes": {
      "apiToken": {
        "bearerFormat": "xrt_",
        "description": "A manager API token. Its authority is the intersection of the issuing manager's live permission set and the token's own scope, recomputed on every request — so editing the owner's roles immediately narrows every token they hold.",
        "scheme": "bearer",
        "type": "http"
      }
    }
  },
  "info": {
    "description": "Public REST API for X-Radius. Every screen in the operator portal calls this surface.",
    "title": "X-Radius API",
    "version": "1"
  },
  "openapi": "3.1.0",
  "paths": {
    "/api/v1/addons": {
      "get": {
        "description": "",
        "operationId": "addons_get-addons",
        "summary": "Sell add-ons",
        "tags": [
          "addons"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_users_addon"
      }
    },
    "/api/v1/admin/addons": {
      "get": {
        "description": "",
        "operationId": "addons_get-admin-addons",
        "summary": "View add-ons",
        "tags": [
          "addons"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_addons_index"
      },
      "post": {
        "description": "",
        "operationId": "addons_post-admin-addons",
        "summary": "Manage add-ons",
        "tags": [
          "addons"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_addons_manage"
      }
    },
    "/api/v1/admin/addons/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "addons_post-admin-addons-bulk-delete",
        "summary": "Manage add-ons",
        "tags": [
          "addons"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_addons_manage"
      }
    },
    "/api/v1/admin/addons/{id}": {
      "delete": {
        "description": "",
        "operationId": "addons_delete-admin-addons",
        "summary": "Manage add-ons",
        "tags": [
          "addons"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_addons_manage"
      },
      "patch": {
        "description": "",
        "operationId": "addons_patch-admin-addons",
        "summary": "Manage add-ons",
        "tags": [
          "addons"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_addons_manage"
      }
    },
    "/api/v1/admin/addons/{id}/allowed-profiles": {
      "get": {
        "description": "",
        "operationId": "addons_get-admin-addons-allowed-profiles",
        "summary": "View add-ons",
        "tags": [
          "addons"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_addons_index"
      },
      "put": {
        "description": "",
        "operationId": "addons_put-admin-addons-allowed-profiles",
        "summary": "Manage add-ons",
        "tags": [
          "addons"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_addons_manage"
      }
    },
    "/api/v1/admin/backup/destinations": {
      "get": {
        "description": "",
        "operationId": "backup_get-admin-backup-destinations",
        "summary": "Manage settings",
        "tags": [
          "backup"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_settings"
      },
      "patch": {
        "description": "",
        "operationId": "backup_patch-admin-backup-destinations",
        "summary": "Manage settings",
        "tags": [
          "backup"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_settings"
      },
      "post": {
        "description": "",
        "operationId": "backup_post-admin-backup-destinations",
        "summary": "Manage settings",
        "tags": [
          "backup"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_settings"
      }
    },
    "/api/v1/admin/backup/destinations/{provider}": {
      "delete": {
        "description": "",
        "operationId": "backup_delete-admin-backup-destinations",
        "summary": "Manage settings",
        "tags": [
          "backup"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_settings"
      }
    },
    "/api/v1/admin/backup/destinations/{provider}/connect": {
      "post": {
        "description": "",
        "operationId": "backup_post-admin-backup-destinations-connect",
        "summary": "Manage settings",
        "tags": [
          "backup"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_probe",
        "x-required-permission": "prm_settings"
      }
    },
    "/api/v1/admin/backup/destinations/{provider}/test": {
      "post": {
        "description": "",
        "operationId": "backup_post-admin-backup-destinations-test",
        "summary": "Manage settings",
        "tags": [
          "backup"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_probe",
        "x-required-permission": "prm_settings"
      }
    },
    "/api/v1/admin/backup/remote-types": {
      "get": {
        "description": "",
        "operationId": "backup_get-admin-backup-remote-types",
        "summary": "Manage settings",
        "tags": [
          "backup"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_settings"
      }
    },
    "/api/v1/admin/cards/redeem-otc": {
      "post": {
        "description": "The same operation as the subscriber-facing redeem, with one difference: the acting manager is recorded as the reseller, so the redemption snapshots what they paid against what they charged. Without that, per-reseller pricing never resolves and every redemption records face value on both sides.",
        "operationId": "cards_post-admin-cards-redeem-otc",
        "summary": "Redeem a card over the counter",
        "tags": [
          "cards"
        ],
        "x-auth": "manager",
        "x-idempotent-on": "request_id",
        "x-rate-limit-bucket": "card_redeem",
        "x-required-permission": "prm_cards_verify"
      }
    },
    "/api/v1/admin/cards/redeem-to-wallet": {
      "post": {
        "description": "",
        "operationId": "cards_post-admin-cards-redeem-to-wallet",
        "summary": "Top up own wallet online",
        "tags": [
          "cards"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "card_wallet_redeem",
        "x-required-permission": "prm_managers_self_deposit"
      }
    },
    "/api/v1/admin/cards/redemptions/{id}": {
      "get": {
        "description": "",
        "operationId": "cards_get-admin-cards-redemptions",
        "summary": "View card batches \u0026 cards",
        "tags": [
          "cards"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_cards_list"
      }
    },
    "/api/v1/admin/cards/redemptions/{id}/reversals": {
      "get": {
        "description": "",
        "operationId": "cards_get-admin-cards-redemptions-reversals",
        "summary": "View card batches \u0026 cards",
        "tags": [
          "cards"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_cards_list"
      },
      "post": {
        "description": "",
        "operationId": "cards_post-admin-cards-redemptions-reversals",
        "summary": "Refund last activation",
        "tags": [
          "cards"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_refund"
      }
    },
    "/api/v1/admin/console-sessions": {
      "delete": {
        "description": "",
        "operationId": "console-sessions_delete-admin-console-sessions",
        "summary": "DELETE /api/v1/admin/console-sessions",
        "tags": [
          "console-sessions"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-any-permission": [
          "prm_nas_remote",
          "prm_nas_devices_remote"
        ]
      },
      "get": {
        "description": "",
        "operationId": "console-sessions_get-admin-console-sessions",
        "summary": "GET /api/v1/admin/console-sessions",
        "tags": [
          "console-sessions"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-any-permission": [
          "prm_nas_remote",
          "prm_nas_devices_remote"
        ]
      }
    },
    "/api/v1/admin/console-sessions/bulk-close": {
      "post": {
        "description": "",
        "operationId": "console-sessions_post-admin-console-sessions-bulk-close",
        "summary": "POST /api/v1/admin/console-sessions/bulk-close",
        "tags": [
          "console-sessions"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-any-permission": [
          "prm_nas_remote",
          "prm_nas_devices_remote"
        ]
      }
    },
    "/api/v1/admin/console-sessions/{sid}": {
      "delete": {
        "description": "",
        "operationId": "console-sessions_delete-admin-console-sessions-by-sid",
        "summary": "DELETE /api/v1/admin/console-sessions/{sid}",
        "tags": [
          "console-sessions"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-any-permission": [
          "prm_nas_remote",
          "prm_nas_devices_remote"
        ]
      }
    },
    "/api/v1/admin/dashboards/me": {
      "get": {
        "description": "",
        "operationId": "dashboards_get-admin-dashboards-me",
        "summary": "GET /api/v1/admin/dashboards/me",
        "tags": [
          "dashboards"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_values"
      }
    },
    "/api/v1/admin/dashboards/me/appearance": {
      "put": {
        "description": "",
        "operationId": "dashboards_put-admin-dashboards-me-appearance",
        "summary": "PUT /api/v1/admin/dashboards/me/appearance",
        "tags": [
          "dashboards"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/admin/dashboards/me/customize": {
      "delete": {
        "description": "",
        "operationId": "dashboards_delete-admin-dashboards-me-customize",
        "summary": "DELETE /api/v1/admin/dashboards/me/customize",
        "tags": [
          "dashboards"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      },
      "put": {
        "description": "",
        "operationId": "dashboards_put-admin-dashboards-me-customize",
        "summary": "PUT /api/v1/admin/dashboards/me/customize",
        "tags": [
          "dashboards"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/admin/dashboards/me/designed": {
      "get": {
        "description": "",
        "operationId": "dashboards_get-admin-dashboards-me-designed",
        "summary": "GET /api/v1/admin/dashboards/me/designed",
        "tags": [
          "dashboards"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy"
      }
    },
    "/api/v1/admin/dashboards/me/tiles/{id}": {
      "get": {
        "description": "",
        "operationId": "dashboards_get-admin-dashboards-me-tiles",
        "summary": "GET /api/v1/admin/dashboards/me/tiles/{id}",
        "tags": [
          "dashboards"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_values"
      }
    },
    "/api/v1/admin/dashboards/me/values": {
      "get": {
        "description": "",
        "operationId": "dashboards_get-admin-dashboards-me-values",
        "summary": "GET /api/v1/admin/dashboards/me/values",
        "tags": [
          "dashboards"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_values"
      }
    },
    "/api/v1/admin/dashboards/support": {
      "get": {
        "description": "",
        "operationId": "dashboards_get-admin-dashboards-support",
        "summary": "View support tickets",
        "tags": [
          "dashboards"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_tickets_view"
      }
    },
    "/api/v1/admin/devgw/ssh/ws": {
      "connect": {
        "description": "",
        "operationId": "devgw_connect-admin-devgw-ssh-ws",
        "summary": "CONNECT /api/v1/admin/devgw/ssh/ws",
        "tags": [
          "devgw"
        ],
        "x-auth": "public",
        "x-generated-stub": true
      },
      "delete": {
        "description": "",
        "operationId": "devgw_delete-admin-devgw-ssh-ws",
        "summary": "DELETE /api/v1/admin/devgw/ssh/ws",
        "tags": [
          "devgw"
        ],
        "x-auth": "public",
        "x-generated-stub": true
      },
      "get": {
        "description": "",
        "operationId": "devgw_get-admin-devgw-ssh-ws",
        "summary": "GET /api/v1/admin/devgw/ssh/ws",
        "tags": [
          "devgw"
        ],
        "x-auth": "public",
        "x-generated-stub": true
      },
      "head": {
        "description": "",
        "operationId": "devgw_head-admin-devgw-ssh-ws",
        "summary": "HEAD /api/v1/admin/devgw/ssh/ws",
        "tags": [
          "devgw"
        ],
        "x-auth": "public",
        "x-generated-stub": true
      },
      "options": {
        "description": "",
        "operationId": "devgw_options-admin-devgw-ssh-ws",
        "summary": "OPTIONS /api/v1/admin/devgw/ssh/ws",
        "tags": [
          "devgw"
        ],
        "x-auth": "public",
        "x-generated-stub": true
      },
      "patch": {
        "description": "",
        "operationId": "devgw_patch-admin-devgw-ssh-ws",
        "summary": "PATCH /api/v1/admin/devgw/ssh/ws",
        "tags": [
          "devgw"
        ],
        "x-auth": "public",
        "x-generated-stub": true
      },
      "post": {
        "description": "",
        "operationId": "devgw_post-admin-devgw-ssh-ws",
        "summary": "POST /api/v1/admin/devgw/ssh/ws",
        "tags": [
          "devgw"
        ],
        "x-auth": "public",
        "x-generated-stub": true
      },
      "put": {
        "description": "",
        "operationId": "devgw_put-admin-devgw-ssh-ws",
        "summary": "PUT /api/v1/admin/devgw/ssh/ws",
        "tags": [
          "devgw"
        ],
        "x-auth": "public",
        "x-generated-stub": true
      },
      "query": {
        "description": "",
        "operationId": "devgw_query-admin-devgw-ssh-ws",
        "summary": "QUERY /api/v1/admin/devgw/ssh/ws",
        "tags": [
          "devgw"
        ],
        "x-auth": "public",
        "x-generated-stub": true
      },
      "trace": {
        "description": "",
        "operationId": "devgw_trace-admin-devgw-ssh-ws",
        "summary": "TRACE /api/v1/admin/devgw/ssh/ws",
        "tags": [
          "devgw"
        ],
        "x-auth": "public",
        "x-generated-stub": true
      }
    },
    "/api/v1/admin/email-templates": {
      "get": {
        "description": "",
        "operationId": "email-templates_get-admin-email-templates",
        "summary": "Manage notification channels \u0026 templates",
        "tags": [
          "email-templates"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_notifications_manage"
      },
      "post": {
        "description": "",
        "operationId": "email-templates_post-admin-email-templates",
        "summary": "Manage notification channels \u0026 templates",
        "tags": [
          "email-templates"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_notifications_manage"
      }
    },
    "/api/v1/admin/email-templates/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "email-templates_post-admin-email-templates-bulk-delete",
        "summary": "Manage notification channels \u0026 templates",
        "tags": [
          "email-templates"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_notifications_manage"
      }
    },
    "/api/v1/admin/email-templates/preview": {
      "post": {
        "description": "",
        "operationId": "email-templates_post-admin-email-templates-preview",
        "summary": "Manage notification channels \u0026 templates",
        "tags": [
          "email-templates"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_notifications_manage"
      }
    },
    "/api/v1/admin/email-templates/test": {
      "post": {
        "description": "",
        "operationId": "email-templates_post-admin-email-templates-test",
        "summary": "Manage notification channels \u0026 templates",
        "tags": [
          "email-templates"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_notifications_manage"
      }
    },
    "/api/v1/admin/email-templates/{id}": {
      "delete": {
        "description": "",
        "operationId": "email-templates_delete-admin-email-templates",
        "summary": "Manage notification channels \u0026 templates",
        "tags": [
          "email-templates"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_notifications_manage"
      }
    },
    "/api/v1/admin/forms": {
      "get": {
        "description": "",
        "operationId": "forms_get-admin-forms",
        "summary": "Manage custom form fields",
        "tags": [
          "forms"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_forms_manage"
      },
      "post": {
        "description": "",
        "operationId": "forms_post-admin-forms",
        "summary": "Manage custom form fields",
        "tags": [
          "forms"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_forms_manage"
      }
    },
    "/api/v1/admin/forms/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "forms_post-admin-forms-bulk-delete",
        "summary": "Manage custom form fields",
        "tags": [
          "forms"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_forms_manage"
      }
    },
    "/api/v1/admin/forms/manifest": {
      "get": {
        "description": "",
        "operationId": "forms_get-admin-forms-manifest",
        "summary": "Create users",
        "tags": [
          "forms"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_users_create"
      }
    },
    "/api/v1/admin/forms/reorder": {
      "post": {
        "description": "",
        "operationId": "forms_post-admin-forms-reorder",
        "summary": "Manage custom form fields",
        "tags": [
          "forms"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_forms_manage"
      }
    },
    "/api/v1/admin/forms/{form_name}/schema": {
      "get": {
        "description": "",
        "operationId": "forms_get-admin-forms-schema",
        "summary": "Create users",
        "tags": [
          "forms"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_users_create"
      }
    },
    "/api/v1/admin/forms/{id}": {
      "delete": {
        "description": "",
        "operationId": "forms_delete-admin-forms",
        "summary": "Manage custom form fields",
        "tags": [
          "forms"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_forms_manage"
      },
      "patch": {
        "description": "",
        "operationId": "forms_patch-admin-forms",
        "summary": "Manage custom form fields",
        "tags": [
          "forms"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_forms_manage"
      }
    },
    "/api/v1/admin/groups": {
      "get": {
        "description": "",
        "operationId": "groups_get-admin-groups",
        "summary": "View groups",
        "tags": [
          "groups"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_groups_index"
      },
      "post": {
        "description": "",
        "operationId": "groups_post-admin-groups",
        "summary": "Create groups",
        "tags": [
          "groups"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_groups_create"
      }
    },
    "/api/v1/admin/groups/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "groups_post-admin-groups-bulk-delete",
        "summary": "Delete groups",
        "tags": [
          "groups"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_groups_delete"
      }
    },
    "/api/v1/admin/groups/{id}": {
      "delete": {
        "description": "",
        "operationId": "groups_delete-admin-groups",
        "summary": "Delete groups",
        "tags": [
          "groups"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_groups_delete"
      },
      "put": {
        "description": "",
        "operationId": "groups_put-admin-groups",
        "summary": "Edit groups",
        "tags": [
          "groups"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_groups_update"
      }
    },
    "/api/v1/admin/import/fields": {
      "get": {
        "description": "",
        "operationId": "import_get-admin-import-fields",
        "summary": "Import data",
        "tags": [
          "import"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tools_import"
      }
    },
    "/api/v1/admin/import/jobs": {
      "get": {
        "description": "",
        "operationId": "import_get-admin-import-jobs",
        "summary": "Import data",
        "tags": [
          "import"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tools_import"
      },
      "post": {
        "description": "",
        "operationId": "import_post-admin-import-jobs",
        "summary": "Import data",
        "tags": [
          "import"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_tools_import"
      }
    },
    "/api/v1/admin/import/jobs/{id}": {
      "get": {
        "description": "",
        "operationId": "import_get-admin-import-jobs-by-id",
        "summary": "Import data",
        "tags": [
          "import"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tools_import"
      }
    },
    "/api/v1/admin/import/jobs/{id}/cancel": {
      "post": {
        "description": "",
        "operationId": "import_post-admin-import-jobs-cancel",
        "summary": "Import data",
        "tags": [
          "import"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tools_import"
      }
    },
    "/api/v1/admin/import/validate": {
      "post": {
        "description": "",
        "operationId": "import_post-admin-import-validate",
        "summary": "Import data",
        "tags": [
          "import"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_tools_import"
      }
    },
    "/api/v1/admin/logs/auth": {
      "get": {
        "description": "",
        "operationId": "logs_get-admin-logs-auth",
        "summary": "User Auth Log",
        "tags": [
          "logs"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_log_auth"
      }
    },
    "/api/v1/admin/logs/system": {
      "get": {
        "description": "",
        "operationId": "logs_get-admin-logs-system",
        "summary": "System Log (manager activity)",
        "tags": [
          "logs"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_log_system"
      }
    },
    "/api/v1/admin/managers/bulk-group": {
      "post": {
        "description": "",
        "operationId": "managers_post-admin-managers-bulk-group",
        "summary": "Assign groups",
        "tags": [
          "managers"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_groups_assign"
      }
    },
    "/api/v1/admin/managers/{id}/group": {
      "post": {
        "description": "",
        "operationId": "managers_post-admin-managers-group",
        "summary": "Assign groups",
        "tags": [
          "managers"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_groups_assign"
      }
    },
    "/api/v1/admin/monitoring/alerts": {
      "get": {
        "description": "",
        "operationId": "monitoring_get-admin-monitoring-alerts",
        "summary": "View monitoring",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_monitoring_view"
      }
    },
    "/api/v1/admin/monitoring/alerts/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "monitoring_post-admin-monitoring-alerts-bulk-delete",
        "summary": "Acknowledge alerts",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_monitoring_ack"
      }
    },
    "/api/v1/admin/monitoring/alerts/clear-all": {
      "post": {
        "description": "",
        "operationId": "monitoring_post-admin-monitoring-alerts-clear-all",
        "summary": "Acknowledge alerts",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_monitoring_ack"
      }
    },
    "/api/v1/admin/monitoring/alerts/unacked-count": {
      "get": {
        "description": "",
        "operationId": "monitoring_get-admin-monitoring-alerts-unacked-count",
        "summary": "View monitoring",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_monitoring_view"
      }
    },
    "/api/v1/admin/monitoring/alerts/{id}/ack": {
      "post": {
        "description": "",
        "operationId": "monitoring_post-admin-monitoring-alerts-ack",
        "summary": "Acknowledge alerts",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_monitoring_ack"
      }
    },
    "/api/v1/admin/monitoring/alerts/{id}/deliveries": {
      "get": {
        "description": "",
        "operationId": "monitoring_get-admin-monitoring-alerts-deliveries",
        "summary": "View monitoring",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_monitoring_view"
      }
    },
    "/api/v1/admin/monitoring/devices": {
      "get": {
        "description": "",
        "operationId": "monitoring_get-admin-monitoring-devices",
        "summary": "View monitoring",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_monitoring_view"
      },
      "post": {
        "description": "",
        "operationId": "monitoring_post-admin-monitoring-devices",
        "summary": "Manage monitored devices \u0026 sensors",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_monitoring_manage"
      }
    },
    "/api/v1/admin/monitoring/devices/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "monitoring_post-admin-monitoring-devices-bulk-delete",
        "summary": "Manage monitored devices \u0026 sensors",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_monitoring_manage"
      }
    },
    "/api/v1/admin/monitoring/devices/{id}": {
      "delete": {
        "description": "",
        "operationId": "monitoring_delete-admin-monitoring-devices",
        "summary": "Manage monitored devices \u0026 sensors",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_monitoring_manage"
      },
      "put": {
        "description": "",
        "operationId": "monitoring_put-admin-monitoring-devices",
        "summary": "Manage monitored devices \u0026 sensors",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_monitoring_manage"
      }
    },
    "/api/v1/admin/monitoring/devices/{kind}/{ref}": {
      "get": {
        "description": "",
        "operationId": "monitoring_get-admin-monitoring-devices-by-ref",
        "summary": "View monitoring",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_monitoring_view"
      }
    },
    "/api/v1/admin/monitoring/devices/{kind}/{ref}/geo": {
      "delete": {
        "description": "",
        "operationId": "monitoring_delete-admin-monitoring-devices-geo",
        "summary": "Edit network map",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_map_edit"
      },
      "put": {
        "description": "",
        "operationId": "monitoring_put-admin-monitoring-devices-geo",
        "summary": "Edit network map",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_map_edit"
      }
    },
    "/api/v1/admin/monitoring/devices/{kind}/{ref}/icon": {
      "put": {
        "description": "",
        "operationId": "monitoring_put-admin-monitoring-devices-icon",
        "summary": "Edit network map",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_map_edit"
      }
    },
    "/api/v1/admin/monitoring/devices/{kind}/{ref}/impact": {
      "get": {
        "description": "",
        "operationId": "monitoring_get-admin-monitoring-devices-impact",
        "summary": "View network map",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_map_view"
      }
    },
    "/api/v1/admin/monitoring/devices/{kind}/{ref}/live-traffic": {
      "get": {
        "description": "",
        "operationId": "monitoring_get-admin-monitoring-devices-live-traffic",
        "summary": "View monitoring",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_probe",
        "x-required-permission": "prm_monitoring_view"
      }
    },
    "/api/v1/admin/monitoring/devices/{kind}/{ref}/live-traffic/stream": {
      "get": {
        "description": "",
        "operationId": "monitoring_get-admin-monitoring-devices-live-traffic-stream",
        "summary": "View monitoring",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_probe",
        "x-required-permission": "prm_monitoring_view"
      }
    },
    "/api/v1/admin/monitoring/devices/{kind}/{ref}/notify": {
      "get": {
        "description": "",
        "operationId": "monitoring_get-admin-monitoring-devices-notify",
        "summary": "View monitoring",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_monitoring_view"
      },
      "put": {
        "description": "",
        "operationId": "monitoring_put-admin-monitoring-devices-notify",
        "summary": "Manage monitored devices \u0026 sensors",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_monitoring_manage"
      }
    },
    "/api/v1/admin/monitoring/devices/{kind}/{ref}/owners": {
      "get": {
        "description": "",
        "operationId": "monitoring_get-admin-monitoring-devices-owners",
        "summary": "View monitoring",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_monitoring_view"
      },
      "put": {
        "description": "",
        "operationId": "monitoring_put-admin-monitoring-devices-owners",
        "summary": "Manage monitored devices \u0026 sensors",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_monitoring_manage"
      }
    },
    "/api/v1/admin/monitoring/devices/{kind}/{ref}/ping": {
      "post": {
        "description": "",
        "operationId": "monitoring_post-admin-monitoring-devices-ping",
        "summary": "Manage monitored devices \u0026 sensors",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_probe",
        "x-required-permission": "prm_monitoring_manage"
      }
    },
    "/api/v1/admin/monitoring/devices/{kind}/{ref}/ping/stream": {
      "get": {
        "description": "",
        "operationId": "monitoring_get-admin-monitoring-devices-ping-stream",
        "summary": "Manage monitored devices \u0026 sensors",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_probe",
        "x-required-permission": "prm_monitoring_manage"
      }
    },
    "/api/v1/admin/monitoring/devices/{kind}/{ref}/share": {
      "post": {
        "description": "",
        "operationId": "monitoring_post-admin-monitoring-devices-share",
        "summary": "View network map",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_egress",
        "x-required-permission": "prm_map_view"
      }
    },
    "/api/v1/admin/monitoring/devices/{kind}/{ref}/snmp-interfaces": {
      "get": {
        "description": "",
        "operationId": "monitoring_get-admin-monitoring-devices-snmp-interfaces",
        "summary": "Manage monitored devices \u0026 sensors",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_probe",
        "x-required-permission": "prm_monitoring_manage"
      }
    },
    "/api/v1/admin/monitoring/devices/{kind}/{ref}/stability": {
      "get": {
        "description": "",
        "operationId": "monitoring_get-admin-monitoring-devices-stability",
        "summary": "View monitoring",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_monitoring_view"
      }
    },
    "/api/v1/admin/monitoring/devices/{kind}/{ref}/users": {
      "get": {
        "description": "",
        "operationId": "monitoring_get-admin-monitoring-devices-users",
        "summary": "View network map",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_map_view"
      },
      "put": {
        "description": "",
        "operationId": "monitoring_put-admin-monitoring-devices-users",
        "summary": "Edit network map",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_map_edit"
      }
    },
    "/api/v1/admin/monitoring/geo": {
      "get": {
        "description": "",
        "operationId": "monitoring_get-admin-monitoring-geo",
        "summary": "View network map",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_map_view"
      }
    },
    "/api/v1/admin/monitoring/geo/hygiene": {
      "get": {
        "description": "",
        "operationId": "monitoring_get-admin-monitoring-geo-hygiene",
        "summary": "View network map",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_map_view"
      }
    },
    "/api/v1/admin/monitoring/geo/import": {
      "post": {
        "description": "",
        "operationId": "monitoring_post-admin-monitoring-geo-import",
        "summary": "Edit network map",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_map_edit"
      }
    },
    "/api/v1/admin/monitoring/geo/incidents": {
      "get": {
        "description": "",
        "operationId": "monitoring_get-admin-monitoring-geo-incidents",
        "summary": "View network map",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_map_view"
      }
    },
    "/api/v1/admin/monitoring/geo/links": {
      "get": {
        "description": "",
        "operationId": "monitoring_get-admin-monitoring-geo-links",
        "summary": "View network map",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_map_view"
      },
      "post": {
        "description": "",
        "operationId": "monitoring_post-admin-monitoring-geo-links",
        "summary": "Edit network map",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_map_edit"
      }
    },
    "/api/v1/admin/monitoring/geo/links/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "monitoring_post-admin-monitoring-geo-links-bulk-delete",
        "summary": "Edit network map",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_map_edit"
      }
    },
    "/api/v1/admin/monitoring/geo/links/{id}": {
      "delete": {
        "description": "",
        "operationId": "monitoring_delete-admin-monitoring-geo-links",
        "summary": "Edit network map",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_map_edit"
      }
    },
    "/api/v1/admin/monitoring/geo/links/{id}/reverse": {
      "post": {
        "description": "",
        "operationId": "monitoring_post-admin-monitoring-geo-links-reverse",
        "summary": "Edit network map",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_map_edit"
      }
    },
    "/api/v1/admin/monitoring/map": {
      "get": {
        "description": "",
        "operationId": "monitoring_get-admin-monitoring-map",
        "summary": "View network map",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_map_view"
      },
      "put": {
        "description": "",
        "operationId": "monitoring_put-admin-monitoring-map",
        "summary": "Edit network map",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_map_edit"
      }
    },
    "/api/v1/admin/monitoring/sensors": {
      "post": {
        "description": "",
        "operationId": "monitoring_post-admin-monitoring-sensors",
        "summary": "Manage monitored devices \u0026 sensors",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_monitoring_manage"
      }
    },
    "/api/v1/admin/monitoring/sensors/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "monitoring_post-admin-monitoring-sensors-bulk-delete",
        "summary": "Manage monitored devices \u0026 sensors",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_monitoring_manage"
      }
    },
    "/api/v1/admin/monitoring/sensors/{id}": {
      "delete": {
        "description": "",
        "operationId": "monitoring_delete-admin-monitoring-sensors",
        "summary": "Manage monitored devices \u0026 sensors",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_monitoring_manage"
      },
      "put": {
        "description": "",
        "operationId": "monitoring_put-admin-monitoring-sensors",
        "summary": "Manage monitored devices \u0026 sensors",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_monitoring_manage"
      }
    },
    "/api/v1/admin/monitoring/sensors/{id}/samples": {
      "get": {
        "description": "",
        "operationId": "monitoring_get-admin-monitoring-sensors-samples",
        "summary": "View monitoring",
        "tags": [
          "monitoring"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_monitoring_view"
      }
    },
    "/api/v1/admin/nas": {
      "get": {
        "description": "Every NAS registered to the caller's tenant, with its reachability cache and the count of sessions currently on it.",
        "operationId": "nas_get-admin-nas",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": [\n    {\n      \"id\": 3,\n      \"tenant_id\": 12,\n      \"nas_identifier\": \"cairo-edge-1\",\n      \"nas_ip\": \"10.20.0.1\",\n      \"description\": \"Nasr City edge\",\n      \"vendor\": \"mikrotik\",\n      \"model\": \"CCR2004\",\n      \"coa_port\": 3799,\n      \"ssh_port\": 22,\n      \"winbox_port\": 8291,\n      \"ip_accounting_enabled\": true,\n      \"ping_status\": \"up\",\n      \"last_ping_at\": \"2026-09-20 09:07:30\",\n      \"last_rtt_ms\": 4.2,\n      \"online_users\": 118,\n      \"ping_fail_count\": 0,\n      \"wg_enabled\": true,\n      \"tunnel_transport\": \"wireguard\",\n      \"active_tunnel_ip\": \"10.8.0.14\",\n      \"zerologin_enabled\": true,\n      \"needs_onboarding\": false,\n      \"created_at\": \"2026-04-11 10:02:00\"\n    }\n  ]\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "List NAS devices",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_nas_index"
      },
      "post": {
        "description": "Creates the device record and its RADIUS shared secret. At least one of nas_identifier, nas_ip and called_station_id must be present — that is what an incoming RADIUS packet will be matched on.",
        "operationId": "nas_post-admin-nas",
        "summary": "Register a NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_create"
      }
    },
    "/api/v1/admin/nas/bulk-apply-hotspot": {
      "post": {
        "description": "",
        "operationId": "nas_post-admin-nas-bulk-apply-hotspot",
        "summary": "Edit NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_update"
      }
    },
    "/api/v1/admin/nas/bulk-apply-parental": {
      "post": {
        "description": "",
        "operationId": "nas_post-admin-nas-bulk-apply-parental",
        "summary": "Edit NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_update"
      }
    },
    "/api/v1/admin/nas/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "nas_post-admin-nas-bulk-delete",
        "summary": "Delete NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_delete"
      }
    },
    "/api/v1/admin/nas/bulk-enable-zerologin": {
      "post": {
        "description": "",
        "operationId": "nas_post-admin-nas-bulk-enable-zerologin",
        "summary": "Edit NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_update"
      }
    },
    "/api/v1/admin/nas/catalog": {
      "get": {
        "description": "The vendor and model catalogue the create and update endpoints validate against. Static data, safe to cache.",
        "operationId": "nas_get-admin-nas-catalog",
        "summary": "List supported NAS vendors and models",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_nas_index"
      }
    },
    "/api/v1/admin/nas/device-groups": {
      "get": {
        "description": "",
        "operationId": "nas_get-admin-nas-device-groups",
        "summary": "View LAN devices",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_nas_devices_index"
      },
      "post": {
        "description": "",
        "operationId": "nas_post-admin-nas-device-groups",
        "summary": "Manage LAN device groups \u0026 manager access",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_device_groups"
      }
    },
    "/api/v1/admin/nas/device-groups/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "nas_post-admin-nas-device-groups-bulk-delete",
        "summary": "Manage LAN device groups \u0026 manager access",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_device_groups"
      }
    },
    "/api/v1/admin/nas/device-groups/{id}": {
      "delete": {
        "description": "",
        "operationId": "nas_delete-admin-nas-device-groups",
        "summary": "Manage LAN device groups \u0026 manager access",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_device_groups"
      },
      "patch": {
        "description": "",
        "operationId": "nas_patch-admin-nas-device-groups",
        "summary": "Manage LAN device groups \u0026 manager access",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_device_groups"
      }
    },
    "/api/v1/admin/nas/device-groups/{id}/managers": {
      "get": {
        "description": "",
        "operationId": "nas_get-admin-nas-device-groups-managers",
        "summary": "Manage LAN device groups \u0026 manager access",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_nas_device_groups"
      },
      "put": {
        "description": "",
        "operationId": "nas_put-admin-nas-device-groups-managers",
        "summary": "Manage LAN device groups \u0026 manager access",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_device_groups"
      }
    },
    "/api/v1/admin/nas/devices": {
      "get": {
        "description": "",
        "operationId": "nas_get-admin-nas-devices",
        "summary": "View LAN devices",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_nas_devices_index"
      }
    },
    "/api/v1/admin/nas/devices/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "nas_post-admin-nas-devices-bulk-delete",
        "summary": "Edit NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_update"
      }
    },
    "/api/v1/admin/nas/devices/bulk-group": {
      "post": {
        "description": "",
        "operationId": "nas_post-admin-nas-devices-bulk-group",
        "summary": "Edit NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_update"
      }
    },
    "/api/v1/admin/nas/devices/{id}": {
      "delete": {
        "description": "",
        "operationId": "nas_delete-admin-nas-devices",
        "summary": "Edit NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_update"
      },
      "patch": {
        "description": "",
        "operationId": "nas_patch-admin-nas-devices",
        "summary": "Edit NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_update"
      }
    },
    "/api/v1/admin/nas/devices/{id}/console": {
      "post": {
        "description": "",
        "operationId": "nas_post-admin-nas-devices-console",
        "summary": "Remote console to a LAN device",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_probe",
        "x-required-permission": "prm_nas_devices_remote"
      }
    },
    "/api/v1/admin/nas/management-credentials/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "nas_post-admin-nas-management-credentials-bulk-delete",
        "summary": "Delete NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_delete"
      }
    },
    "/api/v1/admin/nas/management-credentials/{id}": {
      "delete": {
        "description": "",
        "operationId": "nas_delete-admin-nas-management-credentials",
        "summary": "Delete NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_delete"
      },
      "get": {
        "description": "",
        "operationId": "nas_get-admin-nas-management-credentials-by-id",
        "summary": "View NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_nas_index"
      }
    },
    "/api/v1/admin/nas/management-credentials/{id}/rotate": {
      "post": {
        "description": "",
        "operationId": "nas_post-admin-nas-management-credentials-rotate",
        "summary": "Edit NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_update"
      }
    },
    "/api/v1/admin/nas/onboard": {
      "post": {
        "description": "",
        "operationId": "nas_post-admin-nas-onboard",
        "summary": "Add NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_create"
      }
    },
    "/api/v1/admin/nas/ping": {
      "get": {
        "description": "Probes all of the tenant's devices from the platform and reports reachability. An operator action.",
        "operationId": "nas_get-admin-nas-ping",
        "summary": "Ping every NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_probe",
        "x-required-permission": "prm_nas_index"
      }
    },
    "/api/v1/admin/nas/vpn/peers": {
      "get": {
        "description": "",
        "operationId": "nas_get-admin-nas-vpn-peers",
        "summary": "GET /api/v1/admin/nas/vpn/peers",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-any-permission": [
          "prm_nas_vpn_peers_own",
          "prm_nas_vpn_peers_all"
        ]
      }
    },
    "/api/v1/admin/nas/vpn/peers/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "nas_post-admin-nas-vpn-peers-bulk-delete",
        "summary": "POST /api/v1/admin/nas/vpn/peers/bulk-delete",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-any-permission": [
          "prm_nas_vpn_peers_own",
          "prm_nas_vpn_peers_all"
        ]
      }
    },
    "/api/v1/admin/nas/vpn/peers/bulk-reassign": {
      "post": {
        "description": "",
        "operationId": "nas_post-admin-nas-vpn-peers-bulk-reassign",
        "summary": "All VPN accounts (tenant-wide, incl. reassign)",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_vpn_peers_all"
      }
    },
    "/api/v1/admin/nas/vpn/peers/{peerID}": {
      "delete": {
        "description": "",
        "operationId": "nas_delete-admin-nas-vpn-peers",
        "summary": "DELETE /api/v1/admin/nas/vpn/peers/{peerID}",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-any-permission": [
          "prm_nas_vpn_peers_own",
          "prm_nas_vpn_peers_all"
        ]
      }
    },
    "/api/v1/admin/nas/vpn/peers/{peerID}/credentials": {
      "get": {
        "description": "",
        "operationId": "nas_get-admin-nas-vpn-peers-credentials",
        "summary": "GET /api/v1/admin/nas/vpn/peers/{peerID}/credentials",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-any-permission": [
          "prm_nas_vpn_peers_own",
          "prm_nas_vpn_peers_all"
        ]
      }
    },
    "/api/v1/admin/nas/vpn/peers/{peerID}/history": {
      "get": {
        "description": "",
        "operationId": "nas_get-admin-nas-vpn-peers-history",
        "summary": "GET /api/v1/admin/nas/vpn/peers/{peerID}/history",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-any-permission": [
          "prm_nas_vpn_peers_own",
          "prm_nas_vpn_peers_all"
        ]
      }
    },
    "/api/v1/admin/nas/vpn/peers/{peerID}/reassign": {
      "post": {
        "description": "",
        "operationId": "nas_post-admin-nas-vpn-peers-reassign",
        "summary": "All VPN accounts (tenant-wide, incl. reassign)",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_vpn_peers_all"
      }
    },
    "/api/v1/admin/nas/vpn/peers/{peerID}/rotate": {
      "post": {
        "description": "",
        "operationId": "nas_post-admin-nas-vpn-peers-rotate",
        "summary": "POST /api/v1/admin/nas/vpn/peers/{peerID}/rotate",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-any-permission": [
          "prm_nas_vpn_peers_own",
          "prm_nas_vpn_peers_all"
        ]
      }
    },
    "/api/v1/admin/nas/vpn/servers": {
      "get": {
        "description": "",
        "operationId": "nas_get-admin-nas-vpn-servers",
        "summary": "GET /api/v1/admin/nas/vpn/servers",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-any-permission": [
          "prm_nas_vpn_peers_own",
          "prm_nas_vpn_peers_all"
        ]
      }
    },
    "/api/v1/admin/nas/{id}": {
      "delete": {
        "description": "Removes the device record. Sessions already open on it are not affected.",
        "operationId": "nas_delete-admin-nas",
        "parameters": [
          {
            "description": "NAS id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Delete a NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_delete"
      },
      "get": {
        "description": "The full device record, including tunnel and operator-VPN configuration.",
        "operationId": "nas_get-admin-nas-by-id",
        "parameters": [
          {
            "description": "NAS id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Fetch one NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_nas_index"
      },
      "patch": {
        "description": "Partial update; an omitted field is left alone. The shared secret is not editable here — rotating it has its own endpoint, because it must be pushed to the device in step with the change.",
        "operationId": "nas_patch-admin-nas",
        "parameters": [
          {
            "description": "NAS id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Update a NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_update"
      }
    },
    "/api/v1/admin/nas/{id}/apply-hotspot": {
      "post": {
        "description": "",
        "operationId": "nas_post-admin-nas-apply-hotspot",
        "summary": "Edit NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_update"
      }
    },
    "/api/v1/admin/nas/{id}/apply-parental": {
      "post": {
        "description": "",
        "operationId": "nas_post-admin-nas-apply-parental",
        "summary": "Edit NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_update"
      }
    },
    "/api/v1/admin/nas/{id}/console": {
      "post": {
        "description": "",
        "operationId": "nas_post-admin-nas-console",
        "summary": "Remote console (WebFig/SSH/Winbox) to a NAS router",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_probe",
        "x-required-permission": "prm_nas_remote"
      }
    },
    "/api/v1/admin/nas/{id}/devices": {
      "get": {
        "description": "Customer-premises and infrastructure devices discovered or registered under this NAS, as the monitoring and topology views see them.",
        "operationId": "nas_get-admin-nas-devices-by-id",
        "parameters": [
          {
            "description": "NAS id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "List devices behind a NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_nas_devices_index"
      },
      "post": {
        "description": "",
        "operationId": "nas_post-admin-nas-devices",
        "summary": "Edit NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_update"
      }
    },
    "/api/v1/admin/nas/{id}/enable-zerologin": {
      "post": {
        "description": "",
        "operationId": "nas_post-admin-nas-enable-zerologin",
        "summary": "Edit NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_update"
      }
    },
    "/api/v1/admin/nas/{id}/hotspot-preflight": {
      "get": {
        "description": "",
        "operationId": "nas_get-admin-nas-hotspot-preflight",
        "summary": "View NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_nas_index"
      }
    },
    "/api/v1/admin/nas/{id}/management-credentials": {
      "get": {
        "description": "",
        "operationId": "nas_get-admin-nas-management-credentials-by-nas-id",
        "summary": "View NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_nas_index"
      },
      "post": {
        "description": "",
        "operationId": "nas_post-admin-nas-management-credentials",
        "summary": "Add NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_create"
      }
    },
    "/api/v1/admin/nas/{id}/management-script": {
      "get": {
        "description": "",
        "operationId": "nas_get-admin-nas-management-script",
        "summary": "Edit NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_nas_update"
      }
    },
    "/api/v1/admin/nas/{id}/onboarding-script": {
      "get": {
        "description": "Returns the RouterOS script that configures the device to talk to this platform: RADIUS client, accounting, the management tunnel and the captive portal redirect. Rendered for this specific device.",
        "operationId": "nas_get-admin-nas-onboarding-script",
        "parameters": [
          {
            "description": "NAS id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Render the onboarding script for a NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_nas_update"
      }
    },
    "/api/v1/admin/nas/{id}/parental-script": {
      "get": {
        "description": "",
        "operationId": "nas_get-admin-nas-parental-script",
        "summary": "View NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_nas_index"
      }
    },
    "/api/v1/admin/nas/{id}/ping-history": {
      "get": {
        "description": "",
        "operationId": "nas_get-admin-nas-ping-history",
        "summary": "View NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_nas_index"
      }
    },
    "/api/v1/admin/nas/{id}/provision-tunnel": {
      "post": {
        "description": "",
        "operationId": "nas_post-admin-nas-provision-tunnel",
        "summary": "Edit NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_update"
      }
    },
    "/api/v1/admin/nas/{id}/revert-hotspot": {
      "post": {
        "description": "",
        "operationId": "nas_post-admin-nas-revert-hotspot",
        "summary": "Edit NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_update"
      }
    },
    "/api/v1/admin/nas/{id}/rotate-secret": {
      "post": {
        "description": "Issues a new shared secret for the device. The router must be updated to match, or it stops authenticating — this endpoint changes the platform side only.",
        "operationId": "nas_post-admin-nas-rotate-secret",
        "parameters": [
          {
            "description": "NAS id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Rotate a NAS shared secret",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_update"
      }
    },
    "/api/v1/admin/nas/{id}/scan": {
      "post": {
        "description": "",
        "operationId": "nas_post-admin-nas-scan",
        "summary": "View LAN devices",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_devices_index"
      }
    },
    "/api/v1/admin/nas/{id}/shared-secret": {
      "get": {
        "description": "Returns the device's RADIUS shared secret in the clear, for an operator re-entering it on the router. Gated on the NAS update permission rather than the read one, because seeing it is equivalent to being able to change it.",
        "operationId": "nas_get-admin-nas-shared-secret",
        "parameters": [
          {
            "description": "NAS id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Reveal a NAS shared secret",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_nas_update"
      }
    },
    "/api/v1/admin/nas/{id}/test": {
      "post": {
        "description": "Checks that the platform can reach the device's management interface.",
        "operationId": "nas_post-admin-nas-test",
        "parameters": [
          {
            "description": "NAS id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Test a NAS connection",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_probe",
        "x-required-permission": "prm_nas_update"
      }
    },
    "/api/v1/admin/nas/{id}/test-ssh": {
      "post": {
        "description": "",
        "operationId": "nas_post-admin-nas-test-ssh",
        "summary": "Edit NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_probe",
        "x-required-permission": "prm_nas_update"
      }
    },
    "/api/v1/admin/nas/{id}/transport": {
      "post": {
        "description": "",
        "operationId": "nas_post-admin-nas-transport",
        "summary": "Edit NAS",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_update"
      }
    },
    "/api/v1/admin/nas/{id}/vpn": {
      "get": {
        "description": "",
        "operationId": "nas_get-admin-nas-vpn",
        "summary": "Operator VPN access to NAS (issue/revoke VPN configs)",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_nas_vpn"
      },
      "patch": {
        "description": "",
        "operationId": "nas_patch-admin-nas-vpn",
        "summary": "Operator VPN access to NAS (issue/revoke VPN configs)",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_vpn"
      }
    },
    "/api/v1/admin/nas/{id}/vpn/disable": {
      "post": {
        "description": "",
        "operationId": "nas_post-admin-nas-vpn-disable",
        "summary": "Operator VPN access to NAS (issue/revoke VPN configs)",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_vpn"
      }
    },
    "/api/v1/admin/nas/{id}/vpn/enable": {
      "post": {
        "description": "",
        "operationId": "nas_post-admin-nas-vpn-enable",
        "summary": "Operator VPN access to NAS (issue/revoke VPN configs)",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_vpn"
      }
    },
    "/api/v1/admin/nas/{id}/vpn/history": {
      "get": {
        "description": "",
        "operationId": "nas_get-admin-nas-vpn-history",
        "summary": "Operator VPN access to NAS (issue/revoke VPN configs)",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_nas_vpn"
      }
    },
    "/api/v1/admin/nas/{id}/vpn/peers": {
      "post": {
        "description": "",
        "operationId": "nas_post-admin-nas-vpn-peers",
        "summary": "POST /api/v1/admin/nas/{id}/vpn/peers",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-any-permission": [
          "prm_nas_vpn_peers_own",
          "prm_nas_vpn_peers_all"
        ]
      }
    },
    "/api/v1/admin/nas/{id}/vpn/script": {
      "get": {
        "description": "",
        "operationId": "nas_get-admin-nas-vpn-script",
        "summary": "All VPN accounts (tenant-wide, incl. reassign)",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_nas_vpn_peers_all"
      }
    },
    "/api/v1/admin/nas/{id}/vpn/zerotier/install-package": {
      "post": {
        "description": "",
        "operationId": "nas_post-admin-nas-vpn-zerotier-install-package",
        "summary": "Operator VPN access to NAS (issue/revoke VPN configs)",
        "tags": [
          "nas"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_nas_vpn"
      }
    },
    "/api/v1/admin/notification-channels": {
      "get": {
        "description": "",
        "operationId": "notification-channels_get-admin-notification-channels",
        "summary": "Manage notification channels \u0026 templates",
        "tags": [
          "notification-channels"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_notifications_manage"
      },
      "post": {
        "description": "",
        "operationId": "notification-channels_post-admin-notification-channels",
        "summary": "Manage notification channels \u0026 templates",
        "tags": [
          "notification-channels"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_notifications_manage"
      }
    },
    "/api/v1/admin/notification-channels/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "notification-channels_post-admin-notification-channels-bulk-delete",
        "summary": "Manage notification channels \u0026 templates",
        "tags": [
          "notification-channels"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_notifications_manage"
      }
    },
    "/api/v1/admin/notification-channels/{id}": {
      "delete": {
        "description": "",
        "operationId": "notification-channels_delete-admin-notification-channels",
        "summary": "Manage notification channels \u0026 templates",
        "tags": [
          "notification-channels"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_notifications_manage"
      },
      "patch": {
        "description": "",
        "operationId": "notification-channels_patch-admin-notification-channels",
        "summary": "Manage notification channels \u0026 templates",
        "tags": [
          "notification-channels"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_notifications_manage"
      }
    },
    "/api/v1/admin/notification-channels/{id}/test": {
      "post": {
        "description": "",
        "operationId": "notification-channels_post-admin-notification-channels-test",
        "summary": "Manage notification channels \u0026 templates",
        "tags": [
          "notification-channels"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_notifications_manage"
      }
    },
    "/api/v1/admin/notification-event-options": {
      "put": {
        "description": "",
        "operationId": "notification-event-options_put-admin-notification-event-options",
        "summary": "Manage notification channels \u0026 templates",
        "tags": [
          "notification-event-options"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_notifications_manage"
      }
    },
    "/api/v1/admin/notification-events": {
      "get": {
        "description": "",
        "operationId": "notification-events_get-admin-notification-events",
        "summary": "Manage notification channels \u0026 templates",
        "tags": [
          "notification-events"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_notifications_manage"
      }
    },
    "/api/v1/admin/notification-outbox": {
      "get": {
        "description": "",
        "operationId": "notification-outbox_get-admin-notification-outbox",
        "summary": "Notification Queue",
        "tags": [
          "notification-outbox"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_log_notifications"
      }
    },
    "/api/v1/admin/notification-outbox/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "notification-outbox_post-admin-notification-outbox-bulk-delete",
        "summary": "Manage notification channels \u0026 templates",
        "tags": [
          "notification-outbox"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_notifications_manage"
      }
    },
    "/api/v1/admin/notification-outbox/bulk-retry": {
      "post": {
        "description": "",
        "operationId": "notification-outbox_post-admin-notification-outbox-bulk-retry",
        "summary": "Manage notification channels \u0026 templates",
        "tags": [
          "notification-outbox"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_notifications_manage"
      }
    },
    "/api/v1/admin/notification-outbox/{id}": {
      "delete": {
        "description": "",
        "operationId": "notification-outbox_delete-admin-notification-outbox",
        "summary": "Manage notification channels \u0026 templates",
        "tags": [
          "notification-outbox"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_notifications_manage"
      },
      "get": {
        "description": "",
        "operationId": "notification-outbox_get-admin-notification-outbox-by-id",
        "summary": "Notification Queue",
        "tags": [
          "notification-outbox"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_log_notifications"
      }
    },
    "/api/v1/admin/notification-outbox/{id}/retry": {
      "post": {
        "description": "",
        "operationId": "notification-outbox_post-admin-notification-outbox-retry",
        "summary": "Manage notification channels \u0026 templates",
        "tags": [
          "notification-outbox"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_notifications_manage"
      }
    },
    "/api/v1/admin/notification-outbox/{id}/status": {
      "get": {
        "description": "",
        "operationId": "notification-outbox_get-admin-notification-outbox-status",
        "summary": "Manage notification channels \u0026 templates",
        "tags": [
          "notification-outbox"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_notifications_manage"
      }
    },
    "/api/v1/admin/notification-rules": {
      "get": {
        "description": "",
        "operationId": "notification-rules_get-admin-notification-rules",
        "summary": "Manage usage notifications",
        "tags": [
          "notification-rules"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_profiles_notifications"
      },
      "post": {
        "description": "",
        "operationId": "notification-rules_post-admin-notification-rules",
        "summary": "Manage usage notifications",
        "tags": [
          "notification-rules"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_profiles_notifications"
      }
    },
    "/api/v1/admin/notification-rules/bulk": {
      "post": {
        "description": "",
        "operationId": "notification-rules_post-admin-notification-rules-bulk",
        "summary": "Manage usage notifications",
        "tags": [
          "notification-rules"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_egress",
        "x-required-permission": "prm_profiles_notifications"
      }
    },
    "/api/v1/admin/notification-rules/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "notification-rules_post-admin-notification-rules-bulk-delete",
        "summary": "Manage usage notifications",
        "tags": [
          "notification-rules"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_profiles_notifications"
      }
    },
    "/api/v1/admin/notification-rules/log": {
      "get": {
        "description": "",
        "operationId": "notification-rules_get-admin-notification-rules-log",
        "summary": "Manage usage notifications",
        "tags": [
          "notification-rules"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_profiles_notifications"
      }
    },
    "/api/v1/admin/notification-rules/{id}": {
      "delete": {
        "description": "",
        "operationId": "notification-rules_delete-admin-notification-rules",
        "summary": "Manage usage notifications",
        "tags": [
          "notification-rules"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_profiles_notifications"
      },
      "patch": {
        "description": "",
        "operationId": "notification-rules_patch-admin-notification-rules",
        "summary": "Manage usage notifications",
        "tags": [
          "notification-rules"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_profiles_notifications"
      }
    },
    "/api/v1/admin/notification-templates": {
      "get": {
        "description": "",
        "operationId": "notification-templates_get-admin-notification-templates",
        "summary": "Manage notification channels \u0026 templates",
        "tags": [
          "notification-templates"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_notifications_manage"
      },
      "post": {
        "description": "",
        "operationId": "notification-templates_post-admin-notification-templates",
        "summary": "Manage notification channels \u0026 templates",
        "tags": [
          "notification-templates"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_notifications_manage"
      }
    },
    "/api/v1/admin/notification-templates/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "notification-templates_post-admin-notification-templates-bulk-delete",
        "summary": "Manage notification channels \u0026 templates",
        "tags": [
          "notification-templates"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_notifications_manage"
      }
    },
    "/api/v1/admin/notification-templates/{id}": {
      "delete": {
        "description": "",
        "operationId": "notification-templates_delete-admin-notification-templates",
        "summary": "Manage notification channels \u0026 templates",
        "tags": [
          "notification-templates"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_notifications_manage"
      }
    },
    "/api/v1/admin/payments/config": {
      "get": {
        "description": "Just the tenant's configured rows, with credentials masked, for a page that already holds the catalogue.",
        "operationId": "payments_get-admin-payments-config",
        "summary": "List configured gateways",
        "tags": [
          "payments"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_settings"
      },
      "post": {
        "description": "Upserts one gateway's credentials and settings. Every field is keep-existing, so a partial payload leaves unsent credentials alone rather than clearing them.",
        "operationId": "payments_post-admin-payments-config",
        "summary": "Configure a gateway",
        "tags": [
          "payments"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_settings"
      }
    },
    "/api/v1/admin/payments/config/{gateway}": {
      "delete": {
        "description": "Deletes the tenant's credentials for one driver. Transactions already recorded against it are untouched.",
        "operationId": "payments_delete-admin-payments-config",
        "parameters": [
          {
            "description": "Driver id.",
            "in": "path",
            "name": "gateway",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "summary": "Remove a gateway configuration",
        "tags": [
          "payments"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_settings"
      },
      "patch": {
        "description": "The same upsert as the POST, with the gateway named in the path. The PATH wins over any gateway field in the body, so a stale client cannot retarget an edit at a different gateway.",
        "operationId": "payments_patch-admin-payments-config",
        "parameters": [
          {
            "description": "Driver id.",
            "in": "path",
            "name": "gateway",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "summary": "Update one gateway's configuration",
        "tags": [
          "payments"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_settings"
      }
    },
    "/api/v1/admin/payments/config/{gateway}/test": {
      "post": {
        "description": "Checks the stored credentials against the provider.",
        "operationId": "payments_post-admin-payments-config-test",
        "parameters": [
          {
            "description": "Driver id.",
            "in": "path",
            "name": "gateway",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "summary": "Test a gateway configuration",
        "tags": [
          "payments"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_settings"
      }
    },
    "/api/v1/admin/payments/config/{gateway}/webhook-url": {
      "get": {
        "description": "The exact URL to register with the provider, including the per-tenant secret path segment. Copy it verbatim.",
        "operationId": "payments_get-admin-payments-config-webhook-url",
        "parameters": [
          {
            "description": "Driver id.",
            "in": "path",
            "name": "gateway",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "summary": "Read a gateway's callback URL",
        "tags": [
          "payments"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_settings"
      }
    },
    "/api/v1/admin/payments/deposit": {
      "post": {
        "description": "",
        "operationId": "payments_post-admin-payments-deposit",
        "summary": "Top up own wallet online",
        "tags": [
          "payments"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "pay_init",
        "x-required-permission": "prm_managers_self_deposit"
      }
    },
    "/api/v1/admin/payments/deposit/gateways": {
      "get": {
        "description": "",
        "operationId": "payments_get-admin-payments-deposit-gateways",
        "summary": "Top up own wallet online",
        "tags": [
          "payments"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_managers_self_deposit"
      }
    },
    "/api/v1/admin/payments/gateways": {
      "get": {
        "description": "The drivers this build supports, the tenant's own configured rows with secrets masked, and the public base URL a gateway should call back to.",
        "operationId": "payments_get-admin-payments-gateways",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": {\n    \"catalog\": [\n      {\n        \"id\": \"paymob\",\n        \"label\": \"Paymob\",\n        \"methods\": [],\n        \"fields\": [],\n        \"ttl_seconds\": 900,\n        \"min_amount\": 0,\n        \"implemented\": true,\n        \"pollable\": true\n      }\n    ],\n    \"configured\": [],\n    \"public_base_url\": \"https://acme.example.com\"\n  }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "List the gateway catalogue and what is configured",
        "tags": [
          "payments"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_settings"
      }
    },
    "/api/v1/admin/payments/transactions/{id}": {
      "get": {
        "description": "",
        "operationId": "payments_get-admin-payments-transactions",
        "summary": "GET /api/v1/admin/payments/transactions/{id}",
        "tags": [
          "payments"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-any-permission": [
          "prm_report_gateway_transactions",
          "prm_report_gateway_transactions_all"
        ]
      }
    },
    "/api/v1/admin/payments/transactions/{id}/recheck": {
      "post": {
        "description": "",
        "operationId": "payments_post-admin-payments-transactions-recheck",
        "summary": "Re-check and write off gateway transactions",
        "tags": [
          "payments"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "pay_init",
        "x-required-permission": "prm_payments_manage"
      }
    },
    "/api/v1/admin/payments/transactions/{id}/refund": {
      "post": {
        "description": "",
        "operationId": "payments_post-admin-payments-transactions-refund",
        "summary": "Mark gateway payments paid / refunded (moves money)",
        "tags": [
          "payments"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "pay_init",
        "x-required-permission": "prm_payments_settle"
      }
    },
    "/api/v1/admin/payments/transactions/{id}/settle": {
      "post": {
        "description": "",
        "operationId": "payments_post-admin-payments-transactions-settle",
        "summary": "Mark gateway payments paid / refunded (moves money)",
        "tags": [
          "payments"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "pay_init",
        "x-required-permission": "prm_payments_settle"
      }
    },
    "/api/v1/admin/payments/transactions/{id}/status": {
      "post": {
        "description": "",
        "operationId": "payments_post-admin-payments-transactions-status",
        "summary": "Re-check and write off gateway transactions",
        "tags": [
          "payments"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_payments_manage"
      }
    },
    "/api/v1/admin/postpaid/generate-now": {
      "post": {
        "description": "",
        "operationId": "postpaid_post-admin-postpaid-generate-now",
        "summary": "Billing \u0026 invoices",
        "tags": [
          "postpaid"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_billing"
      }
    },
    "/api/v1/admin/pricing": {
      "get": {
        "description": "",
        "operationId": "pricing_get-admin-pricing",
        "summary": "Manage profile pricing",
        "tags": [
          "pricing"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_profiles_pricing"
      }
    },
    "/api/v1/admin/pricing/manager/{id}": {
      "get": {
        "description": "",
        "operationId": "pricing_get-admin-pricing-manager",
        "summary": "Manage profile pricing",
        "tags": [
          "pricing"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_profiles_pricing"
      },
      "put": {
        "description": "",
        "operationId": "pricing_put-admin-pricing-manager",
        "summary": "Manage profile pricing",
        "tags": [
          "pricing"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_profiles_pricing"
      }
    },
    "/api/v1/admin/pricing/managers": {
      "get": {
        "description": "",
        "operationId": "pricing_get-admin-pricing-managers",
        "summary": "Manage profile pricing",
        "tags": [
          "pricing"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_profiles_pricing"
      }
    },
    "/api/v1/admin/reports/activation-stats": {
      "get": {
        "description": "",
        "operationId": "reports_get-admin-reports-activation-stats",
        "summary": "Activation statistics report",
        "tags": [
          "reports"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_report_activation_stats"
      }
    },
    "/api/v1/admin/reports/activations": {
      "get": {
        "description": "",
        "operationId": "reports_get-admin-reports-activations",
        "summary": "Activations report",
        "tags": [
          "reports"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_report_activations"
      }
    },
    "/api/v1/admin/reports/cards-transfer": {
      "get": {
        "description": "",
        "operationId": "reports_get-admin-reports-cards-transfer",
        "summary": "Cards log report",
        "tags": [
          "reports"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_report_cards_log"
      }
    },
    "/api/v1/admin/reports/cards-usage": {
      "get": {
        "description": "",
        "operationId": "reports_get-admin-reports-cards-usage",
        "summary": "Cards usage report",
        "tags": [
          "reports"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_report_cards_usage"
      }
    },
    "/api/v1/admin/reports/claims-managers": {
      "get": {
        "description": "",
        "operationId": "reports_get-admin-reports-claims-managers",
        "summary": "Debts journal report",
        "tags": [
          "reports"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_report_debts"
      }
    },
    "/api/v1/admin/reports/debtors-managers": {
      "get": {
        "description": "",
        "operationId": "reports_get-admin-reports-debtors-managers",
        "summary": "Debts journal report",
        "tags": [
          "reports"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_report_debts"
      }
    },
    "/api/v1/admin/reports/debtors-users": {
      "get": {
        "description": "",
        "operationId": "reports_get-admin-reports-debtors-users",
        "summary": "Debts journal report",
        "tags": [
          "reports"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_report_debts"
      }
    },
    "/api/v1/admin/reports/debts": {
      "get": {
        "description": "",
        "operationId": "reports_get-admin-reports-debts",
        "summary": "Debts journal report",
        "tags": [
          "reports"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_report_debts"
      }
    },
    "/api/v1/admin/reports/gateway-txns": {
      "get": {
        "description": "",
        "operationId": "reports_get-admin-reports-gateway-txns",
        "summary": "GET /api/v1/admin/reports/gateway-txns",
        "tags": [
          "reports"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-any-permission": [
          "prm_report_gateway_transactions",
          "prm_report_gateway_transactions_all"
        ]
      }
    },
    "/api/v1/admin/reports/manager-invoices": {
      "get": {
        "description": "",
        "operationId": "reports_get-admin-reports-manager-invoices",
        "summary": "View manager invoices",
        "tags": [
          "reports"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_managers_invoices"
      }
    },
    "/api/v1/admin/reports/manager-journal": {
      "get": {
        "description": "",
        "operationId": "reports_get-admin-reports-manager-journal",
        "summary": "View manager journal",
        "tags": [
          "reports"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_managers_journal"
      }
    },
    "/api/v1/admin/reports/manager-receipts": {
      "get": {
        "description": "",
        "operationId": "reports_get-admin-reports-manager-receipts",
        "summary": "View manager receipts",
        "tags": [
          "reports"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_managers_receipts"
      }
    },
    "/api/v1/admin/reports/money-transfer": {
      "get": {
        "description": "",
        "operationId": "reports_get-admin-reports-money-transfer",
        "summary": "Money transfer report",
        "tags": [
          "reports"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_report_money_transfer"
      }
    },
    "/api/v1/admin/reports/profits": {
      "get": {
        "description": "",
        "operationId": "reports_get-admin-reports-profits",
        "summary": "Profits report",
        "tags": [
          "reports"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_report_profits"
      }
    },
    "/api/v1/admin/reports/sessions": {
      "get": {
        "description": "",
        "operationId": "reports_get-admin-reports-sessions",
        "summary": "Sessions report",
        "tags": [
          "reports"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_report_sessions"
      }
    },
    "/api/v1/admin/reports/suspicious": {
      "get": {
        "description": "",
        "operationId": "reports_get-admin-reports-suspicious",
        "summary": "Suspicious users report",
        "tags": [
          "reports"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_report_suspicious"
      }
    },
    "/api/v1/admin/reports/traffic": {
      "get": {
        "description": "",
        "operationId": "reports_get-admin-reports-traffic",
        "summary": "Traffic report",
        "tags": [
          "reports"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_report_traffic"
      }
    },
    "/api/v1/admin/reports/users": {
      "get": {
        "description": "",
        "operationId": "reports_get-admin-reports-users",
        "summary": "Users report",
        "tags": [
          "reports"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_report_users"
      }
    },
    "/api/v1/admin/sas4/export": {
      "get": {
        "description": "",
        "operationId": "sas4_get-admin-sas4-export",
        "summary": "Export SAS4 backup",
        "tags": [
          "sas4"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tools_sas4_export"
      }
    },
    "/api/v1/admin/sas4/import/jobs": {
      "get": {
        "description": "",
        "operationId": "sas4_get-admin-sas4-import-jobs",
        "summary": "Import SAS4 backup",
        "tags": [
          "sas4"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tools_sas4_import"
      },
      "post": {
        "description": "",
        "operationId": "sas4_post-admin-sas4-import-jobs",
        "summary": "Import SAS4 backup",
        "tags": [
          "sas4"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_tools_sas4_import"
      }
    },
    "/api/v1/admin/sas4/import/jobs/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "sas4_post-admin-sas4-import-jobs-bulk-delete",
        "summary": "Import SAS4 backup",
        "tags": [
          "sas4"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tools_sas4_import"
      }
    },
    "/api/v1/admin/sas4/import/jobs/{id}": {
      "delete": {
        "description": "",
        "operationId": "sas4_delete-admin-sas4-import-jobs",
        "summary": "Import SAS4 backup",
        "tags": [
          "sas4"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tools_sas4_import"
      },
      "get": {
        "description": "",
        "operationId": "sas4_get-admin-sas4-import-jobs-by-id",
        "summary": "Import SAS4 backup",
        "tags": [
          "sas4"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tools_sas4_import"
      }
    },
    "/api/v1/admin/sas4/import/jobs/{id}/cancel": {
      "post": {
        "description": "",
        "operationId": "sas4_post-admin-sas4-import-jobs-cancel",
        "summary": "Import SAS4 backup",
        "tags": [
          "sas4"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tools_sas4_import"
      }
    },
    "/api/v1/admin/sas4/import/jobs/{id}/start": {
      "post": {
        "description": "",
        "operationId": "sas4_post-admin-sas4-import-jobs-start",
        "summary": "Import SAS4 backup",
        "tags": [
          "sas4"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_tools_sas4_import"
      }
    },
    "/api/v1/admin/sessions": {
      "get": {
        "description": "Sessions with no stop time, paginated with the standard list parameters. A non-admin caller sees only sessions belonging to their own manager subtree, injected server-side.",
        "operationId": "sessions_get-admin-sessions",
        "parameters": [
          {
            "description": "Searches username, first and last name, framed IP, device MAC and NAS name.",
            "in": "query",
            "name": "q",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Sessions on one registered NAS.",
            "in": "query",
            "name": "filter[nas_id]",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "description": "subscriber, guest, voucher or unknown.",
            "in": "query",
            "name": "filter[kind]",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Sessions that were assigned a framed IP.",
            "in": "query",
            "name": "filter[has_ip]",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "description": "Duration bucket. The value \"stale\" means no accounting update for longer than the tenant's idle window, which is the practical definition of a ghost session.",
            "in": "query",
            "name": "filter[duration_band]",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Sessions whose owner's subscription has run out but who are still connected.",
            "in": "query",
            "name": "filter[expired]",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": [\n    {\n      \"id\": 8821904,\n      \"acct_session_id\": \"81b0c4e2\",\n      \"username\": \"ahmed\",\n      \"user_id\": 4711,\n      \"kind\": \"subscriber\",\n      \"nas_ip\": \"10.20.0.1\",\n      \"nas_id\": 3,\n      \"nas_name\": \"cairo-edge-1\",\n      \"vendor\": \"mikrotik\",\n      \"framed_ip\": \"10.64.12.51\",\n      \"calling_station_id\": \"AA:BB:CC:DD:EE:FF\",\n      \"start_time\": \"2026-09-20 07:11:02\",\n      \"update_time\": \"2026-09-20 09:06:02\",\n      \"session_time\": 6900,\n      \"input_octets\": 412000000,\n      \"output_octets\": 5100000000,\n      \"profile_name\": \"Home 20M\",\n      \"usage\": { \"percent\": 55.0, \"dimension\": \"data\" }\n    }\n  ],\n  \"meta\": { \"page\": 1, \"page_size\": 50, \"total\": 318, \"has_next\": true }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "List live sessions",
        "tags": [
          "sessions"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_report_sessions"
      }
    },
    "/api/v1/admin/sessions/bulk-disconnect": {
      "post": {
        "description": "Sends a Disconnect-Request per session id and reports the per-id outcome. One request against the write budget rather than one per session.",
        "operationId": "sessions_post-admin-sessions-bulk-disconnect",
        "summary": "Disconnect many sessions",
        "tags": [
          "sessions"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_live_traffic"
      }
    },
    "/api/v1/admin/sessions/bulk-lock-mac": {
      "post": {
        "description": "",
        "operationId": "sessions_post-admin-sessions-bulk-lock-mac",
        "summary": "Lock user MAC",
        "tags": [
          "sessions"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_mac_lock"
      }
    },
    "/api/v1/admin/sessions/bulk-ping": {
      "post": {
        "description": "",
        "operationId": "sessions_post-admin-sessions-bulk-ping",
        "summary": "Ping user",
        "tags": [
          "sessions"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_ping"
      }
    },
    "/api/v1/admin/sessions/{id}": {
      "get": {
        "description": "One session with the full projection, including the joined subscriber attributes.",
        "operationId": "sessions_get-admin-sessions-by-id",
        "parameters": [
          {
            "description": "The accounting row id, not the subscriber id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Fetch one live session",
        "tags": [
          "sessions"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_report_sessions"
      }
    },
    "/api/v1/admin/sessions/{id}/disconnect": {
      "post": {
        "description": "Sends an RFC 5176 Disconnect-Request straight from this platform to the NAS that owns the session. The packet goes out over UDP to the device, not through the RADIUS server.",
        "operationId": "sessions_post-admin-sessions-disconnect",
        "parameters": [
          {
            "description": "Session id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": { \"ok\": true, \"nak\": false, \"message\": \"disconnected\" }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "Disconnect a session",
        "tags": [
          "sessions"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_live_traffic"
      }
    },
    "/api/v1/admin/sessions/{id}/live-traffic": {
      "get": {
        "description": "Returns bits per second when the session's NAS has SNMP management credentials with an interface selector configured, by polling the device twice about a second apart. Without them it degrades to the accounting counters.",
        "operationId": "sessions_get-admin-sessions-live-traffic",
        "parameters": [
          {
            "description": "Session id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Read near-real-time throughput",
        "tags": [
          "sessions"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_users_live_traffic"
      }
    },
    "/api/v1/admin/sessions/{id}/live-traffic/stream": {
      "get": {
        "description": "",
        "operationId": "sessions_get-admin-sessions-live-traffic-stream",
        "summary": "Live traffic / disconnect",
        "tags": [
          "sessions"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_users_live_traffic"
      }
    },
    "/api/v1/admin/sessions/{id}/lock-mac": {
      "post": {
        "description": "Writes the session's calling-station MAC into the subscriber's locked-MAC list. From the next authentication onward only that device may connect. The current session is left up, since it already uses the locked MAC.",
        "operationId": "sessions_post-admin-sessions-lock-mac",
        "parameters": [
          {
            "description": "Session id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": {\n    \"user_id\": 4711,\n    \"mac\": \"AA:BB:CC:DD:EE:FF\",\n    \"locked_macs\": [\"AA:BB:CC:DD:EE:FF\"]\n  }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "Bind the subscriber to this session's device",
        "tags": [
          "sessions"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_mac_lock"
      }
    },
    "/api/v1/admin/sessions/{id}/ping": {
      "post": {
        "description": "Sends ICMP echo to the session's framed IP from the platform. An operator diagnostic, not a monitoring feed.",
        "operationId": "sessions_post-admin-sessions-ping",
        "parameters": [
          {
            "description": "Session id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Ping the subscriber's device",
        "tags": [
          "sessions"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_ping"
      }
    },
    "/api/v1/admin/sessions/{id}/traffic": {
      "get": {
        "description": "The lightweight counter snapshot behind a live traffic graph. It is a snapshot, not a rate — derive throughput from the difference between two polls and the difference between their sampled_at stamps.",
        "operationId": "sessions_get-admin-sessions-traffic",
        "parameters": [
          {
            "description": "Session id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": {\n    \"id\": 8821904,\n    \"session_time\": 6900,\n    \"input_octets\": 412000000,\n    \"output_octets\": 5100000000,\n    \"update_time\": \"2026-09-20 09:06:02\",\n    \"sampled_at\": \"2026-09-20 09:08:31\"\n  }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "Poll a session's counters",
        "tags": [
          "sessions"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_report_sessions"
      }
    },
    "/api/v1/admin/setup/checklist": {
      "get": {
        "description": "",
        "operationId": "setup_get-admin-setup-checklist",
        "summary": "Manage settings",
        "tags": [
          "setup"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_settings"
      }
    },
    "/api/v1/admin/setup/sample": {
      "delete": {
        "description": "",
        "operationId": "setup_delete-admin-setup-sample",
        "summary": "Manage settings",
        "tags": [
          "setup"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_settings"
      },
      "post": {
        "description": "",
        "operationId": "setup_post-admin-setup-sample",
        "summary": "Manage settings",
        "tags": [
          "setup"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_settings"
      }
    },
    "/api/v1/admin/setup/state": {
      "patch": {
        "description": "",
        "operationId": "setup_patch-admin-setup-state",
        "summary": "Manage settings",
        "tags": [
          "setup"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_settings"
      }
    },
    "/api/v1/admin/shop/batches/bulk-publish": {
      "post": {
        "description": "",
        "operationId": "shop_post-admin-shop-batches-bulk-publish",
        "summary": "Publish / unpublish card series to the shop",
        "tags": [
          "shop"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_shop_publish"
      }
    },
    "/api/v1/admin/shop/batches/{id}/publish": {
      "post": {
        "description": "",
        "operationId": "shop_post-admin-shop-batches-publish",
        "summary": "Publish / unpublish card series to the shop",
        "tags": [
          "shop"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_shop_publish"
      }
    },
    "/api/v1/admin/shop/batches/{id}/unpublish": {
      "post": {
        "description": "",
        "operationId": "shop_post-admin-shop-batches-unpublish",
        "summary": "Publish / unpublish card series to the shop",
        "tags": [
          "shop"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_shop_publish"
      }
    },
    "/api/v1/admin/shop/readiness": {
      "get": {
        "description": "",
        "operationId": "shop_get-admin-shop-readiness",
        "summary": "View the Card Shop",
        "tags": [
          "shop"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_shop_index"
      }
    },
    "/api/v1/admin/shop/sales": {
      "get": {
        "description": "",
        "operationId": "shop_get-admin-shop-sales",
        "summary": "GET /api/v1/admin/shop/sales",
        "tags": [
          "shop"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-any-permission": [
          "prm_shop_sales",
          "prm_shop_sales_all"
        ]
      }
    },
    "/api/v1/admin/shop/sales/{id}": {
      "get": {
        "description": "",
        "operationId": "shop_get-admin-shop-sales-by-id",
        "summary": "GET /api/v1/admin/shop/sales/{id}",
        "tags": [
          "shop"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-any-permission": [
          "prm_shop_sales",
          "prm_shop_sales_all"
        ]
      }
    },
    "/api/v1/admin/shop/sales/{id}/resend": {
      "post": {
        "description": "",
        "operationId": "shop_post-admin-shop-sales-resend",
        "summary": "POST /api/v1/admin/shop/sales/{id}/resend",
        "tags": [
          "shop"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "pay_init",
        "x-required-any-permission": [
          "prm_shop_sales",
          "prm_shop_sales_all"
        ]
      }
    },
    "/api/v1/admin/shop/sales/{id}/reveal": {
      "post": {
        "description": "",
        "operationId": "shop_post-admin-shop-sales-reveal",
        "summary": "Reveal a shop buyer's name and phone",
        "tags": [
          "shop"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_shop_buyer_contact"
      }
    },
    "/api/v1/admin/shop/storefront": {
      "get": {
        "description": "",
        "operationId": "shop_get-admin-shop-storefront",
        "summary": "View the Card Shop",
        "tags": [
          "shop"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_shop_index"
      }
    },
    "/api/v1/admin/telegram-manager/link": {
      "post": {
        "description": "",
        "operationId": "telegram-manager_post-admin-telegram-manager-link",
        "summary": "Use the manager Telegram bot",
        "tags": [
          "telegram-manager"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_telegram_console"
      }
    },
    "/api/v1/admin/telegram-manager/webhook/register": {
      "post": {
        "description": "",
        "operationId": "telegram-manager_post-admin-telegram-manager-webhook-register",
        "summary": "Manage notification channels \u0026 templates",
        "tags": [
          "telegram-manager"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_notifications_manage"
      }
    },
    "/api/v1/admin/telegram-manager/webhook/status": {
      "get": {
        "description": "",
        "operationId": "telegram-manager_get-admin-telegram-manager-webhook-status",
        "summary": "Manage notification channels \u0026 templates",
        "tags": [
          "telegram-manager"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_notifications_manage"
      }
    },
    "/api/v1/admin/telegram-manager/webhook/unregister": {
      "post": {
        "description": "",
        "operationId": "telegram-manager_post-admin-telegram-manager-webhook-unregister",
        "summary": "Manage notification channels \u0026 templates",
        "tags": [
          "telegram-manager"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_notifications_manage"
      }
    },
    "/api/v1/admin/telegram/broadcast": {
      "post": {
        "description": "",
        "operationId": "telegram_post-admin-telegram-broadcast",
        "summary": "Manage notification channels \u0026 templates",
        "tags": [
          "telegram"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_egress",
        "x-required-permission": "prm_notifications_manage"
      }
    },
    "/api/v1/admin/telegram/broadcast/audience-count": {
      "get": {
        "description": "",
        "operationId": "telegram_get-admin-telegram-broadcast-audience-count",
        "summary": "Manage notification channels \u0026 templates",
        "tags": [
          "telegram"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_notifications_manage"
      }
    },
    "/api/v1/admin/telegram/webhook/register": {
      "post": {
        "description": "",
        "operationId": "telegram_post-admin-telegram-webhook-register",
        "summary": "Manage notification channels \u0026 templates",
        "tags": [
          "telegram"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_notifications_manage"
      }
    },
    "/api/v1/admin/telegram/webhook/status": {
      "get": {
        "description": "",
        "operationId": "telegram_get-admin-telegram-webhook-status",
        "summary": "Manage notification channels \u0026 templates",
        "tags": [
          "telegram"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_notifications_manage"
      }
    },
    "/api/v1/admin/telegram/webhook/unregister": {
      "post": {
        "description": "",
        "operationId": "telegram_post-admin-telegram-webhook-unregister",
        "summary": "Manage notification channels \u0026 templates",
        "tags": [
          "telegram"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_notifications_manage"
      }
    },
    "/api/v1/admin/tools/announcements": {
      "get": {
        "description": "",
        "operationId": "tools_get-admin-tools-announcements",
        "summary": "Manage announcements",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tools_announcements"
      },
      "post": {
        "description": "",
        "operationId": "tools_post-admin-tools-announcements",
        "summary": "Manage announcements",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_egress",
        "x-required-permission": "prm_tools_announcements"
      }
    },
    "/api/v1/admin/tools/announcements/preview-count": {
      "post": {
        "description": "",
        "operationId": "tools_post-admin-tools-announcements-preview-count",
        "summary": "Manage announcements",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tools_announcements"
      }
    },
    "/api/v1/admin/tools/announcements/{id}": {
      "get": {
        "description": "",
        "operationId": "tools_get-admin-tools-announcements-by-id",
        "summary": "Manage announcements",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tools_announcements"
      }
    },
    "/api/v1/admin/tools/backup": {
      "get": {
        "description": "",
        "operationId": "tools_get-admin-tools-backup",
        "summary": "Backup \u0026 restore",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tools_backup"
      },
      "post": {
        "description": "",
        "operationId": "tools_post-admin-tools-backup",
        "summary": "Backup \u0026 restore",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_tools_backup"
      }
    },
    "/api/v1/admin/tools/backup/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "tools_post-admin-tools-backup-bulk-delete",
        "summary": "Backup \u0026 restore",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tools_backup"
      }
    },
    "/api/v1/admin/tools/backup/jobs": {
      "get": {
        "description": "",
        "operationId": "tools_get-admin-tools-backup-jobs",
        "summary": "Backup \u0026 restore",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tools_backup"
      }
    },
    "/api/v1/admin/tools/backup/jobs/{id}": {
      "get": {
        "description": "",
        "operationId": "tools_get-admin-tools-backup-jobs-by-id",
        "summary": "Backup \u0026 restore",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tools_backup"
      }
    },
    "/api/v1/admin/tools/backup/schedule": {
      "get": {
        "description": "",
        "operationId": "tools_get-admin-tools-backup-schedule",
        "summary": "Backup \u0026 restore",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tools_backup"
      },
      "put": {
        "description": "",
        "operationId": "tools_put-admin-tools-backup-schedule",
        "summary": "Backup \u0026 restore",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tools_backup"
      }
    },
    "/api/v1/admin/tools/backup/upload": {
      "post": {
        "description": "",
        "operationId": "tools_post-admin-tools-backup-upload",
        "summary": "Backup \u0026 restore",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_tools_backup"
      }
    },
    "/api/v1/admin/tools/backup/{id}": {
      "delete": {
        "description": "",
        "operationId": "tools_delete-admin-tools-backup",
        "summary": "Backup \u0026 restore",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tools_backup"
      }
    },
    "/api/v1/admin/tools/backup/{id}/download": {
      "get": {
        "description": "",
        "operationId": "tools_get-admin-tools-backup-download",
        "summary": "Backup \u0026 restore",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_tools_backup"
      }
    },
    "/api/v1/admin/tools/backup/{id}/download-ticket": {
      "post": {
        "description": "",
        "operationId": "tools_post-admin-tools-backup-download-ticket",
        "summary": "Backup \u0026 restore",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_tools_backup"
      }
    },
    "/api/v1/admin/tools/backup/{id}/restore": {
      "post": {
        "description": "",
        "operationId": "tools_post-admin-tools-backup-restore",
        "summary": "Backup \u0026 restore",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_tools_backup"
      }
    },
    "/api/v1/admin/tools/bandwidth": {
      "get": {
        "description": "",
        "operationId": "tools_get-admin-tools-bandwidth",
        "summary": "Bandwidth control",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tools_bandwidth_control"
      }
    },
    "/api/v1/admin/tools/bandwidth/apply": {
      "post": {
        "description": "",
        "operationId": "tools_post-admin-tools-bandwidth-apply",
        "summary": "Bandwidth control",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_tools_bandwidth_control"
      }
    },
    "/api/v1/admin/tools/bandwidth/history": {
      "get": {
        "description": "",
        "operationId": "tools_get-admin-tools-bandwidth-history",
        "summary": "Bandwidth control",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tools_bandwidth_control"
      }
    },
    "/api/v1/admin/tools/bandwidth/schedules": {
      "get": {
        "description": "",
        "operationId": "tools_get-admin-tools-bandwidth-schedules",
        "summary": "Bandwidth control",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tools_bandwidth_control"
      },
      "post": {
        "description": "",
        "operationId": "tools_post-admin-tools-bandwidth-schedules",
        "summary": "Bandwidth control",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tools_bandwidth_control"
      }
    },
    "/api/v1/admin/tools/bandwidth/schedules/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "tools_post-admin-tools-bandwidth-schedules-bulk-delete",
        "summary": "Bandwidth control",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tools_bandwidth_control"
      }
    },
    "/api/v1/admin/tools/bandwidth/schedules/{id}": {
      "delete": {
        "description": "",
        "operationId": "tools_delete-admin-tools-bandwidth-schedules",
        "summary": "Bandwidth control",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tools_bandwidth_control"
      },
      "patch": {
        "description": "",
        "operationId": "tools_patch-admin-tools-bandwidth-schedules",
        "summary": "Bandwidth control",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tools_bandwidth_control"
      }
    },
    "/api/v1/admin/tools/bulk/apply": {
      "post": {
        "description": "",
        "operationId": "tools_post-admin-tools-bulk-apply",
        "summary": "Bulk changes",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_tools_bulk_changes"
      }
    },
    "/api/v1/admin/tools/bulk/jobs": {
      "get": {
        "description": "",
        "operationId": "tools_get-admin-tools-bulk-jobs",
        "summary": "Bulk changes",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tools_bulk_changes"
      }
    },
    "/api/v1/admin/tools/bulk/jobs/{id}": {
      "get": {
        "description": "",
        "operationId": "tools_get-admin-tools-bulk-jobs-by-id",
        "summary": "Bulk changes",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tools_bulk_changes"
      }
    },
    "/api/v1/admin/tools/bulk/preview": {
      "post": {
        "description": "",
        "operationId": "tools_post-admin-tools-bulk-preview",
        "summary": "Bulk changes",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tools_bulk_changes"
      }
    },
    "/api/v1/admin/tools/dashboards": {
      "get": {
        "description": "",
        "operationId": "tools_get-admin-tools-dashboards",
        "summary": "Dashboard Manager",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tools_dashboard_manager"
      },
      "post": {
        "description": "",
        "operationId": "tools_post-admin-tools-dashboards",
        "summary": "Dashboard Manager",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tools_dashboard_manager"
      }
    },
    "/api/v1/admin/tools/dashboards/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "tools_post-admin-tools-dashboards-bulk-delete",
        "summary": "Dashboard Manager",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tools_dashboard_manager"
      }
    },
    "/api/v1/admin/tools/dashboards/restore-defaults": {
      "post": {
        "description": "",
        "operationId": "tools_post-admin-tools-dashboards-restore-defaults",
        "summary": "Dashboard Manager",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tools_dashboard_manager"
      }
    },
    "/api/v1/admin/tools/dashboards/{id}": {
      "delete": {
        "description": "",
        "operationId": "tools_delete-admin-tools-dashboards",
        "summary": "Dashboard Manager",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tools_dashboard_manager"
      },
      "get": {
        "description": "",
        "operationId": "tools_get-admin-tools-dashboards-by-id",
        "summary": "Dashboard Manager",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tools_dashboard_manager"
      },
      "put": {
        "description": "",
        "operationId": "tools_put-admin-tools-dashboards",
        "summary": "Dashboard Manager",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tools_dashboard_manager"
      }
    },
    "/api/v1/admin/tools/factory-reset": {
      "post": {
        "description": "",
        "operationId": "tools_post-admin-tools-factory-reset",
        "summary": "Factory reset",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_tools_factory_reset"
      }
    },
    "/api/v1/admin/tools/factory-reset/preview": {
      "get": {
        "description": "",
        "operationId": "tools_get-admin-tools-factory-reset-preview",
        "summary": "Factory reset",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tools_factory_reset"
      }
    },
    "/api/v1/admin/tools/maintenance/operations": {
      "get": {
        "description": "",
        "operationId": "tools_get-admin-tools-maintenance-operations",
        "summary": "System maintenance",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_tools_maintenance"
      }
    },
    "/api/v1/admin/tools/maintenance/run": {
      "post": {
        "description": "",
        "operationId": "tools_post-admin-tools-maintenance-run",
        "summary": "System maintenance",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tools_maintenance"
      }
    },
    "/api/v1/admin/tools/maintenance/runs": {
      "get": {
        "description": "",
        "operationId": "tools_get-admin-tools-maintenance-runs",
        "summary": "System maintenance",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tools_maintenance"
      }
    },
    "/api/v1/admin/tools/widget-data/sources": {
      "get": {
        "description": "",
        "operationId": "tools_get-admin-tools-widget-data-sources",
        "summary": "Dashboard Manager",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tools_dashboard_manager"
      }
    },
    "/api/v1/admin/tools/widget-data/{id}": {
      "get": {
        "description": "",
        "operationId": "tools_get-admin-tools-widget-data",
        "summary": "Dashboard Manager",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tools_dashboard_manager"
      }
    },
    "/api/v1/admin/tools/widgets": {
      "get": {
        "description": "",
        "operationId": "tools_get-admin-tools-widgets",
        "summary": "Widget Factory",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tools_widget_factory"
      },
      "post": {
        "description": "",
        "operationId": "tools_post-admin-tools-widgets",
        "summary": "Widget Factory",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tools_widget_factory"
      }
    },
    "/api/v1/admin/tools/widgets/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "tools_post-admin-tools-widgets-bulk-delete",
        "summary": "Widget Factory",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tools_widget_factory"
      }
    },
    "/api/v1/admin/tools/widgets/{id}": {
      "delete": {
        "description": "",
        "operationId": "tools_delete-admin-tools-widgets",
        "summary": "Widget Factory",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tools_widget_factory"
      },
      "get": {
        "description": "",
        "operationId": "tools_get-admin-tools-widgets-by-id",
        "summary": "Widget Factory",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tools_widget_factory"
      },
      "put": {
        "description": "",
        "operationId": "tools_put-admin-tools-widgets",
        "summary": "Widget Factory",
        "tags": [
          "tools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tools_widget_factory"
      }
    },
    "/api/v1/admin/trash": {
      "get": {
        "description": "",
        "operationId": "trash_get-admin-trash",
        "summary": "View \u0026 restore Trash",
        "tags": [
          "trash"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tools_trash"
      }
    },
    "/api/v1/admin/trash/bulk-purge": {
      "post": {
        "description": "",
        "operationId": "trash_post-admin-trash-bulk-purge",
        "summary": "Permanently delete from Trash",
        "tags": [
          "trash"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tools_trash_purge"
      }
    },
    "/api/v1/admin/trash/bulk-restore": {
      "post": {
        "description": "",
        "operationId": "trash_post-admin-trash-bulk-restore",
        "summary": "View \u0026 restore Trash",
        "tags": [
          "trash"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tools_trash"
      }
    },
    "/api/v1/admin/trash/empty": {
      "post": {
        "description": "",
        "operationId": "trash_post-admin-trash-empty",
        "summary": "Permanently delete from Trash",
        "tags": [
          "trash"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tools_trash_purge"
      }
    },
    "/api/v1/admin/trash/{id}/preflight": {
      "get": {
        "description": "",
        "operationId": "trash_get-admin-trash-preflight",
        "summary": "View \u0026 restore Trash",
        "tags": [
          "trash"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tools_trash"
      }
    },
    "/api/v1/admin/trash/{id}/restore": {
      "post": {
        "description": "",
        "operationId": "trash_post-admin-trash-restore",
        "summary": "View \u0026 restore Trash",
        "tags": [
          "trash"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tools_trash"
      }
    },
    "/api/v1/admin/webhooks/deliveries": {
      "get": {
        "description": "One page of delivery attempts, newest first, without the payload bodies. This is where you diagnose an integration that is not receiving events.",
        "operationId": "webhooks_get-admin-webhooks-deliveries",
        "parameters": [
          {
            "description": "Narrow to one endpoint. Also accepted as a bare endpoint_id parameter.",
            "in": "query",
            "name": "filter[endpoint_id]",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "description": "queued, sending, sent, failed or dead. An unknown value is a 400.",
            "in": "query",
            "name": "filter[state]",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "queued_at, state, attempts or id. Defaults to queued_at descending.",
            "in": "query",
            "name": "sort",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": [\n    {\n      \"id\": 77120,\n      \"endpoint_id\": 4,\n      \"event_type\": \"user.created\",\n      \"state\": \"failed\",\n      \"attempts\": 3,\n      \"max_attempts\": 6,\n      \"response_code\": 502,\n      \"response_ms\": 1204,\n      \"last_error\": \"upstream returned 502\",\n      \"url\": \"https://hooks.acme.example/xradius\",\n      \"queued_at\": \"2026-09-20 09:00:00\",\n      \"sent_at\": \"2026-09-20 09:04:11\",\n      \"next_attempt_at\": \"2026-09-20 09:20:00\"\n    }\n  ],\n  \"meta\": { \"page\": 1, \"page_size\": 50, \"total\": 4102, \"has_next\": true }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "Read the delivery log",
        "tags": [
          "webhooks"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_notifications_manage"
      }
    },
    "/api/v1/admin/webhooks/deliveries/{id}/replay": {
      "post": {
        "description": "Re-queues a past delivery, which is how a dead one is recovered after the receiving side is fixed.",
        "operationId": "webhooks_post-admin-webhooks-deliveries-replay",
        "parameters": [
          {
            "description": "Delivery id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Replay a delivery",
        "tags": [
          "webhooks"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_egress",
        "x-required-permission": "prm_notifications_manage"
      }
    },
    "/api/v1/admin/webhooks/endpoints": {
      "get": {
        "description": "Every configured endpoint for the tenant, with its subscription set. Un-paginated: the whole set is page 1 and has_next is always false.",
        "operationId": "webhooks_get-admin-webhooks-endpoints",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": [\n    {\n      \"id\": 4,\n      \"name\": \"billing-sync\",\n      \"url\": \"https://hooks.acme.example/xradius\",\n      \"events\": [\"user.created\", \"user.disconnected\"],\n      \"all_events\": false,\n      \"enabled\": true,\n      \"created_at\": \"2026-06-11 14:20:00\",\n      \"updated_at\": \"2026-09-02 08:31:12\"\n    }\n  ],\n  \"meta\": { \"page\": 1, \"page_size\": 1, \"total\": 1, \"has_next\": false }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "List webhook endpoints",
        "tags": [
          "webhooks"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_notifications_manage"
      },
      "post": {
        "description": "Registers a URL and the events it should receive. Set all_events to subscribe to everything, present and future, instead of naming keys.",
        "operationId": "webhooks_post-admin-webhooks-endpoints",
        "summary": "Create a webhook endpoint",
        "tags": [
          "webhooks"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_notifications_manage"
      }
    },
    "/api/v1/admin/webhooks/endpoints/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "webhooks_post-admin-webhooks-endpoints-bulk-delete",
        "summary": "Manage notification channels \u0026 templates",
        "tags": [
          "webhooks"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_notifications_manage"
      }
    },
    "/api/v1/admin/webhooks/endpoints/{id}": {
      "delete": {
        "description": "Removes the endpoint. Queued deliveries for it stop.",
        "operationId": "webhooks_delete-admin-webhooks-endpoints",
        "parameters": [
          {
            "description": "Endpoint id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Delete a webhook endpoint",
        "tags": [
          "webhooks"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_notifications_manage"
      },
      "patch": {
        "description": "Replaces name, url, events and all_events outright, and patches enabled only when it is present. Send the full object, because a missing events array clears the subscription rather than leaving it alone.",
        "operationId": "webhooks_patch-admin-webhooks-endpoints",
        "parameters": [
          {
            "description": "Endpoint id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Update a webhook endpoint",
        "tags": [
          "webhooks"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_notifications_manage"
      }
    },
    "/api/v1/admin/webhooks/endpoints/{id}/test": {
      "post": {
        "description": "Queues one synthetic delivery to the endpoint and returns its id so you can follow it in the log.",
        "operationId": "webhooks_post-admin-webhooks-endpoints-test",
        "parameters": [
          {
            "description": "Endpoint id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": { \"delivery_id\": 77120 }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "Send a test delivery",
        "tags": [
          "webhooks"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_egress",
        "x-required-permission": "prm_notifications_manage"
      }
    },
    "/api/v1/admin/webhooks/event-catalog": {
      "get": {
        "description": "Every event an endpoint may subscribe to, with its category. The create and update endpoints validate the events array against exactly this set, so read it before writing one. Static for the life of the release, so fetch it once and cache it.",
        "operationId": "webhooks_get-admin-webhooks-event-catalog",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": [\n    { \"key\": \"user.created\", \"category\": \"lifecycle\" },\n    { \"key\": \"user.disconnected\", \"category\": \"lifecycle\" },\n    { \"key\": \"usage.threshold\", \"category\": \"usage\" }\n  ],\n  \"meta\": { \"page\": 1, \"page_size\": 3, \"total\": 3, \"has_next\": false }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "List subscribable event keys",
        "tags": [
          "webhooks"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_notifications_manage"
      }
    },
    "/api/v1/auth/account": {
      "get": {
        "description": "",
        "operationId": "auth_get-auth-account",
        "summary": "GET /api/v1/auth/account",
        "tags": [
          "auth"
        ],
        "x-auth": "manager",
        "x-generated-stub": true
      },
      "patch": {
        "description": "",
        "operationId": "auth_patch-auth-account",
        "summary": "PATCH /api/v1/auth/account",
        "tags": [
          "auth"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/auth/account/2fa/disable": {
      "post": {
        "description": "",
        "operationId": "auth_post-auth-account-2fa-disable",
        "summary": "POST /api/v1/auth/account/2fa/disable",
        "tags": [
          "auth"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "account_reauth"
      }
    },
    "/api/v1/auth/account/2fa/enable": {
      "post": {
        "description": "",
        "operationId": "auth_post-auth-account-2fa-enable",
        "summary": "POST /api/v1/auth/account/2fa/enable",
        "tags": [
          "auth"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/auth/account/2fa/recovery-codes": {
      "post": {
        "description": "",
        "operationId": "auth_post-auth-account-2fa-recovery-codes",
        "summary": "POST /api/v1/auth/account/2fa/recovery-codes",
        "tags": [
          "auth"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "account_reauth"
      }
    },
    "/api/v1/auth/account/2fa/setup": {
      "post": {
        "description": "",
        "operationId": "auth_post-auth-account-2fa-setup",
        "summary": "POST /api/v1/auth/account/2fa/setup",
        "tags": [
          "auth"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/auth/account/avatar": {
      "post": {
        "description": "",
        "operationId": "auth_post-auth-account-avatar",
        "summary": "POST /api/v1/auth/account/avatar",
        "tags": [
          "auth"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/auth/account/limits": {
      "get": {
        "description": "",
        "operationId": "auth_get-auth-account-limits",
        "summary": "GET /api/v1/auth/account/limits",
        "tags": [
          "auth"
        ],
        "x-auth": "manager",
        "x-generated-stub": true
      }
    },
    "/api/v1/auth/account/password": {
      "post": {
        "description": "",
        "operationId": "auth_post-auth-account-password",
        "summary": "POST /api/v1/auth/account/password",
        "tags": [
          "auth"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "account_reauth"
      }
    },
    "/api/v1/auth/account/sessions": {
      "get": {
        "description": "",
        "operationId": "auth_get-auth-account-sessions",
        "summary": "GET /api/v1/auth/account/sessions",
        "tags": [
          "auth"
        ],
        "x-auth": "manager",
        "x-generated-stub": true
      }
    },
    "/api/v1/auth/account/sessions/revoke-others": {
      "post": {
        "description": "",
        "operationId": "auth_post-auth-account-sessions-revoke-others",
        "summary": "POST /api/v1/auth/account/sessions/revoke-others",
        "tags": [
          "auth"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/auth/account/sessions/{jti}": {
      "delete": {
        "description": "",
        "operationId": "auth_delete-auth-account-sessions",
        "summary": "DELETE /api/v1/auth/account/sessions/{jti}",
        "tags": [
          "auth"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/auth/context": {
      "get": {
        "description": "Tells a login page which flow to render: whether the host it was loaded on is a tenant subdomain, the instance apex, or unknown, plus the public tenant descriptor when it resolves. Unauthenticated, and always 200. It exposes only the public tenant slug, name and branding, and tenant is null for apex and unknown hosts.",
        "operationId": "auth_get-auth-context",
        "summary": "Classify the host before signing in",
        "tags": [
          "auth"
        ],
        "x-auth": "public"
      }
    },
    "/api/v1/auth/impersonation/exit": {
      "post": {
        "description": "",
        "operationId": "auth_post-auth-impersonation-exit",
        "summary": "POST /api/v1/auth/impersonation/exit",
        "tags": [
          "auth"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/auth/login": {
      "post": {
        "description": "Exchanges an email or username and a password for a tenant-scoped session token. The tenant is taken from the host when you call a tenant subdomain, and a selector in the body is discarded in that case.",
        "operationId": "auth_post-auth-login",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": {\n    \"token\": \"eyJhbGciOiJIUzI1NiIs...\",\n    \"user_id\": 41,\n    \"tenant_id\": 12,\n    \"tenant_slug\": \"acme\",\n    \"roles\": [\"support\"],\n    \"expires_at\": 1758358800\n  }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "Sign a manager in",
        "tags": [
          "auth"
        ],
        "x-auth": "public",
        "x-rate-limit-bucket": "login"
      }
    },
    "/api/v1/auth/logout": {
      "post": {
        "description": "Revokes the calling session's token id, so it stops working immediately rather than at expiry.",
        "operationId": "auth_post-auth-logout",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": { \"ok\": true }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "End the current session",
        "tags": [
          "auth"
        ],
        "x-auth": "manager"
      }
    },
    "/api/v1/auth/me": {
      "get": {
        "description": "The one-shot bootstrap call: the current manager, their roles, the resolved permission codes, and the tenant settings a client needs before it can render anything. Authenticated but not permission-gated, so any working credential reaches it.",
        "operationId": "auth_get-auth-me",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": {\n    \"version\": \"0.2.34\",\n    \"manager\": {\n      \"id\": 41,\n      \"tenant_id\": 12,\n      \"email\": \"ops@acme.example\",\n      \"username\": \"ops\",\n      \"status\": \"active\",\n      \"two_factor_enabled\": true\n    },\n    \"roles\": [\"support\"],\n    \"permissions\": [\"prm_users_index\", \"prm_users_update\"],\n    \"is_admin\": false,\n    \"settings\": {\n      \"currency\": \"EGP\",\n      \"timezone\": \"Africa/Cairo\",\n      \"default_language\": \"en\",\n      \"pos_undo_window_seconds\": 60\n    },\n    \"tenant\": {\n      \"license_status\": \"active\",\n      \"license_expires_at\": \"2027-01-31 00:00:00\",\n      \"max_users\": 5000,\n      \"users_count\": 812,\n      \"blocked\": false,\n      \"blocked_reason\": \"\"\n    }\n  }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "Who am I, and what may I do",
        "tags": [
          "auth"
        ],
        "x-auth": "manager"
      }
    },
    "/api/v1/auth/push-tokens": {
      "delete": {
        "description": "",
        "operationId": "auth_delete-auth-push-tokens",
        "summary": "DELETE /api/v1/auth/push-tokens",
        "tags": [
          "auth"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      },
      "post": {
        "description": "",
        "operationId": "auth_post-auth-push-tokens",
        "summary": "POST /api/v1/auth/push-tokens",
        "tags": [
          "auth"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/auth/refresh": {
      "post": {
        "description": "Issues a new session token from a refresh token. Only available when the original login asked for one.",
        "operationId": "auth_post-auth-refresh",
        "summary": "Exchange a refresh token",
        "tags": [
          "auth"
        ],
        "x-auth": "public",
        "x-rate-limit-bucket": "refresh"
      }
    },
    "/api/v1/auth/register/complete": {
      "post": {
        "description": "",
        "operationId": "auth_post-auth-register-complete",
        "summary": "POST /api/v1/auth/register/complete",
        "tags": [
          "auth"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "register_complete"
      }
    },
    "/api/v1/auth/register/resend": {
      "post": {
        "description": "",
        "operationId": "auth_post-auth-register-resend",
        "summary": "POST /api/v1/auth/register/resend",
        "tags": [
          "auth"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "register_resend"
      }
    },
    "/api/v1/auth/register/start": {
      "post": {
        "description": "",
        "operationId": "auth_post-auth-register-start",
        "summary": "POST /api/v1/auth/register/start",
        "tags": [
          "auth"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "register_start"
      }
    },
    "/api/v1/auth/register/verify": {
      "post": {
        "description": "",
        "operationId": "auth_post-auth-register-verify",
        "summary": "POST /api/v1/auth/register/verify",
        "tags": [
          "auth"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "register_verify"
      }
    },
    "/api/v1/billing/invoices": {
      "get": {
        "description": "Every invoice the caller may see, in one list, with filters for reconciling a period. A caller without tenant-wide visibility sees only invoices belonging to subscribers in their own manager subtree.",
        "operationId": "billing_get-billing-invoices",
        "parameters": [
          {
            "description": "Payment status.",
            "in": "query",
            "name": "filter[status]",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Narrow to one subscriber by username.",
            "in": "query",
            "name": "filter[username]",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Inclusive lower bound. A malformed value is a 400, not an ignored filter.",
            "in": "query",
            "name": "filter[date_from]",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Inclusive upper bound.",
            "in": "query",
            "name": "filter[date_to]",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Inclusive lower amount bound.",
            "in": "query",
            "name": "filter[amount_min]",
            "required": false,
            "schema": {
              "type": "number"
            }
          },
          {
            "description": "Inclusive upper amount bound.",
            "in": "query",
            "name": "filter[amount_max]",
            "required": false,
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": [\n    {\n      \"id\": 51204,\n      \"user_id\": 4711,\n      \"username\": \"ahmed\",\n      \"invoice_number\": \"INV-2026-000512\",\n      \"type\": \"activation\",\n      \"amount\": 171.00,\n      \"discount\": 0.00,\n      \"vat\": 14.00,\n      \"status\": \"paid\",\n      \"description\": \"Home 20M (activate)\",\n      \"payment_method\": \"manager_balance\",\n      \"due_date\": \"2026-09-20 00:00:00\",\n      \"paid_on\": \"2026-09-20 09:15:02\",\n      \"created_by_manager_id\": 41,\n      \"created_by_name\": \"cairo-reseller\",\n      \"created_at\": \"2026-09-20 09:15:02\"\n    }\n  ],\n  \"meta\": { \"page\": 1, \"page_size\": 50, \"total\": 1284, \"has_next\": true }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "List invoices across subscribers",
        "tags": [
          "billing"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_billing"
      },
      "post": {
        "description": "Creates an invoice against a named subscriber from line items. discount and vat are percentages from 0 to 100, and the total is computed from the items — never taken from the request.",
        "operationId": "billing_post-billing-invoices",
        "summary": "Issue an invoice",
        "tags": [
          "billing"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_billing"
      }
    },
    "/api/v1/billing/invoices/bulk-pay": {
      "post": {
        "description": "",
        "operationId": "billing_post-billing-invoices-bulk-pay",
        "summary": "Billing \u0026 invoices",
        "tags": [
          "billing"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_billing"
      }
    },
    "/api/v1/branding": {
      "get": {
        "description": "",
        "operationId": "branding_get-branding",
        "summary": "GET /api/v1/branding",
        "tags": [
          "branding"
        ],
        "x-auth": "public",
        "x-generated-stub": true
      }
    },
    "/api/v1/branding/assets/{key}": {
      "get": {
        "description": "",
        "operationId": "branding_get-branding-assets",
        "summary": "GET /api/v1/branding/assets/{key}",
        "tags": [
          "branding"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "branding_asset"
      }
    },
    "/api/v1/branding/assets/{slot}": {
      "post": {
        "description": "",
        "operationId": "branding_post-branding-assets",
        "summary": "Manage settings",
        "tags": [
          "branding"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_settings"
      }
    },
    "/api/v1/branding/icons/{key}/{variant}.png": {
      "get": {
        "description": "",
        "operationId": "branding_get-branding-icons",
        "summary": "GET /api/v1/branding/icons/{key}/{variant}.png",
        "tags": [
          "branding"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "branding_icon"
      }
    },
    "/api/v1/branding/manifest.webmanifest": {
      "get": {
        "description": "",
        "operationId": "branding_get-branding-manifest-webmanifest",
        "summary": "GET /api/v1/branding/manifest.webmanifest",
        "tags": [
          "branding"
        ],
        "x-auth": "public",
        "x-generated-stub": true
      }
    },
    "/api/v1/branding/user/manifest.webmanifest": {
      "get": {
        "description": "",
        "operationId": "branding_get-branding-user-manifest-webmanifest",
        "summary": "GET /api/v1/branding/user/manifest.webmanifest",
        "tags": [
          "branding"
        ],
        "x-auth": "public",
        "x-generated-stub": true
      }
    },
    "/api/v1/card-batches": {
      "get": {
        "description": "One page of card series with their stock breakdown. A non-admin caller sees only series created within their own manager subtree.",
        "operationId": "card-batches_get-card-batches",
        "parameters": [
          {
            "description": "Generation status — generating, ready, failed.",
            "in": "query",
            "name": "filter[status]",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The series mode.",
            "in": "query",
            "name": "filter[card_mode]",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The reseller holding the series after any transfer.",
            "in": "query",
            "name": "filter[owner_manager_id]",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "description": "Series whose unused cards have been revoked.",
            "in": "query",
            "name": "filter[suspended]",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "description": "Series cut from one saved card template.",
            "in": "query",
            "name": "filter[template_id]",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "description": "Plan name, distribution note, or series id.",
            "in": "query",
            "name": "q",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": [\n    {\n      \"id\": 208,\n      \"plan_id\": 7,\n      \"plan_name\": \"Home 20M\",\n      \"card_mode\": \"voucher_account\",\n      \"quantity\": 500,\n      \"face_value\": 150.00,\n      \"code_length\": 10,\n      \"code_charset\": \"alnum_no_ambig\",\n      \"status\": \"ready\",\n      \"suspended\": false,\n      \"processed\": 500,\n      \"used\": 312,\n      \"available\": 171,\n      \"sold_online\": 9,\n      \"sold_counter\": 8,\n      \"stuck_sale\": 0,\n      \"expiration\": \"2027-01-01 00:00:00\",\n      \"printed_at\": \"2026-08-30 12:01:44\",\n      \"print_count\": 1,\n      \"pdf_ready\": true,\n      \"has_cards\": true,\n      \"owner_manager_id\": 41,\n      \"sell_online\": false,\n      \"auto_activate\": false,\n      \"created_by\": 41\n    }\n  ],\n  \"meta\": { \"page\": 1, \"page_size\": 50, \"total\": 24, \"has_next\": false }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "List card series",
        "tags": [
          "card-batches"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_cards_list"
      },
      "post": {
        "description": "Stages an asynchronous generation job and returns immediately. The cards and the printable artifact are produced in the background; poll the series until status is ready, then fetch the print job.",
        "operationId": "card-batches_post-card-batches",
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": {\n    \"batch_id\": 209,\n    \"mode\": \"voucher_account\",\n    \"status\": \"generating\",\n    \"replay\": false\n  }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "Generate a card series",
        "tags": [
          "card-batches"
        ],
        "x-auth": "manager",
        "x-idempotent-on": "request_id",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_cards_generate_user"
      }
    },
    "/api/v1/card-batches/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "card-batches_post-card-batches-bulk-delete",
        "summary": "Delete card batches",
        "tags": [
          "card-batches"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_cards_delete"
      }
    },
    "/api/v1/card-batches/bulk-expiry": {
      "post": {
        "description": "",
        "operationId": "card-batches_post-card-batches-bulk-expiry",
        "summary": "Change card expiry",
        "tags": [
          "card-batches"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_cards_change_expiry"
      }
    },
    "/api/v1/card-batches/bulk-print-job": {
      "post": {
        "description": "",
        "operationId": "card-batches_post-card-batches-bulk-print-job",
        "summary": "Download / export cards",
        "tags": [
          "card-batches"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_cards_download"
      }
    },
    "/api/v1/card-batches/bulk-printed": {
      "post": {
        "description": "",
        "operationId": "card-batches_post-card-batches-bulk-printed",
        "summary": "Download / export cards",
        "tags": [
          "card-batches"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_cards_download"
      }
    },
    "/api/v1/card-batches/bulk-release": {
      "post": {
        "description": "",
        "operationId": "card-batches_post-card-batches-bulk-release",
        "summary": "Suspend / release cards",
        "tags": [
          "card-batches"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_cards_suspend_release"
      }
    },
    "/api/v1/card-batches/bulk-suspend": {
      "post": {
        "description": "",
        "operationId": "card-batches_post-card-batches-bulk-suspend",
        "summary": "Suspend / release cards",
        "tags": [
          "card-batches"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_cards_suspend_release"
      }
    },
    "/api/v1/card-batches/code-length": {
      "get": {
        "description": "",
        "operationId": "card-batches_get-card-batches-code-length",
        "summary": "Generate user cards",
        "tags": [
          "card-batches"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_cards_generate_user"
      }
    },
    "/api/v1/card-batches/{id}": {
      "delete": {
        "description": "Deletes the series and its cards. Refuses outright once any card in it has been redeemed, transferred or sold at the till, because those are financial records.",
        "operationId": "card-batches_delete-card-batches",
        "parameters": [
          {
            "description": "Series id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Delete a card series",
        "tags": [
          "card-batches"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_cards_delete"
      },
      "get": {
        "description": "The series header, its generation spec and its stock breakdown.",
        "operationId": "card-batches_get-card-batches-by-id",
        "parameters": [
          {
            "description": "Series id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Fetch one card series",
        "tags": [
          "card-batches"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_cards_list"
      },
      "patch": {
        "description": "",
        "operationId": "card-batches_patch-card-batches",
        "summary": "Manage card designs",
        "tags": [
          "card-batches"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_cards_designer"
      }
    },
    "/api/v1/card-batches/{id}/cards": {
      "get": {
        "description": "One row per card, carrying the plaintext code and, for prepaid series, the login username and password. Behind both the card-list permission and the per-series subtree gate for that reason.",
        "operationId": "card-batches_get-card-batches-cards",
        "parameters": [
          {
            "description": "Series id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "description": "Stored state — unused, consumed, active, exhausted, revoked.",
            "in": "query",
            "name": "filter[state]",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Who holds the card, which is orthogonal to state.",
            "in": "query",
            "name": "filter[disposition]",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Cards linked to a subscriber.",
            "in": "query",
            "name": "filter[has_customer]",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": [\n    {\n      \"id\": 90211,\n      \"serial\": \"000312\",\n      \"code\": \"K7P4M2Q9XD\",\n      \"username\": \"v90211\",\n      \"password\": \"8sk3ndq1\",\n      \"state\": \"unused\",\n      \"effective_state\": \"unused\",\n      \"disposition\": \"available\",\n      \"redemptions_left\": 1,\n      \"expires_at\": \"2027-01-01 00:00:00\",\n      \"used_bytes\": 0,\n      \"used_seconds\": 0\n    }\n  ],\n  \"meta\": { \"page\": 1, \"page_size\": 50, \"total\": 500, \"has_next\": true }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "List the cards in a series",
        "tags": [
          "card-batches"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_cards_list"
      }
    },
    "/api/v1/card-batches/{id}/expiry": {
      "post": {
        "description": "",
        "operationId": "card-batches_post-card-batches-expiry",
        "summary": "Change card expiry",
        "tags": [
          "card-batches"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_cards_change_expiry"
      }
    },
    "/api/v1/card-batches/{id}/pdf": {
      "get": {
        "description": "",
        "operationId": "card-batches_get-card-batches-pdf",
        "summary": "Download / export cards",
        "tags": [
          "card-batches"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_cards_download"
      }
    },
    "/api/v1/card-batches/{id}/pricing": {
      "get": {
        "description": "",
        "operationId": "card-batches_get-card-batches-pricing",
        "summary": "View card batches \u0026 cards",
        "tags": [
          "card-batches"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_cards_list"
      }
    },
    "/api/v1/card-batches/{id}/pricing/{resellerId}": {
      "delete": {
        "description": "",
        "operationId": "card-batches_delete-card-batches-pricing",
        "summary": "Manage card designs",
        "tags": [
          "card-batches"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_cards_designer"
      },
      "put": {
        "description": "",
        "operationId": "card-batches_put-card-batches-pricing",
        "summary": "Manage card designs",
        "tags": [
          "card-batches"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_cards_designer"
      }
    },
    "/api/v1/card-batches/{id}/print-job": {
      "get": {
        "description": "The data a client needs to render the printable sheet in the browser. Rendering happens client-side; the server ships no PDF engine.",
        "operationId": "card-batches_get-card-batches-print-job",
        "parameters": [
          {
            "description": "Series id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Fetch a series' print job",
        "tags": [
          "card-batches"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_cards_download"
      }
    },
    "/api/v1/card-batches/{id}/printed": {
      "post": {
        "description": "Records that the sheet was rendered, stamping printed_at and incrementing print_count.",
        "operationId": "card-batches_post-card-batches-printed",
        "parameters": [
          {
            "description": "Series id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Mark a series printed",
        "tags": [
          "card-batches"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_cards_download"
      }
    },
    "/api/v1/card-batches/{id}/regenerate": {
      "post": {
        "description": "",
        "operationId": "card-batches_post-card-batches-regenerate",
        "summary": "Generate user cards",
        "tags": [
          "card-batches"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_cards_generate_user"
      }
    },
    "/api/v1/card-batches/{id}/release": {
      "post": {
        "description": "Puts the revoked-but-unused cards of a suspended series back into stock.",
        "operationId": "card-batches_post-card-batches-release",
        "parameters": [
          {
            "description": "Series id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Release a suspended card series",
        "tags": [
          "card-batches"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_cards_suspend_release"
      }
    },
    "/api/v1/card-batches/{id}/suspend": {
      "post": {
        "description": "Revokes every still-unused card in the series. Cards already in flight are left alive. Re-running it is a harmless no-op.",
        "operationId": "card-batches_post-card-batches-suspend",
        "parameters": [
          {
            "description": "Series id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": { \"message_key\": \"card_batch_suspended\" }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "Suspend a card series",
        "tags": [
          "card-batches"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_cards_suspend_release"
      }
    },
    "/api/v1/card-batches/{id}/transfer-count": {
      "post": {
        "description": "Like transfer-whole, but moves a count of cards off the top of the available stock rather than the entire series.",
        "operationId": "card-batches_post-card-batches-transfer-count",
        "parameters": [
          {
            "description": "Series id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Transfer N cards from a series",
        "tags": [
          "card-batches"
        ],
        "x-auth": "manager",
        "x-idempotent-on": "request_id",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_cards_change_owner"
      }
    },
    "/api/v1/card-batches/{id}/transfer-range": {
      "post": {
        "description": "Moves a contiguous range of card ids from the series, for the case where the physical cards handed over are a known block.",
        "operationId": "card-batches_post-card-batches-transfer-range",
        "parameters": [
          {
            "description": "Series id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Transfer a card id range",
        "tags": [
          "card-batches"
        ],
        "x-auth": "manager",
        "x-idempotent-on": "request_id",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_cards_change_owner"
      }
    },
    "/api/v1/card-batches/{id}/transfer-whole": {
      "post": {
        "description": "Moves every card in the series from one manager to another at an agreed unit price, posting the matching ledger entries on both sides.",
        "operationId": "card-batches_post-card-batches-transfer-whole",
        "parameters": [
          {
            "description": "Series id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Transfer a whole series to another reseller",
        "tags": [
          "card-batches"
        ],
        "x-auth": "manager",
        "x-idempotent-on": "request_id",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_cards_change_owner"
      }
    },
    "/api/v1/card-batches/{id}/transferable-cards": {
      "get": {
        "description": "",
        "operationId": "card-batches_get-card-batches-transferable-cards",
        "summary": "View card batches \u0026 cards",
        "tags": [
          "card-batches"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_cards_list"
      }
    },
    "/api/v1/card-batches/{id}/transfers": {
      "get": {
        "description": "",
        "operationId": "card-batches_get-card-batches-transfers",
        "summary": "View card batches \u0026 cards",
        "tags": [
          "card-batches"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_cards_list"
      }
    },
    "/api/v1/card-templates": {
      "get": {
        "description": "",
        "operationId": "card-templates_get-card-templates",
        "summary": "GET /api/v1/card-templates",
        "tags": [
          "card-templates"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-any-permission": [
          "prm_card_templates_index",
          "prm_card_templates_index_all"
        ]
      },
      "post": {
        "description": "",
        "operationId": "card-templates_post-card-templates",
        "summary": "Create / edit card templates",
        "tags": [
          "card-templates"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_card_templates_manage"
      }
    },
    "/api/v1/card-templates/from-batch": {
      "post": {
        "description": "",
        "operationId": "card-templates_post-card-templates-from-batch",
        "summary": "Create / edit card templates",
        "tags": [
          "card-templates"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_card_templates_manage"
      }
    },
    "/api/v1/card-templates/{id}": {
      "delete": {
        "description": "",
        "operationId": "card-templates_delete-card-templates",
        "summary": "Delete card templates",
        "tags": [
          "card-templates"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_card_templates_delete"
      },
      "get": {
        "description": "",
        "operationId": "card-templates_get-card-templates-by-id",
        "summary": "GET /api/v1/card-templates/{id}",
        "tags": [
          "card-templates"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-any-permission": [
          "prm_card_templates_index",
          "prm_card_templates_index_all"
        ]
      },
      "patch": {
        "description": "",
        "operationId": "card-templates_patch-card-templates",
        "summary": "Create / edit card templates",
        "tags": [
          "card-templates"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_card_templates_manage"
      }
    },
    "/api/v1/card-templates/{id}/generate": {
      "post": {
        "description": "",
        "operationId": "card-templates_post-card-templates-generate",
        "summary": "Generate user cards",
        "tags": [
          "card-templates"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-any-permission": [
          "prm_card_templates_index",
          "prm_card_templates_index_all"
        ],
        "x-required-permission": "prm_cards_generate_user"
      }
    },
    "/api/v1/card-templates/{id}/sharing": {
      "get": {
        "description": "",
        "operationId": "card-templates_get-card-templates-sharing",
        "summary": "Share card templates (public / allow-list)",
        "tags": [
          "card-templates"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_card_templates_share"
      },
      "put": {
        "description": "",
        "operationId": "card-templates_put-card-templates-sharing",
        "summary": "Share card templates (public / allow-list)",
        "tags": [
          "card-templates"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_card_templates_share"
      }
    },
    "/api/v1/cards/redeem": {
      "post": {
        "description": "Spends a card and applies its effect to the named subscriber. Two authority checks run, both derived from your credential and neither from the body: the card must be in your subtree, and the subscriber must be one you may write to. Both denials are 404s identical to \"no such card\" and \"no such subscriber\".",
        "operationId": "cards_post-cards-redeem",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": {\n    \"card_id\": 90211,\n    \"mode\": \"refill_balance\",\n    \"user_id\": 4711,\n    \"effect_applied\": { \"type\": \"add_balance\", \"amount\": 150.00 },\n    \"new_balance\": 400.00\n  }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "Redeem a card onto a subscriber",
        "tags": [
          "cards"
        ],
        "x-auth": "manager",
        "x-idempotent-on": "request_id",
        "x-rate-limit-bucket": "card_redeem",
        "x-required-permission": "prm_cards_verify"
      }
    },
    "/api/v1/cards/redeem-create": {
      "post": {
        "description": "",
        "operationId": "cards_post-cards-redeem-create",
        "summary": "POST /api/v1/cards/redeem-create",
        "tags": [
          "cards"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "card_redeem"
      }
    },
    "/api/v1/cards/search": {
      "get": {
        "description": "The counter-staff lookup. Finds a single card and reports its state, its owning reseller and who spent it. Confined to the caller's manager subtree unless they are an administrator.",
        "operationId": "cards_get-cards-search",
        "parameters": [
          {
            "description": "code, serial or username.",
            "in": "query",
            "name": "kind",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The value to match. A code is normalised first, so separators and mixed case still resolve.",
            "in": "query",
            "name": "keyword",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": {\n    \"card_id\": 90211,\n    \"serial\": \"000312\",\n    \"state\": \"consumed\",\n    \"effective_state\": \"consumed\",\n    \"disposition\": \"\",\n    \"mode\": \"voucher_account\",\n    \"plan_name\": \"Home 20M\",\n    \"batch_id\": 208,\n    \"face_value\": 150.00,\n    \"redemptions_left\": 0,\n    \"owner_manager_id\": 41,\n    \"owner_username\": \"cairo-reseller\",\n    \"used_by_kind\": \"user\",\n    \"used_by_user_id\": 4711,\n    \"used_by_username\": \"ahmed\",\n    \"used_channel\": \"customer_portal\",\n    \"first_use_at\": \"2026-09-14 18:22:10\",\n    \"expires_at\": \"2027-01-01 00:00:00\"\n  }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "Verify one card by code, serial or username",
        "tags": [
          "cards"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "card_search",
        "x-required-permission": "prm_cards_verify"
      }
    },
    "/api/v1/cards/{id}/revoke": {
      "post": {
        "description": "Flips a single card to revoked. A revoked card can never be redeemed, and the state is terminal.",
        "operationId": "cards_post-cards-revoke",
        "parameters": [
          {
            "description": "Card id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Revoke one card",
        "tags": [
          "cards"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_cards_suspend_release"
      }
    },
    "/api/v1/cards/{id}/timeline": {
      "get": {
        "description": "Header facts plus the chronological event list for a single card: when it was minted, printed, sold, transferred and redeemed.",
        "operationId": "cards_get-cards-timeline",
        "parameters": [
          {
            "description": "Card id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "One card's full lifecycle",
        "tags": [
          "cards"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "card_timeline",
        "x-required-permission": "prm_cards_list"
      }
    },
    "/api/v1/control/managers/2fa-reset": {
      "post": {
        "description": "",
        "operationId": "control_post-control-managers-2fa-reset",
        "summary": "POST /api/v1/control/managers/2fa-reset",
        "tags": [
          "control"
        ],
        "x-auth": "control",
        "x-generated-stub": true
      }
    },
    "/api/v1/control/ping": {
      "get": {
        "description": "",
        "operationId": "control_get-control-ping",
        "summary": "GET /api/v1/control/ping",
        "tags": [
          "control"
        ],
        "x-auth": "control",
        "x-generated-stub": true
      }
    },
    "/api/v1/control/registrations": {
      "get": {
        "description": "",
        "operationId": "control_get-control-registrations",
        "summary": "GET /api/v1/control/registrations",
        "tags": [
          "control"
        ],
        "x-auth": "control",
        "x-generated-stub": true
      }
    },
    "/api/v1/control/registrations/{public_id}/approve": {
      "post": {
        "description": "",
        "operationId": "control_post-control-registrations-approve",
        "summary": "POST /api/v1/control/registrations/{public_id}/approve",
        "tags": [
          "control"
        ],
        "x-auth": "control",
        "x-generated-stub": true
      }
    },
    "/api/v1/control/registrations/{public_id}/reject": {
      "post": {
        "description": "",
        "operationId": "control_post-control-registrations-reject",
        "summary": "POST /api/v1/control/registrations/{public_id}/reject",
        "tags": [
          "control"
        ],
        "x-auth": "control",
        "x-generated-stub": true
      }
    },
    "/api/v1/control/sync": {
      "post": {
        "description": "",
        "operationId": "control_post-control-sync",
        "summary": "POST /api/v1/control/sync",
        "tags": [
          "control"
        ],
        "x-auth": "control",
        "x-generated-stub": true
      }
    },
    "/api/v1/control/sysbackup/ticket": {
      "post": {
        "description": "",
        "operationId": "control_post-control-sysbackup-ticket",
        "summary": "POST /api/v1/control/sysbackup/ticket",
        "tags": [
          "control"
        ],
        "x-auth": "control",
        "x-generated-stub": true
      }
    },
    "/api/v1/developer/admin/api-tokens": {
      "get": {
        "description": "",
        "operationId": "developer_get-developer-admin-api-tokens",
        "summary": "View and revoke ALL API tokens in this tenant",
        "tags": [
          "developer"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_api_tokens_all"
      }
    },
    "/api/v1/developer/admin/api-tokens/{id}": {
      "delete": {
        "description": "",
        "operationId": "developer_delete-developer-admin-api-tokens",
        "summary": "View and revoke ALL API tokens in this tenant",
        "tags": [
          "developer"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_api_tokens_all"
      }
    },
    "/api/v1/developer/api-tokens": {
      "get": {
        "description": "",
        "operationId": "developer_get-developer-api-tokens",
        "summary": "Create and manage my API tokens",
        "tags": [
          "developer"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_api_tokens"
      },
      "post": {
        "description": "",
        "operationId": "developer_post-developer-api-tokens",
        "summary": "Create and manage my API tokens",
        "tags": [
          "developer"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_api_tokens"
      }
    },
    "/api/v1/developer/api-tokens/scopes": {
      "get": {
        "description": "",
        "operationId": "developer_get-developer-api-tokens-scopes",
        "summary": "Create and manage my API tokens",
        "tags": [
          "developer"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_api_tokens"
      }
    },
    "/api/v1/developer/api-tokens/{id}": {
      "delete": {
        "description": "",
        "operationId": "developer_delete-developer-api-tokens",
        "summary": "Create and manage my API tokens",
        "tags": [
          "developer"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_api_tokens"
      },
      "patch": {
        "description": "",
        "operationId": "developer_patch-developer-api-tokens",
        "summary": "Create and manage my API tokens",
        "tags": [
          "developer"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_api_tokens"
      }
    },
    "/api/v1/developer/api-tokens/{id}/record": {
      "delete": {
        "description": "",
        "operationId": "developer_delete-developer-api-tokens-record",
        "summary": "Create and manage my API tokens",
        "tags": [
          "developer"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_api_tokens"
      }
    },
    "/api/v1/developer/api-tokens/{id}/reveal": {
      "post": {
        "description": "",
        "operationId": "developer_post-developer-api-tokens-reveal",
        "summary": "Create and manage my API tokens",
        "tags": [
          "developer"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "api_token_reveal",
        "x-required-permission": "prm_api_tokens"
      }
    },
    "/api/v1/developer/api-tokens/{id}/roll": {
      "post": {
        "description": "",
        "operationId": "developer_post-developer-api-tokens-roll",
        "summary": "Create and manage my API tokens",
        "tags": [
          "developer"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_api_tokens"
      }
    },
    "/api/v1/exports": {
      "get": {
        "description": "Jobs the caller owns, with their progress. A non-admin sees only jobs from their own manager subtree.",
        "operationId": "exports_get-exports",
        "parameters": [
          {
            "description": "Job status.",
            "in": "query",
            "name": "filter[status]",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "csv or xlsx.",
            "in": "query",
            "name": "filter[format]",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "One dataset key. The special value \"reports\" expands to every report dataset rather than matching exactly.",
            "in": "query",
            "name": "filter[target_table]",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": [\n    {\n      \"id\": 3312,\n      \"target_table\": \"users\",\n      \"format\": \"xlsx\",\n      \"status\": \"running\",\n      \"processed\": 4200,\n      \"total\": 8120,\n      \"row_count\": 0,\n      \"manager_id\": 41,\n      \"created_at\": \"2026-09-20 09:10:00\",\n      \"started_at\": \"2026-09-20 09:10:04\"\n    }\n  ],\n  \"meta\": { \"page\": 1, \"page_size\": 50, \"total\": 12, \"has_next\": false }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "List export jobs",
        "tags": [
          "exports"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_exports_index"
      },
      "post": {
        "description": "Creates the job and returns immediately; a separate worker produces the file. The caller's authority scope is stamped onto the job server-side, so an export contains exactly what that manager's list view would show and nothing more.",
        "operationId": "exports_post-exports",
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": { \"id\": 3312 }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "Queue an export",
        "tags": [
          "exports"
        ],
        "x-auth": "manager",
        "x-idempotent-on": "request_id",
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_exports_create"
      }
    },
    "/api/v1/exports/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "exports_post-exports-bulk-delete",
        "summary": "Create / delete export jobs",
        "tags": [
          "exports"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_exports_create"
      }
    },
    "/api/v1/exports/datasets": {
      "get": {
        "description": "Every table this build can export, with its key. target_table on the enqueue call must be one of these, and an unknown value is a 400. Static for the life of the release, so fetch it once and cache it.",
        "operationId": "exports_get-exports-datasets",
        "summary": "List exportable datasets",
        "tags": [
          "exports"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_exports_index"
      }
    },
    "/api/v1/exports/{id}": {
      "delete": {
        "description": "Removes the job and its artifact.",
        "operationId": "exports_delete-exports",
        "parameters": [
          {
            "description": "Job id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Delete an export job",
        "tags": [
          "exports"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_exports_create"
      },
      "get": {
        "description": "The job's current state and progress. Poll this until status reports the job is finished, then download.",
        "operationId": "exports_get-exports-by-id",
        "parameters": [
          {
            "description": "Job id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Poll one export job",
        "tags": [
          "exports"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_exports_index"
      }
    },
    "/api/v1/exports/{id}/download": {
      "get": {
        "description": "Streams the finished file. The ownership check runs again here, because the artifact itself can contain another reseller's card codes and balances.",
        "operationId": "exports_get-exports-download",
        "parameters": [
          {
            "description": "Job id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Download an export artifact",
        "tags": [
          "exports"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_heavy",
        "x-required-permission": "prm_exports_download"
      }
    },
    "/api/v1/freezone/preview-address-list": {
      "get": {
        "description": "",
        "operationId": "freezone_get-freezone-preview-address-list",
        "summary": "Manage Free Zone networks",
        "tags": [
          "freezone"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_freezone_manage"
      }
    },
    "/api/v1/freezone/push": {
      "post": {
        "description": "",
        "operationId": "freezone_post-freezone-push",
        "summary": "Manage Free Zone networks",
        "tags": [
          "freezone"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_freezone_manage"
      }
    },
    "/api/v1/freezone/router-script": {
      "get": {
        "description": "",
        "operationId": "freezone_get-freezone-router-script",
        "summary": "Manage Free Zone networks",
        "tags": [
          "freezone"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_freezone_manage"
      }
    },
    "/api/v1/freezone/zones": {
      "get": {
        "description": "",
        "operationId": "freezone_get-freezone-zones",
        "summary": "Manage Free Zone networks",
        "tags": [
          "freezone"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_freezone_manage"
      },
      "post": {
        "description": "",
        "operationId": "freezone_post-freezone-zones",
        "summary": "Manage Free Zone networks",
        "tags": [
          "freezone"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_freezone_manage"
      }
    },
    "/api/v1/freezone/zones/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "freezone_post-freezone-zones-bulk-delete",
        "summary": "Manage Free Zone networks",
        "tags": [
          "freezone"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_freezone_manage"
      }
    },
    "/api/v1/freezone/zones/{id}": {
      "delete": {
        "description": "",
        "operationId": "freezone_delete-freezone-zones",
        "summary": "Manage Free Zone networks",
        "tags": [
          "freezone"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_freezone_manage"
      },
      "patch": {
        "description": "",
        "operationId": "freezone_patch-freezone-zones",
        "summary": "Manage Free Zone networks",
        "tags": [
          "freezone"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_freezone_manage"
      }
    },
    "/api/v1/freezone/zones/{id}/entries": {
      "get": {
        "description": "",
        "operationId": "freezone_get-freezone-zones-entries",
        "summary": "Manage Free Zone networks",
        "tags": [
          "freezone"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_freezone_manage"
      },
      "post": {
        "description": "",
        "operationId": "freezone_post-freezone-zones-entries",
        "summary": "Manage Free Zone networks",
        "tags": [
          "freezone"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_freezone_manage"
      }
    },
    "/api/v1/freezone/zones/{id}/entries/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "freezone_post-freezone-zones-entries-bulk-delete",
        "summary": "Manage Free Zone networks",
        "tags": [
          "freezone"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_freezone_manage"
      }
    },
    "/api/v1/freezone/zones/{id}/entries/{entryId}": {
      "delete": {
        "description": "",
        "operationId": "freezone_delete-freezone-zones-entries",
        "summary": "Manage Free Zone networks",
        "tags": [
          "freezone"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_freezone_manage"
      }
    },
    "/api/v1/hotspot/pages": {
      "get": {
        "description": "",
        "operationId": "hotspot_get-hotspot-pages",
        "summary": "Manage hotspot pages",
        "tags": [
          "hotspot"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_hotspot_manage"
      },
      "post": {
        "description": "",
        "operationId": "hotspot_post-hotspot-pages",
        "summary": "Manage hotspot pages",
        "tags": [
          "hotspot"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_hotspot_manage"
      }
    },
    "/api/v1/hotspot/pages/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "hotspot_post-hotspot-pages-bulk-delete",
        "summary": "Manage hotspot pages",
        "tags": [
          "hotspot"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_hotspot_manage"
      }
    },
    "/api/v1/hotspot/pages/{id}": {
      "delete": {
        "description": "",
        "operationId": "hotspot_delete-hotspot-pages",
        "summary": "Manage hotspot pages",
        "tags": [
          "hotspot"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_hotspot_manage"
      },
      "get": {
        "description": "",
        "operationId": "hotspot_get-hotspot-pages-by-id",
        "summary": "Manage hotspot pages",
        "tags": [
          "hotspot"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_hotspot_manage"
      },
      "patch": {
        "description": "",
        "operationId": "hotspot_patch-hotspot-pages",
        "summary": "Manage hotspot pages",
        "tags": [
          "hotspot"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_hotspot_manage"
      }
    },
    "/api/v1/hotspot/pages/{id}/download": {
      "get": {
        "description": "",
        "operationId": "hotspot_get-hotspot-pages-download",
        "summary": "Manage hotspot pages",
        "tags": [
          "hotspot"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_hotspot_manage"
      }
    },
    "/api/v1/hotspot/pages/{id}/duplicate": {
      "post": {
        "description": "",
        "operationId": "hotspot_post-hotspot-pages-duplicate",
        "summary": "Manage hotspot pages",
        "tags": [
          "hotspot"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_hotspot_manage"
      }
    },
    "/api/v1/hotspot/preview": {
      "post": {
        "description": "",
        "operationId": "hotspot_post-hotspot-preview",
        "summary": "Manage hotspot pages",
        "tags": [
          "hotspot"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_hotspot_manage"
      }
    },
    "/api/v1/hotspot/templates": {
      "get": {
        "description": "",
        "operationId": "hotspot_get-hotspot-templates",
        "summary": "Manage hotspot pages",
        "tags": [
          "hotspot"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_hotspot_manage"
      }
    },
    "/api/v1/ip-pools": {
      "get": {
        "description": "",
        "operationId": "ip-pools_get-ip-pools",
        "summary": "View IP pools",
        "tags": [
          "ip-pools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_ippool_view"
      },
      "post": {
        "description": "",
        "operationId": "ip-pools_post-ip-pools",
        "summary": "Manage IP pools",
        "tags": [
          "ip-pools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_ippool_manage"
      }
    },
    "/api/v1/ip-pools/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "ip-pools_post-ip-pools-bulk-delete",
        "summary": "Manage IP pools",
        "tags": [
          "ip-pools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_ippool_manage"
      }
    },
    "/api/v1/ip-pools/names": {
      "get": {
        "description": "",
        "operationId": "ip-pools_get-ip-pools-names",
        "summary": "View IP pools",
        "tags": [
          "ip-pools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_ippool_view"
      }
    },
    "/api/v1/ip-pools/{id}": {
      "delete": {
        "description": "",
        "operationId": "ip-pools_delete-ip-pools",
        "summary": "Manage IP pools",
        "tags": [
          "ip-pools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_ippool_manage"
      },
      "get": {
        "description": "",
        "operationId": "ip-pools_get-ip-pools-by-id",
        "summary": "View IP pools",
        "tags": [
          "ip-pools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_ippool_view"
      },
      "patch": {
        "description": "",
        "operationId": "ip-pools_patch-ip-pools",
        "summary": "Manage IP pools",
        "tags": [
          "ip-pools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_ippool_manage"
      }
    },
    "/api/v1/ip-pools/{id}/leases": {
      "get": {
        "description": "",
        "operationId": "ip-pools_get-ip-pools-leases",
        "summary": "View IP pools",
        "tags": [
          "ip-pools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_ippool_view"
      }
    },
    "/api/v1/ip-pools/{id}/leases/{leaseId}/release": {
      "post": {
        "description": "",
        "operationId": "ip-pools_post-ip-pools-leases-release",
        "summary": "Manage IP pools",
        "tags": [
          "ip-pools"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_ippool_manage"
      }
    },
    "/api/v1/license": {
      "get": {
        "description": "",
        "operationId": "license_get-license",
        "summary": "GET /api/v1/license",
        "tags": [
          "license"
        ],
        "x-auth": "manager",
        "x-generated-stub": true
      }
    },
    "/api/v1/managers": {
      "get": {
        "description": "One page of managers. A caller without tenant-wide visibility sees their own descendants only — never their parent, never a sibling branch.",
        "operationId": "managers_get-managers",
        "parameters": [
          {
            "description": "Direct children of one manager. Also accepted as a bare parent_id query parameter. Narrows within the caller's subtree, never past it.",
            "in": "query",
            "name": "filter[parent_id]",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "description": "Searches name, username and email.",
            "in": "query",
            "name": "q",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": [\n    {\n      \"id\": 57,\n      \"tenant_id\": 12,\n      \"email\": \"giza@acme.example\",\n      \"username\": \"giza-reseller\",\n      \"firstname\": \"Mona\",\n      \"status\": \"active\",\n      \"parent_manager_id\": 41,\n      \"parent_username\": \"cairo-reseller\",\n      \"balance\": 1840.00,\n      \"debt_limit\": 5000.00,\n      \"debt\": 0.00,\n      \"discount_rate\": 10.00,\n      \"points_balance\": 240,\n      \"users_count\": 312,\n      \"created_at\": \"2026-05-02 09:00:00\"\n    }\n  ],\n  \"meta\": { \"page\": 1, \"page_size\": 50, \"total\": 9, \"has_next\": false }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "List managers",
        "tags": [
          "managers"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_managers_index"
      },
      "post": {
        "description": "Creates a staff or reseller account. A manager needs at least one login identity, so email or username must be present.",
        "operationId": "managers_post-managers",
        "summary": "Create a manager",
        "tags": [
          "managers"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_managers_create"
      }
    },
    "/api/v1/managers/all": {
      "get": {
        "description": "Id and name only, un-paginated, for populating a select control. Same subtree scope as the full list.",
        "operationId": "managers_get-managers-all",
        "summary": "List managers for a picker",
        "tags": [
          "managers"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_managers_index"
      }
    },
    "/api/v1/managers/bulk-activate": {
      "post": {
        "description": "",
        "operationId": "managers_post-managers-bulk-activate",
        "summary": "Edit managers",
        "tags": [
          "managers"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_managers_update"
      }
    },
    "/api/v1/managers/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "managers_post-managers-bulk-delete",
        "summary": "Delete managers",
        "tags": [
          "managers"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_managers_delete"
      }
    },
    "/api/v1/managers/bulk-suspend": {
      "post": {
        "description": "",
        "operationId": "managers_post-managers-bulk-suspend",
        "summary": "Edit managers",
        "tags": [
          "managers"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_managers_update"
      }
    },
    "/api/v1/managers/{id}": {
      "delete": {
        "description": "Hard-deletes the manager. Refused while they are still referenced by subscribers, card stock or ledger records — move those first.",
        "operationId": "managers_delete-managers",
        "parameters": [
          {
            "description": "Manager id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Delete a manager",
        "tags": [
          "managers"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_managers_delete"
      },
      "get": {
        "description": "The manager record, including their custom form fields.",
        "operationId": "managers_get-managers-by-id",
        "parameters": [
          {
            "description": "Manager id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Fetch one manager",
        "tags": [
          "managers"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_managers_index"
      },
      "patch": {
        "description": "Partial update. An omitted field is left alone.",
        "operationId": "managers_patch-managers",
        "parameters": [
          {
            "description": "Manager id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Update a manager",
        "tags": [
          "managers"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_managers_update"
      }
    },
    "/api/v1/managers/{id}/2fa/reset": {
      "post": {
        "description": "",
        "operationId": "managers_post-managers-2fa-reset",
        "summary": "Edit managers",
        "tags": [
          "managers"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_managers_update"
      }
    },
    "/api/v1/managers/{id}/activate": {
      "post": {
        "description": "",
        "operationId": "managers_post-managers-activate",
        "summary": "Edit managers",
        "tags": [
          "managers"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_managers_update"
      }
    },
    "/api/v1/managers/{id}/debt": {
      "get": {
        "description": "Outstanding debt for this manager, read off the loan ledger.",
        "operationId": "managers_get-managers-debt",
        "parameters": [
          {
            "description": "Manager id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Read a manager's debt",
        "tags": [
          "managers"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_managers_journal"
      }
    },
    "/api/v1/managers/{id}/invoices": {
      "get": {
        "description": "",
        "operationId": "managers_get-managers-invoices",
        "summary": "View manager invoices",
        "tags": [
          "managers"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_managers_invoices"
      }
    },
    "/api/v1/managers/{id}/journal": {
      "get": {
        "description": "Every money movement on this manager's wallet, newest first, with a running balance. This is the authoritative record — the wallet balance is its consequence, not a parallel truth.",
        "operationId": "managers_get-managers-journal",
        "parameters": [
          {
            "description": "Manager id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Read a manager's ledger",
        "tags": [
          "managers"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_managers_journal"
      }
    },
    "/api/v1/managers/{id}/loans": {
      "get": {
        "description": "",
        "operationId": "managers_get-managers-loans",
        "summary": "View manager journal",
        "tags": [
          "managers"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_managers_journal"
      }
    },
    "/api/v1/managers/{id}/login-as": {
      "post": {
        "description": "",
        "operationId": "managers_post-managers-login-as",
        "summary": "Log in as manager",
        "tags": [
          "managers"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_managers_login_as"
      }
    },
    "/api/v1/managers/{id}/overview": {
      "get": {
        "description": "",
        "operationId": "managers_get-managers-overview",
        "summary": "View managers",
        "tags": [
          "managers"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_managers_index"
      }
    },
    "/api/v1/managers/{id}/payments": {
      "get": {
        "description": "",
        "operationId": "managers_get-managers-payments",
        "summary": "View manager receipts",
        "tags": [
          "managers"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_managers_receipts"
      }
    },
    "/api/v1/managers/{id}/points/add": {
      "post": {
        "description": "",
        "operationId": "managers_post-managers-points-add",
        "summary": "Add / deduct manager reward points",
        "tags": [
          "managers"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_managers_reward_points"
      }
    },
    "/api/v1/managers/{id}/points/deduct": {
      "post": {
        "description": "",
        "operationId": "managers_post-managers-points-deduct",
        "summary": "Add / deduct manager reward points",
        "tags": [
          "managers"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_managers_reward_points"
      }
    },
    "/api/v1/managers/{id}/profile": {
      "get": {
        "description": "",
        "operationId": "managers_get-managers-profile",
        "summary": "View managers",
        "tags": [
          "managers"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_managers_index"
      }
    },
    "/api/v1/managers/{id}/receipts": {
      "get": {
        "description": "",
        "operationId": "managers_get-managers-receipts",
        "summary": "View manager receipts",
        "tags": [
          "managers"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_managers_receipts"
      }
    },
    "/api/v1/managers/{id}/reset-password": {
      "post": {
        "description": "",
        "operationId": "managers_post-managers-reset-password",
        "summary": "Edit managers",
        "tags": [
          "managers"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_managers_update"
      }
    },
    "/api/v1/managers/{id}/roles": {
      "get": {
        "description": "The roles assigned to this manager, which is what their permissions resolve from.",
        "operationId": "managers_get-managers-roles",
        "parameters": [
          {
            "description": "Manager id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Read a manager's roles",
        "tags": [
          "managers"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_managers_index"
      },
      "put": {
        "description": "Replaces the whole set. A caller may only grant roles whose permissions are a subset of their own, so this cannot be used to escalate.",
        "operationId": "managers_put-managers-roles",
        "parameters": [
          {
            "description": "Manager id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Replace a manager's roles",
        "tags": [
          "managers"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_roles_manage"
      }
    },
    "/api/v1/managers/{id}/suspend": {
      "post": {
        "description": "Sets the account to suspended. They can no longer sign in, and every API token they own stops authenticating with reason api_token_owner_inactive.",
        "operationId": "managers_post-managers-suspend",
        "parameters": [
          {
            "description": "Manager id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Suspend a manager",
        "tags": [
          "managers"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_managers_update"
      }
    },
    "/api/v1/managers/{id}/wallet/deposit": {
      "post": {
        "description": "Moves money into a reseller's wallet and posts the matching ledger entry. Idempotent on request_id through the ledger's own unique constraint.",
        "operationId": "managers_post-managers-wallet-deposit",
        "parameters": [
          {
            "description": "Manager id. May not be the caller themselves.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Credit a manager wallet",
        "tags": [
          "managers"
        ],
        "x-auth": "manager",
        "x-idempotent-on": "request_id",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_managers_deposit"
      }
    },
    "/api/v1/managers/{id}/wallet/pay-debt": {
      "post": {
        "description": "Records a repayment against a creditor. The creditor defaults to the debtor's parent manager.",
        "operationId": "managers_post-managers-wallet-pay-debt",
        "parameters": [
          {
            "description": "The debtor. May not be the caller themselves.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Settle a manager's debt",
        "tags": [
          "managers"
        ],
        "x-auth": "manager",
        "x-idempotent-on": "request_id",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_managers_pay_debt"
      }
    },
    "/api/v1/managers/{id}/wallet/topup": {
      "post": {
        "description": "",
        "operationId": "managers_post-managers-wallet-topup",
        "summary": "Deposit to manager wallet",
        "tags": [
          "managers"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_managers_deposit"
      }
    },
    "/api/v1/managers/{id}/wallet/withdraw": {
      "post": {
        "description": "The inverse of deposit, posting the matching ledger entry.",
        "operationId": "managers_post-managers-wallet-withdraw",
        "parameters": [
          {
            "description": "Manager id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Debit a manager wallet",
        "tags": [
          "managers"
        ],
        "x-auth": "manager",
        "x-idempotent-on": "request_id",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_managers_withdrawal"
      }
    },
    "/api/v1/nas/hotspot-asset": {
      "get": {
        "description": "",
        "operationId": "nas_get-nas-hotspot-asset",
        "summary": "GET /api/v1/nas/hotspot-asset",
        "tags": [
          "nas"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "nas_provision"
      }
    },
    "/api/v1/nas/provision": {
      "get": {
        "description": "",
        "operationId": "nas_get-nas-provision",
        "summary": "GET /api/v1/nas/provision",
        "tags": [
          "nas"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "nas_provision"
      }
    },
    "/api/v1/permissions": {
      "get": {
        "description": "Every permission code this build defines, with its group, label, help text, stated effect and risk class. This is the authoritative list a role editor or a token scope picker should render from.",
        "operationId": "permissions_get-permissions",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": [\n    {\n      \"code\": \"prm_users_index\",\n      \"group\": \"Subscribers\",\n      \"label\": \"View subscribers\",\n      \"desc\": \"See the subscriber list and open a subscriber record.\",\n      \"effect\": \"Read-only.\",\n      \"risk\": \"read\"\n    }\n  ]\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "List the permission catalogue",
        "tags": [
          "permissions"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_roles_manage"
      }
    },
    "/api/v1/portal/account": {
      "patch": {
        "description": "",
        "operationId": "portal_patch-portal-account",
        "summary": "PATCH /api/v1/portal/account",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/portal/auto-renew": {
      "post": {
        "description": "",
        "operationId": "portal_post-portal-auto-renew",
        "summary": "POST /api/v1/portal/auto-renew",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/portal/bucket-order": {
      "put": {
        "description": "",
        "operationId": "portal_put-portal-bucket-order",
        "summary": "PUT /api/v1/portal/bucket-order",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/portal/captcha": {
      "get": {
        "description": "",
        "operationId": "portal_get-portal-captcha",
        "summary": "GET /api/v1/portal/captcha",
        "tags": [
          "portal"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "portal_captcha"
      }
    },
    "/api/v1/portal/cards/redeem": {
      "post": {
        "description": "",
        "operationId": "portal_post-portal-cards-redeem",
        "summary": "POST /api/v1/portal/cards/redeem",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/portal/change-profile": {
      "post": {
        "description": "",
        "operationId": "portal_post-portal-change-profile",
        "summary": "POST /api/v1/portal/change-profile",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/portal/config": {
      "get": {
        "description": "",
        "operationId": "portal_get-portal-config",
        "summary": "GET /api/v1/portal/config",
        "tags": [
          "portal"
        ],
        "x-auth": "public",
        "x-generated-stub": true
      }
    },
    "/api/v1/portal/credentials": {
      "get": {
        "description": "",
        "operationId": "portal_get-portal-credentials",
        "summary": "GET /api/v1/portal/credentials",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/portal/deposit": {
      "post": {
        "description": "",
        "operationId": "portal_post-portal-deposit",
        "summary": "POST /api/v1/portal/deposit",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "portal_deposit"
      }
    },
    "/api/v1/portal/exchange": {
      "post": {
        "description": "",
        "operationId": "portal_post-portal-exchange",
        "summary": "POST /api/v1/portal/exchange",
        "tags": [
          "portal"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "portal_exchange"
      }
    },
    "/api/v1/portal/extend": {
      "post": {
        "description": "",
        "operationId": "portal_post-portal-extend",
        "summary": "POST /api/v1/portal/extend",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/portal/extensions": {
      "get": {
        "description": "",
        "operationId": "portal_get-portal-extensions",
        "summary": "GET /api/v1/portal/extensions",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/portal/extensions/{id}": {
      "get": {
        "description": "",
        "operationId": "portal_get-portal-extensions-by-id",
        "summary": "GET /api/v1/portal/extensions/{id}",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/portal/guest/context": {
      "get": {
        "description": "",
        "operationId": "portal_get-portal-guest-context",
        "summary": "GET /api/v1/portal/guest/context",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "portal_guest"
      }
    },
    "/api/v1/portal/guest/register": {
      "post": {
        "description": "",
        "operationId": "portal_post-portal-guest-register",
        "summary": "POST /api/v1/portal/guest/register",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "portal_guest"
      }
    },
    "/api/v1/portal/invoices": {
      "get": {
        "description": "",
        "operationId": "portal_get-portal-invoices",
        "summary": "GET /api/v1/portal/invoices",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/portal/invoices/{id}": {
      "get": {
        "description": "",
        "operationId": "portal_get-portal-invoices-by-id",
        "summary": "GET /api/v1/portal/invoices/{id}",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/portal/invoices/{id}/render-data": {
      "get": {
        "description": "",
        "operationId": "portal_get-portal-invoices-render-data",
        "summary": "GET /api/v1/portal/invoices/{id}/render-data",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy"
      }
    },
    "/api/v1/portal/join": {
      "post": {
        "description": "",
        "operationId": "portal_post-portal-join",
        "summary": "POST /api/v1/portal/join",
        "tags": [
          "portal"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "portal_join"
      }
    },
    "/api/v1/portal/join/context": {
      "get": {
        "description": "",
        "operationId": "portal_get-portal-join-context",
        "summary": "GET /api/v1/portal/join/context",
        "tags": [
          "portal"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "portal_join"
      }
    },
    "/api/v1/portal/ledger": {
      "get": {
        "description": "",
        "operationId": "portal_get-portal-ledger",
        "summary": "GET /api/v1/portal/ledger",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/portal/login": {
      "post": {
        "description": "",
        "operationId": "portal_post-portal-login",
        "summary": "POST /api/v1/portal/login",
        "tags": [
          "portal"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "portal_login"
      }
    },
    "/api/v1/portal/me": {
      "get": {
        "description": "",
        "operationId": "portal_get-portal-me",
        "summary": "GET /api/v1/portal/me",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/portal/parental": {
      "get": {
        "description": "",
        "operationId": "portal_get-portal-parental",
        "summary": "GET /api/v1/portal/parental",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/portal/parental/pause": {
      "post": {
        "description": "",
        "operationId": "portal_post-portal-parental-pause",
        "summary": "POST /api/v1/portal/parental/pause",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/portal/parental/pin": {
      "post": {
        "description": "",
        "operationId": "portal_post-portal-parental-pin",
        "summary": "POST /api/v1/portal/parental/pin",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/portal/parental/rules": {
      "put": {
        "description": "",
        "operationId": "portal_put-portal-parental-rules",
        "summary": "PUT /api/v1/portal/parental/rules",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/portal/parental/unlock": {
      "post": {
        "description": "",
        "operationId": "portal_post-portal-parental-unlock",
        "summary": "POST /api/v1/portal/parental/unlock",
        "tags": [
          "portal"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "portal_parental_unlock"
      }
    },
    "/api/v1/portal/password": {
      "post": {
        "description": "",
        "operationId": "portal_post-portal-password",
        "summary": "POST /api/v1/portal/password",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/portal/payments/gateways": {
      "get": {
        "description": "",
        "operationId": "portal_get-portal-payments-gateways",
        "summary": "GET /api/v1/portal/payments/gateways",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/portal/payments/transactions": {
      "get": {
        "description": "",
        "operationId": "portal_get-portal-payments-transactions",
        "summary": "GET /api/v1/portal/payments/transactions",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/portal/profiles": {
      "get": {
        "description": "",
        "operationId": "portal_get-portal-profiles",
        "summary": "GET /api/v1/portal/profiles",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/portal/purchase": {
      "post": {
        "description": "",
        "operationId": "portal_post-portal-purchase",
        "summary": "POST /api/v1/portal/purchase",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "portal_deposit"
      }
    },
    "/api/v1/portal/push-tokens": {
      "delete": {
        "description": "",
        "operationId": "portal_delete-portal-push-tokens",
        "summary": "DELETE /api/v1/portal/push-tokens",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      },
      "post": {
        "description": "",
        "operationId": "portal_post-portal-push-tokens",
        "summary": "POST /api/v1/portal/push-tokens",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/portal/quota-buckets": {
      "get": {
        "description": "",
        "operationId": "portal_get-portal-quota-buckets",
        "summary": "GET /api/v1/portal/quota-buckets",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/portal/quote": {
      "post": {
        "description": "",
        "operationId": "portal_post-portal-quote",
        "summary": "POST /api/v1/portal/quote",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/portal/refresh": {
      "post": {
        "description": "",
        "operationId": "portal_post-portal-refresh",
        "summary": "POST /api/v1/portal/refresh",
        "tags": [
          "portal"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "portal_refresh"
      }
    },
    "/api/v1/portal/renew": {
      "post": {
        "description": "",
        "operationId": "portal_post-portal-renew",
        "summary": "POST /api/v1/portal/renew",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/portal/sessions": {
      "get": {
        "description": "",
        "operationId": "portal_get-portal-sessions",
        "summary": "GET /api/v1/portal/sessions",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/portal/signup": {
      "post": {
        "description": "",
        "operationId": "portal_post-portal-signup",
        "summary": "POST /api/v1/portal/signup",
        "tags": [
          "portal"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "portal_signup"
      }
    },
    "/api/v1/portal/signup/schema": {
      "get": {
        "description": "",
        "operationId": "portal_get-portal-signup-schema",
        "summary": "GET /api/v1/portal/signup/schema",
        "tags": [
          "portal"
        ],
        "x-auth": "public",
        "x-generated-stub": true
      }
    },
    "/api/v1/portal/speed": {
      "delete": {
        "description": "",
        "operationId": "portal_delete-portal-speed",
        "summary": "DELETE /api/v1/portal/speed",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      },
      "get": {
        "description": "",
        "operationId": "portal_get-portal-speed",
        "summary": "GET /api/v1/portal/speed",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      },
      "put": {
        "description": "",
        "operationId": "portal_put-portal-speed",
        "summary": "PUT /api/v1/portal/speed",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/portal/telegram-exchange": {
      "post": {
        "description": "",
        "operationId": "portal_post-portal-telegram-exchange",
        "summary": "POST /api/v1/portal/telegram-exchange",
        "tags": [
          "portal"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "portal_telegram_exchange"
      }
    },
    "/api/v1/portal/telegram/link": {
      "get": {
        "description": "",
        "operationId": "portal_get-portal-telegram-link",
        "summary": "GET /api/v1/portal/telegram/link",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/portal/tickets": {
      "get": {
        "description": "",
        "operationId": "portal_get-portal-tickets",
        "summary": "GET /api/v1/portal/tickets",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      },
      "post": {
        "description": "",
        "operationId": "portal_post-portal-tickets",
        "summary": "POST /api/v1/portal/tickets",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/portal/tickets/form": {
      "get": {
        "description": "",
        "operationId": "portal_get-portal-tickets-form",
        "summary": "GET /api/v1/portal/tickets/form",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/portal/tickets/{id}": {
      "get": {
        "description": "",
        "operationId": "portal_get-portal-tickets-by-id",
        "summary": "GET /api/v1/portal/tickets/{id}",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/portal/tickets/{id}/attach": {
      "post": {
        "description": "",
        "operationId": "portal_post-portal-tickets-attach",
        "summary": "POST /api/v1/portal/tickets/{id}/attach",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/portal/tickets/{id}/attachments/{attId}": {
      "delete": {
        "description": "",
        "operationId": "portal_delete-portal-tickets-attachments",
        "summary": "DELETE /api/v1/portal/tickets/{id}/attachments/{attId}",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      },
      "get": {
        "description": "",
        "operationId": "portal_get-portal-tickets-attachments",
        "summary": "GET /api/v1/portal/tickets/{id}/attachments/{attId}",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/portal/tickets/{id}/messages": {
      "post": {
        "description": "",
        "operationId": "portal_post-portal-tickets-messages",
        "summary": "POST /api/v1/portal/tickets/{id}/messages",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/portal/tunnel-identify": {
      "post": {
        "description": "",
        "operationId": "portal_post-portal-tunnel-identify",
        "summary": "POST /api/v1/portal/tunnel-identify",
        "tags": [
          "portal"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "portal_tunnel_identify"
      }
    },
    "/api/v1/portal/tunnel-tenant": {
      "post": {
        "description": "",
        "operationId": "portal_post-portal-tunnel-tenant",
        "summary": "POST /api/v1/portal/tunnel-tenant",
        "tags": [
          "portal"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "portal_tunnel_tenant"
      }
    },
    "/api/v1/portal/usage": {
      "get": {
        "description": "",
        "operationId": "portal_get-portal-usage",
        "summary": "GET /api/v1/portal/usage",
        "tags": [
          "portal"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/pos/products": {
      "get": {
        "description": "",
        "operationId": "pos_get-pos-products",
        "summary": "Sell cards at the counter (till)",
        "tags": [
          "pos"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_pos_sell"
      }
    },
    "/api/v1/pos/sales": {
      "get": {
        "description": "",
        "operationId": "pos_get-pos-sales",
        "summary": "Sell cards at the counter (till)",
        "tags": [
          "pos"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_pos_sell"
      },
      "post": {
        "description": "",
        "operationId": "pos_post-pos-sales",
        "summary": "Sell cards at the counter (till)",
        "tags": [
          "pos"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_pos_sell"
      }
    },
    "/api/v1/pos/sales/{id}/print-job": {
      "get": {
        "description": "",
        "operationId": "pos_get-pos-sales-print-job",
        "summary": "Sell cards at the counter (till)",
        "tags": [
          "pos"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_pos_sell"
      }
    },
    "/api/v1/pos/sales/{id}/printed": {
      "post": {
        "description": "",
        "operationId": "pos_post-pos-sales-printed",
        "summary": "Sell cards at the counter (till)",
        "tags": [
          "pos"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_pos_sell"
      }
    },
    "/api/v1/pos/sales/{id}/void": {
      "post": {
        "description": "",
        "operationId": "pos_post-pos-sales-void",
        "summary": "POST /api/v1/pos/sales/{id}/void",
        "tags": [
          "pos"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-any-permission": [
          "prm_pos_sell",
          "prm_pos_void"
        ]
      }
    },
    "/api/v1/pos/shifts": {
      "get": {
        "description": "",
        "operationId": "pos_get-pos-shifts",
        "summary": "Sell cards at the counter (till)",
        "tags": [
          "pos"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_pos_sell"
      },
      "post": {
        "description": "",
        "operationId": "pos_post-pos-shifts",
        "summary": "Sell cards at the counter (till)",
        "tags": [
          "pos"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_pos_sell"
      }
    },
    "/api/v1/pos/shifts/current": {
      "get": {
        "description": "",
        "operationId": "pos_get-pos-shifts-current",
        "summary": "Sell cards at the counter (till)",
        "tags": [
          "pos"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_pos_sell"
      }
    },
    "/api/v1/pos/shifts/{id}/close": {
      "post": {
        "description": "",
        "operationId": "pos_post-pos-shifts-close",
        "summary": "Sell cards at the counter (till)",
        "tags": [
          "pos"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_pos_sell"
      }
    },
    "/api/v1/pos/shifts/{id}/report": {
      "get": {
        "description": "",
        "operationId": "pos_get-pos-shifts-report",
        "summary": "Sell cards at the counter (till)",
        "tags": [
          "pos"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_pos_sell"
      }
    },
    "/api/v1/profiles": {
      "get": {
        "description": "One page of service plans, scoped to what the calling manager may actually see. A private plan is visible only to managers it was explicitly allow-listed for.",
        "operationId": "profiles_get-profiles",
        "parameters": [
          {
            "description": "prepaid, postpaid, fup, extension or addon.",
            "in": "query",
            "name": "filter[type]",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Plan status.",
            "in": "query",
            "name": "filter[status]",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Only plans this caller may bind to a subscriber. Narrower than visibility, and the right filter behind a plan picker.",
            "in": "query",
            "name": "filter[assignable]",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "description": "ppp, hotspot or both.",
            "in": "query",
            "name": "filter[allowed_services]",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Plans the subscriber portal offers for self-service renewal.",
            "in": "query",
            "name": "filter[show_in_ucp]",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "description": "Plans restricted to an explicit manager allow-list.",
            "in": "query",
            "name": "filter[private]",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "description": "Plans that fall back to another plan on expiry or quota exhaustion.",
            "in": "query",
            "name": "filter[has_fup_chain]",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "description": "id, created_at, name, type or status. Defaults to name ascending.",
            "in": "query",
            "name": "sort",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": [\n    {\n      \"id\": 7,\n      \"tenant_id\": 12,\n      \"name\": \"Home 20M\",\n      \"type\": \"prepaid\",\n      \"base_fee\": 150.00,\n      \"end_user_price\": 180.00,\n      \"vat_percent\": \"14.00\",\n      \"enforce_expiration\": true,\n      \"expiration_value\": 30,\n      \"expiration_unit\": \"days\",\n      \"combined_bytes_limit\": 107374182400,\n      \"enforce_combined_bytes\": true,\n      \"enforce_period_seconds\": false,\n      \"download_kbps\": 20480,\n      \"upload_kbps\": 4096,\n      \"speed_share_mode\": \"per_session\",\n      \"allowed_services\": \"both\",\n      \"private\": false,\n      \"show_in_ucp\": true,\n      \"carry_over_remaining_quota\": false,\n      \"auto_renew_supported\": true,\n      \"points_award\": 10\n    }\n  ],\n  \"meta\": { \"page\": 1, \"page_size\": 50, \"total\": 18, \"has_next\": false }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "List plans",
        "tags": [
          "profiles"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_profiles_index"
      },
      "post": {
        "description": "name and type are the only required fields; everything else has a schema default. A plan created with no enforce toggles on is an unlimited plan.",
        "operationId": "profiles_post-profiles",
        "summary": "Create a plan",
        "tags": [
          "profiles"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_profiles_create"
      }
    },
    "/api/v1/profiles/all": {
      "get": {
        "description": "Id and name only, un-paginated, for populating a select control. Cheaper than the full list when you do not need the plan bodies.",
        "operationId": "profiles_get-profiles-all",
        "summary": "List plans for a picker",
        "tags": [
          "profiles"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_profiles_index"
      }
    },
    "/api/v1/profiles/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "profiles_post-profiles-bulk-delete",
        "summary": "Delete profiles",
        "tags": [
          "profiles"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_profiles_delete"
      }
    },
    "/api/v1/profiles/{id}": {
      "delete": {
        "description": "Refused while the plan is still referenced — by a subscriber, a card series or another plan's fall-back chain.",
        "operationId": "profiles_delete-profiles",
        "parameters": [
          {
            "description": "Plan id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Delete a plan",
        "tags": [
          "profiles"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_profiles_delete"
      },
      "get": {
        "description": "The full plan definition: pricing, quota limits and their enforce toggles, speed, lifecycle flags and the fall-back chain.",
        "operationId": "profiles_get-profiles-by-id",
        "parameters": [
          {
            "description": "Plan id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Fetch one plan",
        "tags": [
          "profiles"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_profiles_index"
      },
      "patch": {
        "description": "Partial update. Numeric and foreign-key fields can be cleared to null by sending null explicitly, which is distinct from omitting them.",
        "operationId": "profiles_patch-profiles",
        "parameters": [
          {
            "description": "Plan id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Update a plan",
        "tags": [
          "profiles"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_profiles_update"
      }
    },
    "/api/v1/profiles/{id}/allowed-extensions": {
      "get": {
        "description": "",
        "operationId": "profiles_get-profiles-allowed-extensions",
        "summary": "Manage profile visibility / policy",
        "tags": [
          "profiles"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_profiles_policy_manager"
      },
      "put": {
        "description": "",
        "operationId": "profiles_put-profiles-allowed-extensions",
        "summary": "Manage profile visibility / policy",
        "tags": [
          "profiles"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_profiles_policy_manager"
      }
    },
    "/api/v1/profiles/{id}/allowed-managers": {
      "get": {
        "description": "Which managers may see and assign this plan. Only meaningful while the plan is private; a public plan is visible to everyone regardless of this list.",
        "operationId": "profiles_get-profiles-allowed-managers",
        "parameters": [
          {
            "description": "Plan id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Read a private plan's manager allow-list",
        "tags": [
          "profiles"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_profiles_policy_manager"
      },
      "put": {
        "description": "Replaces the whole list. Managers omitted from the payload lose access.",
        "operationId": "profiles_put-profiles-allowed-managers",
        "parameters": [
          {
            "description": "Plan id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Replace a private plan's manager allow-list",
        "tags": [
          "profiles"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_profiles_policy_manager"
      }
    },
    "/api/v1/profiles/{id}/allowed-parents": {
      "get": {
        "description": "",
        "operationId": "profiles_get-profiles-allowed-parents",
        "summary": "Manage profile visibility / policy",
        "tags": [
          "profiles"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_profiles_policy_manager"
      },
      "put": {
        "description": "",
        "operationId": "profiles_put-profiles-allowed-parents",
        "summary": "Manage profile visibility / policy",
        "tags": [
          "profiles"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_profiles_policy_manager"
      }
    },
    "/api/v1/profiles/{id}/clone": {
      "post": {
        "description": "Copies the plan, including its RADIUS attributes and policies, under a new name. The usual way to build a variant without re-entering forty fields.",
        "operationId": "profiles_post-profiles-clone",
        "parameters": [
          {
            "description": "Plan to copy.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Clone a plan",
        "tags": [
          "profiles"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_profiles_create"
      }
    },
    "/api/v1/profiles/{id}/policies": {
      "get": {
        "description": "",
        "operationId": "profiles_get-profiles-policies",
        "summary": "Manage plan policy rules",
        "tags": [
          "profiles"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_profiles_policies"
      },
      "post": {
        "description": "",
        "operationId": "profiles_post-profiles-policies",
        "summary": "Manage plan policy rules",
        "tags": [
          "profiles"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_profiles_policies"
      }
    },
    "/api/v1/profiles/{id}/policies/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "profiles_post-profiles-policies-bulk-delete",
        "summary": "Manage plan policy rules",
        "tags": [
          "profiles"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_profiles_policies"
      }
    },
    "/api/v1/profiles/{id}/policies/{policyID}": {
      "delete": {
        "description": "",
        "operationId": "profiles_delete-profiles-policies",
        "summary": "Manage plan policy rules",
        "tags": [
          "profiles"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_profiles_policies"
      },
      "patch": {
        "description": "",
        "operationId": "profiles_patch-profiles-policies",
        "summary": "Manage plan policy rules",
        "tags": [
          "profiles"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_profiles_policies"
      }
    },
    "/api/v1/profiles/{id}/price-list": {
      "get": {
        "description": "The pricing-tree overrides for this plan: what each manager in the tree pays and may charge, where it differs from the plan default.",
        "operationId": "profiles_get-profiles-price-list",
        "parameters": [
          {
            "description": "Plan id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Read a plan's per-reseller prices",
        "tags": [
          "profiles"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_profiles_pricing"
      },
      "put": {
        "description": "Replaces the whole override set for this plan in one call. An entry omitted from the payload is removed, not left alone.",
        "operationId": "profiles_put-profiles-price-list",
        "parameters": [
          {
            "description": "Plan id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Replace a plan's per-reseller prices",
        "tags": [
          "profiles"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_profiles_pricing"
      }
    },
    "/api/v1/profiles/{id}/radius-attrs": {
      "get": {
        "description": "The reply attributes this plan adds to an Access-Accept, beyond the ones derived from its speed and quota settings.",
        "operationId": "profiles_get-profiles-radius-attrs",
        "parameters": [
          {
            "description": "Plan id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "List a plan's RADIUS attributes",
        "tags": [
          "profiles"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_profiles_radius_attributes"
      },
      "post": {
        "description": "Adds one reply attribute. Attributes set here ride on every session of every subscriber on the plan.",
        "operationId": "profiles_post-profiles-radius-attrs",
        "parameters": [
          {
            "description": "Plan id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Add a RADIUS attribute to a plan",
        "tags": [
          "profiles"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_profiles_radius_attributes"
      }
    },
    "/api/v1/profiles/{id}/radius-attrs/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "profiles_post-profiles-radius-attrs-bulk-delete",
        "summary": "Manage RADIUS attributes",
        "tags": [
          "profiles"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_profiles_radius_attributes"
      }
    },
    "/api/v1/profiles/{id}/radius-attrs/{attrId}": {
      "delete": {
        "description": "",
        "operationId": "profiles_delete-profiles-radius-attrs",
        "summary": "Manage RADIUS attributes",
        "tags": [
          "profiles"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_profiles_radius_attributes"
      },
      "patch": {
        "description": "",
        "operationId": "profiles_patch-profiles-radius-attrs",
        "summary": "Manage RADIUS attributes",
        "tags": [
          "profiles"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_profiles_radius_attributes"
      }
    },
    "/api/v1/public/auth/resolve-host": {
      "post": {
        "description": "",
        "operationId": "public_post-public-auth-resolve-host",
        "summary": "POST /api/v1/public/auth/resolve-host",
        "tags": [
          "public"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "resolve_host"
      }
    },
    "/api/v1/public/backup/oauth/{provider}/callback": {
      "get": {
        "description": "",
        "operationId": "public_get-public-backup-oauth-callback",
        "summary": "GET /api/v1/public/backup/oauth/{provider}/callback",
        "tags": [
          "public"
        ],
        "x-auth": "public",
        "x-generated-stub": true
      }
    },
    "/api/v1/public/csat/{token}": {
      "get": {
        "description": "",
        "operationId": "public_get-public-csat",
        "summary": "GET /api/v1/public/csat/{token}",
        "tags": [
          "public"
        ],
        "x-auth": "public",
        "x-generated-stub": true
      },
      "post": {
        "description": "",
        "operationId": "public_post-public-csat",
        "summary": "POST /api/v1/public/csat/{token}",
        "tags": [
          "public"
        ],
        "x-auth": "public",
        "x-generated-stub": true
      }
    },
    "/api/v1/public/csp-report": {
      "post": {
        "description": "",
        "operationId": "public_post-public-csp-report",
        "summary": "POST /api/v1/public/csp-report",
        "tags": [
          "public"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "csp_report"
      }
    },
    "/api/v1/public/pay/gateways": {
      "get": {
        "description": "",
        "operationId": "public_get-public-pay-gateways",
        "summary": "GET /api/v1/public/pay/gateways",
        "tags": [
          "public"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "pay_guest_gateways"
      }
    },
    "/api/v1/public/pay/guest-checkout": {
      "post": {
        "description": "",
        "operationId": "public_post-public-pay-guest-checkout",
        "summary": "POST /api/v1/public/pay/guest-checkout",
        "tags": [
          "public"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "pay_guest_init"
      }
    },
    "/api/v1/public/pay/lookup": {
      "post": {
        "description": "",
        "operationId": "public_post-public-pay-lookup",
        "summary": "POST /api/v1/public/pay/lookup",
        "tags": [
          "public"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "pay_guest_lookup"
      }
    },
    "/api/v1/public/pay/recover": {
      "post": {
        "description": "",
        "operationId": "public_post-public-pay-recover",
        "summary": "POST /api/v1/public/pay/recover",
        "tags": [
          "public"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "pay_guest_recover"
      }
    },
    "/api/v1/public/pay/status/{state}": {
      "get": {
        "description": "",
        "operationId": "public_get-public-pay-status",
        "summary": "GET /api/v1/public/pay/status/{state}",
        "tags": [
          "public"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "pay_status"
      }
    },
    "/api/v1/public/pay/{gateway}/redirect/{tenant_id}/{token}/{outcome}": {
      "get": {
        "description": "",
        "operationId": "public_get-public-pay-redirect",
        "summary": "GET /api/v1/public/pay/{gateway}/redirect/{tenant_id}/{token}/{outcome}",
        "tags": [
          "public"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "pay_return"
      }
    },
    "/api/v1/public/pay/{gateway}/return/{state}": {
      "get": {
        "description": "",
        "operationId": "public_get-public-pay-return",
        "summary": "GET /api/v1/public/pay/{gateway}/return/{state}",
        "tags": [
          "public"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "pay_return"
      }
    },
    "/api/v1/public/pay/{gateway}/webhook/{tenant_id}/{secret}": {
      "post": {
        "description": "",
        "operationId": "public_post-public-pay-webhook",
        "summary": "POST /api/v1/public/pay/{gateway}/webhook/{tenant_id}/{secret}",
        "tags": [
          "public"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "pay_webhook"
      }
    },
    "/api/v1/public/register/captcha": {
      "get": {
        "description": "",
        "operationId": "public_get-public-register-captcha",
        "summary": "GET /api/v1/public/register/captcha",
        "tags": [
          "public"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "register_captcha"
      }
    },
    "/api/v1/public/register/policy": {
      "get": {
        "description": "",
        "operationId": "public_get-public-register-policy",
        "summary": "GET /api/v1/public/register/policy",
        "tags": [
          "public"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "register_policy"
      }
    },
    "/api/v1/public/register/slug-available": {
      "get": {
        "description": "",
        "operationId": "public_get-public-register-slug-available",
        "summary": "GET /api/v1/public/register/slug-available",
        "tags": [
          "public"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "slug_available"
      }
    },
    "/api/v1/public/site/captcha": {
      "get": {
        "description": "",
        "operationId": "public_get-public-site-captcha",
        "summary": "GET /api/v1/public/site/captcha",
        "tags": [
          "public"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "site_captcha"
      }
    },
    "/api/v1/public/site/leads": {
      "post": {
        "description": "",
        "operationId": "public_post-public-site-leads",
        "summary": "POST /api/v1/public/site/leads",
        "tags": [
          "public"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "site_leads"
      }
    },
    "/api/v1/public/sysbackup/{name}": {
      "connect": {
        "description": "",
        "operationId": "public_connect-public-sysbackup",
        "summary": "CONNECT /api/v1/public/sysbackup/{name}",
        "tags": [
          "public"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "sysbackup"
      },
      "delete": {
        "description": "",
        "operationId": "public_delete-public-sysbackup",
        "summary": "DELETE /api/v1/public/sysbackup/{name}",
        "tags": [
          "public"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "sysbackup"
      },
      "get": {
        "description": "",
        "operationId": "public_get-public-sysbackup",
        "summary": "GET /api/v1/public/sysbackup/{name}",
        "tags": [
          "public"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "sysbackup"
      },
      "head": {
        "description": "",
        "operationId": "public_head-public-sysbackup",
        "summary": "HEAD /api/v1/public/sysbackup/{name}",
        "tags": [
          "public"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "sysbackup"
      },
      "options": {
        "description": "",
        "operationId": "public_options-public-sysbackup",
        "summary": "OPTIONS /api/v1/public/sysbackup/{name}",
        "tags": [
          "public"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "sysbackup"
      },
      "patch": {
        "description": "",
        "operationId": "public_patch-public-sysbackup",
        "summary": "PATCH /api/v1/public/sysbackup/{name}",
        "tags": [
          "public"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "sysbackup"
      },
      "post": {
        "description": "",
        "operationId": "public_post-public-sysbackup",
        "summary": "POST /api/v1/public/sysbackup/{name}",
        "tags": [
          "public"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "sysbackup"
      },
      "put": {
        "description": "",
        "operationId": "public_put-public-sysbackup",
        "summary": "PUT /api/v1/public/sysbackup/{name}",
        "tags": [
          "public"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "sysbackup"
      },
      "query": {
        "description": "",
        "operationId": "public_query-public-sysbackup",
        "summary": "QUERY /api/v1/public/sysbackup/{name}",
        "tags": [
          "public"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "sysbackup"
      },
      "trace": {
        "description": "",
        "operationId": "public_trace-public-sysbackup",
        "summary": "TRACE /api/v1/public/sysbackup/{name}",
        "tags": [
          "public"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "sysbackup"
      }
    },
    "/api/v1/public/telegram/{bot_kind}/webhook/{license_id}/{secret}": {
      "post": {
        "description": "",
        "operationId": "public_post-public-telegram-webhook",
        "summary": "POST /api/v1/public/telegram/{bot_kind}/webhook/{license_id}/{secret}",
        "tags": [
          "public"
        ],
        "x-auth": "public",
        "x-generated-stub": true
      }
    },
    "/api/v1/roles": {
      "get": {
        "description": "Every role visible to the tenant, with its permission count and the exact code set it grants. System roles sort first.",
        "operationId": "roles_get-roles",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": [\n    {\n      \"id\": 2,\n      \"tenant_id\": 12,\n      \"name\": \"support\",\n      \"description\": \"Read subscribers, reply to tickets\",\n      \"is_system\": false,\n      \"template_key\": \"support\",\n      \"immutable\": false,\n      \"permission_count\": 14,\n      \"permissions\": [\"prm_tickets_reply\", \"prm_tickets_view\", \"prm_users_index\"]\n    }\n  ]\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "List roles",
        "tags": [
          "roles"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_roles_manage"
      },
      "post": {
        "description": "Creates a named permission set. A caller may only grant codes they hold themselves, so a role cannot be used to mint authority its author does not have.",
        "operationId": "roles_post-roles",
        "summary": "Create a role",
        "tags": [
          "roles"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_roles_manage"
      }
    },
    "/api/v1/roles/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "roles_post-roles-bulk-delete",
        "summary": "Manage roles \u0026 permissions",
        "tags": [
          "roles"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_roles_manage"
      }
    },
    "/api/v1/roles/{id}": {
      "delete": {
        "description": "Removes the role. System and immutable roles are refused, and so is a role that is still assigned.",
        "operationId": "roles_delete-roles",
        "parameters": [
          {
            "description": "Role id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Delete a role",
        "tags": [
          "roles"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_roles_manage"
      },
      "get": {
        "description": "The role and the exact set of permission codes it grants.",
        "operationId": "roles_get-roles-by-id",
        "parameters": [
          {
            "description": "Role id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Fetch one role",
        "tags": [
          "roles"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_roles_manage"
      },
      "patch": {
        "description": "Edits the name, description and permission set. The immutable administrator role cannot be edited at all.",
        "operationId": "roles_patch-roles",
        "parameters": [
          {
            "description": "Role id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Update a role",
        "tags": [
          "roles"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_roles_manage"
      }
    },
    "/api/v1/roles/{id}/portal-permissions": {
      "put": {
        "description": "The separate set that governs what a SUBSCRIBER may do in the self-service portal, not what a manager may do in the admin API. Different catalogue, different meaning.",
        "operationId": "roles_put-roles-portal-permissions",
        "parameters": [
          {
            "description": "Role id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Set a role's subscriber-portal permissions",
        "tags": [
          "roles"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_roles_manage"
      }
    },
    "/api/v1/settings": {
      "get": {
        "description": "",
        "operationId": "settings_get-settings",
        "summary": "Manage settings",
        "tags": [
          "settings"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_settings"
      },
      "patch": {
        "description": "",
        "operationId": "settings_patch-settings",
        "summary": "Manage settings",
        "tags": [
          "settings"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_settings"
      }
    },
    "/api/v1/settings/reset": {
      "post": {
        "description": "",
        "operationId": "settings_post-settings-reset",
        "summary": "Manage settings",
        "tags": [
          "settings"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_settings"
      }
    },
    "/api/v1/settings/{category}/{key}": {
      "get": {
        "description": "",
        "operationId": "settings_get-settings-by-key",
        "summary": "Manage settings",
        "tags": [
          "settings"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_settings"
      }
    },
    "/api/v1/studio/designs": {
      "get": {
        "description": "",
        "operationId": "studio_get-studio-designs",
        "summary": "View designs",
        "tags": [
          "studio"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_studio_index"
      },
      "post": {
        "description": "",
        "operationId": "studio_post-studio-designs",
        "summary": "Create and edit designs",
        "tags": [
          "studio"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_studio_edit"
      }
    },
    "/api/v1/studio/designs/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "studio_post-studio-designs-bulk-delete",
        "summary": "Delete designs",
        "tags": [
          "studio"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_studio_delete"
      }
    },
    "/api/v1/studio/designs/{id}": {
      "delete": {
        "description": "",
        "operationId": "studio_delete-studio-designs",
        "summary": "Delete designs",
        "tags": [
          "studio"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_studio_delete"
      },
      "get": {
        "description": "",
        "operationId": "studio_get-studio-designs-by-id",
        "summary": "View designs",
        "tags": [
          "studio"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_studio_index"
      },
      "patch": {
        "description": "",
        "operationId": "studio_patch-studio-designs",
        "summary": "Create and edit designs",
        "tags": [
          "studio"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_studio_edit"
      }
    },
    "/api/v1/studio/designs/{id}/thumbnail": {
      "get": {
        "description": "",
        "operationId": "studio_get-studio-designs-thumbnail",
        "summary": "View designs",
        "tags": [
          "studio"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_studio_index"
      }
    },
    "/api/v1/studio/store": {
      "get": {
        "description": "",
        "operationId": "studio_get-studio-store",
        "summary": "View designs",
        "tags": [
          "studio"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_studio_index"
      },
      "post": {
        "description": "",
        "operationId": "studio_post-studio-store",
        "summary": "Publish designs to the store",
        "tags": [
          "studio"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_studio_publish"
      }
    },
    "/api/v1/studio/store/{id}": {
      "get": {
        "description": "",
        "operationId": "studio_get-studio-store-by-id",
        "summary": "View designs",
        "tags": [
          "studio"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_studio_index"
      }
    },
    "/api/v1/studio/store/{id}/comments": {
      "get": {
        "description": "",
        "operationId": "studio_get-studio-store-comments",
        "summary": "View designs",
        "tags": [
          "studio"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_studio_index"
      },
      "post": {
        "description": "",
        "operationId": "studio_post-studio-store-comments",
        "summary": "View designs",
        "tags": [
          "studio"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_studio_index"
      }
    },
    "/api/v1/studio/store/{id}/import": {
      "post": {
        "description": "",
        "operationId": "studio_post-studio-store-import",
        "summary": "Create and edit designs",
        "tags": [
          "studio"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_studio_edit"
      }
    },
    "/api/v1/studio/store/{id}/reviews": {
      "get": {
        "description": "",
        "operationId": "studio_get-studio-store-reviews",
        "summary": "View designs",
        "tags": [
          "studio"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_studio_index"
      },
      "post": {
        "description": "",
        "operationId": "studio_post-studio-store-reviews",
        "summary": "View designs",
        "tags": [
          "studio"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_studio_index"
      }
    },
    "/api/v1/studio/store/{id}/star": {
      "delete": {
        "description": "",
        "operationId": "studio_delete-studio-store-star",
        "summary": "View designs",
        "tags": [
          "studio"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_studio_index"
      },
      "post": {
        "description": "",
        "operationId": "studio_post-studio-store-star",
        "summary": "View designs",
        "tags": [
          "studio"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_studio_index"
      }
    },
    "/api/v1/studio/store/{id}/thumbnail": {
      "get": {
        "description": "",
        "operationId": "studio_get-studio-store-thumbnail",
        "summary": "View designs",
        "tags": [
          "studio"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_studio_index"
      }
    },
    "/api/v1/system/updates": {
      "get": {
        "description": "",
        "operationId": "system_get-system-updates",
        "summary": "GET /api/v1/system/updates",
        "tags": [
          "system"
        ],
        "x-auth": "manager",
        "x-generated-stub": true
      }
    },
    "/api/v1/tenants": {
      "post": {
        "description": "",
        "operationId": "tenants_post-tenants",
        "summary": "POST /api/v1/tenants",
        "tags": [
          "tenants"
        ],
        "x-auth": "control",
        "x-generated-stub": true
      }
    },
    "/api/v1/tickets": {
      "get": {
        "description": "",
        "operationId": "tickets_get-tickets",
        "summary": "View support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tickets_view"
      },
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets",
        "summary": "Reply to support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_reply"
      }
    },
    "/api/v1/tickets/assignees": {
      "get": {
        "description": "",
        "operationId": "tickets_get-tickets-assignees",
        "summary": "View support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tickets_view"
      }
    },
    "/api/v1/tickets/assignment-strategies": {
      "get": {
        "description": "",
        "operationId": "tickets_get-tickets-assignment-strategies",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tickets_config"
      }
    },
    "/api/v1/tickets/blocklist": {
      "get": {
        "description": "",
        "operationId": "tickets_get-tickets-blocklist",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tickets_config"
      },
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets-blocklist",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_config"
      }
    },
    "/api/v1/tickets/blocklist/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets-blocklist-bulk-delete",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_config"
      }
    },
    "/api/v1/tickets/blocklist/{id}": {
      "delete": {
        "description": "",
        "operationId": "tickets_delete-tickets-blocklist",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_config"
      }
    },
    "/api/v1/tickets/bulk-assign": {
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets-bulk-assign",
        "summary": "Claim / assign support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_assign"
      }
    },
    "/api/v1/tickets/bulk-category": {
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets-bulk-category",
        "summary": "Reply to support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_reply"
      }
    },
    "/api/v1/tickets/bulk-close": {
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets-bulk-close",
        "summary": "Reply to support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_reply"
      }
    },
    "/api/v1/tickets/bulk-priority": {
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets-bulk-priority",
        "summary": "Claim / assign support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_assign"
      }
    },
    "/api/v1/tickets/bulk-reopen": {
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets-bulk-reopen",
        "summary": "Reply to support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_reply"
      }
    },
    "/api/v1/tickets/bulk-resolve": {
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets-bulk-resolve",
        "summary": "Reply to support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_reply"
      }
    },
    "/api/v1/tickets/bulk-snooze": {
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets-bulk-snooze",
        "summary": "Reply to support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_reply"
      }
    },
    "/api/v1/tickets/bulk-team": {
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets-bulk-team",
        "summary": "Claim / assign support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_assign"
      }
    },
    "/api/v1/tickets/canned-replies": {
      "get": {
        "description": "",
        "operationId": "tickets_get-tickets-canned-replies",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tickets_config"
      },
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets-canned-replies",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_config"
      }
    },
    "/api/v1/tickets/canned-replies/{id}": {
      "delete": {
        "description": "",
        "operationId": "tickets_delete-tickets-canned-replies",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_config"
      },
      "put": {
        "description": "",
        "operationId": "tickets_put-tickets-canned-replies",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_config"
      }
    },
    "/api/v1/tickets/categories": {
      "get": {
        "description": "",
        "operationId": "tickets_get-tickets-categories",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tickets_config"
      },
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets-categories",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_config"
      }
    },
    "/api/v1/tickets/categories/{id}": {
      "delete": {
        "description": "",
        "operationId": "tickets_delete-tickets-categories",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_config"
      },
      "patch": {
        "description": "",
        "operationId": "tickets_patch-tickets-categories",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_config"
      }
    },
    "/api/v1/tickets/categories/{id}/fields": {
      "get": {
        "description": "",
        "operationId": "tickets_get-tickets-categories-fields",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tickets_config"
      },
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets-categories-fields",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_config"
      }
    },
    "/api/v1/tickets/categories/{id}/fields/{fid}": {
      "delete": {
        "description": "",
        "operationId": "tickets_delete-tickets-categories-fields",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_config"
      },
      "patch": {
        "description": "",
        "operationId": "tickets_patch-tickets-categories-fields",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_config"
      }
    },
    "/api/v1/tickets/counts": {
      "get": {
        "description": "",
        "operationId": "tickets_get-tickets-counts",
        "summary": "View support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tickets_view"
      }
    },
    "/api/v1/tickets/form": {
      "get": {
        "description": "",
        "operationId": "tickets_get-tickets-form",
        "summary": "View support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tickets_view"
      }
    },
    "/api/v1/tickets/macros": {
      "get": {
        "description": "",
        "operationId": "tickets_get-tickets-macros",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tickets_config"
      },
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets-macros",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_config"
      }
    },
    "/api/v1/tickets/macros/{id}": {
      "delete": {
        "description": "",
        "operationId": "tickets_delete-tickets-macros",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_config"
      },
      "put": {
        "description": "",
        "operationId": "tickets_put-tickets-macros",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_config"
      }
    },
    "/api/v1/tickets/sla/breaches": {
      "get": {
        "description": "",
        "operationId": "tickets_get-tickets-sla-breaches",
        "summary": "View support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tickets_view"
      }
    },
    "/api/v1/tickets/sla/calendars": {
      "get": {
        "description": "",
        "operationId": "tickets_get-tickets-sla-calendars",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tickets_config"
      },
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets-sla-calendars",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_config"
      }
    },
    "/api/v1/tickets/sla/calendars/{id}": {
      "delete": {
        "description": "",
        "operationId": "tickets_delete-tickets-sla-calendars",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_config"
      },
      "put": {
        "description": "",
        "operationId": "tickets_put-tickets-sla-calendars",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_config"
      }
    },
    "/api/v1/tickets/sla/policies": {
      "get": {
        "description": "",
        "operationId": "tickets_get-tickets-sla-policies",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tickets_config"
      },
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets-sla-policies",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_config"
      }
    },
    "/api/v1/tickets/sla/policies/{id}": {
      "delete": {
        "description": "",
        "operationId": "tickets_delete-tickets-sla-policies",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_config"
      },
      "put": {
        "description": "",
        "operationId": "tickets_put-tickets-sla-policies",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_config"
      }
    },
    "/api/v1/tickets/teams": {
      "get": {
        "description": "",
        "operationId": "tickets_get-tickets-teams",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tickets_config"
      },
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets-teams",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_config"
      }
    },
    "/api/v1/tickets/teams/{id}": {
      "delete": {
        "description": "",
        "operationId": "tickets_delete-tickets-teams",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_config"
      },
      "patch": {
        "description": "",
        "operationId": "tickets_patch-tickets-teams",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_config"
      }
    },
    "/api/v1/tickets/teams/{id}/members": {
      "get": {
        "description": "",
        "operationId": "tickets_get-tickets-teams-members",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tickets_config"
      },
      "put": {
        "description": "",
        "operationId": "tickets_put-tickets-teams-members",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_config"
      }
    },
    "/api/v1/tickets/views": {
      "get": {
        "description": "",
        "operationId": "tickets_get-tickets-views",
        "summary": "View support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tickets_view"
      },
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets-views",
        "summary": "View support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_view"
      }
    },
    "/api/v1/tickets/views/{id}": {
      "delete": {
        "description": "",
        "operationId": "tickets_delete-tickets-views",
        "summary": "View support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_view"
      },
      "patch": {
        "description": "",
        "operationId": "tickets_patch-tickets-views",
        "summary": "View support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_view"
      }
    },
    "/api/v1/tickets/{id}": {
      "get": {
        "description": "",
        "operationId": "tickets_get-tickets-by-id",
        "summary": "View support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tickets_view"
      }
    },
    "/api/v1/tickets/{id}/answers": {
      "get": {
        "description": "",
        "operationId": "tickets_get-tickets-answers",
        "summary": "View support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tickets_view"
      }
    },
    "/api/v1/tickets/{id}/assign": {
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets-assign",
        "summary": "Claim / assign support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_assign"
      }
    },
    "/api/v1/tickets/{id}/attach": {
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets-attach",
        "summary": "Reply to support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_reply"
      }
    },
    "/api/v1/tickets/{id}/attachments/{attId}": {
      "delete": {
        "description": "",
        "operationId": "tickets_delete-tickets-attachments",
        "summary": "Reply to support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_reply"
      },
      "get": {
        "description": "",
        "operationId": "tickets_get-tickets-attachments",
        "summary": "View support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tickets_view"
      }
    },
    "/api/v1/tickets/{id}/auto-assign": {
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets-auto-assign",
        "summary": "Claim / assign support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_assign"
      }
    },
    "/api/v1/tickets/{id}/block-candidates": {
      "get": {
        "description": "",
        "operationId": "tickets_get-tickets-block-candidates",
        "summary": "Manage ticket categories \u0026 settings",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tickets_config"
      }
    },
    "/api/v1/tickets/{id}/canned-replies": {
      "get": {
        "description": "",
        "operationId": "tickets_get-tickets-canned-replies-by-id",
        "summary": "Reply to support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tickets_reply"
      }
    },
    "/api/v1/tickets/{id}/claim": {
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets-claim",
        "summary": "Claim / assign support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_assign"
      }
    },
    "/api/v1/tickets/{id}/events": {
      "get": {
        "description": "",
        "operationId": "tickets_get-tickets-events",
        "summary": "View support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tickets_view"
      }
    },
    "/api/v1/tickets/{id}/internal-note": {
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets-internal-note",
        "summary": "Add internal notes to support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_note"
      }
    },
    "/api/v1/tickets/{id}/macros/{macroId}/apply": {
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets-macros-apply",
        "summary": "Reply to support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_reply"
      }
    },
    "/api/v1/tickets/{id}/participants": {
      "get": {
        "description": "",
        "operationId": "tickets_get-tickets-participants",
        "summary": "View support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tickets_view"
      },
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets-participants",
        "summary": "Reply to support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_reply"
      }
    },
    "/api/v1/tickets/{id}/participants/{userId}": {
      "delete": {
        "description": "",
        "operationId": "tickets_delete-tickets-participants",
        "summary": "Reply to support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_reply"
      }
    },
    "/api/v1/tickets/{id}/presence": {
      "get": {
        "description": "",
        "operationId": "tickets_get-tickets-presence",
        "summary": "View support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tickets_view"
      },
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets-presence",
        "summary": "View support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_view"
      }
    },
    "/api/v1/tickets/{id}/priority": {
      "put": {
        "description": "",
        "operationId": "tickets_put-tickets-priority",
        "summary": "Claim / assign support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_assign"
      }
    },
    "/api/v1/tickets/{id}/read": {
      "put": {
        "description": "",
        "operationId": "tickets_put-tickets-read",
        "summary": "View support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_view"
      }
    },
    "/api/v1/tickets/{id}/reminders": {
      "get": {
        "description": "",
        "operationId": "tickets_get-tickets-reminders",
        "summary": "Reply to support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tickets_reply"
      },
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets-reminders",
        "summary": "Reply to support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_reply"
      }
    },
    "/api/v1/tickets/{id}/reminders/{remId}": {
      "delete": {
        "description": "",
        "operationId": "tickets_delete-tickets-reminders",
        "summary": "Reply to support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_reply"
      }
    },
    "/api/v1/tickets/{id}/reopen": {
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets-reopen",
        "summary": "Reply to support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_reply"
      }
    },
    "/api/v1/tickets/{id}/reply": {
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets-reply",
        "summary": "Reply to support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_reply"
      }
    },
    "/api/v1/tickets/{id}/resolve": {
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets-resolve",
        "summary": "Reply to support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_reply"
      }
    },
    "/api/v1/tickets/{id}/sla": {
      "get": {
        "description": "",
        "operationId": "tickets_get-tickets-sla",
        "summary": "View support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_tickets_view"
      }
    },
    "/api/v1/tickets/{id}/snooze": {
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets-snooze",
        "summary": "Reply to support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_reply"
      }
    },
    "/api/v1/tickets/{id}/team": {
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets-team",
        "summary": "Claim / assign support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_assign"
      }
    },
    "/api/v1/tickets/{id}/unsnooze": {
      "post": {
        "description": "",
        "operationId": "tickets_post-tickets-unsnooze",
        "summary": "Reply to support tickets",
        "tags": [
          "tickets"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_tickets_reply"
      }
    },
    "/api/v1/user/account": {
      "patch": {
        "description": "",
        "operationId": "user_patch-user-account",
        "summary": "PATCH /api/v1/user/account",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/user/auto-renew": {
      "post": {
        "description": "",
        "operationId": "user_post-user-auto-renew",
        "summary": "POST /api/v1/user/auto-renew",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/user/bucket-order": {
      "put": {
        "description": "",
        "operationId": "user_put-user-bucket-order",
        "summary": "PUT /api/v1/user/bucket-order",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/user/captcha": {
      "get": {
        "description": "",
        "operationId": "user_get-user-captcha",
        "summary": "GET /api/v1/user/captcha",
        "tags": [
          "user"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "portal_captcha"
      }
    },
    "/api/v1/user/cards/redeem": {
      "post": {
        "description": "",
        "operationId": "user_post-user-cards-redeem",
        "summary": "POST /api/v1/user/cards/redeem",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/user/change-profile": {
      "post": {
        "description": "",
        "operationId": "user_post-user-change-profile",
        "summary": "POST /api/v1/user/change-profile",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/user/config": {
      "get": {
        "description": "",
        "operationId": "user_get-user-config",
        "summary": "GET /api/v1/user/config",
        "tags": [
          "user"
        ],
        "x-auth": "public",
        "x-generated-stub": true
      }
    },
    "/api/v1/user/credentials": {
      "get": {
        "description": "",
        "operationId": "user_get-user-credentials",
        "summary": "GET /api/v1/user/credentials",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/user/deposit": {
      "post": {
        "description": "",
        "operationId": "user_post-user-deposit",
        "summary": "POST /api/v1/user/deposit",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "portal_deposit"
      }
    },
    "/api/v1/user/exchange": {
      "post": {
        "description": "",
        "operationId": "user_post-user-exchange",
        "summary": "POST /api/v1/user/exchange",
        "tags": [
          "user"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "portal_exchange"
      }
    },
    "/api/v1/user/extend": {
      "post": {
        "description": "",
        "operationId": "user_post-user-extend",
        "summary": "POST /api/v1/user/extend",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/user/extensions": {
      "get": {
        "description": "",
        "operationId": "user_get-user-extensions",
        "summary": "GET /api/v1/user/extensions",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/user/extensions/{id}": {
      "get": {
        "description": "",
        "operationId": "user_get-user-extensions-by-id",
        "summary": "GET /api/v1/user/extensions/{id}",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/user/guest/context": {
      "get": {
        "description": "",
        "operationId": "user_get-user-guest-context",
        "summary": "GET /api/v1/user/guest/context",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "portal_guest"
      }
    },
    "/api/v1/user/guest/register": {
      "post": {
        "description": "",
        "operationId": "user_post-user-guest-register",
        "summary": "POST /api/v1/user/guest/register",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "portal_guest"
      }
    },
    "/api/v1/user/invoices": {
      "get": {
        "description": "",
        "operationId": "user_get-user-invoices",
        "summary": "GET /api/v1/user/invoices",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/user/invoices/{id}": {
      "get": {
        "description": "",
        "operationId": "user_get-user-invoices-by-id",
        "summary": "GET /api/v1/user/invoices/{id}",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/user/invoices/{id}/render-data": {
      "get": {
        "description": "",
        "operationId": "user_get-user-invoices-render-data",
        "summary": "GET /api/v1/user/invoices/{id}/render-data",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_heavy"
      }
    },
    "/api/v1/user/join": {
      "post": {
        "description": "",
        "operationId": "user_post-user-join",
        "summary": "POST /api/v1/user/join",
        "tags": [
          "user"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "portal_join"
      }
    },
    "/api/v1/user/join/context": {
      "get": {
        "description": "",
        "operationId": "user_get-user-join-context",
        "summary": "GET /api/v1/user/join/context",
        "tags": [
          "user"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "portal_join"
      }
    },
    "/api/v1/user/ledger": {
      "get": {
        "description": "",
        "operationId": "user_get-user-ledger",
        "summary": "GET /api/v1/user/ledger",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/user/login": {
      "post": {
        "description": "",
        "operationId": "user_post-user-login",
        "summary": "POST /api/v1/user/login",
        "tags": [
          "user"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "portal_login"
      }
    },
    "/api/v1/user/me": {
      "get": {
        "description": "",
        "operationId": "user_get-user-me",
        "summary": "GET /api/v1/user/me",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/user/parental": {
      "get": {
        "description": "",
        "operationId": "user_get-user-parental",
        "summary": "GET /api/v1/user/parental",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/user/parental/pause": {
      "post": {
        "description": "",
        "operationId": "user_post-user-parental-pause",
        "summary": "POST /api/v1/user/parental/pause",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/user/parental/pin": {
      "post": {
        "description": "",
        "operationId": "user_post-user-parental-pin",
        "summary": "POST /api/v1/user/parental/pin",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/user/parental/rules": {
      "put": {
        "description": "",
        "operationId": "user_put-user-parental-rules",
        "summary": "PUT /api/v1/user/parental/rules",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/user/parental/unlock": {
      "post": {
        "description": "",
        "operationId": "user_post-user-parental-unlock",
        "summary": "POST /api/v1/user/parental/unlock",
        "tags": [
          "user"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "portal_parental_unlock"
      }
    },
    "/api/v1/user/password": {
      "post": {
        "description": "",
        "operationId": "user_post-user-password",
        "summary": "POST /api/v1/user/password",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/user/payments/gateways": {
      "get": {
        "description": "",
        "operationId": "user_get-user-payments-gateways",
        "summary": "GET /api/v1/user/payments/gateways",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/user/payments/transactions": {
      "get": {
        "description": "",
        "operationId": "user_get-user-payments-transactions",
        "summary": "GET /api/v1/user/payments/transactions",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/user/profiles": {
      "get": {
        "description": "",
        "operationId": "user_get-user-profiles",
        "summary": "GET /api/v1/user/profiles",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/user/purchase": {
      "post": {
        "description": "",
        "operationId": "user_post-user-purchase",
        "summary": "POST /api/v1/user/purchase",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "portal_deposit"
      }
    },
    "/api/v1/user/push-tokens": {
      "delete": {
        "description": "",
        "operationId": "user_delete-user-push-tokens",
        "summary": "DELETE /api/v1/user/push-tokens",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      },
      "post": {
        "description": "",
        "operationId": "user_post-user-push-tokens",
        "summary": "POST /api/v1/user/push-tokens",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/user/quota-buckets": {
      "get": {
        "description": "",
        "operationId": "user_get-user-quota-buckets",
        "summary": "GET /api/v1/user/quota-buckets",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/user/quote": {
      "post": {
        "description": "",
        "operationId": "user_post-user-quote",
        "summary": "POST /api/v1/user/quote",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/user/refresh": {
      "post": {
        "description": "",
        "operationId": "user_post-user-refresh",
        "summary": "POST /api/v1/user/refresh",
        "tags": [
          "user"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "portal_refresh"
      }
    },
    "/api/v1/user/renew": {
      "post": {
        "description": "",
        "operationId": "user_post-user-renew",
        "summary": "POST /api/v1/user/renew",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/user/sessions": {
      "get": {
        "description": "",
        "operationId": "user_get-user-sessions",
        "summary": "GET /api/v1/user/sessions",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/user/signup": {
      "post": {
        "description": "",
        "operationId": "user_post-user-signup",
        "summary": "POST /api/v1/user/signup",
        "tags": [
          "user"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "portal_signup"
      }
    },
    "/api/v1/user/signup/schema": {
      "get": {
        "description": "",
        "operationId": "user_get-user-signup-schema",
        "summary": "GET /api/v1/user/signup/schema",
        "tags": [
          "user"
        ],
        "x-auth": "public",
        "x-generated-stub": true
      }
    },
    "/api/v1/user/speed": {
      "delete": {
        "description": "",
        "operationId": "user_delete-user-speed",
        "summary": "DELETE /api/v1/user/speed",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      },
      "get": {
        "description": "",
        "operationId": "user_get-user-speed",
        "summary": "GET /api/v1/user/speed",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      },
      "put": {
        "description": "",
        "operationId": "user_put-user-speed",
        "summary": "PUT /api/v1/user/speed",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/user/telegram-exchange": {
      "post": {
        "description": "",
        "operationId": "user_post-user-telegram-exchange",
        "summary": "POST /api/v1/user/telegram-exchange",
        "tags": [
          "user"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "portal_telegram_exchange"
      }
    },
    "/api/v1/user/telegram/link": {
      "get": {
        "description": "",
        "operationId": "user_get-user-telegram-link",
        "summary": "GET /api/v1/user/telegram/link",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/user/tickets": {
      "get": {
        "description": "",
        "operationId": "user_get-user-tickets",
        "summary": "GET /api/v1/user/tickets",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      },
      "post": {
        "description": "",
        "operationId": "user_post-user-tickets",
        "summary": "POST /api/v1/user/tickets",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/user/tickets/form": {
      "get": {
        "description": "",
        "operationId": "user_get-user-tickets-form",
        "summary": "GET /api/v1/user/tickets/form",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/user/tickets/{id}": {
      "get": {
        "description": "",
        "operationId": "user_get-user-tickets-by-id",
        "summary": "GET /api/v1/user/tickets/{id}",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/user/tickets/{id}/attach": {
      "post": {
        "description": "",
        "operationId": "user_post-user-tickets-attach",
        "summary": "POST /api/v1/user/tickets/{id}/attach",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/user/tickets/{id}/attachments/{attId}": {
      "delete": {
        "description": "",
        "operationId": "user_delete-user-tickets-attachments",
        "summary": "DELETE /api/v1/user/tickets/{id}/attachments/{attId}",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      },
      "get": {
        "description": "",
        "operationId": "user_get-user-tickets-attachments",
        "summary": "GET /api/v1/user/tickets/{id}/attachments/{attId}",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/user/tickets/{id}/messages": {
      "post": {
        "description": "",
        "operationId": "user_post-user-tickets-messages",
        "summary": "POST /api/v1/user/tickets/{id}/messages",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate"
      }
    },
    "/api/v1/user/tunnel-identify": {
      "post": {
        "description": "",
        "operationId": "user_post-user-tunnel-identify",
        "summary": "POST /api/v1/user/tunnel-identify",
        "tags": [
          "user"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "portal_tunnel_identify"
      }
    },
    "/api/v1/user/tunnel-tenant": {
      "post": {
        "description": "",
        "operationId": "user_post-user-tunnel-tenant",
        "summary": "POST /api/v1/user/tunnel-tenant",
        "tags": [
          "user"
        ],
        "x-auth": "public",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "portal_tunnel_tenant"
      }
    },
    "/api/v1/user/usage": {
      "get": {
        "description": "",
        "operationId": "user_get-user-usage",
        "summary": "GET /api/v1/user/usage",
        "tags": [
          "user"
        ],
        "x-auth": "portal",
        "x-generated-stub": true
      }
    },
    "/api/v1/users": {
      "get": {
        "description": "One page of subscribers under the caller's authority. A manager without tenant-wide visibility sees only subscribers owned by their own manager subtree, and that scope is injected server-side, so a filter can narrow within it but never widen past it.",
        "operationId": "users_get-users",
        "parameters": [
          {
            "description": "Searches username, email, first and last name, phone, contract id, national id and static IP. A purely numeric term also matches the subscriber id exactly.",
            "in": "query",
            "name": "q",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "The admin suspend flag. Not the same thing as expired.",
            "in": "query",
            "name": "filter[enabled]",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "description": "Subscription window has passed.",
            "in": "query",
            "name": "filter[expired]",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "description": "An open RADIUS session exists right now.",
            "in": "query",
            "name": "filter[online]",
            "required": false,
            "schema": {
              "type": "boolean"
            }
          },
          {
            "description": "Bound plan.",
            "in": "query",
            "name": "filter[profile_id]",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "description": "Owning manager. Ignored, not honoured, when it would widen a restricted caller's scope.",
            "in": "query",
            "name": "filter[parent_id]",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "description": "Case-insensitive exact username, for a caller that already knows the identity and wants one deterministic row instead of a page of substring hits.",
            "in": "query",
            "name": "filter[username_exact]",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "description": "Future expiries only.",
            "in": "query",
            "name": "filter[expiring_within_days]",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "description": "yyyy-MM-dd HH:mm:ss in UTC. A malformed value is a 400, not an ignored filter.",
            "in": "query",
            "name": "filter[created_from]",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": [\n    {\n      \"id\": 4711,\n      \"tenant_id\": 12,\n      \"username\": \"ahmed\",\n      \"email\": \"ahmed@example.test\",\n      \"enabled\": true,\n      \"status\": {\n        \"enabled\": true,\n        \"deleted\": false,\n        \"online\": true,\n        \"expired\": false,\n        \"have_quota\": true,\n        \"fup\": false,\n        \"can_connect\": true\n      },\n      \"profile_id\": 7,\n      \"profile_name\": \"Home 20M\",\n      \"parent_id\": 41,\n      \"parent_username\": \"cairo-reseller\",\n      \"bytes_remaining\": 48318382080,\n      \"plan_bytes_limit\": 107374182400,\n      \"used_bytes\": 59055800320,\n      \"expiration\": \"2026-10-14 00:00:00\",\n      \"balance\": 0.00,\n      \"debt\": 0.00,\n      \"mac_lock_enabled\": false,\n      \"mac_locked_addrs\": [],\n      \"enforces_bytes\": true,\n      \"enforces_seconds\": false,\n      \"created_at\": \"2026-03-02 11:40:12\"\n    }\n  ],\n  \"meta\": { \"page\": 1, \"page_size\": 50, \"total\": 812, \"has_next\": true }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "List subscribers",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "user_list",
        "x-required-permission": "prm_users_index"
      },
      "post": {
        "description": "Creates the account and its identity only. It does not activate a plan, take money or grant quota — binding profile_id here is metadata. Use the activation endpoint for the paid part.",
        "operationId": "users_post-users",
        "responses": {
          "201": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": {\n    \"id\": 4712,\n    \"tenant_id\": 12,\n    \"username\": \"ahmed\",\n    \"enabled\": true,\n    \"profile_id\": 7,\n    \"parent_id\": 41,\n    \"balance\": 0.00,\n    \"debt\": 0.00,\n    \"created_at\": \"2026-09-20 09:14:55\"\n  }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "Create a subscriber",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_create"
      }
    },
    "/api/v1/users/bulk-add-days": {
      "post": {
        "description": "",
        "operationId": "users_post-users-bulk-add-days",
        "summary": "Extend subscription",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_extend"
      }
    },
    "/api/v1/users/bulk-add-hours": {
      "post": {
        "description": "",
        "operationId": "users_post-users-bulk-add-hours",
        "summary": "Extend subscription",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_extend"
      }
    },
    "/api/v1/users/bulk-add-traffic": {
      "post": {
        "description": "",
        "operationId": "users_post-users-bulk-add-traffic",
        "summary": "Add traffic",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_add_traffic"
      }
    },
    "/api/v1/users/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "users_post-users-bulk-delete",
        "summary": "Delete users",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_delete"
      }
    },
    "/api/v1/users/bulk-deposit": {
      "post": {
        "description": "",
        "operationId": "users_post-users-bulk-deposit",
        "summary": "Deposit to user wallet",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_deposit"
      }
    },
    "/api/v1/users/bulk-deposit/preview": {
      "post": {
        "description": "",
        "operationId": "users_post-users-bulk-deposit-preview",
        "summary": "Deposit to user wallet",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_deposit"
      }
    },
    "/api/v1/users/bulk-disable": {
      "post": {
        "description": "Takes an array of ids and suspends each. One request against the per-tenant write budget instead of one per subscriber, which is the difference between fitting in a minute and not.",
        "operationId": "users_post-users-bulk-disable",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": {\n    \"updated\": [4711, 4713],\n    \"failed\": [\n      { \"id\": 4712, \"reason\": \"not_authorized\", \"message\": \"You may not act on this record.\" }\n    ]\n  }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "Suspend many subscribers",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_enable_disable"
      }
    },
    "/api/v1/users/bulk-disconnect": {
      "post": {
        "description": "",
        "operationId": "users_post-users-bulk-disconnect",
        "summary": "Live traffic / disconnect",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_live_traffic"
      }
    },
    "/api/v1/users/bulk-enable": {
      "post": {
        "description": "",
        "operationId": "users_post-users-bulk-enable",
        "summary": "Enable / suspend users",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_enable_disable"
      }
    },
    "/api/v1/users/bulk-extend": {
      "post": {
        "description": "",
        "operationId": "users_post-users-bulk-extend",
        "summary": "POST /api/v1/users/bulk-extend",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-any-permission": [
          "prm_users_activate",
          "prm_users_extend"
        ]
      }
    },
    "/api/v1/users/bulk-extend/preview": {
      "post": {
        "description": "",
        "operationId": "users_post-users-bulk-extend-preview",
        "summary": "POST /api/v1/users/bulk-extend/preview",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-any-permission": [
          "prm_users_activate",
          "prm_users_extend"
        ]
      }
    },
    "/api/v1/users/bulk-reset-balance": {
      "post": {
        "description": "",
        "operationId": "users_post-users-bulk-reset-balance",
        "summary": "Withdraw / settle user debt",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_withdrawal"
      }
    },
    "/api/v1/users/bulk-reset-quota": {
      "post": {
        "description": "",
        "operationId": "users_post-users-bulk-reset-quota",
        "summary": "Reset user quota",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_reset_quota"
      }
    },
    "/api/v1/users/bulk-set-expiration": {
      "post": {
        "description": "",
        "operationId": "users_post-users-bulk-set-expiration",
        "summary": "Extend subscription",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_extend"
      }
    },
    "/api/v1/users/bulk-set-group": {
      "post": {
        "description": "",
        "operationId": "users_post-users-bulk-set-group",
        "summary": "Assign groups",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_groups_assign"
      }
    },
    "/api/v1/users/bulk-set-parent": {
      "post": {
        "description": "",
        "operationId": "users_post-users-bulk-set-parent",
        "summary": "Change user parent",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_change_parent"
      }
    },
    "/api/v1/users/bulk-set-profile": {
      "post": {
        "description": "",
        "operationId": "users_post-users-bulk-set-profile",
        "summary": "Change user profile",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_change_profile"
      }
    },
    "/api/v1/users/bulk-withdraw": {
      "post": {
        "description": "",
        "operationId": "users_post-users-bulk-withdraw",
        "summary": "Withdraw / settle user debt",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_withdrawal"
      }
    },
    "/api/v1/users/bulk-withdraw/preview": {
      "post": {
        "description": "",
        "operationId": "users_post-users-bulk-withdraw-preview",
        "summary": "Withdraw / settle user debt",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_withdrawal"
      }
    },
    "/api/v1/users/owner-context": {
      "get": {
        "description": "",
        "operationId": "users_get-users-owner-context",
        "summary": "Create users",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_users_create"
      }
    },
    "/api/v1/users/resolve": {
      "get": {
        "description": "Exchanges the opaque per-subscriber scan token, the one encoded in a printed QR code, for the subscriber record. Scoped to the caller's subtree exactly like a direct fetch.",
        "operationId": "users_get-users-resolve",
        "parameters": [
          {
            "description": "The scan token. The QR payload is prefixed with xr:u: — strip the prefix before sending.",
            "in": "query",
            "name": "code",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "summary": "Resolve a subscriber by scan code",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "user_resolve",
        "x-required-permission": "prm_users_index"
      }
    },
    "/api/v1/users/summary": {
      "get": {
        "description": "Fleet-health counters over exactly the same authority scope as the list, so a count and the rows behind it always agree.",
        "operationId": "users_get-users-summary",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": {\n    \"total\": 812,\n    \"active\": 640,\n    \"disabled\": 44,\n    \"online\": 318,\n    \"expired\": 128\n  }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "Count subscribers by state",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_users_index"
      }
    },
    "/api/v1/users/{id}": {
      "delete": {
        "description": "Soft-deletes the account and frees its username slot by renaming the row. The subscriber's live portal sessions are ended.",
        "operationId": "users_delete-users",
        "parameters": [
          {
            "description": "Subscriber id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Delete a subscriber",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_delete"
      },
      "get": {
        "description": "The full record, including the computed status object and the fields the list projection leaves out.",
        "operationId": "users_get-users-by-id",
        "parameters": [
          {
            "description": "Subscriber id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": {\n    \"id\": 4711,\n    \"tenant_id\": 12,\n    \"username\": \"ahmed\",\n    \"enabled\": true,\n    \"status\": { \"online\": true, \"expired\": false, \"have_quota\": true, \"can_connect\": true },\n    \"profile_id\": 7,\n    \"fup_profile_id\": null,\n    \"bytes_remaining\": 48318382080,\n    \"seconds_remaining\": null,\n    \"expiration\": \"2026-10-14 00:00:00\",\n    \"balance\": 0.00,\n    \"debt\": 0.00,\n    \"debt_limit\": null,\n    \"mac_lock_enabled\": false,\n    \"mac_locked_addrs\": [],\n    \"simultaneous_sessions\": 1,\n    \"allowed_services\": \"both\",\n    \"lookup_token\": \"n8Qk2vRa1pLd7WxYzB0cEf\",\n    \"custom_fields\": {},\n    \"created_at\": \"2026-03-02 11:40:12\"\n  }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "Fetch one subscriber",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_users_index"
      },
      "patch": {
        "description": "Partial update. An omitted field is left alone. Three fields are separately permission-gated and are dropped silently rather than refused when the caller lacks the right: parent_id, profile_id and expiration.",
        "operationId": "users_patch-users",
        "parameters": [
          {
            "description": "Subscriber id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Update a subscriber",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_update"
      }
    },
    "/api/v1/users/{id}/activate": {
      "post": {
        "description": "Sets enabled back to true. This is the inverse of suspend and has nothing to do with activating a plan — that is the activation endpoint, which charges money.",
        "operationId": "users_post-users-activate",
        "parameters": [
          {
            "description": "Subscriber id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Un-suspend a subscriber",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_enable_disable"
      }
    },
    "/api/v1/users/{id}/activation": {
      "post": {
        "description": "Prices, charges and provisions in one operation. Funds are reserved first, then the plan is applied, and both halves are keyed off your request_id, so a retry after a crash re-runs neither the charge nor the grant.",
        "operationId": "users_post-users-activation",
        "parameters": [
          {
            "description": "Subscriber id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": {\n    \"quote\": { \"profile_id\": 7, \"required_amount\": 171.00, \"new_expiration\": \"2026-10-14 00:00:00\" },\n    \"activation\": {\n      \"UserID\": 4711,\n      \"ProfileID\": 7,\n      \"NewSubscriptionEnd\": \"2026-10-14T00:00:00Z\",\n      \"BytesRemaining\": 107374182400,\n      \"SecondsRemaining\": -1,\n      \"PointsAwarded\": 10,\n      \"QuotaCarried\": false,\n      \"Replay\": false\n    },\n    \"manager_balance\": 4029.00,\n    \"replay\": false\n  }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "Charge and provision an activation",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-idempotent-on": "request_id",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-any-permission": [
          "prm_users_activate",
          "prm_users_extend"
        ]
      }
    },
    "/api/v1/users/{id}/activation-quote": {
      "post": {
        "description": "Read-only preview of what an activation would cost and grant: unit price, VAT, the computed new expiration, the plan's quota, both wallets, reward points and whether the chosen method can cover it. Writes nothing, so it is safe to call on every keystroke of a form.",
        "operationId": "users_post-users-activation-quote",
        "parameters": [
          {
            "description": "Subscriber id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": {\n    \"user_id\": 4711,\n    \"username\": \"ahmed\",\n    \"profile_id\": 7,\n    \"profile_name\": \"Home 20M\",\n    \"operation\": \"activate\",\n    \"method\": \"manager_balance\",\n    \"units\": 1,\n    \"unit_price\": 150.00,\n    \"end_user_price\": 180.00,\n    \"vat_percent\": 14.00,\n    \"vat_amount\": 21.00,\n    \"required_amount\": 171.00,\n    \"price_overridden\": false,\n    \"duration_value\": 30,\n    \"duration_unit\": \"days\",\n    \"total_bytes\": 107374182400,\n    \"uptime_seconds\": -1,\n    \"old_expiration\": \"2026-09-14 00:00:00\",\n    \"new_expiration\": \"2026-10-14 00:00:00\",\n    \"manager_balance\": 4200.00,\n    \"manager_available\": 4200.00,\n    \"user_balance\": 0.00,\n    \"points_awarded\": 10,\n    \"can_afford\": true,\n    \"warnings\": [],\n    \"debitable\": false\n  }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "Price an activation or extension",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-any-permission": [
          "prm_users_activate",
          "prm_users_extend"
        ]
      }
    },
    "/api/v1/users/{id}/add-traffic": {
      "post": {
        "description": "Adds bytes and/or seconds to the subscriber's remaining period quota without pricing or charging anything, and drops the hot-path quota cache so the grant applies on the next RADIUS request.",
        "operationId": "users_post-users-add-traffic",
        "parameters": [
          {
            "description": "Subscriber id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Grant quota directly",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_add_traffic"
      }
    },
    "/api/v1/users/{id}/addon-quote": {
      "post": {
        "description": "",
        "operationId": "users_post-users-addon-quote",
        "summary": "Sell add-ons",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_addon"
      }
    },
    "/api/v1/users/{id}/addons": {
      "post": {
        "description": "",
        "operationId": "users_post-users-addons",
        "summary": "Sell add-ons",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_addon"
      }
    },
    "/api/v1/users/{id}/approve": {
      "post": {
        "description": "",
        "operationId": "users_post-users-approve",
        "summary": "Approve pending signups",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_approve_signup"
      }
    },
    "/api/v1/users/{id}/assign-profile": {
      "post": {
        "description": "",
        "operationId": "users_post-users-assign-profile",
        "summary": "Edit users",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_update"
      }
    },
    "/api/v1/users/{id}/bucket-order": {
      "put": {
        "description": "Replaces the subscriber's custom drain order. Every id must be one of their active buckets, except the sentinel 0, which stands for the plan's own main quota and may be placed anywhere in the sequence.",
        "operationId": "users_put-users-bucket-order",
        "parameters": [
          {
            "description": "Subscriber id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Set the bucket drain order",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_buckets"
      }
    },
    "/api/v1/users/{id}/cancel-service": {
      "post": {
        "description": "",
        "operationId": "users_post-users-cancel-service",
        "summary": "Cancel service",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_cancel"
      }
    },
    "/api/v1/users/{id}/change-parent": {
      "post": {
        "description": "Re-points the subscriber at a different owning manager. The destination must be a manager the caller may act on, because the owner is both the creditor on a debt and the revenue attribution. Naturally idempotent, so request_id is accepted for your own tracing but is not enforced.",
        "operationId": "users_post-users-change-parent",
        "parameters": [
          {
            "description": "Subscriber id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Move a subscriber to another owner",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_change_parent"
      }
    },
    "/api/v1/users/{id}/change-profile": {
      "post": {
        "description": "",
        "operationId": "users_post-users-change-profile",
        "summary": "Change user profile",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_change_profile"
      }
    },
    "/api/v1/users/{id}/compensate": {
      "post": {
        "description": "",
        "operationId": "users_post-users-compensate",
        "summary": "Compensate users",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_compensate"
      }
    },
    "/api/v1/users/{id}/compensations/{reqId}/approve": {
      "post": {
        "description": "",
        "operationId": "users_post-users-compensations-approve",
        "summary": "Approve/reject compensation requests",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_compensate_approve"
      }
    },
    "/api/v1/users/{id}/compensations/{reqId}/reject": {
      "post": {
        "description": "",
        "operationId": "users_post-users-compensations-reject",
        "summary": "Approve/reject compensation requests",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_compensate_approve"
      }
    },
    "/api/v1/users/{id}/cpe-console": {
      "post": {
        "description": "",
        "operationId": "users_post-users-cpe-console",
        "summary": "Remote access to user's CPE (router admin UI)",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_probe",
        "x-required-permission": "prm_users_remote"
      }
    },
    "/api/v1/users/{id}/debt": {
      "get": {
        "description": "Total outstanding debt across all creditors, plus the slice of it owed to the calling manager specifically, read live off the loan ledger.",
        "operationId": "users_get-users-debt",
        "parameters": [
          {
            "description": "Subscriber id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": { \"total\": 340.00, \"owed_to_me\": 120.00 }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "Read a subscriber's debt",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_users_index"
      }
    },
    "/api/v1/users/{id}/deposit": {
      "post": {
        "description": "Moves money into the subscriber's wallet and writes the matching ledger line. Idempotent on request_id through a unique constraint on the ledger itself, so the charge and the record of it cannot disagree.",
        "operationId": "users_post-users-deposit",
        "parameters": [
          {
            "description": "Subscriber id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": {\n    \"journal_id\": 90412,\n    \"balance\": 250.00,\n    \"debt\": 0.00,\n    \"replay\": false\n  }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "Credit a subscriber wallet",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-idempotent-on": "request_id",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_deposit"
      }
    },
    "/api/v1/users/{id}/documents": {
      "get": {
        "description": "",
        "operationId": "users_get-users-documents",
        "summary": "Manage user documents",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_users_documents"
      },
      "post": {
        "description": "",
        "operationId": "users_post-users-documents",
        "summary": "Manage user documents",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_documents"
      }
    },
    "/api/v1/users/{id}/documents/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "users_post-users-documents-bulk-delete",
        "summary": "Manage user documents",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_documents"
      }
    },
    "/api/v1/users/{id}/documents/{docId}": {
      "delete": {
        "description": "",
        "operationId": "users_delete-users-documents",
        "summary": "Manage user documents",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_documents"
      },
      "patch": {
        "description": "",
        "operationId": "users_patch-users-documents",
        "summary": "Manage user documents",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_documents"
      }
    },
    "/api/v1/users/{id}/documents/{docId}/download": {
      "get": {
        "description": "",
        "operationId": "users_get-users-documents-download",
        "summary": "Manage user documents",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_users_documents"
      }
    },
    "/api/v1/users/{id}/free-zone-traffic": {
      "post": {
        "description": "",
        "operationId": "users_post-users-free-zone-traffic",
        "summary": "View free-zone traffic",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_freezone_traffic"
      }
    },
    "/api/v1/users/{id}/free-zones": {
      "get": {
        "description": "",
        "operationId": "users_get-users-free-zones",
        "summary": "View free-zone traffic",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_users_freezone_traffic"
      }
    },
    "/api/v1/users/{id}/history": {
      "get": {
        "description": "",
        "operationId": "users_get-users-history",
        "summary": "View usage history",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_users_history"
      }
    },
    "/api/v1/users/{id}/invoices": {
      "get": {
        "description": "Invoices belonging to a single subscriber, newest first.",
        "operationId": "users_get-users-invoices",
        "parameters": [
          {
            "description": "Subscriber id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "List one subscriber's invoices",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_users_invoices_view"
      },
      "post": {
        "description": "The per-subscriber form of issuing an invoice. Same validation and the same server-computed total; the subscriber comes from the path rather than the body.",
        "operationId": "users_post-users-invoices",
        "parameters": [
          {
            "description": "Subscriber id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Create an invoice for a subscriber",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_invoices_create"
      }
    },
    "/api/v1/users/{id}/invoices/bulk-pay": {
      "post": {
        "description": "",
        "operationId": "users_post-users-invoices-bulk-pay",
        "summary": "Edit / pay user invoices",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_invoices_edit"
      }
    },
    "/api/v1/users/{id}/invoices/bulk-unpay": {
      "post": {
        "description": "",
        "operationId": "users_post-users-invoices-bulk-unpay",
        "summary": "Edit / pay user invoices",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_invoices_edit"
      }
    },
    "/api/v1/users/{id}/invoices/{invoiceId}": {
      "delete": {
        "description": "Deletes a hand-created invoice. Auto-issued documents cannot be deleted here, for the same reason they cannot be edited.",
        "operationId": "users_delete-users-invoices",
        "parameters": [
          {
            "description": "Subscriber id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "description": "Invoice id.",
            "in": "path",
            "name": "invoiceId",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Delete an invoice",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_invoices_delete"
      },
      "get": {
        "description": "The invoice with its line items.",
        "operationId": "users_get-users-invoices-by-invoice-id",
        "parameters": [
          {
            "description": "Subscriber id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "description": "Invoice id.",
            "in": "path",
            "name": "invoiceId",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Fetch one invoice",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_users_invoices_view"
      },
      "patch": {
        "description": "Edits a hand-created invoice. Auto-issued documents — activations, extensions, add-ons, deposits and withdrawals — are not editable through this path.",
        "operationId": "users_patch-users-invoices",
        "parameters": [
          {
            "description": "Subscriber id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "description": "Invoice id.",
            "in": "path",
            "name": "invoiceId",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Edit an invoice",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_invoices_edit"
      }
    },
    "/api/v1/users/{id}/invoices/{invoiceId}/pay": {
      "post": {
        "description": "Records the invoice as settled and stamps paid_on. This is bookkeeping: it does not move money between wallets.",
        "operationId": "users_post-users-invoices-pay",
        "parameters": [
          {
            "description": "Subscriber id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "description": "Invoice id.",
            "in": "path",
            "name": "invoiceId",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Mark an invoice paid",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_invoices_edit"
      }
    },
    "/api/v1/users/{id}/invoices/{invoiceId}/render-data": {
      "get": {
        "description": "",
        "operationId": "users_get-users-invoices-render-data",
        "summary": "View user invoices",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_users_invoices_view"
      }
    },
    "/api/v1/users/{id}/invoices/{invoiceId}/unpay": {
      "post": {
        "description": "Reverses the paid stamp. Again, bookkeeping only.",
        "operationId": "users_post-users-invoices-unpay",
        "parameters": [
          {
            "description": "Subscriber id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "description": "Invoice id.",
            "in": "path",
            "name": "invoiceId",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Mark an invoice unpaid",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_invoices_edit"
      }
    },
    "/api/v1/users/{id}/journal": {
      "get": {
        "description": "",
        "operationId": "users_get-users-journal",
        "summary": "View users",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_users_index"
      }
    },
    "/api/v1/users/{id}/login-as": {
      "post": {
        "description": "",
        "operationId": "users_post-users-login-as",
        "summary": "Log in as subscriber",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "user_login_as",
        "x-required-permission": "prm_users_login_as"
      }
    },
    "/api/v1/users/{id}/lookup-token/rotate": {
      "post": {
        "description": "",
        "operationId": "users_post-users-lookup-token-rotate",
        "summary": "Edit users",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_update"
      }
    },
    "/api/v1/users/{id}/parental": {
      "get": {
        "description": "",
        "operationId": "users_get-users-parental",
        "summary": "Manage parental controls",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_users_parental"
      }
    },
    "/api/v1/users/{id}/parental/reset-pin": {
      "post": {
        "description": "",
        "operationId": "users_post-users-parental-reset-pin",
        "summary": "Manage parental controls",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_parental"
      }
    },
    "/api/v1/users/{id}/pay-debt": {
      "post": {
        "description": "",
        "operationId": "users_post-users-pay-debt",
        "summary": "Withdraw / settle user debt",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_withdrawal"
      }
    },
    "/api/v1/users/{id}/payments": {
      "get": {
        "description": "",
        "operationId": "users_get-users-payments",
        "summary": "View users",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_users_index"
      }
    },
    "/api/v1/users/{id}/quota-buckets": {
      "get": {
        "description": "Separately-metered grants layered on top of the plan's own quota — add-ons, extensions, card top-ups — in the order they will be drained.",
        "operationId": "users_get-users-quota-buckets",
        "parameters": [
          {
            "description": "Subscriber id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": [\n    {\n      \"id\": 331,\n      \"source\": \"addon\",\n      \"label\": \"Night 50GB\",\n      \"priority\": 10,\n      \"bytes_granted\": 53687091200,\n      \"bytes_remaining\": 41231686144,\n      \"seconds_granted\": 0,\n      \"seconds_remaining\": 0,\n      \"activated_at\": \"2026-09-12 20:04:01\",\n      \"valid_until\": \"2026-10-12 20:04:01\",\n      \"works_when_expired\": false,\n      \"status\": \"active\"\n    }\n  ],\n  \"meta\": { \"page\": 1, \"page_size\": 1, \"total\": 1, \"has_next\": false }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "List a subscriber's quota buckets",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_users_index"
      }
    },
    "/api/v1/users/{id}/quota-buckets/{bid}/cancel": {
      "post": {
        "description": "",
        "operationId": "users_post-users-quota-buckets-cancel",
        "summary": "Manage quota buckets",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_buckets"
      }
    },
    "/api/v1/users/{id}/quota-history": {
      "get": {
        "description": "",
        "operationId": "users_get-users-quota-history",
        "summary": "View usage history",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_users_history"
      }
    },
    "/api/v1/users/{id}/radius-attrs": {
      "get": {
        "description": "",
        "operationId": "users_get-users-radius-attrs",
        "summary": "Manage user RADIUS attributes",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_users_radius_attributes"
      },
      "post": {
        "description": "",
        "operationId": "users_post-users-radius-attrs",
        "summary": "Manage user RADIUS attributes",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_radius_attributes"
      }
    },
    "/api/v1/users/{id}/radius-attrs/bulk-delete": {
      "post": {
        "description": "",
        "operationId": "users_post-users-radius-attrs-bulk-delete",
        "summary": "Manage user RADIUS attributes",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_radius_attributes"
      }
    },
    "/api/v1/users/{id}/radius-attrs/{attrId}": {
      "delete": {
        "description": "",
        "operationId": "users_delete-users-radius-attrs",
        "summary": "Manage user RADIUS attributes",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_radius_attributes"
      },
      "patch": {
        "description": "",
        "operationId": "users_patch-users-radius-attrs",
        "summary": "Manage user RADIUS attributes",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_radius_attributes"
      }
    },
    "/api/v1/users/{id}/receipts": {
      "get": {
        "description": "",
        "operationId": "users_get-users-receipts",
        "summary": "View users",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_users_index"
      }
    },
    "/api/v1/users/{id}/redeem-points": {
      "post": {
        "description": "",
        "operationId": "users_post-users-redeem-points",
        "summary": "Redeem reward points",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_reward_points"
      }
    },
    "/api/v1/users/{id}/refund-activation": {
      "post": {
        "description": "",
        "operationId": "users_post-users-refund-activation",
        "summary": "Refund last activation",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_refund"
      }
    },
    "/api/v1/users/{id}/rename": {
      "post": {
        "description": "",
        "operationId": "users_post-users-rename",
        "summary": "Rename users",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_rename"
      }
    },
    "/api/v1/users/{id}/reset-password": {
      "post": {
        "description": "",
        "operationId": "users_post-users-reset-password",
        "summary": "Edit users",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_update"
      }
    },
    "/api/v1/users/{id}/reset-quota": {
      "post": {
        "description": "Always zeroes the daily counters. With clear_period true it also nulls the period quota, which is the destructive form. Lifts a daily FUP throttle and kicks the live session so full speed returns immediately. An empty body is accepted and means clear_period false.",
        "operationId": "users_post-users-reset-quota",
        "parameters": [
          {
            "description": "Subscriber id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Reset quota counters",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_reset_quota"
      }
    },
    "/api/v1/users/{id}/sessions": {
      "get": {
        "description": "Accounting history for this subscriber, newest first, paginated with the standard list parameters.",
        "operationId": "users_get-users-sessions",
        "parameters": [
          {
            "description": "Subscriber id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "description": "Narrows to open or closed sessions.",
            "in": "query",
            "name": "filter[status]",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "summary": "List a subscriber's session history",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-required-permission": "prm_users_sessions_index"
      }
    },
    "/api/v1/users/{id}/speed": {
      "delete": {
        "description": "",
        "operationId": "users_delete-users-speed",
        "summary": "Edit users",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_update"
      },
      "get": {
        "description": "",
        "operationId": "users_get-users-speed",
        "summary": "View users",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_users_index"
      },
      "put": {
        "description": "",
        "operationId": "users_put-users-speed",
        "summary": "Edit users",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_update"
      }
    },
    "/api/v1/users/{id}/suspend": {
      "post": {
        "description": "Sets enabled to false and, when the tenant has disconnect-on-update enabled, kicks any live session so the suspension takes effect now rather than at the next re-auth.",
        "operationId": "users_post-users-suspend",
        "parameters": [
          {
            "description": "Subscriber id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "example": "{\n  \"data\": {\n    \"id\": 4711,\n    \"username\": \"ahmed\",\n    \"enabled\": false,\n    \"status\": { \"enabled\": false, \"can_connect\": false }\n  }\n}"
              }
            },
            "description": "Success"
          }
        },
        "summary": "Suspend a subscriber",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_enable_disable"
      }
    },
    "/api/v1/users/{id}/usage-history": {
      "get": {
        "description": "",
        "operationId": "users_get-users-usage-history",
        "summary": "View usage history",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-generated-stub": true,
        "x-required-permission": "prm_users_history"
      }
    },
    "/api/v1/users/{id}/withdraw": {
      "post": {
        "description": "The inverse of deposit. Refuses to take the balance below zero unless allow_negative is set.",
        "operationId": "users_post-users-withdraw",
        "parameters": [
          {
            "description": "Subscriber id.",
            "in": "path",
            "name": "id",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "summary": "Debit a subscriber wallet",
        "tags": [
          "users"
        ],
        "x-auth": "manager",
        "x-idempotent-on": "request_id",
        "x-rate-limit-bucket": "t_mutate",
        "x-required-permission": "prm_users_withdrawal"
      }
    }
  },
  "security": [
    {
      "apiToken": []
    }
  ],
  "servers": [
    {
      "description": "This instance",
      "url": "https://x-radius.com/api/v1"
    }
  ]
}