"""Organizations API endpoints.

This file is automatically @generated from the Meraki API specification.
Do not edit this file manually.

"""

from __future__ import annotations

import urllib.parse
from typing import TYPE_CHECKING, Any, Literal

from meraki_client.schemas import (
    AssignOrganizationLicensesSeatsResponse,
    BulkOrganizationDevicesPacketCaptureCapturesCreateAdvanced,
    BulkOrganizationDevicesPacketCaptureCapturesCreateDevicesItem,
    BulkOrganizationDevicesPacketCaptureCapturesCreateResponse,
    BulkUpdateOrganizationDevicesDetailsDetailsItem,
    BulkUpdateOrganizationDevicesDetailsResponse,
    ClaimIntoOrganizationInventoryLicensesItem,
    ClaimIntoOrganizationInventoryResponse,
    ClaimIntoOrganizationLicensesItem,
    ClaimIntoOrganizationResponse,
    ClaimOrganizationInventoryOrdersResponse,
    ClaimOrganizationInventoryOrdersSubscriptionsItem,
    CloneOrganizationResponse,
    CombineOrganizationNetworksResponse,
    CreateNetworkMoveNetwork,
    CreateNetworkMoveOrganizations,
    CreateNetworkMoveResponse,
    CreateOrganizationActionBatchActionsItem,
    CreateOrganizationActionBatchCallback,
    CreateOrganizationActionBatchResponse,
    CreateOrganizationAdaptivePolicyAclResponse,
    CreateOrganizationAdaptivePolicyAclRulesItem,
    CreateOrganizationAdaptivePolicyGroupPolicyObjectsItem,
    CreateOrganizationAdaptivePolicyGroupResponse,
    CreateOrganizationAdaptivePolicyPolicyAclsItem,
    CreateOrganizationAdaptivePolicyPolicyDestinationGroup,
    CreateOrganizationAdaptivePolicyPolicyResponse,
    CreateOrganizationAdaptivePolicyPolicySourceGroup,
    CreateOrganizationAdminNetworksItem,
    CreateOrganizationAdminResponse,
    CreateOrganizationAdminTagsItem,
    CreateOrganizationAlertsProfileAlertCondition,
    CreateOrganizationAlertsProfileRecipients,
    CreateOrganizationAlertsProfileResponse,
    CreateOrganizationBrandingPolicyAdminSettings,
    CreateOrganizationBrandingPolicyCustomLogo,
    CreateOrganizationBrandingPolicyHelpSettings,
    CreateOrganizationBrandingPolicyResponse,
    CreateOrganizationConfigTemplateResponse,
    CreateOrganizationDevicesControllerMigrationResponse,
    CreateOrganizationDevicesPacketCaptureCaptureAdvanced,
    CreateOrganizationDevicesPacketCaptureCaptureResponse,
    CreateOrganizationDevicesPacketCaptureScheduleDevicesItem,
    CreateOrganizationDevicesPacketCaptureScheduleResponse,
    CreateOrganizationDevicesPacketCaptureScheduleSchedule,
    CreateOrganizationEarlyAccessFeaturesOptInResponse,
    CreateOrganizationInventoryDevicesSwapsBulkResponse,
    CreateOrganizationInventoryDevicesSwapsBulkSwapsItem,
    CreateOrganizationInventoryOnboardingCloudMonitoringImportDevicesItem,
    CreateOrganizationInventoryOnboardingCloudMonitoringImportResponse,
    CreateOrganizationInventoryOnboardingCloudMonitoringPrepareDevicesItem,
    CreateOrganizationInventoryOnboardingCloudMonitoringPrepareOptions,
    CreateOrganizationInventoryOnboardingCloudMonitoringPrepareResponse,
    CreateOrganizationManagement,
    CreateOrganizationNetworkResponse,
    CreateOrganizationPolicyObjectResponse,
    CreateOrganizationPolicyObjectsGroupResponse,
    CreateOrganizationResponse,
    CreateOrganizationSamlIdpResponse,
    CreateOrganizationSamlRoleNetworksItem,
    CreateOrganizationSamlRoleResponse,
    CreateOrganizationSamlRoleTagsItem,
    CreateOrganizationSplashThemeAssetResponse,
    CreateOrganizationSplashThemeResponse,
    DictResponse,
    DisableOrganizationIntegrationsXdrNetworksNetworksItem,
    DisableOrganizationIntegrationsXdrNetworksResponse,
    EnableOrganizationIntegrationsXdrNetworksNetworksItem,
    EnableOrganizationIntegrationsXdrNetworksResponse,
    GenerateOrganizationDevicesPacketCaptureCaptureDownloadUrlResponse,
    GetNetworkMovesResponseItemsItem,
    GetOrganizationActionBatchesResponseItem,
    GetOrganizationActionBatchResponse,
    GetOrganizationAdaptivePolicyAclResponse,
    GetOrganizationAdaptivePolicyAclsResponseItem,
    GetOrganizationAdaptivePolicyGroupResponse,
    GetOrganizationAdaptivePolicyGroupsResponseItem,
    GetOrganizationAdaptivePolicyOverviewResponse,
    GetOrganizationAdaptivePolicyPoliciesResponseItem,
    GetOrganizationAdaptivePolicyPolicyResponse,
    GetOrganizationAdaptivePolicySettingsResponse,
    GetOrganizationAdminsResponseItem,
    GetOrganizationAlertsProfilesResponseItem,
    GetOrganizationApiRequestsOverviewResponse,
    GetOrganizationApiRequestsOverviewResponseCodesByIntervalResponseItem,
    GetOrganizationApiRequestsResponseItem,
    GetOrganizationAssuranceAlertResponse,
    GetOrganizationAssuranceAlertsOverviewByNetworkResponseItemsItem,
    GetOrganizationAssuranceAlertsOverviewByTypeResponseItemsItem,
    GetOrganizationAssuranceAlertsOverviewHistoricalResponseItemsItem,
    GetOrganizationAssuranceAlertsOverviewResponse,
    GetOrganizationAssuranceAlertsResponseItem,
    GetOrganizationAssuranceAlertsTaxonomyCategoriesResponseItem,
    GetOrganizationAssuranceAlertsTaxonomyTypesResponseItem,
    GetOrganizationBrandingPoliciesPrioritiesResponse,
    GetOrganizationBrandingPoliciesResponseItem,
    GetOrganizationBrandingPolicyResponse,
    GetOrganizationClientsBandwidthUsageHistoryResponseItem,
    GetOrganizationClientsOverviewResponse,
    GetOrganizationClientsSearchResponseRecordsItem,
    GetOrganizationConfigTemplateResponse,
    GetOrganizationConfigTemplatesResponseItem,
    GetOrganizationConfigurationChangesResponseItem,
    GetOrganizationDevicesAvailabilitiesChangeHistoryResponseItem,
    GetOrganizationDevicesAvailabilitiesResponseItem,
    GetOrganizationDevicesControllerMigrationsResponseItemsItem,
    GetOrganizationDevicesOverviewByModelResponse,
    GetOrganizationDevicesPacketCaptureCapturesResponseItemsItem,
    GetOrganizationDevicesPacketCaptureSchedulesResponseItemsItem,
    GetOrganizationDevicesPowerModulesStatusesByDeviceResponseItem,
    GetOrganizationDevicesProvisioningStatusesResponseItem,
    GetOrganizationDevicesResponseItem,
    GetOrganizationDevicesStatusesOverviewResponse,
    GetOrganizationDevicesStatusesResponseItem,
    GetOrganizationDevicesSystemMemoryUsageHistoryByIntervalResponseItemsItem,
    GetOrganizationDevicesUplinksAddressesByDeviceResponseItem,
    GetOrganizationDevicesUplinksLossAndLatencyResponseItem,
    GetOrganizationEarlyAccessFeaturesOptInResponse,
    GetOrganizationEarlyAccessFeaturesResponseItem,
    GetOrganizationFirmwareUpgradesByDeviceResponseItem,
    GetOrganizationFirmwareUpgradesResponseItem,
    GetOrganizationFloorPlansAutoLocateDevicesResponseItem,
    GetOrganizationFloorPlansAutoLocateStatusesResponseItem,
    GetOrganizationIntegrationsXdrNetworksResponseItemsItem,
    GetOrganizationInventoryDeviceResponse,
    GetOrganizationInventoryDevicesEoxOverviewResponse,
    GetOrganizationInventoryDevicesResponseItem,
    GetOrganizationInventoryDevicesSwapsBulkResponse,
    GetOrganizationInventoryOnboardingCloudMonitoringImportsResponseItem,
    GetOrganizationInventoryOnboardingCloudMonitoringNetworksResponseItem,
    GetOrganizationLicenseResponse,
    GetOrganizationLicensesOverviewResponse,
    GetOrganizationLicensesResponseItem,
    GetOrganizationLoginSecurityResponse,
    GetOrganizationNetworksResponseItem,
    GetOrganizationPoliciesAssignmentsByClientResponseItem,
    GetOrganizationPolicyObjectResponse,
    GetOrganizationPolicyObjectsGroupResponse,
    GetOrganizationPolicyObjectsGroupsResponseItem,
    GetOrganizationPolicyObjectsResponseItem,
    GetOrganizationResponse,
    GetOrganizationSamlIdpResponse,
    GetOrganizationSamlIdpsResponseItem,
    GetOrganizationSamlResponse,
    GetOrganizationSamlRoleResponse,
    GetOrganizationSamlRolesResponseItem,
    GetOrganizationSnmpResponse,
    GetOrganizationSplashAssetResponse,
    GetOrganizationSplashThemesResponseItem,
    GetOrganizationsResponseItem,
    GetOrganizationSummaryTopAppliancesByUtilizationResponseItem,
    GetOrganizationSummaryTopApplicationsByUsageResponseItem,
    GetOrganizationSummaryTopApplicationsCategoriesByUsageResponseItem,
    GetOrganizationSummaryTopClientsByUsageResponseItem,
    GetOrganizationSummaryTopClientsManufacturersByUsageResponseItem,
    GetOrganizationSummaryTopDevicesByUsageResponseItem,
    GetOrganizationSummaryTopDevicesModelsByUsageResponseItem,
    GetOrganizationSummaryTopNetworksByStatusResponseItem,
    GetOrganizationSummaryTopSsidsByUsageResponseItem,
    GetOrganizationSummaryTopSwitchesByEnergyUsageResponseItem,
    GetOrganizationUplinksStatusesResponseItem,
    GetOrganizationWebhooksAlertTypesResponse,
    GetOrganizationWebhooksCallbacksStatusResponse,
    GetOrganizationWebhooksLogsResponseItem,
    MoveOrganizationLicensesResponse,
    MoveOrganizationLicensesSeatsResponse,
    OrganizationsPolicyObjectsItem,
    PreviewOrganizationInventoryOrdersResponse,
    ReleaseFromOrganizationInventoryResponse,
    RenewOrganizationLicensesSeatsResponse,
    ReorderOrganizationDevicesPacketCaptureSchedulesOrderItem,
    ReorderOrganizationDevicesPacketCaptureSchedulesResponse,
    StopOrganizationDevicesPacketCaptureCaptureResponse,
    UpdateOrganizationActionBatchResponse,
    UpdateOrganizationAdaptivePolicyAclResponse,
    UpdateOrganizationAdaptivePolicyAclRulesItem,
    UpdateOrganizationAdaptivePolicyGroupPolicyObjectsItem,
    UpdateOrganizationAdaptivePolicyGroupResponse,
    UpdateOrganizationAdaptivePolicyPolicyAclsItem,
    UpdateOrganizationAdaptivePolicyPolicyDestinationGroup,
    UpdateOrganizationAdaptivePolicyPolicyResponse,
    UpdateOrganizationAdaptivePolicyPolicySourceGroup,
    UpdateOrganizationAdaptivePolicySettingsResponse,
    UpdateOrganizationAdminNetworksItem,
    UpdateOrganizationAdminResponse,
    UpdateOrganizationAdminTagsItem,
    UpdateOrganizationAlertsProfileAlertCondition,
    UpdateOrganizationAlertsProfileRecipients,
    UpdateOrganizationAlertsProfileResponse,
    UpdateOrganizationApi,
    UpdateOrganizationBrandingPoliciesPrioritiesResponse,
    UpdateOrganizationBrandingPolicyAdminSettings,
    UpdateOrganizationBrandingPolicyCustomLogo,
    UpdateOrganizationBrandingPolicyHelpSettings,
    UpdateOrganizationBrandingPolicyResponse,
    UpdateOrganizationConfigTemplateResponse,
    UpdateOrganizationDevicesPacketCaptureScheduleDevicesItem,
    UpdateOrganizationDevicesPacketCaptureScheduleResponse,
    UpdateOrganizationDevicesPacketCaptureScheduleSchedule,
    UpdateOrganizationEarlyAccessFeaturesOptInResponse,
    UpdateOrganizationLicenseResponse,
    UpdateOrganizationLoginSecurityApiAuthentication,
    UpdateOrganizationLoginSecurityResponse,
    UpdateOrganizationManagement,
    UpdateOrganizationPolicyObjectResponse,
    UpdateOrganizationPolicyObjectsGroupResponse,
    UpdateOrganizationResponse,
    UpdateOrganizationSamlIdpResponse,
    UpdateOrganizationSamlResponse,
    UpdateOrganizationSamlRoleNetworksItem,
    UpdateOrganizationSamlRoleResponse,
    UpdateOrganizationSamlRoleTagsItem,
    UpdateOrganizationSamlSpInitiated,
    UpdateOrganizationSnmpResponse,
)
from meraki_client.types import (
    CreateOrganizationAdaptivePolicyAclIpVersion,
    CreateOrganizationAdaptivePolicyPolicyLastEntryRule,
    CreateOrganizationAdminAuthenticationMethod,
    CreateOrganizationAdminOrgAccess,
    CreateOrganizationAlertsProfileType,
    CreateOrganizationDevicesControllerMigrationTarget,
    CreateOrganizationNetworkProductTypes,
    GetOrganizationActionBatchesStatus,
    GetOrganizationApiRequestsMethod,
    GetOrganizationApiRequestsOverviewResponseCodesByIntervalVersion,
    GetOrganizationApiRequestsVersion,
    GetOrganizationAssuranceAlertsCategory,
    GetOrganizationAssuranceAlertsDeviceTypes,
    GetOrganizationAssuranceAlertsOverviewByNetworkCategory,
    GetOrganizationAssuranceAlertsOverviewByNetworkDeviceTypes,
    GetOrganizationAssuranceAlertsOverviewByNetworkSortOrder,
    GetOrganizationAssuranceAlertsOverviewByNetworkTypes,
    GetOrganizationAssuranceAlertsOverviewByTypeCategory,
    GetOrganizationAssuranceAlertsOverviewByTypeDeviceTypes,
    GetOrganizationAssuranceAlertsOverviewByTypeSortBy,
    GetOrganizationAssuranceAlertsOverviewByTypeSortOrder,
    GetOrganizationAssuranceAlertsOverviewByTypeTypes,
    GetOrganizationAssuranceAlertsOverviewCategory,
    GetOrganizationAssuranceAlertsOverviewDeviceTypes,
    GetOrganizationAssuranceAlertsOverviewHistoricalCategory,
    GetOrganizationAssuranceAlertsOverviewHistoricalDeviceTypes,
    GetOrganizationAssuranceAlertsOverviewHistoricalTypes,
    GetOrganizationAssuranceAlertsOverviewTypes,
    GetOrganizationAssuranceAlertsSortBy,
    GetOrganizationAssuranceAlertsSortOrder,
    GetOrganizationAssuranceAlertsTypes,
    GetOrganizationDevicesAvailabilitiesChangeHistoryStatuses,
    GetOrganizationDevicesAvailabilitiesStatuses,
    GetOrganizationDevicesAvailabilitiesTagsFilterType,
    GetOrganizationDevicesControllerMigrationsTarget,
    GetOrganizationDevicesOverviewByModelProductTypes,
    GetOrganizationDevicesPacketCaptureCapturesSortOrder,
    GetOrganizationDevicesPowerModulesStatusesByDeviceTagsFilterType,
    GetOrganizationDevicesProductTypes,
    GetOrganizationDevicesProvisioningStatusesStatus,
    GetOrganizationDevicesProvisioningStatusesTagsFilterType,
    GetOrganizationDevicesSensorMetrics,
    GetOrganizationDevicesStatusesOverviewProductTypes,
    GetOrganizationDevicesStatusesProductTypes,
    GetOrganizationDevicesStatusesStatuses,
    GetOrganizationDevicesStatusesTagsFilterType,
    GetOrganizationDevicesSystemMemoryUsageHistoryByIntervalProductTypes,
    GetOrganizationDevicesTagsFilterType,
    GetOrganizationDevicesUplinksAddressesByDeviceTagsFilterType,
    GetOrganizationDevicesUplinksLossAndLatencyUplink,
    GetOrganizationFirmwareUpgradesByDeviceUpgradeStatuses,
    GetOrganizationInventoryDevicesEoxStatuses,
    GetOrganizationInventoryDevicesProductTypes,
    GetOrganizationInventoryDevicesTagsFilterType,
    GetOrganizationInventoryDevicesUsedState,
    GetOrganizationInventoryOnboardingCloudMonitoringNetworksDeviceType,
    GetOrganizationLicensesState,
    GetOrganizationNetworksProductTypes,
    GetOrganizationNetworksTagsFilterType,
    GetOrganizationOpenapiSpecVersion,
    GetOrganizationWebhooksAlertTypesProductType,
    UpdateOrganizationAdaptivePolicyAclIpVersion,
    UpdateOrganizationAdaptivePolicyPolicyLastEntryRule,
    UpdateOrganizationAdminOrgAccess,
    UpdateOrganizationAlertsProfileType,
    UpdateOrganizationSnmpV3AuthMode,
    UpdateOrganizationSnmpV3PrivMode,
)

if TYPE_CHECKING:
    from meraki_client._session import PaginatedResponse, Session


class Organizations:
    """Organizations class."""

    def __init__(self, session: Session) -> None:
        self._session = session

    def get_organizations(
        self,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetOrganizationsResponseItem]:
        """List the organizations that the user has privileges on.

        [API documentation: getOrganizations](https://developer.cisco.com/meraki/api-v1/#!get-organizations)

        Args:
            per_page: The number of entries per page returned. Acceptable range is 3 - 9000. Default
                is 9000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "id": "2930418",
                "name": "My organization",
                "url": "https://dashboard.meraki.com/o/VjjsAd/manage/organization/overview",
                "api": {
                  "enabled": true
                },
                "licensing": {
                  "model": "co-term"
                },
                "cloud": {
                  "region": {
                    "name": "North America",
                    "host": {
                      "name": "United States"
                    }
                  }
                },
                "management": {
                  "details": [
                    {
                      "name": "MSP ID",
                      "value": "123456"
                    }
                  ]
                }
              }
            ]
            ```

        """
        path = f"/organizations"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizations",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationsResponseItem,
        )

    def create_organization(
        self, name: str, *, management: CreateOrganizationManagement | None = None
    ) -> CreateOrganizationResponse:
        """Create a new organization.

        [API documentation: createOrganization](https://developer.cisco.com/meraki/api-v1/#!create-organization)

        Args:
            name: The name of the organization.
            management: Information about the organization's management system.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "2930418",
              "name": "My organization",
              "url": "https://dashboard.meraki.com/o/VjjsAd/manage/organization/overview",
              "api": {
                "enabled": true
              },
              "licensing": {
                "model": "co-term"
              },
              "cloud": {
                "region": {
                  "name": "North America",
                  "host": {
                    "name": "United States"
                  }
                }
              },
              "management": {
                "details": [
                  {
                    "name": "MSP ID",
                    "value": "123456"
                  }
                ]
              }
            }
            ```

        """
        path = f"/organizations"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if management is not None:
            payload["management"] = management.model_dump(by_alias=True, exclude_none=True)

        return self._session.post(
            scope="organizations",
            operation_id="createOrganization",
            path=path,
            json=payload,
            response_schema=CreateOrganizationResponse,
        )

    def get_organization(self, organization_id: str) -> GetOrganizationResponse:
        """Return an organization.

        [API documentation: getOrganization](https://developer.cisco.com/meraki/api-v1/#!get-organization)

        Args:
            organization_id: Organization ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "2930418",
              "name": "My organization",
              "url": "https://dashboard.meraki.com/o/VjjsAd/manage/organization/overview",
              "api": {
                "enabled": true
              },
              "licensing": {
                "model": "co-term"
              },
              "cloud": {
                "region": {
                  "name": "North America",
                  "host": {
                    "name": "United States"
                  }
                }
              },
              "management": {
                "details": [
                  {
                    "name": "MSP ID",
                    "value": "123456"
                  }
                ]
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}"

        return self._session.get(
            scope="organizations",
            operation_id="getOrganization",
            path=path,
            response_schema=GetOrganizationResponse,
        )

    def update_organization(
        self,
        organization_id: str,
        *,
        name: str | None = None,
        management: UpdateOrganizationManagement | None = None,
        api: UpdateOrganizationApi | None = None,
    ) -> UpdateOrganizationResponse:
        """Update an organization.

        [API documentation: updateOrganization](https://developer.cisco.com/meraki/api-v1/#!update-organization)

        Args:
            organization_id: Organization ID.
            name: The name of the organization.
            management: Information about the organization's management system.
            api: API-specific settings.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "2930418",
              "name": "My organization",
              "url": "https://dashboard.meraki.com/o/VjjsAd/manage/organization/overview",
              "api": {
                "enabled": true
              },
              "licensing": {
                "model": "co-term"
              },
              "cloud": {
                "region": {
                  "name": "North America",
                  "host": {
                    "name": "United States"
                  }
                }
              },
              "management": {
                "details": [
                  {
                    "name": "MSP ID",
                    "value": "123456"
                  }
                ]
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if management is not None:
            payload["management"] = management.model_dump(by_alias=True, exclude_none=True)
        if api is not None:
            payload["api"] = api.model_dump(by_alias=True, exclude_none=True)

        return self._session.put(
            scope="organizations",
            operation_id="updateOrganization",
            path=path,
            json=payload,
            response_schema=UpdateOrganizationResponse,
        )

    def delete_organization(self, organization_id: str) -> None:
        """Delete an organization.

        [API documentation: deleteOrganization](https://developer.cisco.com/meraki/api-v1/#!delete-organization)

        Args:
            organization_id: Organization ID.

        Returns:
            Successful operation.

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}"

        return self._session.delete(
            scope="organizations", operation_id="deleteOrganization", path=path
        )

    def get_organization_action_batches(
        self, organization_id: str, *, status: GetOrganizationActionBatchesStatus | None = None
    ) -> PaginatedResponse[GetOrganizationActionBatchesResponseItem]:
        """Return the list of action batches in the organization.

        [API documentation: getOrganizationActionBatches](https://developer.cisco.com/meraki/api-v1/#!get-organization-action-batches)

        Args:
            organization_id: Organization ID.
            status: Filter batches by status. Valid types are pending, completed, and failed.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "id": "1234",
                "organizationId": "2930418",
                "confirmed": true,
                "synchronous": false,
                "status": {
                  "completed": true,
                  "failed": false,
                  "errors": [],
                  "createdResources": [
                    {
                      "id": "1284392014819",
                      "uri": "/networks/L_XXXXX/groupPolicies/100"
                    }
                  ]
                },
                "actions": [
                  {
                    "resource": "/devices/QXXX-XXXX-XXXX/switch/ports/3",
                    "operation": "update"
                  }
                ]
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/actionBatches"

        params: dict[str, Any] = {}
        if status is not None:
            params["status"] = status

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationActionBatches",
            path=path,
            params=params,
            item_schema=GetOrganizationActionBatchesResponseItem,
        )

    def create_organization_action_batch(
        self,
        *,
        organization_id: str,
        actions: list[CreateOrganizationActionBatchActionsItem],
        confirmed: bool | None = None,
        synchronous: bool | None = None,
        callback: CreateOrganizationActionBatchCallback | None = None,
    ) -> CreateOrganizationActionBatchResponse:
        """Create an action batch.

        [API documentation: createOrganizationActionBatch](https://developer.cisco.com/meraki/api-v1/#!create-organization-action-batch)

        Args:
            organization_id: Organization ID.
            confirmed: Set to true for immediate execution. Set to false if the action should be
                previewed before executing. This property cannot be unset once it is
                true. Defaults to false.
            synchronous: Set to true to force the batch to run synchronous. There can be at most 20
                actions in synchronous batch. Defaults to false.
            actions: A set of changes to make as part of this action (<a
                href='https://developer.cisco.com/meraki/api/#/rest/guides/action-
                batches/'>more details</a>).
            callback: Details for the callback. Please include either an httpServerId OR url and
                sharedSecret.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "1234",
              "organizationId": "2930418",
              "confirmed": true,
              "synchronous": false,
              "status": {
                "completed": true,
                "failed": false,
                "errors": [],
                "createdResources": [
                  {
                    "id": "1284392014819",
                    "uri": "/networks/L_XXXXX/groupPolicies/100"
                  }
                ]
              },
              "actions": [
                {
                  "resource": "/devices/QXXX-XXXX-XXXX/switch/ports/3",
                  "operation": "update"
                }
              ],
              "callback": {
                "id": "1284392014819",
                "url": "https://webhook.site/28efa24e-f830-4d9f-a12b-fbb9e5035031",
                "status": "new"
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/actionBatches"

        payload: dict[str, Any] = {}
        if confirmed is not None:
            payload["confirmed"] = confirmed
        if synchronous is not None:
            payload["synchronous"] = synchronous
        if actions is not None:
            payload["actions"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in actions
            ]
        if callback is not None:
            payload["callback"] = callback.model_dump(by_alias=True, exclude_none=True)

        return self._session.post(
            scope="organizations",
            operation_id="createOrganizationActionBatch",
            path=path,
            json=payload,
            response_schema=CreateOrganizationActionBatchResponse,
        )

    def get_organization_action_batch(
        self, *, organization_id: str, action_batch_id: str
    ) -> GetOrganizationActionBatchResponse:
        """Return an action batch.

        [API documentation: getOrganizationActionBatch](https://developer.cisco.com/meraki/api-v1/#!get-organization-action-batch)

        Args:
            organization_id: Organization ID.
            action_batch_id: Action batch ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "1234",
              "organizationId": "2930418",
              "confirmed": true,
              "synchronous": false,
              "status": {
                "completed": true,
                "failed": false,
                "errors": [],
                "createdResources": [
                  {
                    "id": "1284392014819",
                    "uri": "/networks/L_XXXXX/groupPolicies/100"
                  }
                ]
              },
              "actions": [
                {
                  "resource": "/devices/QXXX-XXXX-XXXX/switch/ports/3",
                  "operation": "update"
                }
              ],
              "callback": {
                "id": "1284392014819",
                "url": "https://webhook.site/28efa24e-f830-4d9f-a12b-fbb9e5035031",
                "status": "new"
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        action_batch_id = urllib.parse.quote(str(action_batch_id), safe="")
        path = f"/organizations/{organization_id}/actionBatches/{action_batch_id}"

        return self._session.get(
            scope="organizations",
            operation_id="getOrganizationActionBatch",
            path=path,
            response_schema=GetOrganizationActionBatchResponse,
        )

    def update_organization_action_batch(
        self,
        *,
        organization_id: str,
        action_batch_id: str,
        confirmed: bool | None = None,
        synchronous: bool | None = None,
    ) -> UpdateOrganizationActionBatchResponse:
        """Update an action batch.

        [API documentation: updateOrganizationActionBatch](https://developer.cisco.com/meraki/api-v1/#!update-organization-action-batch)

        Args:
            organization_id: Organization ID.
            action_batch_id: Action batch ID.
            confirmed: A boolean representing whether or not the batch has been confirmed. This
                property cannot be unset once it is true.
            synchronous: Set to true to force the batch to run synchronous. There can be at most 20
                actions in synchronous batch.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "1234",
              "organizationId": "2930418",
              "confirmed": true,
              "synchronous": false,
              "status": {
                "completed": true,
                "failed": false,
                "errors": [],
                "createdResources": [
                  {
                    "id": "1284392014819",
                    "uri": "/networks/L_XXXXX/groupPolicies/100"
                  }
                ]
              },
              "actions": [
                {
                  "resource": "/devices/QXXX-XXXX-XXXX/switch/ports/3",
                  "operation": "update"
                }
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        action_batch_id = urllib.parse.quote(str(action_batch_id), safe="")
        path = f"/organizations/{organization_id}/actionBatches/{action_batch_id}"

        payload: dict[str, Any] = {}
        if confirmed is not None:
            payload["confirmed"] = confirmed
        if synchronous is not None:
            payload["synchronous"] = synchronous

        return self._session.put(
            scope="organizations",
            operation_id="updateOrganizationActionBatch",
            path=path,
            json=payload,
            response_schema=UpdateOrganizationActionBatchResponse,
        )

    def delete_organization_action_batch(
        self, *, organization_id: str, action_batch_id: str
    ) -> None:
        """Delete an action batch.

        [API documentation: deleteOrganizationActionBatch](https://developer.cisco.com/meraki/api-v1/#!delete-organization-action-batch)

        Args:
            organization_id: Organization ID.
            action_batch_id: Action batch ID.

        Returns:
            Successful operation.

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        action_batch_id = urllib.parse.quote(str(action_batch_id), safe="")
        path = f"/organizations/{organization_id}/actionBatches/{action_batch_id}"

        return self._session.delete(
            scope="organizations", operation_id="deleteOrganizationActionBatch", path=path
        )

    def get_organization_adaptive_policy_acls(
        self, organization_id: str
    ) -> PaginatedResponse[GetOrganizationAdaptivePolicyAclsResponseItem]:
        """List adaptive policy ACLs in a organization.

        [API documentation: getOrganizationAdaptivePolicyAcls](https://developer.cisco.com/meraki/api-v1/#!get-organization-adaptive-policy-acls)

        Args:
            organization_id: Organization ID.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "aclId": "12345678",
                "name": "Block sensitive web traffic",
                "description": "Blocks sensitive web traffic",
                "ipVersion": "ipv6",
                "rules": [
                  {
                    "policy": "deny",
                    "protocol": "tcp",
                    "srcPort": "1,33",
                    "dstPort": "22-30",
                    "log": true,
                    "tcpEstablished": true
                  }
                ],
                "createdAt": "2021-05-19T17:08:25Z",
                "updatedAt": "2021-05-19T17:11:54Z"
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/adaptivePolicy/acls"

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationAdaptivePolicyAcls",
            path=path,
            item_schema=GetOrganizationAdaptivePolicyAclsResponseItem,
        )

    def create_organization_adaptive_policy_acl(
        self,
        *,
        organization_id: str,
        name: str,
        rules: list[CreateOrganizationAdaptivePolicyAclRulesItem],
        ip_version: CreateOrganizationAdaptivePolicyAclIpVersion,
        description: str | None = None,
    ) -> CreateOrganizationAdaptivePolicyAclResponse:
        """Creates new adaptive policy ACL.

        [API documentation: createOrganizationAdaptivePolicyAcl](https://developer.cisco.com/meraki/api-v1/#!create-organization-adaptive-policy-acl)

        Args:
            organization_id: Organization ID.
            name: Name of the adaptive policy ACL.
            description: Description of the adaptive policy ACL.
            rules: An ordered array of the adaptive policy ACL rules.
            ip_version: IP version of adpative policy ACL. One of: 'any', 'ipv4' or 'ipv6'.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "aclId": "12345678",
              "name": "Block sensitive web traffic",
              "description": "Blocks sensitive web traffic",
              "ipVersion": "ipv6",
              "rules": [
                {
                  "policy": "deny",
                  "protocol": "tcp",
                  "srcPort": "1,33",
                  "dstPort": "22-30",
                  "log": true,
                  "tcpEstablished": true
                }
              ],
              "createdAt": "2021-05-19T17:08:25Z",
              "updatedAt": "2021-05-19T17:11:54Z"
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/adaptivePolicy/acls"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if description is not None:
            payload["description"] = description
        if rules is not None:
            payload["rules"] = [item.model_dump(by_alias=True, exclude_none=True) for item in rules]
        if ip_version is not None:
            payload["ipVersion"] = ip_version

        return self._session.post(
            scope="organizations",
            operation_id="createOrganizationAdaptivePolicyAcl",
            path=path,
            json=payload,
            response_schema=CreateOrganizationAdaptivePolicyAclResponse,
        )

    def get_organization_adaptive_policy_acl(
        self, *, organization_id: str, acl_id: str
    ) -> GetOrganizationAdaptivePolicyAclResponse:
        """Returns the adaptive policy ACL information.

        [API documentation: getOrganizationAdaptivePolicyAcl](https://developer.cisco.com/meraki/api-v1/#!get-organization-adaptive-policy-acl)

        Args:
            organization_id: Organization ID.
            acl_id: Acl ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "aclId": "12345678",
              "name": "Block sensitive web traffic",
              "description": "Blocks sensitive web traffic",
              "ipVersion": "ipv6",
              "rules": [
                {
                  "policy": "deny",
                  "protocol": "tcp",
                  "srcPort": "1,33",
                  "dstPort": "22-30",
                  "log": true,
                  "tcpEstablished": true
                }
              ],
              "createdAt": "2021-05-19T17:08:25Z",
              "updatedAt": "2021-05-19T17:11:54Z"
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        acl_id = urllib.parse.quote(str(acl_id), safe="")
        path = f"/organizations/{organization_id}/adaptivePolicy/acls/{acl_id}"

        return self._session.get(
            scope="organizations",
            operation_id="getOrganizationAdaptivePolicyAcl",
            path=path,
            response_schema=GetOrganizationAdaptivePolicyAclResponse,
        )

    def update_organization_adaptive_policy_acl(
        self,
        *,
        organization_id: str,
        acl_id: str,
        name: str | None = None,
        description: str | None = None,
        rules: list[UpdateOrganizationAdaptivePolicyAclRulesItem] | None = None,
        ip_version: UpdateOrganizationAdaptivePolicyAclIpVersion | None = None,
    ) -> UpdateOrganizationAdaptivePolicyAclResponse:
        """Updates an adaptive policy ACL.

        [API documentation: updateOrganizationAdaptivePolicyAcl](https://developer.cisco.com/meraki/api-v1/#!update-organization-adaptive-policy-acl)

        Args:
            organization_id: Organization ID.
            acl_id: Acl ID.
            name: Name of the adaptive policy ACL.
            description: Description of the adaptive policy ACL.
            rules: An ordered array of the adaptive policy ACL rules. An empty array will clear the
                rules.
            ip_version: IP version of adpative policy ACL. One of: 'any', 'ipv4' or 'ipv6'.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "aclId": "12345678",
              "name": "Block sensitive web traffic",
              "description": "Blocks sensitive web traffic",
              "ipVersion": "ipv6",
              "rules": [
                {
                  "policy": "deny",
                  "protocol": "tcp",
                  "srcPort": "1,33",
                  "dstPort": "22-30",
                  "log": true,
                  "tcpEstablished": true
                }
              ],
              "createdAt": "2021-05-19T17:08:25Z",
              "updatedAt": "2021-05-19T17:11:54Z"
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        acl_id = urllib.parse.quote(str(acl_id), safe="")
        path = f"/organizations/{organization_id}/adaptivePolicy/acls/{acl_id}"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if description is not None:
            payload["description"] = description
        if rules is not None:
            payload["rules"] = [item.model_dump(by_alias=True, exclude_none=True) for item in rules]
        if ip_version is not None:
            payload["ipVersion"] = ip_version

        return self._session.put(
            scope="organizations",
            operation_id="updateOrganizationAdaptivePolicyAcl",
            path=path,
            json=payload,
            response_schema=UpdateOrganizationAdaptivePolicyAclResponse,
        )

    def delete_organization_adaptive_policy_acl(self, *, organization_id: str, acl_id: str) -> None:
        """Deletes the specified adaptive policy ACL.

        [API documentation: deleteOrganizationAdaptivePolicyAcl](https://developer.cisco.com/meraki/api-v1/#!delete-organization-adaptive-policy-acl)

        Args:
            organization_id: Organization ID.
            acl_id: Acl ID.

        Returns:
            Successful operation.

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        acl_id = urllib.parse.quote(str(acl_id), safe="")
        path = f"/organizations/{organization_id}/adaptivePolicy/acls/{acl_id}"

        return self._session.delete(
            scope="organizations", operation_id="deleteOrganizationAdaptivePolicyAcl", path=path
        )

    def get_organization_adaptive_policy_groups(
        self, organization_id: str
    ) -> PaginatedResponse[GetOrganizationAdaptivePolicyGroupsResponseItem]:
        """List adaptive policy groups in a organization.

        [API documentation: getOrganizationAdaptivePolicyGroups](https://developer.cisco.com/meraki/api-v1/#!get-organization-adaptive-policy-groups)

        Args:
            organization_id: Organization ID.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "groupId": "1234",
                "name": "Employee Group",
                "sgt": 1000,
                "description": "Group of XYZ Corp Employees",
                "policyObjects": [
                  {
                    "id": "2345",
                    "name": "Example Policy Object"
                  }
                ],
                "isDefaultGroup": false,
                "requiredIpMappings": [],
                "createdAt": "2019-06-27T21:34:25.253480Z",
                "updatedAt": "2019-06-27T21:34:25.253480Z"
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/adaptivePolicy/groups"

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationAdaptivePolicyGroups",
            path=path,
            item_schema=GetOrganizationAdaptivePolicyGroupsResponseItem,
        )

    def create_organization_adaptive_policy_group(
        self,
        *,
        organization_id: str,
        name: str,
        sgt: int,
        description: str | None = None,
        policy_objects: list[CreateOrganizationAdaptivePolicyGroupPolicyObjectsItem] | None = None,
    ) -> CreateOrganizationAdaptivePolicyGroupResponse:
        """Creates a new adaptive policy group.

        [API documentation: createOrganizationAdaptivePolicyGroup](https://developer.cisco.com/meraki/api-v1/#!create-organization-adaptive-policy-group)

        Args:
            organization_id: Organization ID.
            name: Name of the group.
            sgt: SGT value of the group.
            description: Description of the group (default: "").
            policy_objects: The policy objects that belong to this group; traffic from addresses
                specified by these policy objects will be tagged with this group's SGT
                value if no other tagging scheme is being used (each requires one unique
                attribute) (default: []).

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "groupId": "1234",
              "name": "Employee Group",
              "sgt": 1000,
              "description": "Group of XYZ Corp Employees",
              "policyObjects": [
                {
                  "id": "2345",
                  "name": "Example Policy Object"
                }
              ],
              "isDefaultGroup": false,
              "requiredIpMappings": [],
              "createdAt": "2019-06-27T21:34:25.253480Z",
              "updatedAt": "2019-06-27T21:34:25.253480Z"
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/adaptivePolicy/groups"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if sgt is not None:
            payload["sgt"] = sgt
        if description is not None:
            payload["description"] = description
        if policy_objects is not None:
            payload["policyObjects"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in policy_objects
            ]

        return self._session.post(
            scope="organizations",
            operation_id="createOrganizationAdaptivePolicyGroup",
            path=path,
            json=payload,
            response_schema=CreateOrganizationAdaptivePolicyGroupResponse,
        )

    def get_organization_adaptive_policy_group(
        self, *, organization_id: str, id: str
    ) -> GetOrganizationAdaptivePolicyGroupResponse:
        """Returns an adaptive policy group.

        [API documentation: getOrganizationAdaptivePolicyGroup](https://developer.cisco.com/meraki/api-v1/#!get-organization-adaptive-policy-group)

        Args:
            organization_id: Organization ID.
            id: ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "groupId": "1234",
              "name": "Employee Group",
              "sgt": 1000,
              "description": "Group of XYZ Corp Employees",
              "policyObjects": [
                {
                  "id": "2345",
                  "name": "Example Policy Object"
                }
              ],
              "isDefaultGroup": false,
              "requiredIpMappings": [],
              "createdAt": "2019-06-27T21:34:25.253480Z",
              "updatedAt": "2019-06-27T21:34:25.253480Z"
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        id = urllib.parse.quote(str(id), safe="")
        path = f"/organizations/{organization_id}/adaptivePolicy/groups/{id}"

        return self._session.get(
            scope="organizations",
            operation_id="getOrganizationAdaptivePolicyGroup",
            path=path,
            response_schema=GetOrganizationAdaptivePolicyGroupResponse,
        )

    def update_organization_adaptive_policy_group(
        self,
        *,
        organization_id: str,
        id: str,
        name: str | None = None,
        sgt: int | None = None,
        description: str | None = None,
        policy_objects: list[UpdateOrganizationAdaptivePolicyGroupPolicyObjectsItem] | None = None,
    ) -> UpdateOrganizationAdaptivePolicyGroupResponse:
        """Updates an adaptive policy group.

        [API documentation: updateOrganizationAdaptivePolicyGroup](https://developer.cisco.com/meraki/api-v1/#!update-organization-adaptive-policy-group)

        Args:
            organization_id: Organization ID.
            id: ID.
            name: Name of the group.
            sgt: SGT value of the group.
            description: Description of the group.
            policy_objects: The policy objects that belong to this group; traffic from addresses
                specified by these policy objects will be tagged with this group's SGT
                value if no other tagging scheme is being used (each requires one unique
                attribute).

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "groupId": "1234",
              "name": "Employee Group",
              "sgt": 1000,
              "description": "Group of XYZ Corp Employees",
              "policyObjects": [
                {
                  "id": "2345",
                  "name": "Example Policy Object"
                }
              ],
              "isDefaultGroup": false,
              "requiredIpMappings": [],
              "createdAt": "2019-06-27T21:34:25.253480Z",
              "updatedAt": "2019-06-27T21:34:25.253480Z"
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        id = urllib.parse.quote(str(id), safe="")
        path = f"/organizations/{organization_id}/adaptivePolicy/groups/{id}"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if sgt is not None:
            payload["sgt"] = sgt
        if description is not None:
            payload["description"] = description
        if policy_objects is not None:
            payload["policyObjects"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in policy_objects
            ]

        return self._session.put(
            scope="organizations",
            operation_id="updateOrganizationAdaptivePolicyGroup",
            path=path,
            json=payload,
            response_schema=UpdateOrganizationAdaptivePolicyGroupResponse,
        )

    def delete_organization_adaptive_policy_group(self, *, organization_id: str, id: str) -> None:
        """Deletes the specified adaptive policy group and any associated policies and references.

        [API documentation: deleteOrganizationAdaptivePolicyGroup](https://developer.cisco.com/meraki/api-v1/#!delete-organization-adaptive-policy-group)

        Args:
            organization_id: Organization ID.
            id: ID.

        Returns:
            Successful operation.

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        id = urllib.parse.quote(str(id), safe="")
        path = f"/organizations/{organization_id}/adaptivePolicy/groups/{id}"

        return self._session.delete(
            scope="organizations", operation_id="deleteOrganizationAdaptivePolicyGroup", path=path
        )

    def get_organization_adaptive_policy_overview(
        self, organization_id: str
    ) -> GetOrganizationAdaptivePolicyOverviewResponse:
        """Returns adaptive policy aggregate statistics for an organization.

        [API documentation: getOrganizationAdaptivePolicyOverview](https://developer.cisco.com/meraki/api-v1/#!get-organization-adaptive-policy-overview)

        Args:
            organization_id: Organization ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "counts": {
                "groups": 10,
                "customGroups": 8,
                "customAcls": 12,
                "policies": 100,
                "denyPolicies": 30,
                "allowPolicies": 70,
                "policyObjects": 13
              },
              "limits": {
                "customGroups": 60,
                "rulesInAnAcl": 16,
                "aclsInAPolicy": 7,
                "policyObjects": 8000
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/adaptivePolicy/overview"

        return self._session.get(
            scope="organizations",
            operation_id="getOrganizationAdaptivePolicyOverview",
            path=path,
            response_schema=GetOrganizationAdaptivePolicyOverviewResponse,
        )

    def get_organization_adaptive_policy_policies(
        self, organization_id: str
    ) -> PaginatedResponse[GetOrganizationAdaptivePolicyPoliciesResponseItem]:
        """List adaptive policies in an organization.

        [API documentation: getOrganizationAdaptivePolicyPolicies](https://developer.cisco.com/meraki/api-v1/#!get-organization-adaptive-policy-policies)

        Args:
            organization_id: Organization ID.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "adaptivePolicyId": "111",
                "sourceGroup": {
                  "id": "222",
                  "name": "IoT Devices",
                  "sgt": 50
                },
                "destinationGroup": {
                  "id": "333",
                  "name": "IoT Servers",
                  "sgt": 51
                },
                "acls": [
                  {
                    "id": "444",
                    "name": "Block web"
                  }
                ],
                "lastEntryRule": "allow",
                "createdAt": "2019-06-27T21:34:25.253480Z",
                "updatedAt": "2019-06-27T21:34:25.253480Z"
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/adaptivePolicy/policies"

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationAdaptivePolicyPolicies",
            path=path,
            item_schema=GetOrganizationAdaptivePolicyPoliciesResponseItem,
        )

    def create_organization_adaptive_policy_policy(
        self,
        *,
        organization_id: str,
        source_group: CreateOrganizationAdaptivePolicyPolicySourceGroup,
        destination_group: CreateOrganizationAdaptivePolicyPolicyDestinationGroup,
        acls: list[CreateOrganizationAdaptivePolicyPolicyAclsItem] | None = None,
        last_entry_rule: CreateOrganizationAdaptivePolicyPolicyLastEntryRule | None = None,
    ) -> CreateOrganizationAdaptivePolicyPolicyResponse:
        """Add an Adaptive Policy.

        [API documentation: createOrganizationAdaptivePolicyPolicy](https://developer.cisco.com/meraki/api-v1/#!create-organization-adaptive-policy-policy)

        Args:
            organization_id: Organization ID.
            source_group: The source adaptive policy group (requires one unique attribute).
            destination_group: The destination adaptive policy group (requires one unique
                attribute).
            acls: An ordered array of adaptive policy ACLs (each requires one unique attribute) that
                apply to this policy (default: []).
            last_entry_rule: The rule to apply if there is no matching ACL (default: "default").

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "adaptivePolicyId": "111",
              "sourceGroup": {
                "id": "222",
                "name": "IoT Devices",
                "sgt": 50
              },
              "destinationGroup": {
                "id": "333",
                "name": "IoT Servers",
                "sgt": 51
              },
              "acls": [
                {
                  "id": "444",
                  "name": "Block web"
                }
              ],
              "lastEntryRule": "allow",
              "createdAt": "2019-06-27T21:34:25.253480Z",
              "updatedAt": "2019-06-27T21:34:25.253480Z"
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/adaptivePolicy/policies"

        payload: dict[str, Any] = {}
        if source_group is not None:
            payload["sourceGroup"] = source_group.model_dump(by_alias=True, exclude_none=True)
        if destination_group is not None:
            payload["destinationGroup"] = destination_group.model_dump(
                by_alias=True, exclude_none=True
            )
        if acls is not None:
            payload["acls"] = [item.model_dump(by_alias=True, exclude_none=True) for item in acls]
        if last_entry_rule is not None:
            payload["lastEntryRule"] = last_entry_rule

        return self._session.post(
            scope="organizations",
            operation_id="createOrganizationAdaptivePolicyPolicy",
            path=path,
            json=payload,
            response_schema=CreateOrganizationAdaptivePolicyPolicyResponse,
        )

    def get_organization_adaptive_policy_policy(
        self, *, organization_id: str, id: str
    ) -> GetOrganizationAdaptivePolicyPolicyResponse:
        """Return an adaptive policy.

        [API documentation: getOrganizationAdaptivePolicyPolicy](https://developer.cisco.com/meraki/api-v1/#!get-organization-adaptive-policy-policy)

        Args:
            organization_id: Organization ID.
            id: ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "adaptivePolicyId": "111",
              "sourceGroup": {
                "id": "222",
                "name": "IoT Devices",
                "sgt": 50
              },
              "destinationGroup": {
                "id": "333",
                "name": "IoT Servers",
                "sgt": 51
              },
              "acls": [
                {
                  "id": "444",
                  "name": "Block web"
                }
              ],
              "lastEntryRule": "allow",
              "createdAt": "2019-06-27T21:34:25.253480Z",
              "updatedAt": "2019-06-27T21:34:25.253480Z"
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        id = urllib.parse.quote(str(id), safe="")
        path = f"/organizations/{organization_id}/adaptivePolicy/policies/{id}"

        return self._session.get(
            scope="organizations",
            operation_id="getOrganizationAdaptivePolicyPolicy",
            path=path,
            response_schema=GetOrganizationAdaptivePolicyPolicyResponse,
        )

    def update_organization_adaptive_policy_policy(
        self,
        *,
        organization_id: str,
        id: str,
        source_group: UpdateOrganizationAdaptivePolicyPolicySourceGroup | None = None,
        destination_group: UpdateOrganizationAdaptivePolicyPolicyDestinationGroup | None = None,
        acls: list[UpdateOrganizationAdaptivePolicyPolicyAclsItem] | None = None,
        last_entry_rule: UpdateOrganizationAdaptivePolicyPolicyLastEntryRule | None = None,
    ) -> UpdateOrganizationAdaptivePolicyPolicyResponse:
        """Update an Adaptive Policy.

        [API documentation: updateOrganizationAdaptivePolicyPolicy](https://developer.cisco.com/meraki/api-v1/#!update-organization-adaptive-policy-policy)

        Args:
            organization_id: Organization ID.
            id: ID.
            source_group: The source adaptive policy group (requires one unique attribute).
            destination_group: The destination adaptive policy group (requires one unique
                attribute).
            acls: An ordered array of adaptive policy ACLs (each requires one unique attribute) that
                apply to this policy.
            last_entry_rule: The rule to apply if there is no matching ACL.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "adaptivePolicyId": "111",
              "sourceGroup": {
                "id": "222",
                "name": "IoT Devices",
                "sgt": 50
              },
              "destinationGroup": {
                "id": "333",
                "name": "IoT Servers",
                "sgt": 51
              },
              "acls": [
                {
                  "id": "444",
                  "name": "Block web"
                }
              ],
              "lastEntryRule": "allow",
              "createdAt": "2019-06-27T21:34:25.253480Z",
              "updatedAt": "2019-06-27T21:34:25.253480Z"
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        id = urllib.parse.quote(str(id), safe="")
        path = f"/organizations/{organization_id}/adaptivePolicy/policies/{id}"

        payload: dict[str, Any] = {}
        if source_group is not None:
            payload["sourceGroup"] = source_group.model_dump(by_alias=True, exclude_none=True)
        if destination_group is not None:
            payload["destinationGroup"] = destination_group.model_dump(
                by_alias=True, exclude_none=True
            )
        if acls is not None:
            payload["acls"] = [item.model_dump(by_alias=True, exclude_none=True) for item in acls]
        if last_entry_rule is not None:
            payload["lastEntryRule"] = last_entry_rule

        return self._session.put(
            scope="organizations",
            operation_id="updateOrganizationAdaptivePolicyPolicy",
            path=path,
            json=payload,
            response_schema=UpdateOrganizationAdaptivePolicyPolicyResponse,
        )

    def delete_organization_adaptive_policy_policy(self, *, organization_id: str, id: str) -> None:
        """Delete an Adaptive Policy.

        [API documentation: deleteOrganizationAdaptivePolicyPolicy](https://developer.cisco.com/meraki/api-v1/#!delete-organization-adaptive-policy-policy)

        Args:
            organization_id: Organization ID.
            id: ID.

        Returns:
            Successful operation.

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        id = urllib.parse.quote(str(id), safe="")
        path = f"/organizations/{organization_id}/adaptivePolicy/policies/{id}"

        return self._session.delete(
            scope="organizations", operation_id="deleteOrganizationAdaptivePolicyPolicy", path=path
        )

    def get_organization_adaptive_policy_settings(
        self, organization_id: str
    ) -> GetOrganizationAdaptivePolicySettingsResponse:
        """Returns global adaptive policy settings in an organization.

        [API documentation: getOrganizationAdaptivePolicySettings](https://developer.cisco.com/meraki/api-v1/#!get-organization-adaptive-policy-settings)

        Args:
            organization_id: Organization ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "enabledNetworks": [
                "L_11111111",
                "L_22222222",
                "N_33333333",
                "L_44444444"
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/adaptivePolicy/settings"

        return self._session.get(
            scope="organizations",
            operation_id="getOrganizationAdaptivePolicySettings",
            path=path,
            response_schema=GetOrganizationAdaptivePolicySettingsResponse,
        )

    def update_organization_adaptive_policy_settings(
        self, organization_id: str, *, enabled_networks: list[str] | None = None
    ) -> UpdateOrganizationAdaptivePolicySettingsResponse:
        """Update global adaptive policy settings.

        [API documentation: updateOrganizationAdaptivePolicySettings](https://developer.cisco.com/meraki/api-v1/#!update-organization-adaptive-policy-settings)

        Args:
            organization_id: Organization ID.
            enabled_networks: List of network IDs with adaptive policy enabled.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "enabledNetworks": [
                "L_11111111",
                "L_22222222",
                "N_33333333",
                "L_44444444"
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/adaptivePolicy/settings"

        payload: dict[str, Any] = {}
        if enabled_networks is not None:
            payload["enabledNetworks"] = enabled_networks

        return self._session.put(
            scope="organizations",
            operation_id="updateOrganizationAdaptivePolicySettings",
            path=path,
            json=payload,
            response_schema=UpdateOrganizationAdaptivePolicySettingsResponse,
        )

    def get_organization_admins(
        self, organization_id: str, *, network_ids: list[str] | None = None
    ) -> PaginatedResponse[GetOrganizationAdminsResponseItem]:
        """List the dashboard administrators in this organization.

        [API documentation: getOrganizationAdmins](https://developer.cisco.com/meraki/api-v1/#!get-organization-admins)

        Args:
            organization_id: Organization ID.
            network_ids: Optional parameter to filter the result set by the included set of network
                IDs.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "id": "212406",
                "name": "Miles Meraki",
                "email": "miles@meraki.com",
                "orgAccess": "none",
                "accountStatus": "ok",
                "twoFactorAuthEnabled": false,
                "hasApiKey": true,
                "lastActive": "2018-02-11T00:00:00Z",
                "tags": [
                  {
                    "tag": "west",
                    "access": "read-only"
                  }
                ],
                "networks": [
                  {
                    "id": "N_24329156",
                    "access": "full"
                  }
                ],
                "authenticationMethod": "Email"
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/admins"

        params: dict[str, Any] = {}
        if network_ids is not None:
            params["networkIds[]"] = network_ids

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationAdmins",
            path=path,
            params=params,
            item_schema=GetOrganizationAdminsResponseItem,
        )

    def create_organization_admin(
        self,
        *,
        organization_id: str,
        email: str,
        name: str,
        org_access: CreateOrganizationAdminOrgAccess,
        tags: list[CreateOrganizationAdminTagsItem] | None = None,
        networks: list[CreateOrganizationAdminNetworksItem] | None = None,
        authentication_method: CreateOrganizationAdminAuthenticationMethod | None = None,
    ) -> CreateOrganizationAdminResponse:
        """Create a new dashboard administrator.

        [API documentation: createOrganizationAdmin](https://developer.cisco.com/meraki/api-v1/#!create-organization-admin)

        Args:
            organization_id: Organization ID.
            email: The email of the dashboard administrator. This attribute can not be updated.
            name: The name of the dashboard administrator.
            org_access: The privilege of the dashboard administrator on the organization. Can be one
                of 'full', 'read-only', 'enterprise' or 'none'.
            tags: The list of tags that the dashboard administrator has privileges on.
            networks: The list of networks that the dashboard administrator has privileges on.
            authentication_method: No longer used as of Cisco SecureX end-of-life. Can be one of
                'Email'. The default is Email authentication.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "212406",
              "name": "Miles Meraki",
              "email": "miles@meraki.com",
              "orgAccess": "none",
              "accountStatus": "ok",
              "twoFactorAuthEnabled": false,
              "hasApiKey": true,
              "lastActive": "2018-02-11T00:00:00Z",
              "tags": [
                {
                  "tag": "west",
                  "access": "read-only"
                }
              ],
              "networks": [
                {
                  "id": "N_24329156",
                  "access": "full"
                }
              ],
              "authenticationMethod": "Email"
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/admins"

        payload: dict[str, Any] = {}
        if email is not None:
            payload["email"] = email
        if name is not None:
            payload["name"] = name
        if org_access is not None:
            payload["orgAccess"] = org_access
        if tags is not None:
            payload["tags"] = [item.model_dump(by_alias=True, exclude_none=True) for item in tags]
        if networks is not None:
            payload["networks"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in networks
            ]
        if authentication_method is not None:
            payload["authenticationMethod"] = authentication_method

        return self._session.post(
            scope="organizations",
            operation_id="createOrganizationAdmin",
            path=path,
            json=payload,
            response_schema=CreateOrganizationAdminResponse,
        )

    def update_organization_admin(
        self,
        *,
        organization_id: str,
        admin_id: str,
        name: str | None = None,
        org_access: UpdateOrganizationAdminOrgAccess | None = None,
        tags: list[UpdateOrganizationAdminTagsItem] | None = None,
        networks: list[UpdateOrganizationAdminNetworksItem] | None = None,
    ) -> UpdateOrganizationAdminResponse:
        """Update an administrator.

        [API documentation: updateOrganizationAdmin](https://developer.cisco.com/meraki/api-v1/#!update-organization-admin)

        Args:
            organization_id: Organization ID.
            admin_id: Admin ID.
            name: The name of the dashboard administrator.
            org_access: The privilege of the dashboard administrator on the organization. Can be one
                of 'full', 'read-only', 'enterprise' or 'none'.
            tags: The list of tags that the dashboard administrator has privileges on.
            networks: The list of networks that the dashboard administrator has privileges on.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "212406",
              "name": "Miles Meraki",
              "email": "miles@meraki.com",
              "orgAccess": "none",
              "accountStatus": "ok",
              "twoFactorAuthEnabled": false,
              "hasApiKey": true,
              "lastActive": "2018-02-11T00:00:00Z",
              "tags": [
                {
                  "tag": "west",
                  "access": "read-only"
                }
              ],
              "networks": [
                {
                  "id": "N_24329156",
                  "access": "full"
                }
              ],
              "authenticationMethod": "Email"
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        admin_id = urllib.parse.quote(str(admin_id), safe="")
        path = f"/organizations/{organization_id}/admins/{admin_id}"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if org_access is not None:
            payload["orgAccess"] = org_access
        if tags is not None:
            payload["tags"] = [item.model_dump(by_alias=True, exclude_none=True) for item in tags]
        if networks is not None:
            payload["networks"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in networks
            ]

        return self._session.put(
            scope="organizations",
            operation_id="updateOrganizationAdmin",
            path=path,
            json=payload,
            response_schema=UpdateOrganizationAdminResponse,
        )

    def delete_organization_admin(self, *, organization_id: str, admin_id: str) -> None:
        """Revoke all access for a dashboard administrator within this organization.

        [API documentation: deleteOrganizationAdmin](https://developer.cisco.com/meraki/api-v1/#!delete-organization-admin)

        Args:
            organization_id: Organization ID.
            admin_id: Admin ID.

        Returns:
            Successful operation.

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        admin_id = urllib.parse.quote(str(admin_id), safe="")
        path = f"/organizations/{organization_id}/admins/{admin_id}"

        return self._session.delete(
            scope="organizations", operation_id="deleteOrganizationAdmin", path=path
        )

    def get_organization_alerts_profiles(
        self, organization_id: str
    ) -> PaginatedResponse[GetOrganizationAlertsProfilesResponseItem]:
        """List all organization-wide alert configurations.

        [API documentation: getOrganizationAlertsProfiles](https://developer.cisco.com/meraki/api-v1/#!get-organization-alerts-profiles)

        Args:
            organization_id: Organization ID.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "id": "1284392014819",
                "type": "wanUtilization",
                "enabled": true,
                "alertCondition": {
                  "duration": 60,
                  "window": 600,
                  "bit_rate_bps": 10000,
                  "interface": "wan1"
                },
                "recipients": {
                  "emails": [
                    "admin@example.org"
                  ],
                  "httpServerIds": [
                    "aHR0cHM6Ly93d3cuZXhhbXBsZS5jb20vcGF0aA=="
                  ]
                },
                "networkTags": [
                  "tag1",
                  "tag2"
                ],
                "description": "WAN 1 high utilization"
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/alerts/profiles"

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationAlertsProfiles",
            path=path,
            item_schema=GetOrganizationAlertsProfilesResponseItem,
        )

    def create_organization_alerts_profile(
        self,
        *,
        organization_id: str,
        type_: CreateOrganizationAlertsProfileType,
        alert_condition: CreateOrganizationAlertsProfileAlertCondition,
        recipients: CreateOrganizationAlertsProfileRecipients,
        network_tags: list[str],
        description: str | None = None,
    ) -> CreateOrganizationAlertsProfileResponse:
        """Create an organization-wide alert configuration.

        [API documentation: createOrganizationAlertsProfile](https://developer.cisco.com/meraki/api-v1/#!create-organization-alerts-profile)

        Args:
            organization_id: Organization ID.
            type_: The alert type.
            alert_condition: The conditions that determine if the alert triggers.
            recipients: List of recipients that will recieve the alert.
            network_tags: Networks with these tags will be monitored for the alert.
            description: User supplied description of the alert.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "1284392014819",
              "type": "wanUtilization",
              "enabled": true,
              "alertCondition": {
                "duration": 60,
                "window": 600,
                "bit_rate_bps": 10000,
                "interface": "wan1"
              },
              "recipients": {
                "emails": [
                  "admin@example.org"
                ],
                "httpServerIds": [
                  "aHR0cHM6Ly93d3cuZXhhbXBsZS5jb20vcGF0aA=="
                ]
              },
              "networkTags": [
                "tag1",
                "tag2"
              ],
              "description": "WAN 1 high utilization"
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/alerts/profiles"

        payload: dict[str, Any] = {}
        if type_ is not None:
            payload["type"] = type_
        if alert_condition is not None:
            payload["alertCondition"] = alert_condition.model_dump(by_alias=True, exclude_none=True)
        if recipients is not None:
            payload["recipients"] = recipients.model_dump(by_alias=True, exclude_none=True)
        if network_tags is not None:
            payload["networkTags"] = network_tags
        if description is not None:
            payload["description"] = description

        return self._session.post(
            scope="organizations",
            operation_id="createOrganizationAlertsProfile",
            path=path,
            json=payload,
            response_schema=CreateOrganizationAlertsProfileResponse,
        )

    def update_organization_alerts_profile(
        self,
        *,
        organization_id: str,
        alert_config_id: str,
        enabled: bool | None = None,
        type_: UpdateOrganizationAlertsProfileType | None = None,
        alert_condition: UpdateOrganizationAlertsProfileAlertCondition | None = None,
        recipients: UpdateOrganizationAlertsProfileRecipients | None = None,
        network_tags: list[str] | None = None,
        description: str | None = None,
    ) -> UpdateOrganizationAlertsProfileResponse:
        """Update an organization-wide alert config.

        [API documentation: updateOrganizationAlertsProfile](https://developer.cisco.com/meraki/api-v1/#!update-organization-alerts-profile)

        Args:
            organization_id: Organization ID.
            alert_config_id: Alert config ID.
            enabled: Is the alert config enabled.
            type_: The alert type.
            alert_condition: The conditions that determine if the alert triggers.
            recipients: List of recipients that will recieve the alert.
            network_tags: Networks with these tags will be monitored for the alert.
            description: User supplied description of the alert.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "1284392014819",
              "type": "wanUtilization",
              "enabled": true,
              "alertCondition": {
                "duration": 60,
                "window": 600,
                "bit_rate_bps": 10000,
                "interface": "wan1"
              },
              "recipients": {
                "emails": [
                  "admin@example.org"
                ],
                "httpServerIds": [
                  "aHR0cHM6Ly93d3cuZXhhbXBsZS5jb20vcGF0aA=="
                ]
              },
              "networkTags": [
                "tag1",
                "tag2"
              ],
              "description": "WAN 1 high utilization"
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        alert_config_id = urllib.parse.quote(str(alert_config_id), safe="")
        path = f"/organizations/{organization_id}/alerts/profiles/{alert_config_id}"

        payload: dict[str, Any] = {}
        if enabled is not None:
            payload["enabled"] = enabled
        if type_ is not None:
            payload["type"] = type_
        if alert_condition is not None:
            payload["alertCondition"] = alert_condition.model_dump(by_alias=True, exclude_none=True)
        if recipients is not None:
            payload["recipients"] = recipients.model_dump(by_alias=True, exclude_none=True)
        if network_tags is not None:
            payload["networkTags"] = network_tags
        if description is not None:
            payload["description"] = description

        return self._session.put(
            scope="organizations",
            operation_id="updateOrganizationAlertsProfile",
            path=path,
            json=payload,
            response_schema=UpdateOrganizationAlertsProfileResponse,
        )

    def delete_organization_alerts_profile(
        self, *, organization_id: str, alert_config_id: str
    ) -> None:
        """Removes an organization-wide alert config.

        [API documentation: deleteOrganizationAlertsProfile](https://developer.cisco.com/meraki/api-v1/#!delete-organization-alerts-profile)

        Args:
            organization_id: Organization ID.
            alert_config_id: Alert config ID.

        Returns:
            Successful operation.

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        alert_config_id = urllib.parse.quote(str(alert_config_id), safe="")
        path = f"/organizations/{organization_id}/alerts/profiles/{alert_config_id}"

        return self._session.delete(
            scope="organizations", operation_id="deleteOrganizationAlertsProfile", path=path
        )

    def get_organization_api_requests(
        self,
        organization_id: str,
        *,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        admin_id: str | None = None,
        path: str | None = None,
        method: GetOrganizationApiRequestsMethod | None = None,
        response_code: int | None = None,
        source_ip: str | None = None,
        user_agent: str | None = None,
        version: GetOrganizationApiRequestsVersion | None = None,
        operation_ids: list[str] | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetOrganizationApiRequestsResponseItem]:
        """List the API requests made by an organization.

        [API documentation: getOrganizationApiRequests](https://developer.cisco.com/meraki/api-v1/#!get-organization-api-requests)

        Args:
            organization_id: Organization ID.
            t0: The beginning of the timespan for the data. The maximum lookback period is 31 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 31 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 31 days. The default is 31 days.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 50.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            admin_id: Filter the results by the ID of the admin who made the API requests.
            path: Filter the results by the path of the API requests.
            method: Filter the results by the method of the API requests (must be 'GET', 'PUT',
                'POST' or 'DELETE').
            response_code: Filter the results by the response code of the API requests.
            source_ip: Filter the results by the IP address of the originating API request.
            user_agent: Filter the results by the user agent string of the API request.
            version: Filter the results by the API version of the API request.
            operation_ids: Filter the results by one or more operation IDs for the API request.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "adminId": "212406",
                "method": "GET",
                "host": "server.example.com",
                "path": "/api/v1/organizations/12345/apiRequests",
                "queryString": "timespan=604800",
                "userAgent": "PostmanRuntime/7.6.0",
                "ts": "2018-02-11T00:00:00.090210Z",
                "responseCode": 200,
                "sourceIp": "123.123.123.1",
                "version": 1,
                "operationId": "getOrganizationApiRequests",
                "client": {
                  "id": "0hoXjtjX6C-Nk4Nr6kEbCJJFRmIgycaG1HBE572hlIc",
                  "type": "oauth"
                }
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/apiRequests"

        params: dict[str, Any] = {}
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if admin_id is not None:
            params["adminId"] = admin_id
        if path is not None:
            params["path"] = path
        if method is not None:
            params["method"] = method
        if response_code is not None:
            params["responseCode"] = response_code
        if source_ip is not None:
            params["sourceIp"] = source_ip
        if user_agent is not None:
            params["userAgent"] = user_agent
        if version is not None:
            params["version"] = version
        if operation_ids is not None:
            params["operationIds[]"] = operation_ids

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationApiRequests",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationApiRequestsResponseItem,
        )

    def get_organization_api_requests_overview(
        self,
        organization_id: str,
        *,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
    ) -> GetOrganizationApiRequestsOverviewResponse:
        """Return an aggregated overview of API requests data.

        [API documentation: getOrganizationApiRequestsOverview](https://developer.cisco.com/meraki/api-v1/#!get-organization-api-requests-overview)

        Args:
            organization_id: Organization ID.
            t0: The beginning of the timespan for the data. The maximum lookback period is 31 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 31 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 31 days. The default is 31 days.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "responseCodeCounts": {
                "200": 500,
                "201": 100,
                "202": 20,
                "203": 50,
                "204": 75,
                "205": 0,
                "206": 0,
                "207": 0,
                "208": 0,
                "226": 0,
                "300": 0,
                "301": 60,
                "302": 0,
                "303": 0,
                "304": 0,
                "305": 0,
                "306": 0,
                "307": 0,
                "308": 0,
                "400": 20,
                "401": 0,
                "402": 32,
                "403": 0,
                "404": 55,
                "405": 0,
                "406": 0,
                "407": 0,
                "408": 0,
                "409": 0,
                "410": 0,
                "411": 0,
                "412": 0,
                "413": 0,
                "414": 0,
                "415": 0,
                "416": 0,
                "417": 0,
                "421": 0,
                "422": 0,
                "423": 0,
                "424": 0,
                "425": 0,
                "426": 0,
                "428": 0,
                "429": 0,
                "431": 0,
                "451": 0,
                "500": 3
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/apiRequests/overview"

        params: dict[str, Any] = {}
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan

        return self._session.get(
            scope="organizations",
            operation_id="getOrganizationApiRequestsOverview",
            path=path,
            params=params,
            response_schema=GetOrganizationApiRequestsOverviewResponse,
        )

    def get_organization_api_requests_overview_response_codes_by_interval(
        self,
        organization_id: str,
        *,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        interval: int | None = None,
        version: GetOrganizationApiRequestsOverviewResponseCodesByIntervalVersion | None = None,
        operation_ids: list[str] | None = None,
        source_ips: list[str] | None = None,
        admin_ids: list[str] | None = None,
        user_agent: str | None = None,
    ) -> PaginatedResponse[GetOrganizationApiRequestsOverviewResponseCodesByIntervalResponseItem]:
        """Tracks organizations' API requests by response code across a given time period.

        [API documentation: getOrganizationApiRequestsOverviewResponseCodesByInterval](https://developer.cisco.com/meraki/api-v1/#!get-organization-api-requests-overview-response-codes-by-interval)

        Args:
            organization_id: Organization ID.
            t0: The beginning of the timespan for the data. The maximum lookback period is 31 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 31 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 31 days. The default is 31 days. If
                interval is provided, the timespan will be autocalculated.
            interval: The time interval in seconds for returned data. The valid intervals are: 120,
                3600, 14400, 21600. The default is 21600. Interval is calculated if time
                params are provided.
            version: Filter by API version of the endpoint. Allowable values are: [0, 1].
            operation_ids: Filter by operation ID of the endpoint.
            source_ips: Filter by source IP that made the API request.
            admin_ids: Filter by admin ID of user that made the API request.
            user_agent: Filter by user agent string for API request. This will filter by a complete
                or partial match.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "startTs": "2018-02-11T00:00:00Z",
                "endTs": "2018-05-12T00:00:00Z",
                "counts": [
                  {
                    "code": 200,
                    "count": 198938
                  }
                ]
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/apiRequests/overview/responseCodes/byInterval"

        params: dict[str, Any] = {}
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan
        if interval is not None:
            params["interval"] = interval
        if version is not None:
            params["version"] = version
        if operation_ids is not None:
            params["operationIds[]"] = operation_ids
        if source_ips is not None:
            params["sourceIps[]"] = source_ips
        if admin_ids is not None:
            params["adminIds[]"] = admin_ids
        if user_agent is not None:
            params["userAgent"] = user_agent

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationApiRequestsOverviewResponseCodesByInterval",
            path=path,
            params=params,
            item_schema=GetOrganizationApiRequestsOverviewResponseCodesByIntervalResponseItem,
        )

    def get_organization_assurance_alerts(
        self,
        organization_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        sort_order: GetOrganizationAssuranceAlertsSortOrder | None = None,
        network_id: str | None = None,
        severity: str | None = None,
        types: GetOrganizationAssuranceAlertsTypes | None = None,
        ts_start: str | None = None,
        ts_end: str | None = None,
        category: GetOrganizationAssuranceAlertsCategory | None = None,
        sort_by: GetOrganizationAssuranceAlertsSortBy | None = None,
        serials: list[str] | None = None,
        device_types: GetOrganizationAssuranceAlertsDeviceTypes | None = None,
        device_tags: list[str] | None = None,
        active: bool | None = None,
        dismissed: bool | None = None,
        resolved: bool | None = None,
        suppress_alerts_for_offline_nodes: bool | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetOrganizationAssuranceAlertsResponseItem]:
        """Return all health alerts for an organization.

        [API documentation: getOrganizationAssuranceAlerts](https://developer.cisco.com/meraki/api-v1/#!get-organization-assurance-alerts)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 4 - 300. Default
                is 30.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            sort_order: Sorted order of entries. Order options are 'ascending' and 'descending'.
                Default is 'ascending'.
            network_id: Optional parameter to filter alerts by network ids.
            severity: Optional parameter to filter by severity type.
            types: Optional parameter to filter by alert type.
            ts_start: Optional parameter to filter by starting timestamp.
            ts_end: Optional parameter to filter by end timestamp.
            category: Optional parameter to filter by category.
            sort_by: Optional parameter to set column to sort by.
            serials: Optional parameter to filter by primary device serial.
            device_types: Optional parameter to filter by device types.
            device_tags: Optional parameter to filter by device tags.
            active: Optional parameter to filter by active alerts defaults to true.
            dismissed: Optional parameter to filter by dismissed alerts defaults to false.
            resolved: Optional parameter to filter by resolved alerts defaults to false.
            suppress_alerts_for_offline_nodes: When set to true the api will only return
                connectivity alerts for a given device if that device is in an offline
                state. This only applies to devices. This is ignored when resolved is
                true. Example: If a Switch has a VLan Mismatch and is Unreachable. only
                the Unreachable alert will be returned. Defaults to false.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "id": "1234",
                "categoryType": "connectivity",
                "network": {
                  "name": "Network 2",
                  "id": "L_1020981"
                },
                "startedAt": "2022-04-01T15:48:57Z",
                "resolvedAt": "2022-04-02T15:48:57Z",
                "dismissedAt": "2022-04-02T15:48:57Z",
                "deviceType": "MS",
                "type": "crc_errors_error",
                "title": "CRC errors detected",
                "description": "Very high proportion of CRC errors on port id",
                "severity": "warning",
                "scope": {
                  "devices": [
                    {
                      "url": "https://n237.meraki.com/MS-PM-First-Floo/n/_5kUKaTd/manage/nodes/new_list/7911238",
                      "name": "Device 1",
                      "order": 0,
                      "productType": "switch",
                      "serial": "Q2QP-5VYM-YM8H",
                      "mac": "aa:bb:cd:dd",
                      "imei": "353593090031649",
                      "lldp": {
                        "port": "33"
                      }
                    }
                  ]
                }
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/assurance/alerts"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if sort_order is not None:
            params["sortOrder"] = sort_order
        if network_id is not None:
            params["networkId"] = network_id
        if severity is not None:
            params["severity"] = severity
        if types is not None:
            params["types[]"] = types
        if ts_start is not None:
            params["tsStart"] = ts_start
        if ts_end is not None:
            params["tsEnd"] = ts_end
        if category is not None:
            params["category"] = category
        if sort_by is not None:
            params["sortBy"] = sort_by
        if serials is not None:
            params["serials[]"] = serials
        if device_types is not None:
            params["deviceTypes[]"] = device_types
        if device_tags is not None:
            params["deviceTags[]"] = device_tags
        if active is not None:
            params["active"] = active
        if dismissed is not None:
            params["dismissed"] = dismissed
        if resolved is not None:
            params["resolved"] = resolved
        if suppress_alerts_for_offline_nodes is not None:
            params["suppressAlertsForOfflineNodes"] = suppress_alerts_for_offline_nodes

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationAssuranceAlerts",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationAssuranceAlertsResponseItem,
        )

    def dismiss_organization_assurance_alerts(
        self, *, organization_id: str, alert_ids: list[str]
    ) -> None:
        """Dismiss health alerts.

        [API documentation: dismissOrganizationAssuranceAlerts](https://developer.cisco.com/meraki/api-v1/#!dismiss-organization-assurance-alerts)

        Args:
            organization_id: Organization ID.
            alert_ids: Array of alert IDs to dismiss.

        Returns:
            Successful operation.

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/assurance/alerts/dismiss"

        payload: dict[str, Any] = {}
        if alert_ids is not None:
            payload["alertIds"] = alert_ids

        return self._session.post(
            scope="organizations",
            operation_id="dismissOrganizationAssuranceAlerts",
            path=path,
            json=payload,
        )

    def get_organization_assurance_alerts_overview(
        self,
        organization_id: str,
        *,
        network_id: str | None = None,
        severity: str | None = None,
        types: GetOrganizationAssuranceAlertsOverviewTypes | None = None,
        ts_start: str | None = None,
        ts_end: str | None = None,
        category: GetOrganizationAssuranceAlertsOverviewCategory | None = None,
        serials: list[str] | None = None,
        device_types: GetOrganizationAssuranceAlertsOverviewDeviceTypes | None = None,
        device_tags: list[str] | None = None,
        active: bool | None = None,
        dismissed: bool | None = None,
        resolved: bool | None = None,
        suppress_alerts_for_offline_nodes: bool | None = None,
    ) -> GetOrganizationAssuranceAlertsOverviewResponse:
        """Return overview of active health alerts for an organization.

        [API documentation: getOrganizationAssuranceAlertsOverview](https://developer.cisco.com/meraki/api-v1/#!get-organization-assurance-alerts-overview)

        Args:
            organization_id: Organization ID.
            network_id: Optional parameter to filter alerts overview by network ids.
            severity: Optional parameter to filter alerts overview by severity type.
            types: Optional parameter to filter by alert type.
            ts_start: Optional parameter to filter by starting timestamp.
            ts_end: Optional parameter to filter by end timestamp.
            category: Optional parameter to filter by category.
            serials: Optional parameter to filter by primary device serial.
            device_types: Optional parameter to filter by device types.
            device_tags: Optional parameter to filter by device tags.
            active: Optional parameter to filter by active alerts defaults to true.
            dismissed: Optional parameter to filter by dismissed alerts defaults to false.
            resolved: Optional parameter to filter by resolved alerts defaults to false.
            suppress_alerts_for_offline_nodes: When set to true the api will only return
                connectivity alerts for a given device if that device is in an offline
                state. This only applies to devices. This is ignored when resolved is
                true. Example: If a Switch has a VLan Mismatch and is Unreachable. only
                the Unreachable alert will be returned. Defaults to false.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "counts": {
                "total": 14,
                "bySeverity": [
                  {
                    "type": "critical",
                    "count": 1
                  }
                ]
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/assurance/alerts/overview"

        params: dict[str, Any] = {}
        if network_id is not None:
            params["networkId"] = network_id
        if severity is not None:
            params["severity"] = severity
        if types is not None:
            params["types[]"] = types
        if ts_start is not None:
            params["tsStart"] = ts_start
        if ts_end is not None:
            params["tsEnd"] = ts_end
        if category is not None:
            params["category"] = category
        if serials is not None:
            params["serials[]"] = serials
        if device_types is not None:
            params["deviceTypes[]"] = device_types
        if device_tags is not None:
            params["deviceTags[]"] = device_tags
        if active is not None:
            params["active"] = active
        if dismissed is not None:
            params["dismissed"] = dismissed
        if resolved is not None:
            params["resolved"] = resolved
        if suppress_alerts_for_offline_nodes is not None:
            params["suppressAlertsForOfflineNodes"] = suppress_alerts_for_offline_nodes

        return self._session.get(
            scope="organizations",
            operation_id="getOrganizationAssuranceAlertsOverview",
            path=path,
            params=params,
            response_schema=GetOrganizationAssuranceAlertsOverviewResponse,
        )

    def get_organization_assurance_alerts_overview_by_network(
        self,
        organization_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        sort_order: GetOrganizationAssuranceAlertsOverviewByNetworkSortOrder | None = None,
        network_id: str | None = None,
        severity: str | None = None,
        types: GetOrganizationAssuranceAlertsOverviewByNetworkTypes | None = None,
        ts_start: str | None = None,
        ts_end: str | None = None,
        category: GetOrganizationAssuranceAlertsOverviewByNetworkCategory | None = None,
        serials: list[str] | None = None,
        device_types: GetOrganizationAssuranceAlertsOverviewByNetworkDeviceTypes | None = None,
        device_tags: list[str] | None = None,
        active: bool | None = None,
        dismissed: bool | None = None,
        resolved: bool | None = None,
        suppress_alerts_for_offline_nodes: bool | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetOrganizationAssuranceAlertsOverviewByNetworkResponseItemsItem]:
        """Return a Summary of Alerts grouped by network and severity.

        [API documentation: getOrganizationAssuranceAlertsOverviewByNetwork](https://developer.cisco.com/meraki/api-v1/#!get-organization-assurance-alerts-overview-by-network)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            sort_order: Sorted order of entries. Order options are 'ascending' and 'descending'.
                Default is 'ascending'.
            network_id: Optional parameter to filter alerts overview by network id.
            severity: Optional parameter to filter alerts overview by severity type.
            types: Optional parameter to filter by alert type.
            ts_start: Optional parameter to filter by starting timestamp.
            ts_end: Optional parameter to filter by end timestamp.
            category: Optional parameter to filter by category.
            serials: Optional parameter to filter by primary device serial.
            device_types: Optional parameter to filter by device types.
            device_tags: Optional parameter to filter by device tags.
            active: Optional parameter to filter by active alerts defaults to true.
            dismissed: Optional parameter to filter by dismissed alerts defaults to false.
            resolved: Optional parameter to filter by resolved alerts defaults to false.
            suppress_alerts_for_offline_nodes: When set to true the api will only return
                connectivity alerts for a given device if that device is in an offline
                state. This only applies to devices. This is ignored when resolved is
                true. Example: If a Switch has a VLan Mismatch and is Unreachable. only
                the Unreachable alert will be returned. Defaults to false.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            {
              "items": [
                {
                  "networkId": "L_30618",
                  "networkName": "s01797.us",
                  "alertCount": 3,
                  "severityCounts": [
                    {
                      "type": "warning",
                      "count": 3
                    }
                  ]
                }
              ],
              "meta": {
                "counts": {
                  "items": 2
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/assurance/alerts/overview/byNetwork"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if sort_order is not None:
            params["sortOrder"] = sort_order
        if network_id is not None:
            params["networkId"] = network_id
        if severity is not None:
            params["severity"] = severity
        if types is not None:
            params["types[]"] = types
        if ts_start is not None:
            params["tsStart"] = ts_start
        if ts_end is not None:
            params["tsEnd"] = ts_end
        if category is not None:
            params["category"] = category
        if serials is not None:
            params["serials[]"] = serials
        if device_types is not None:
            params["deviceTypes[]"] = device_types
        if device_tags is not None:
            params["deviceTags[]"] = device_tags
        if active is not None:
            params["active"] = active
        if dismissed is not None:
            params["dismissed"] = dismissed
        if resolved is not None:
            params["resolved"] = resolved
        if suppress_alerts_for_offline_nodes is not None:
            params["suppressAlertsForOfflineNodes"] = suppress_alerts_for_offline_nodes

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationAssuranceAlertsOverviewByNetwork",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationAssuranceAlertsOverviewByNetworkResponseItemsItem,
        )

    def get_organization_assurance_alerts_overview_by_type(
        self,
        organization_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        sort_order: GetOrganizationAssuranceAlertsOverviewByTypeSortOrder | None = None,
        network_id: str | None = None,
        severity: str | None = None,
        types: GetOrganizationAssuranceAlertsOverviewByTypeTypes | None = None,
        ts_start: str | None = None,
        ts_end: str | None = None,
        category: GetOrganizationAssuranceAlertsOverviewByTypeCategory | None = None,
        sort_by: GetOrganizationAssuranceAlertsOverviewByTypeSortBy | None = None,
        serials: list[str] | None = None,
        device_types: GetOrganizationAssuranceAlertsOverviewByTypeDeviceTypes | None = None,
        device_tags: list[str] | None = None,
        active: bool | None = None,
        dismissed: bool | None = None,
        resolved: bool | None = None,
        suppress_alerts_for_offline_nodes: bool | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetOrganizationAssuranceAlertsOverviewByTypeResponseItemsItem]:
        """Return a Summary of Alerts grouped by type and severity.

        [API documentation: getOrganizationAssuranceAlertsOverviewByType](https://developer.cisco.com/meraki/api-v1/#!get-organization-assurance-alerts-overview-by-type)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            sort_order: Sorted order of entries. Order options are 'ascending' and 'descending'.
                Default is 'ascending'.
            network_id: Optional parameter to filter alerts overview by network ids.
            severity: Optional parameter to filter alerts overview by severity type.
            types: Optional parameter to filter by alert type.
            ts_start: Optional parameter to filter by starting timestamp.
            ts_end: Optional parameter to filter by end timestamp.
            category: Optional parameter to filter by category.
            sort_by: Optional parameter to set column to sort by.
            serials: Optional parameter to filter by primary device serial.
            device_types: Optional parameter to filter by device types.
            device_tags: Optional parameter to filter by device tags.
            active: Optional parameter to filter by active alerts defaults to true.
            dismissed: Optional parameter to filter by dismissed alerts defaults to false.
            resolved: Optional parameter to filter by resolved alerts defaults to false.
            suppress_alerts_for_offline_nodes: When set to true the api will only return
                connectivity alerts for a given device if that device is in an offline
                state. This only applies to devices. This is ignored when resolved is
                true. Example: If a Switch has a VLan Mismatch and is Unreachable. only
                the Unreachable alert will be returned. Defaults to false.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            {
              "items": [
                {
                  "type": "vlan_mismatch",
                  "lastResolvedAt": "2022-04-01T16:48:57Z",
                  "count": 3
                }
              ],
              "meta": {
                "counts": {
                  "items": 4
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/assurance/alerts/overview/byType"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if sort_order is not None:
            params["sortOrder"] = sort_order
        if network_id is not None:
            params["networkId"] = network_id
        if severity is not None:
            params["severity"] = severity
        if types is not None:
            params["types[]"] = types
        if ts_start is not None:
            params["tsStart"] = ts_start
        if ts_end is not None:
            params["tsEnd"] = ts_end
        if category is not None:
            params["category"] = category
        if sort_by is not None:
            params["sortBy"] = sort_by
        if serials is not None:
            params["serials[]"] = serials
        if device_types is not None:
            params["deviceTypes[]"] = device_types
        if device_tags is not None:
            params["deviceTags[]"] = device_tags
        if active is not None:
            params["active"] = active
        if dismissed is not None:
            params["dismissed"] = dismissed
        if resolved is not None:
            params["resolved"] = resolved
        if suppress_alerts_for_offline_nodes is not None:
            params["suppressAlertsForOfflineNodes"] = suppress_alerts_for_offline_nodes

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationAssuranceAlertsOverviewByType",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationAssuranceAlertsOverviewByTypeResponseItemsItem,
        )

    def get_organization_assurance_alerts_overview_historical(
        self,
        *,
        organization_id: str,
        segment_duration: int,
        ts_start: str,
        network_id: str | None = None,
        severity: str | None = None,
        types: GetOrganizationAssuranceAlertsOverviewHistoricalTypes | None = None,
        ts_end: str | None = None,
        category: GetOrganizationAssuranceAlertsOverviewHistoricalCategory | None = None,
        serials: list[str] | None = None,
        device_types: GetOrganizationAssuranceAlertsOverviewHistoricalDeviceTypes | None = None,
    ) -> PaginatedResponse[GetOrganizationAssuranceAlertsOverviewHistoricalResponseItemsItem]:
        """Returns historical health alert overviews.

        [API documentation: getOrganizationAssuranceAlertsOverviewHistorical](https://developer.cisco.com/meraki/api-v1/#!get-organization-assurance-alerts-overview-historical)

        Args:
            organization_id: Organization ID.
            segment_duration: Amount of time in seconds for each segment in the returned dataset.
            network_id: Optional parameter to filter alerts overview by network ids.
            severity: Optional parameter to filter alerts overview by severity type.
            types: Optional parameter to filter by alert type.
            ts_start: Parameter to define starting timestamp of historical totals.
            ts_end: Optional parameter to filter by end timestamp defaults to the current time.
            category: Optional parameter to filter by category.
            serials: Optional parameter to filter by primary device serial.
            device_types: Optional parameter to filter by device types.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            {
              "items": [
                {
                  "segmentStart": "2018-02-11T00:00:00Z",
                  "totals": {
                    "informational": 1,
                    "warning": 1,
                    "critical": 1
                  },
                  "byAlertType": [
                    {
                      "type": "vlan_mismatch",
                      "informational": 1,
                      "warning": 1,
                      "critical": 1
                    }
                  ]
                }
              ],
              "meta": {
                "counts": {
                  "items": 4
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/assurance/alerts/overview/historical"

        params: dict[str, Any] = {}
        if segment_duration is not None:
            params["segmentDuration"] = segment_duration
        if network_id is not None:
            params["networkId"] = network_id
        if severity is not None:
            params["severity"] = severity
        if types is not None:
            params["types[]"] = types
        if ts_start is not None:
            params["tsStart"] = ts_start
        if ts_end is not None:
            params["tsEnd"] = ts_end
        if category is not None:
            params["category"] = category
        if serials is not None:
            params["serials[]"] = serials
        if device_types is not None:
            params["deviceTypes[]"] = device_types

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationAssuranceAlertsOverviewHistorical",
            path=path,
            params=params,
            item_schema=GetOrganizationAssuranceAlertsOverviewHistoricalResponseItemsItem,
        )

    def restore_organization_assurance_alerts(
        self, *, organization_id: str, alert_ids: list[str]
    ) -> None:
        """Restore health alerts from dismissed.

        [API documentation: restoreOrganizationAssuranceAlerts](https://developer.cisco.com/meraki/api-v1/#!restore-organization-assurance-alerts)

        Args:
            organization_id: Organization ID.
            alert_ids: Array of alert IDs to restore.

        Returns:
            Successful operation.

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/assurance/alerts/restore"

        payload: dict[str, Any] = {}
        if alert_ids is not None:
            payload["alertIds"] = alert_ids

        return self._session.post(
            scope="organizations",
            operation_id="restoreOrganizationAssuranceAlerts",
            path=path,
            json=payload,
        )

    def get_organization_assurance_alerts_taxonomy_categories(
        self, organization_id: str
    ) -> PaginatedResponse[GetOrganizationAssuranceAlertsTaxonomyCategoriesResponseItem]:
        """Return a list of Category Types.

        [API documentation: getOrganizationAssuranceAlertsTaxonomyCategories](https://developer.cisco.com/meraki/api-v1/#!get-organization-assurance-alerts-taxonomy-categories)

        Args:
            organization_id: Organization ID.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "type": "connectivity",
                "title": "Connectivity"
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/assurance/alerts/taxonomy/categories"

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationAssuranceAlertsTaxonomyCategories",
            path=path,
            item_schema=GetOrganizationAssuranceAlertsTaxonomyCategoriesResponseItem,
        )

    def get_organization_assurance_alerts_taxonomy_types(
        self, organization_id: str
    ) -> PaginatedResponse[GetOrganizationAssuranceAlertsTaxonomyTypesResponseItem]:
        """Return a list of alert types.

        [API documentation: getOrganizationAssuranceAlertsTaxonomyTypes](https://developer.cisco.com/meraki/api-v1/#!get-organization-assurance-alerts-taxonomy-types)

        Args:
            organization_id: Organization ID.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "type": "unreachable",
                "title": "Unreachable device",
                "categoryType": "connectivity",
                "severities": [
                  {
                    "type": "critical"
                  }
                ],
                "deviceTypes": [
                  "Campus Gateway",
                  "Catalyst AP",
                  "Catalyst Controller",
                  "Catalyst Switch",
                  "MG",
                  "MR",
                  "MS",
                  "MT",
                  "MV",
                  "MX",
                  "VMX",
                  "Z"
                ]
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/assurance/alerts/taxonomy/types"

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationAssuranceAlertsTaxonomyTypes",
            path=path,
            item_schema=GetOrganizationAssuranceAlertsTaxonomyTypesResponseItem,
        )

    def get_organization_assurance_alert(
        self, *, organization_id: str, id: str
    ) -> GetOrganizationAssuranceAlertResponse:
        """Return a singular Health Alert by its id.

        [API documentation: getOrganizationAssuranceAlert](https://developer.cisco.com/meraki/api-v1/#!get-organization-assurance-alert)

        Args:
            organization_id: Organization ID.
            id: ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "1234",
              "categoryType": "connectivity",
              "network": {
                "name": "Network 2",
                "id": "L_1020981"
              },
              "startedAt": "2022-04-01T15:48:57Z",
              "resolvedAt": "2022-04-02T15:48:57Z",
              "dismissedAt": "2022-04-02T15:48:57Z",
              "deviceType": "MS",
              "type": "crc_errors_error",
              "title": "CRC errors detected",
              "description": "Very high proportion of CRC errors on port id",
              "severity": "warning",
              "scope": {
                "devices": [
                  {
                    "url": "https://n237.meraki.com/MS-PM-First-Floo/n/_5kUKaTd/manage/nodes/new_list/7911238",
                    "name": "Device 1",
                    "order": 0,
                    "productType": "switch",
                    "serial": "Q2QP-5VYM-YM8H",
                    "mac": "aa:bb:cd:dd",
                    "imei": "353593090031649",
                    "lldp": {
                      "port": "33"
                    }
                  }
                ]
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        id = urllib.parse.quote(str(id), safe="")
        path = f"/organizations/{organization_id}/assurance/alerts/{id}"

        return self._session.get(
            scope="organizations",
            operation_id="getOrganizationAssuranceAlert",
            path=path,
            response_schema=GetOrganizationAssuranceAlertResponse,
        )

    def get_organization_branding_policies(
        self, organization_id: str
    ) -> PaginatedResponse[GetOrganizationBrandingPoliciesResponseItem]:
        """List the branding policies of an organization.

        [API documentation: getOrganizationBrandingPolicies](https://developer.cisco.com/meraki/api-v1/#!get-organization-branding-policies)

        Args:
            organization_id: Organization ID.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "name": "My Branding Policy",
                "enabled": true,
                "adminSettings": {
                  "appliesTo": "All admins of networks...",
                  "values": [
                    "N_1234",
                    "L_5678"
                  ]
                },
                "helpSettings": {
                  "helpTab": "show",
                  "getHelpSubtab": "default or inherit",
                  "communitySubtab": "show",
                  "casesSubtab": "hide",
                  "dataProtectionRequestsSubtab": "default or inherit",
                  "getHelpSubtabKnowledgeBaseSearch": "<h1>Some custom HTML content</h1>",
                  "universalSearchKnowledgeBaseSearch": "hide",
                  "ciscoMerakiProductDocumentation": "show",
                  "supportContactInfo": "show",
                  "newFeaturesSubtab": "show",
                  "firewallInfoSubtab": "hide",
                  "apiDocsSubtab": "default or inherit",
                  "hardwareReplacementsSubtab": "hide",
                  "smForums": "hide",
                  "helpWidget": "hide"
                },
                "customLogo": {
                  "enabled": true,
                  "image": {
                    "preview": {
                      "url": "https://meraki-na.s3.amazonaws.com/org-assets/my-image.png",
                      "expiresAt": "2022-04-06T06:19:27-07:00"
                    }
                  }
                }
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/brandingPolicies"

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationBrandingPolicies",
            path=path,
            item_schema=GetOrganizationBrandingPoliciesResponseItem,
        )

    def create_organization_branding_policy(
        self,
        *,
        organization_id: str,
        name: str,
        enabled: bool | None = None,
        admin_settings: CreateOrganizationBrandingPolicyAdminSettings | None = None,
        help_settings: CreateOrganizationBrandingPolicyHelpSettings | None = None,
        custom_logo: CreateOrganizationBrandingPolicyCustomLogo | None = None,
    ) -> CreateOrganizationBrandingPolicyResponse:
        """Add a new branding policy to an organization.

        [API documentation: createOrganizationBrandingPolicy](https://developer.cisco.com/meraki/api-v1/#!create-organization-branding-policy)

        Args:
            organization_id: Organization ID.
            name: Name of the Dashboard branding policy.
            enabled: Boolean indicating whether this policy is enabled.
            admin_settings: Settings for describing which kinds of admins this policy applies to.
            help_settings: Settings for describing the modifications to various Help page features.
                Each property in this object accepts one of 'default or inherit' (do not
                modify functionality), 'hide' (remove the section from Dashboard), or
                'show' (always show the section on Dashboard). Some properties in this
                object also accept custom HTML used to replace the section on Dashboard;
                see the documentation for each property to see the allowed values. Each
                property defaults to 'default or inherit' when not provided.
            custom_logo: Properties describing the custom logo attached to the branding policy.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "name": "My Branding Policy",
              "enabled": true,
              "adminSettings": {
                "appliesTo": "All admins of networks...",
                "values": [
                  "N_1234",
                  "L_5678"
                ]
              },
              "helpSettings": {
                "helpTab": "show",
                "getHelpSubtab": "default or inherit",
                "communitySubtab": "show",
                "casesSubtab": "hide",
                "dataProtectionRequestsSubtab": "default or inherit",
                "getHelpSubtabKnowledgeBaseSearch": "<h1>Some custom HTML content</h1>",
                "universalSearchKnowledgeBaseSearch": "hide",
                "ciscoMerakiProductDocumentation": "show",
                "supportContactInfo": "show",
                "newFeaturesSubtab": "show",
                "firewallInfoSubtab": "hide",
                "apiDocsSubtab": "default or inherit",
                "hardwareReplacementsSubtab": "hide",
                "smForums": "hide",
                "helpWidget": "hide"
              },
              "customLogo": {
                "enabled": true,
                "image": {
                  "preview": {
                    "url": "https://meraki-na.s3.amazonaws.com/org-assets/my-image.png",
                    "expiresAt": "2022-04-06T06:19:27-07:00"
                  }
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/brandingPolicies"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if enabled is not None:
            payload["enabled"] = enabled
        if admin_settings is not None:
            payload["adminSettings"] = admin_settings.model_dump(by_alias=True, exclude_none=True)
        if help_settings is not None:
            payload["helpSettings"] = help_settings.model_dump(by_alias=True, exclude_none=True)
        if custom_logo is not None:
            payload["customLogo"] = custom_logo.model_dump(by_alias=True, exclude_none=True)

        return self._session.post(
            scope="organizations",
            operation_id="createOrganizationBrandingPolicy",
            path=path,
            json=payload,
            response_schema=CreateOrganizationBrandingPolicyResponse,
        )

    def get_organization_branding_policies_priorities(
        self, organization_id: str
    ) -> GetOrganizationBrandingPoliciesPrioritiesResponse:
        """Return the branding policy IDs of an organization in priority order.

        [API documentation: getOrganizationBrandingPoliciesPriorities](https://developer.cisco.com/meraki/api-v1/#!get-organization-branding-policies-priorities)

        Args:
            organization_id: Organization ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "brandingPolicyIds": [
                "123",
                "456",
                "789"
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/brandingPolicies/priorities"

        return self._session.get(
            scope="organizations",
            operation_id="getOrganizationBrandingPoliciesPriorities",
            path=path,
            response_schema=GetOrganizationBrandingPoliciesPrioritiesResponse,
        )

    def update_organization_branding_policies_priorities(
        self, organization_id: str, *, branding_policy_ids: list[str] | None = None
    ) -> UpdateOrganizationBrandingPoliciesPrioritiesResponse:
        """Update the priority ordering of an organization's branding policies.

        [API documentation: updateOrganizationBrandingPoliciesPriorities](https://developer.cisco.com/meraki/api-v1/#!update-organization-branding-policies-priorities)

        Args:
            organization_id: Organization ID.
            branding_policy_ids: An ordered list of branding policy IDs that determines the priority
                order of how to apply the policies.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "brandingPolicyIds": [
                "123",
                "456",
                "789"
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/brandingPolicies/priorities"

        payload: dict[str, Any] = {}
        if branding_policy_ids is not None:
            payload["brandingPolicyIds"] = branding_policy_ids

        return self._session.put(
            scope="organizations",
            operation_id="updateOrganizationBrandingPoliciesPriorities",
            path=path,
            json=payload,
            response_schema=UpdateOrganizationBrandingPoliciesPrioritiesResponse,
        )

    def get_organization_branding_policy(
        self, *, organization_id: str, branding_policy_id: str
    ) -> GetOrganizationBrandingPolicyResponse:
        """Return a branding policy.

        [API documentation: getOrganizationBrandingPolicy](https://developer.cisco.com/meraki/api-v1/#!get-organization-branding-policy)

        Args:
            organization_id: Organization ID.
            branding_policy_id: Branding policy ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "name": "My Branding Policy",
              "enabled": true,
              "adminSettings": {
                "appliesTo": "All admins of networks...",
                "values": [
                  "N_1234",
                  "L_5678"
                ]
              },
              "helpSettings": {
                "helpTab": "show",
                "getHelpSubtab": "default or inherit",
                "communitySubtab": "show",
                "casesSubtab": "hide",
                "dataProtectionRequestsSubtab": "default or inherit",
                "getHelpSubtabKnowledgeBaseSearch": "<h1>Some custom HTML content</h1>",
                "universalSearchKnowledgeBaseSearch": "hide",
                "ciscoMerakiProductDocumentation": "show",
                "supportContactInfo": "show",
                "newFeaturesSubtab": "show",
                "firewallInfoSubtab": "hide",
                "apiDocsSubtab": "default or inherit",
                "hardwareReplacementsSubtab": "hide",
                "smForums": "hide",
                "helpWidget": "hide"
              },
              "customLogo": {
                "enabled": true,
                "image": {
                  "preview": {
                    "url": "https://meraki-na.s3.amazonaws.com/org-assets/my-image.png",
                    "expiresAt": "2022-04-06T06:19:27-07:00"
                  }
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        branding_policy_id = urllib.parse.quote(str(branding_policy_id), safe="")
        path = f"/organizations/{organization_id}/brandingPolicies/{branding_policy_id}"

        return self._session.get(
            scope="organizations",
            operation_id="getOrganizationBrandingPolicy",
            path=path,
            response_schema=GetOrganizationBrandingPolicyResponse,
        )

    def update_organization_branding_policy(
        self,
        *,
        organization_id: str,
        branding_policy_id: str,
        name: str,
        enabled: bool | None = None,
        admin_settings: UpdateOrganizationBrandingPolicyAdminSettings | None = None,
        help_settings: UpdateOrganizationBrandingPolicyHelpSettings | None = None,
        custom_logo: UpdateOrganizationBrandingPolicyCustomLogo | None = None,
    ) -> UpdateOrganizationBrandingPolicyResponse:
        """Update a branding policy.

        [API documentation: updateOrganizationBrandingPolicy](https://developer.cisco.com/meraki/api-v1/#!update-organization-branding-policy)

        Args:
            organization_id: Organization ID.
            branding_policy_id: Branding policy ID.
            name: Name of the Dashboard branding policy.
            enabled: Boolean indicating whether this policy is enabled.
            admin_settings: Settings for describing which kinds of admins this policy applies to.
            help_settings: Settings for describing the modifications to various Help page features.
                Each property in this object accepts one of 'default or inherit' (do not
                modify functionality), 'hide' (remove the section from Dashboard), or
                'show' (always show the section on Dashboard). Some properties in this
                object also accept custom HTML used to replace the section on Dashboard;
                see the documentation for each property to see the allowed values.
            custom_logo: Properties describing the custom logo attached to the branding policy.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "name": "My Branding Policy",
              "enabled": true,
              "adminSettings": {
                "appliesTo": "All admins of networks...",
                "values": [
                  "N_1234",
                  "L_5678"
                ]
              },
              "helpSettings": {
                "helpTab": "show",
                "getHelpSubtab": "default or inherit",
                "communitySubtab": "show",
                "casesSubtab": "hide",
                "dataProtectionRequestsSubtab": "default or inherit",
                "getHelpSubtabKnowledgeBaseSearch": "<h1>Some custom HTML content</h1>",
                "universalSearchKnowledgeBaseSearch": "hide",
                "ciscoMerakiProductDocumentation": "show",
                "supportContactInfo": "show",
                "newFeaturesSubtab": "show",
                "firewallInfoSubtab": "hide",
                "apiDocsSubtab": "default or inherit",
                "hardwareReplacementsSubtab": "hide",
                "smForums": "hide",
                "helpWidget": "hide"
              },
              "customLogo": {
                "enabled": true,
                "image": {
                  "preview": {
                    "url": "https://meraki-na.s3.amazonaws.com/org-assets/my-image.png",
                    "expiresAt": "2022-04-06T06:19:27-07:00"
                  }
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        branding_policy_id = urllib.parse.quote(str(branding_policy_id), safe="")
        path = f"/organizations/{organization_id}/brandingPolicies/{branding_policy_id}"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if enabled is not None:
            payload["enabled"] = enabled
        if admin_settings is not None:
            payload["adminSettings"] = admin_settings.model_dump(by_alias=True, exclude_none=True)
        if help_settings is not None:
            payload["helpSettings"] = help_settings.model_dump(by_alias=True, exclude_none=True)
        if custom_logo is not None:
            payload["customLogo"] = custom_logo.model_dump(by_alias=True, exclude_none=True)

        return self._session.put(
            scope="organizations",
            operation_id="updateOrganizationBrandingPolicy",
            path=path,
            json=payload,
            response_schema=UpdateOrganizationBrandingPolicyResponse,
        )

    def delete_organization_branding_policy(
        self, *, organization_id: str, branding_policy_id: str
    ) -> None:
        """Delete a branding policy.

        [API documentation: deleteOrganizationBrandingPolicy](https://developer.cisco.com/meraki/api-v1/#!delete-organization-branding-policy)

        Args:
            organization_id: Organization ID.
            branding_policy_id: Branding policy ID.

        Returns:
            Successful operation.

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        branding_policy_id = urllib.parse.quote(str(branding_policy_id), safe="")
        path = f"/organizations/{organization_id}/brandingPolicies/{branding_policy_id}"

        return self._session.delete(
            scope="organizations", operation_id="deleteOrganizationBrandingPolicy", path=path
        )

    def claim_into_organization(
        self,
        organization_id: str,
        *,
        orders: list[str] | None = None,
        serials: list[str] | None = None,
        licenses: list[ClaimIntoOrganizationLicensesItem] | None = None,
    ) -> ClaimIntoOrganizationResponse:
        """Claim a list of devices, licenses, and/or orders into an organization inventory.

        [API documentation: claimIntoOrganization](https://developer.cisco.com/meraki/api-v1/#!claim-into-organization)

        Args:
            organization_id: Organization ID.
            orders: The numbers of the orders that should be claimed.
            serials: The serials of the devices that should be claimed.
            licenses: The licenses that should be claimed.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "orders": [
                "4CXXXXXXX"
              ],
              "serials": [
                "Q234-ABCD-5678"
              ],
              "licenses": [
                {
                  "key": "Z2XXXXXXXXXX",
                  "mode": "addDevices"
                }
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/claim"

        payload: dict[str, Any] = {}
        if orders is not None:
            payload["orders"] = orders
        if serials is not None:
            payload["serials"] = serials
        if licenses is not None:
            payload["licenses"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in licenses
            ]

        return self._session.post(
            scope="organizations",
            operation_id="claimIntoOrganization",
            path=path,
            json=payload,
            response_schema=ClaimIntoOrganizationResponse,
        )

    def get_organization_clients_bandwidth_usage_history(
        self,
        organization_id: str,
        *,
        network_tag: str | None = None,
        device_tag: str | None = None,
        ssid_name: str | None = None,
        usage_uplink: str | None = None,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
    ) -> PaginatedResponse[GetOrganizationClientsBandwidthUsageHistoryResponseItem]:
        """Return data usage (in megabits per second) over time for all clients in the given organization within a given time range.

        [API documentation: getOrganizationClientsBandwidthUsageHistory](https://developer.cisco.com/meraki/api-v1/#!get-organization-clients-bandwidth-usage-history)

        Args:
            organization_id: Organization ID.
            network_tag: Match result to an exact network tag.
            device_tag: Match result to an exact device tag.
            ssid_name: Filter results by ssid name.
            usage_uplink: Filter results by usage uplink.
            t0: The beginning of the timespan for the data.
            t1: The end of the timespan for the data. t1 can be a maximum of 186 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 186 days. The default is 1 day.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "ts": "2021-06-20T01:00:00.000Z",
                "total": 345,
                "upstream": 60,
                "downstream": 285
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/clients/bandwidthUsageHistory"

        params: dict[str, Any] = {}
        if network_tag is not None:
            params["networkTag"] = network_tag
        if device_tag is not None:
            params["deviceTag"] = device_tag
        if ssid_name is not None:
            params["ssidName"] = ssid_name
        if usage_uplink is not None:
            params["usageUplink"] = usage_uplink
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationClientsBandwidthUsageHistory",
            path=path,
            params=params,
            item_schema=GetOrganizationClientsBandwidthUsageHistoryResponseItem,
        )

    def get_organization_clients_overview(
        self,
        organization_id: str,
        *,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
    ) -> GetOrganizationClientsOverviewResponse:
        """Return summary information around client data usage (in kb) across the given organization.

        [API documentation: getOrganizationClientsOverview](https://developer.cisco.com/meraki/api-v1/#!get-organization-clients-overview)

        Args:
            organization_id: Organization ID.
            t0: The beginning of the timespan for the data.
            t1: The end of the timespan for the data. t1 can be a maximum of 31 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 31 days. The default is 1 day.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "usage": {
                "overall": {
                  "total": 18000.0,
                  "downstream": 10000.0,
                  "upstream": 8000.0
                },
                "average": 1.37
              },
              "counts": {
                "total": 20
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/clients/overview"

        params: dict[str, Any] = {}
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan

        return self._session.get(
            scope="organizations",
            operation_id="getOrganizationClientsOverview",
            path=path,
            params=params,
            response_schema=GetOrganizationClientsOverviewResponse,
        )

    def get_organization_clients_search(
        self,
        *,
        organization_id: str,
        mac: str,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetOrganizationClientsSearchResponseRecordsItem]:
        """Return the client details in an organization.

        [API documentation: getOrganizationClientsSearch](https://developer.cisco.com/meraki/api-v1/#!get-organization-clients-search)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 5. Default is
                5.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            mac: The MAC address of the client. Required.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            {
              "clientId": "k74272e",
              "mac": "22:33:44:55:66:77",
              "manufacturer": "Apple",
              "records": [
                {
                  "network": {
                    "id": "N_24329156",
                    "organizationId": "2930418",
                    "name": "Main Office",
                    "productTypes": [
                      "appliance",
                      "switch",
                      "wireless"
                    ],
                    "timeZone": "America/Los_Angeles",
                    "tags": [
                      "tag1",
                      "tag2"
                    ],
                    "enrollmentString": "my-enrollment-string",
                    "url": "https://n1.meraki.com//n//manage/nodes/list",
                    "notes": "Additional description of the network",
                    "isBoundToConfigTemplate": false
                  },
                  "ip": "1.2.3.4",
                  "ip6": "2001:db8:3c4d:15::1",
                  "description": "Miles's phone",
                  "firstSeen": 1518365681,
                  "lastSeen": 1526087474,
                  "os": "iOS",
                  "user": "milesmeraki",
                  "vlan": "100",
                  "ssid": "My SSID",
                  "switchport": "My switch port",
                  "wirelessCapabilities": "802.11b - 2.4 GHz",
                  "smInstalled": true,
                  "recentDeviceMac": "22:33:44:55:66:77",
                  "clientVpnConnections": [
                    {
                      "remoteIp": "1.2.3.4",
                      "connectedAt": 1522613355,
                      "disconnectedAt": 1522613360
                    }
                  ],
                  "lldp": [
                    [
                      "System name",
                      "Some system name"
                    ],
                    [
                      "System description",
                      "Some system description"
                    ],
                    [
                      "Port ID",
                      "1"
                    ],
                    [
                      "Chassis ID",
                      "00:18:0a:00:00:00"
                    ],
                    [
                      "Port description",
                      "eth0"
                    ],
                    [
                      "System capabilities",
                      "Two-port MAC Relay"
                    ]
                  ],
                  "cdp": [
                    [
                      "System name",
                      "Some system name"
                    ],
                    [
                      "System description",
                      "Some system description"
                    ],
                    [
                      "Port ID",
                      "1"
                    ],
                    [
                      "Chassis ID",
                      "00:18:0a:00:00:00"
                    ],
                    [
                      "Port description",
                      "eth0"
                    ],
                    [
                      "System capabilities",
                      "Two-port MAC Relay"
                    ]
                  ],
                  "status": "Online"
                }
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/clients/search"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if mac is not None:
            params["mac"] = mac

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationClientsSearch",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationClientsSearchResponseRecordsItem,
        )

    def clone_organization(self, *, organization_id: str, name: str) -> CloneOrganizationResponse:
        """Create a new organization by cloning the addressed organization.

        [API documentation: cloneOrganization](https://developer.cisco.com/meraki/api-v1/#!clone-organization)

        Args:
            organization_id: Organization ID.
            name: The name of the new organization.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "2930418",
              "name": "My organization",
              "url": "https://dashboard.meraki.com/o/VjjsAd/manage/organization/overview",
              "api": {
                "enabled": true
              },
              "licensing": {
                "model": "co-term"
              },
              "cloud": {
                "region": {
                  "name": "North America",
                  "host": {
                    "name": "United States"
                  }
                }
              },
              "management": {
                "details": [
                  {
                    "name": "MSP ID",
                    "value": "123456"
                  }
                ]
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/clone"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name

        return self._session.post(
            scope="organizations",
            operation_id="cloneOrganization",
            path=path,
            json=payload,
            response_schema=CloneOrganizationResponse,
        )

    def get_organization_config_templates(
        self, organization_id: str
    ) -> PaginatedResponse[GetOrganizationConfigTemplatesResponseItem]:
        """List the configuration templates for this organization.

        [API documentation: getOrganizationConfigTemplates](https://developer.cisco.com/meraki/api-v1/#!get-organization-config-templates)

        Args:
            organization_id: Organization ID.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "id": "N_24329156",
                "name": "My config template",
                "productTypes": [
                  "appliance",
                  "switch",
                  "wireless"
                ],
                "timeZone": "America/Los_Angeles"
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/configTemplates"

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationConfigTemplates",
            path=path,
            item_schema=GetOrganizationConfigTemplatesResponseItem,
        )

    def create_organization_config_template(
        self,
        *,
        organization_id: str,
        name: str,
        time_zone: str | None = None,
        copy_from_network_id: str | None = None,
    ) -> CreateOrganizationConfigTemplateResponse:
        """Create a new configuration template.

        [API documentation: createOrganizationConfigTemplate](https://developer.cisco.com/meraki/api-v1/#!create-organization-config-template)

        Args:
            organization_id: Organization ID.
            name: The name of the configuration template.
            time_zone: The timezone of the configuration template. For a list of allowed timezones,
                please see the 'TZ' column in the table in <a target='_blank'
                href='https://en.wikipedia.org/wiki/List_of_tz_database_time_zones'>this
                article</a>. Not applicable if copying from existing network or
                template.
            copy_from_network_id: The ID of the network or config template to copy configuration
                from.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "N_24329156",
              "name": "My config template",
              "productTypes": [
                "appliance",
                "switch",
                "wireless"
              ],
              "timeZone": "America/Los_Angeles"
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/configTemplates"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if time_zone is not None:
            payload["timeZone"] = time_zone
        if copy_from_network_id is not None:
            payload["copyFromNetworkId"] = copy_from_network_id

        return self._session.post(
            scope="organizations",
            operation_id="createOrganizationConfigTemplate",
            path=path,
            json=payload,
            response_schema=CreateOrganizationConfigTemplateResponse,
        )

    def get_organization_config_template(
        self, *, organization_id: str, config_template_id: str
    ) -> GetOrganizationConfigTemplateResponse:
        """Return a single configuration template.

        [API documentation: getOrganizationConfigTemplate](https://developer.cisco.com/meraki/api-v1/#!get-organization-config-template)

        Args:
            organization_id: Organization ID.
            config_template_id: Config template ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "N_24329156",
              "name": "My config template",
              "productTypes": [
                "appliance",
                "switch",
                "wireless"
              ],
              "timeZone": "America/Los_Angeles"
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        config_template_id = urllib.parse.quote(str(config_template_id), safe="")
        path = f"/organizations/{organization_id}/configTemplates/{config_template_id}"

        return self._session.get(
            scope="organizations",
            operation_id="getOrganizationConfigTemplate",
            path=path,
            response_schema=GetOrganizationConfigTemplateResponse,
        )

    def update_organization_config_template(
        self,
        *,
        organization_id: str,
        config_template_id: str,
        name: str | None = None,
        time_zone: str | None = None,
    ) -> UpdateOrganizationConfigTemplateResponse:
        """Update a configuration template.

        [API documentation: updateOrganizationConfigTemplate](https://developer.cisco.com/meraki/api-v1/#!update-organization-config-template)

        Args:
            organization_id: Organization ID.
            config_template_id: Config template ID.
            name: The name of the configuration template.
            time_zone: The timezone of the configuration template. For a list of allowed timezones,
                please see the 'TZ' column in the table in <a target='_blank'
                href='https://en.wikipedia.org/wiki/List_of_tz_database_time_zones'>this
                article.</a>.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "N_24329156",
              "name": "My config template",
              "productTypes": [
                "appliance",
                "switch",
                "wireless"
              ],
              "timeZone": "America/Los_Angeles"
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        config_template_id = urllib.parse.quote(str(config_template_id), safe="")
        path = f"/organizations/{organization_id}/configTemplates/{config_template_id}"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if time_zone is not None:
            payload["timeZone"] = time_zone

        return self._session.put(
            scope="organizations",
            operation_id="updateOrganizationConfigTemplate",
            path=path,
            json=payload,
            response_schema=UpdateOrganizationConfigTemplateResponse,
        )

    def delete_organization_config_template(
        self, *, organization_id: str, config_template_id: str
    ) -> None:
        """Remove a configuration template.

        [API documentation: deleteOrganizationConfigTemplate](https://developer.cisco.com/meraki/api-v1/#!delete-organization-config-template)

        Args:
            organization_id: Organization ID.
            config_template_id: Config template ID.

        Returns:
            Successful operation.

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        config_template_id = urllib.parse.quote(str(config_template_id), safe="")
        path = f"/organizations/{organization_id}/configTemplates/{config_template_id}"

        return self._session.delete(
            scope="organizations", operation_id="deleteOrganizationConfigTemplate", path=path
        )

    def get_organization_configuration_changes(
        self,
        organization_id: str,
        *,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        network_id: str | None = None,
        admin_id: str | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "prev",
    ) -> PaginatedResponse[GetOrganizationConfigurationChangesResponseItem]:
        r"""View the Change Log for your organization.

        [API documentation: getOrganizationConfigurationChanges](https://developer.cisco.com/meraki/api-v1/#!get-organization-configuration-changes)

        Args:
            organization_id: Organization ID.
            t0: The beginning of the timespan for the data. The maximum lookback period is 365 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 365 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 365 days. The default is 365 days.
            per_page: The number of entries per page returned. Acceptable range is 3 - 5000. Default
                is 5000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            network_id: Filters on the given network.
            admin_id: Filters on the given Admin.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" or "prev" (default) page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "ts": "2018-02-11T00:00:00.090210Z",
                "adminName": "Miles Meraki",
                "adminEmail": "miles@meraki.com",
                "adminId": "212406",
                "networkName": "Main Office",
                "networkId": "N_24329156",
                "networkUrl": "https://n1.meraki.com//n//manage/nodes/list",
                "ssidName": "My SSID",
                "ssidNumber": 1,
                "page": "via API",
                "label": "PUT /api/v1/organizations/2930418",
                "oldValue": "{\"id\":\"2930418\",\"name\":\"My organization\",\"url\":\"https://dashboard.meraki.com/o/VjjsAd/manage/organization/overview\"}",
                "newValue": "{\"id\":\"2930418\",\"name\":\"My organization changed\",\"url\":\"https://dashboard.meraki.com/o/VjjsAd/manage/organization/overview\"}",
                "client": {
                  "id": "0hoXjtjX6C-Nk4Nr6kEbCJJFRmIgycaG1HBE572hlIc",
                  "type": "oauth"
                }
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/configurationChanges"

        params: dict[str, Any] = {}
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if network_id is not None:
            params["networkId"] = network_id
        if admin_id is not None:
            params["adminId"] = admin_id

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationConfigurationChanges",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationConfigurationChangesResponseItem,
        )

    def get_organization_devices(
        self,
        organization_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        configuration_updated_after: str | None = None,
        network_ids: list[str] | None = None,
        product_types: GetOrganizationDevicesProductTypes | None = None,
        tags: list[str] | None = None,
        tags_filter_type: GetOrganizationDevicesTagsFilterType | None = None,
        name: str | None = None,
        mac: str | None = None,
        serial: str | None = None,
        model: str | None = None,
        macs: list[str] | None = None,
        serials: list[str] | None = None,
        sensor_metrics: GetOrganizationDevicesSensorMetrics | None = None,
        sensor_alert_profile_ids: list[str] | None = None,
        models: list[str] | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetOrganizationDevicesResponseItem]:
        """List the devices in an organization that have been assigned to a network.

        [API documentation: getOrganizationDevices](https://developer.cisco.com/meraki/api-v1/#!get-organization-devices)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 5000. Default
                is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            configuration_updated_after: Filter results by whether or not the device's configuration
                has been updated after the given timestamp.
            network_ids: Optional parameter to filter devices by network.
            product_types: Optional parameter to filter devices by product type. Valid types are
                wireless, appliance, switch, systemsManager, camera, cellularGateway,
                sensor, wirelessController, campusGateway, and secureConnect.
            tags: Optional parameter to filter devices by tags.
            tags_filter_type: Optional parameter of value 'withAnyTags' or 'withAllTags' to indicate
                whether to return networks which contain ANY or ALL of the included
                tags. If no type is included, 'withAnyTags' will be selected.
            name: Optional parameter to filter devices by name. All returned devices will have a
                name that contains the search term or is an exact match.
            mac: Optional parameter to filter devices by MAC address. All returned devices will have
                a MAC address that contains the search term or is an exact match.
            serial: Optional parameter to filter devices by serial number. All returned devices will
                have a serial number that contains the search term or is an exact match.
            model: Optional parameter to filter devices by model. All returned devices will have a
                model that contains the search term or is an exact match.
            macs: Optional parameter to filter devices by one or more MAC addresses. All returned
                devices will have a MAC address that is an exact match.
            serials: Optional parameter to filter devices by one or more serial numbers. All
                returned devices will have a serial number that is an exact match.
            sensor_metrics: Optional parameter to filter devices by the metrics that they provide.
                Only applies to sensor devices.
            sensor_alert_profile_ids: Optional parameter to filter devices by the alert profiles
                that are bound to them. Only applies to sensor devices.
            models: Optional parameter to filter devices by one or more models. All returned devices
                will have a model that is an exact match.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "name": "My AP",
                "lat": 37.4180951010362,
                "lng": -122.098531723022,
                "address": "1600 Pennsylvania Ave",
                "notes": "My AP's note",
                "tags": [
                  "recently-added"
                ],
                "networkId": "N_24329156",
                "serial": "Q234-ABCD-5678",
                "model": "MR34",
                "imei": "123456789000000",
                "mac": "00:11:22:33:44:55",
                "lanIp": "1.2.3.4",
                "firmware": "wireless-25-14",
                "productType": "wireless",
                "details": [
                  {
                    "name": "Catalyst serial",
                    "value": "123ABC"
                  }
                ]
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/devices"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if configuration_updated_after is not None:
            params["configurationUpdatedAfter"] = configuration_updated_after
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if product_types is not None:
            params["productTypes[]"] = product_types
        if tags is not None:
            params["tags[]"] = tags
        if tags_filter_type is not None:
            params["tagsFilterType"] = tags_filter_type
        if name is not None:
            params["name"] = name
        if mac is not None:
            params["mac"] = mac
        if serial is not None:
            params["serial"] = serial
        if model is not None:
            params["model"] = model
        if macs is not None:
            params["macs[]"] = macs
        if serials is not None:
            params["serials[]"] = serials
        if sensor_metrics is not None:
            params["sensorMetrics[]"] = sensor_metrics
        if sensor_alert_profile_ids is not None:
            params["sensorAlertProfileIds[]"] = sensor_alert_profile_ids
        if models is not None:
            params["models[]"] = models

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationDevices",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationDevicesResponseItem,
        )

    def get_organization_devices_availabilities(
        self,
        organization_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        network_ids: list[str] | None = None,
        product_types: list[str] | None = None,
        serials: list[str] | None = None,
        tags: list[str] | None = None,
        tags_filter_type: GetOrganizationDevicesAvailabilitiesTagsFilterType | None = None,
        statuses: GetOrganizationDevicesAvailabilitiesStatuses | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetOrganizationDevicesAvailabilitiesResponseItem]:
        """List the availability information for devices in an organization.

        [API documentation: getOrganizationDevicesAvailabilities](https://developer.cisco.com/meraki/api-v1/#!get-organization-devices-availabilities)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            network_ids: Optional parameter to filter device availabilities by network ID. This
                filter uses multiple exact matches.
            product_types: Optional parameter to filter device availabilities by device product
                types. This filter uses multiple exact matches. Valid types are
                wireless, appliance, switch, camera, cellularGateway, sensor,
                wirelessController, and campusGateway.
            serials: Optional parameter to filter device availabilities by device serial numbers.
                This filter uses multiple exact matches.
            tags: An optional parameter to filter devices by tags. The filtering is case-sensitive.
                If tags are included, 'tagsFilterType' should also be included (see
                below). This filter uses multiple exact matches.
            tags_filter_type: An optional parameter of value 'withAnyTags' or 'withAllTags' to
                indicate whether to return devices which contain ANY or ALL of the
                included tags. If no type is included, 'withAnyTags' will be selected.
            statuses: Optional parameter to filter device availabilities by device status. This
                filter uses multiple exact matches.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "mac": "00:11:22:33:44:55",
                "name": "My AP",
                "network": {
                  "id": "N_24329156"
                },
                "productType": "switch",
                "serial": "Q234-ABCD-5678",
                "status": "online",
                "tags": [
                  "tag1",
                  "tag2"
                ]
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/devices/availabilities"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if product_types is not None:
            params["productTypes[]"] = product_types
        if serials is not None:
            params["serials[]"] = serials
        if tags is not None:
            params["tags[]"] = tags
        if tags_filter_type is not None:
            params["tagsFilterType"] = tags_filter_type
        if statuses is not None:
            params["statuses[]"] = statuses

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationDevicesAvailabilities",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationDevicesAvailabilitiesResponseItem,
        )

    def get_organization_devices_availabilities_change_history(
        self,
        organization_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        serials: list[str] | None = None,
        product_types: list[str] | None = None,
        network_ids: list[str] | None = None,
        statuses: GetOrganizationDevicesAvailabilitiesChangeHistoryStatuses | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetOrganizationDevicesAvailabilitiesChangeHistoryResponseItem]:
        """List the availability history information for devices in an organization.

        [API documentation: getOrganizationDevicesAvailabilitiesChangeHistory](https://developer.cisco.com/meraki/api-v1/#!get-organization-devices-availabilities-change-history)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            t0: The beginning of the timespan for the data. The maximum lookback period is 31 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 31 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 31 days. The default is 1 day.
            serials: Optional parameter to filter device availabilities history by device serial
                numbers.
            product_types: Optional parameter to filter device availabilities history by device
                product types.
            network_ids: Optional parameter to filter device availabilities history by network IDs.
            statuses: Optional parameter to filter device availabilities history by device statuses.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "ts": "2018-02-11T00:00:00.090210Z",
                "device": {
                  "serial": "Q234-ABCD-5678",
                  "name": "My AP",
                  "productType": "wireless",
                  "model": "MR34"
                },
                "details": {
                  "old": [
                    {
                      "name": "status",
                      "value": "online"
                    }
                  ],
                  "new": [
                    {
                      "name": "status",
                      "value": "offline"
                    }
                  ]
                },
                "network": {
                  "id": "N_24329156",
                  "name": "Main Office",
                  "url": "https://n1.meraki.com//n//manage/nodes/list",
                  "tags": [
                    "tag1",
                    "tag2"
                  ]
                }
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/devices/availabilities/changeHistory"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan
        if serials is not None:
            params["serials[]"] = serials
        if product_types is not None:
            params["productTypes[]"] = product_types
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if statuses is not None:
            params["statuses[]"] = statuses

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationDevicesAvailabilitiesChangeHistory",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationDevicesAvailabilitiesChangeHistoryResponseItem,
        )

    def get_organization_devices_controller_migrations(
        self,
        organization_id: str,
        *,
        serials: list[str] | None = None,
        network_ids: list[str] | None = None,
        target: GetOrganizationDevicesControllerMigrationsTarget | None = None,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetOrganizationDevicesControllerMigrationsResponseItemsItem]:
        """Retrieve device migration statuses in an organization.

        [API documentation: getOrganizationDevicesControllerMigrations](https://developer.cisco.com/meraki/api-v1/#!get-organization-devices-controller-migrations)

        Args:
            organization_id: Organization ID.
            serials: A list of Meraki Serials for which to retrieve migrations.
            network_ids: Filter device migrations by network IDs.
            target: Filter device migrations by target destination.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 100.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            {
              "items": [
                {
                  "serial": "QXYZ-DEFG-HIJK",
                  "target": "wirelessController",
                  "createdAt": "2020-10-21T02:00:00Z",
                  "migratedAt": "2020-10-21T03:00:00Z"
                }
              ],
              "meta": {
                "counts": {
                  "items": {
                    "total": 10,
                    "remaining": 0
                  }
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/devices/controller/migrations"

        params: dict[str, Any] = {}
        if serials is not None:
            params["serials[]"] = serials
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if target is not None:
            params["target"] = target
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationDevicesControllerMigrations",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationDevicesControllerMigrationsResponseItemsItem,
        )

    def create_organization_devices_controller_migration(
        self,
        *,
        organization_id: str,
        serials: list[str],
        target: CreateOrganizationDevicesControllerMigrationTarget,
    ) -> CreateOrganizationDevicesControllerMigrationResponse:
        """Migrate devices to another controller or management mode.

        [API documentation: createOrganizationDevicesControllerMigration](https://developer.cisco.com/meraki/api-v1/#!create-organization-devices-controller-migration)

        Args:
            organization_id: Organization ID.
            serials: A list of Meraki Serials to migrate.
            target: The controller or management mode to which the devices will be migrated.

        Returns:
            Successful operation.

        Example API response:
            ```json
            [
              {
                "serial": "QXYZ-DEFG-HIJK",
                "target": "wirelessController",
                "createdAt": "2020-10-21T02:00:00Z",
                "migratedAt": "2020-10-21T03:00:00Z"
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/devices/controller/migrations"

        payload: dict[str, Any] = {}
        if serials is not None:
            payload["serials"] = serials
        if target is not None:
            payload["target"] = target

        return self._session.post(
            scope="organizations",
            operation_id="createOrganizationDevicesControllerMigration",
            path=path,
            json=payload,
            response_schema=CreateOrganizationDevicesControllerMigrationResponse,
        )

    def bulk_update_organization_devices_details(
        self,
        *,
        organization_id: str,
        serials: list[str],
        details: list[BulkUpdateOrganizationDevicesDetailsDetailsItem],
    ) -> BulkUpdateOrganizationDevicesDetailsResponse:
        """Updating device details (currently only used for Catalyst devices).

        [API documentation: bulkUpdateOrganizationDevicesDetails](https://developer.cisco.com/meraki/api-v1/#!bulk-update-organization-devices-details)

        Args:
            organization_id: Organization ID.
            serials: A list of serials of devices to update.
            details: An array of details.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "serials": [
                "Q234-ABCD-0001",
                "Q234-ABCD-0002",
                "Q234-ABCD-0003"
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/devices/details/bulkUpdate"

        payload: dict[str, Any] = {}
        if serials is not None:
            payload["serials"] = serials
        if details is not None:
            payload["details"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in details
            ]

        return self._session.post(
            scope="organizations",
            operation_id="bulkUpdateOrganizationDevicesDetails",
            path=path,
            json=payload,
            response_schema=BulkUpdateOrganizationDevicesDetailsResponse,
        )

    def get_organization_devices_overview_by_model(
        self,
        organization_id: str,
        *,
        models: list[str] | None = None,
        network_ids: list[str] | None = None,
        product_types: GetOrganizationDevicesOverviewByModelProductTypes | None = None,
    ) -> GetOrganizationDevicesOverviewByModelResponse:
        """Lists the count for each device model.

        [API documentation: getOrganizationDevicesOverviewByModel](https://developer.cisco.com/meraki/api-v1/#!get-organization-devices-overview-by-model)

        Args:
            organization_id: Organization ID.
            models: Optional parameter to filter devices by one or more models. All returned devices
                will have a model that is an exact match.
            network_ids: Optional parameter to filter devices by networkId.
            product_types: Optional parameter to filter device by device product types. This filter
                uses multiple exact matches.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "counts": [
                {
                  "model": "MR34",
                  "total": 1
                }
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/devices/overview/byModel"

        params: dict[str, Any] = {}
        if models is not None:
            params["models[]"] = models
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if product_types is not None:
            params["productTypes[]"] = product_types

        return self._session.get(
            scope="organizations",
            operation_id="getOrganizationDevicesOverviewByModel",
            path=path,
            params=params,
            response_schema=GetOrganizationDevicesOverviewByModelResponse,
        )

    def get_organization_devices_packet_capture_captures(
        self,
        organization_id: str,
        *,
        capture_ids: list[str] | None = None,
        network_ids: list[str] | None = None,
        serials: list[str] | None = None,
        process: list[str] | None = None,
        capture_status: list[str] | None = None,
        name: list[str] | None = None,
        client_mac: list[str] | None = None,
        notes: str | None = None,
        device_name: str | None = None,
        admin_name: str | None = None,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        sort_order: GetOrganizationDevicesPacketCaptureCapturesSortOrder | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetOrganizationDevicesPacketCaptureCapturesResponseItemsItem]:
        """List Packet Captures.

        [API documentation: getOrganizationDevicesPacketCaptureCaptures](https://developer.cisco.com/meraki/api-v1/#!get-organization-devices-packet-capture-captures)

        Args:
            organization_id: Organization ID.
            capture_ids: Return the packet captures of the specified capture ids.
            network_ids: Return the packet captures of the specified network(s).
            serials: Return the packet captures of the specified device(s).
            process: Return the packet captures of the specified process.
            capture_status: Return the packet captures of the specified capture status.
            name: Return the packet captures matching the specified name.
            client_mac: Return the packet captures matching the specified client macs.
            notes: Return the packet captures matching the specified notes.
            device_name: Return the packet captures matching the specified device name.
            admin_name: Return the packet captures matching the admin name.
            t0: The beginning of the timespan for the data. The maximum lookback period is 365 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 365 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 365 days. The default is 365 days.
            per_page: The number of entries per page returned. Acceptable range is 3 - 100. Default
                is 10.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            sort_order: Sorted order of entries. Order options are 'ascending' and 'descending'.
                Default is 'descending'.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            {
              "items": [
                {
                  "captureId": "1234",
                  "network": {
                    "id": "N_24329156",
                    "name": "Main Office"
                  },
                  "device": {
                    "name": "My AP",
                    "serial": "Q234-ABCD-5678"
                  },
                  "admin": {
                    "id": "1234",
                    "name": "Miles Meraki"
                  },
                  "client": {
                    "id": "k74272e",
                    "mac": "22:33:44:55:66:77"
                  },
                  "details": [
                    {
                      "name": "reason",
                      "value": "bad_password",
                      "productType": "wireless"
                    }
                  ],
                  "name": "file_name",
                  "startTs": "2018-02-11T00:00:00.090210Z",
                  "ports": "1, 2",
                  "status": "new",
                  "errorMessage": "Some error message",
                  "destination": "upload_to_cloud",
                  "process": "manual",
                  "file": {
                    "size": 1066
                  },
                  "duration": 60,
                  "filterExpression": "(icmp)",
                  "counts": {
                    "packets": {
                      "total": 10
                    }
                  },
                  "interface": "wired"
                }
              ],
              "meta": {
                "counts": {
                  "items": {
                    "total": 100,
                    "remaining": 100
                  }
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/devices/packetCapture/captures"

        params: dict[str, Any] = {}
        if capture_ids is not None:
            params["captureIds[]"] = capture_ids
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if serials is not None:
            params["serials[]"] = serials
        if process is not None:
            params["process[]"] = process
        if capture_status is not None:
            params["captureStatus[]"] = capture_status
        if name is not None:
            params["name[]"] = name
        if client_mac is not None:
            params["clientMac[]"] = client_mac
        if notes is not None:
            params["notes"] = notes
        if device_name is not None:
            params["deviceName"] = device_name
        if admin_name is not None:
            params["adminName"] = admin_name
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if sort_order is not None:
            params["sortOrder"] = sort_order

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationDevicesPacketCaptureCaptures",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationDevicesPacketCaptureCapturesResponseItemsItem,
        )

    def create_organization_devices_packet_capture_capture(
        self,
        *,
        organization_id: str,
        serials: list[str],
        name: str,
        output_type: str | None = None,
        destination: str | None = None,
        ports: str | None = None,
        notes: str | None = None,
        duration: int | None = None,
        filter_expression: str | None = None,
        interface: str | None = None,
        advanced: CreateOrganizationDevicesPacketCaptureCaptureAdvanced | None = None,
    ) -> CreateOrganizationDevicesPacketCaptureCaptureResponse:
        """Perform a packet capture on a device and store in Meraki Cloud.

        [API documentation: createOrganizationDevicesPacketCaptureCapture](https://developer.cisco.com/meraki/api-v1/#!create-organization-devices-packet-capture-capture)

        Args:
            organization_id: Organization ID.
            serials: The serial(s) of the device(s).
            name: Name of packet capture file.
            output_type: Output type of packet capture file. Possible values: text, pcap,
                cloudshark, or upload_to_cloud.
            destination: Destination of packet capture file. Possible values: [upload_to_cloud].
            ports: Ports of packet capture file, comma-separated.
            notes: Reason for taking the packet capture.
            duration: Duration in seconds of packet capture.
            filter_expression: Filter expression for packet capture.
            interface: Interface of the device.
            advanced: Advanced filters for IOSXE devices (supported for Campus Gateway devices
                only).

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "captureId": "1234",
              "network": {
                "id": "N_24329156",
                "name": "Main Office"
              },
              "device": {
                "name": "My AP",
                "serial": "Q234-ABCD-5678"
              },
              "admin": {
                "id": "1234",
                "name": "Miles Meraki"
              },
              "client": {
                "id": "k74272e",
                "mac": "22:33:44:55:66:77"
              },
              "details": [
                {
                  "name": "reason",
                  "value": "bad_password",
                  "productType": "wireless"
                }
              ],
              "name": "file_name",
              "startTs": "2018-02-11T00:00:00.090210Z",
              "ports": "1, 2",
              "status": "new",
              "errorMessage": "Some error message",
              "destination": "upload_to_cloud",
              "process": "manual",
              "file": {
                "size": 1066
              },
              "duration": 60,
              "filterExpression": "(icmp)",
              "counts": {
                "packets": {
                  "total": 10
                }
              },
              "interface": "wired"
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/devices/packetCapture/captures"

        payload: dict[str, Any] = {}
        if serials is not None:
            payload["serials"] = serials
        if name is not None:
            payload["name"] = name
        if output_type is not None:
            payload["outputType"] = output_type
        if destination is not None:
            payload["destination"] = destination
        if ports is not None:
            payload["ports"] = ports
        if notes is not None:
            payload["notes"] = notes
        if duration is not None:
            payload["duration"] = duration
        if filter_expression is not None:
            payload["filterExpression"] = filter_expression
        if interface is not None:
            payload["interface"] = interface
        if advanced is not None:
            payload["advanced"] = advanced.model_dump(by_alias=True, exclude_none=True)

        return self._session.post(
            scope="organizations",
            operation_id="createOrganizationDevicesPacketCaptureCapture",
            path=path,
            json=payload,
            response_schema=CreateOrganizationDevicesPacketCaptureCaptureResponse,
        )

    def bulk_organization_devices_packet_capture_captures_create(
        self,
        *,
        organization_id: str,
        devices: list[BulkOrganizationDevicesPacketCaptureCapturesCreateDevicesItem],
        name: str,
        notes: str | None = None,
        duration: int | None = None,
        filter_expression: str | None = None,
        advanced: BulkOrganizationDevicesPacketCaptureCapturesCreateAdvanced | None = None,
    ) -> BulkOrganizationDevicesPacketCaptureCapturesCreateResponse:
        """Perform a packet capture on multiple devices and store in Meraki Cloud.

        [API documentation: bulkOrganizationDevicesPacketCaptureCapturesCreate](https://developer.cisco.com/meraki/api-v1/#!bulk-organization-devices-packet-capture-captures-create)

        Args:
            organization_id: Organization ID.
            devices: Device details (maximum of 20 devices allowed).
            notes: Reason for capture.
            duration: Duration of the capture in seconds.
            filter_expression: Filter expression for the capture.
            name: Name of packet capture file.
            advanced: Advanced capture options (optional).

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "items": [
                {
                  "captureId": "1234",
                  "network": {
                    "id": "N_24329156",
                    "name": "Main Office"
                  },
                  "device": {
                    "name": "My AP",
                    "serial": "Q234-ABCD-5678"
                  },
                  "admin": {
                    "id": "1234",
                    "name": "Miles Meraki"
                  },
                  "client": {
                    "id": "k74272e",
                    "mac": "22:33:44:55:66:77"
                  },
                  "details": [
                    {
                      "name": "reason",
                      "value": "bad_password",
                      "productType": "wireless"
                    }
                  ],
                  "name": "file_name",
                  "startTs": "2018-02-11T00:00:00.090210Z",
                  "ports": "1, 2",
                  "status": "new",
                  "errorMessage": "Some error message",
                  "destination": "upload_to_cloud",
                  "process": "manual",
                  "file": {
                    "size": 1066
                  },
                  "duration": 60,
                  "filterExpression": "(icmp)",
                  "counts": {
                    "packets": {
                      "total": 10
                    }
                  },
                  "interface": "wired"
                }
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/devices/packetCapture/captures/bulkCreate"

        payload: dict[str, Any] = {}
        if devices is not None:
            payload["devices"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in devices
            ]
        if notes is not None:
            payload["notes"] = notes
        if duration is not None:
            payload["duration"] = duration
        if filter_expression is not None:
            payload["filterExpression"] = filter_expression
        if name is not None:
            payload["name"] = name
        if advanced is not None:
            payload["advanced"] = advanced.model_dump(by_alias=True, exclude_none=True)

        return self._session.post(
            scope="organizations",
            operation_id="bulkOrganizationDevicesPacketCaptureCapturesCreate",
            path=path,
            json=payload,
            response_schema=BulkOrganizationDevicesPacketCaptureCapturesCreateResponse,
        )

    def bulk_organization_devices_packet_capture_captures_delete(
        self, *, organization_id: str, capture_ids: list[str]
    ) -> None:
        """BulkDelete packet captures from cloud.

        [API documentation: bulkOrganizationDevicesPacketCaptureCapturesDelete](https://developer.cisco.com/meraki/api-v1/#!bulk-organization-devices-packet-capture-captures-delete)

        Args:
            organization_id: Organization ID.
            capture_ids: Delete the packet captures of the specified capture ids.

        Returns:
            Successful operation.

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/devices/packetCapture/captures/bulkDelete"

        payload: dict[str, Any] = {}
        if capture_ids is not None:
            payload["captureIds"] = capture_ids

        return self._session.post(
            scope="organizations",
            operation_id="bulkOrganizationDevicesPacketCaptureCapturesDelete",
            path=path,
            json=payload,
        )

    def delete_organization_devices_packet_capture_capture(
        self, *, organization_id: str, capture_id: str
    ) -> None:
        """Delete a single packet capture from cloud using captureId.

        [API documentation: deleteOrganizationDevicesPacketCaptureCapture](https://developer.cisco.com/meraki/api-v1/#!delete-organization-devices-packet-capture-capture)

        Args:
            organization_id: Organization ID.
            capture_id: Capture ID.

        Returns:
            Successful operation.

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        capture_id = urllib.parse.quote(str(capture_id), safe="")
        path = f"/organizations/{organization_id}/devices/packetCapture/captures/{capture_id}"

        return self._session.delete(
            scope="organizations",
            operation_id="deleteOrganizationDevicesPacketCaptureCapture",
            path=path,
        )

    def generate_organization_devices_packet_capture_capture_download_url(
        self, *, organization_id: str, capture_id: str
    ) -> GenerateOrganizationDevicesPacketCaptureCaptureDownloadUrlResponse:
        """Get presigned download URL for given packet capture id.

        [API documentation: generateOrganizationDevicesPacketCaptureCaptureDownloadUrl](https://developer.cisco.com/meraki/api-v1/#!generate-organization-devices-packet-capture-capture-download-url)

        Args:
            organization_id: Organization ID.
            capture_id: Capture ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "captureId": "1234",
              "downloadUrl": "example.com",
              "url": "example.com"
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        capture_id = urllib.parse.quote(str(capture_id), safe="")
        path = f"/organizations/{organization_id}/devices/packetCapture/captures/{capture_id}/downloadUrl/generate"

        return self._session.post(
            scope="organizations",
            operation_id="generateOrganizationDevicesPacketCaptureCaptureDownloadUrl",
            path=path,
            response_schema=GenerateOrganizationDevicesPacketCaptureCaptureDownloadUrlResponse,
        )

    def stop_organization_devices_packet_capture_capture(
        self, *, organization_id: str, capture_id: str, serials: list[str]
    ) -> StopOrganizationDevicesPacketCaptureCaptureResponse:
        """Stop a specific packet capture (not supported for Catalyst devices).

        [API documentation: stopOrganizationDevicesPacketCaptureCapture](https://developer.cisco.com/meraki/api-v1/#!stop-organization-devices-packet-capture-capture)

        Args:
            organization_id: Organization ID.
            capture_id: Capture ID.
            serials: The serial(s) of the device(s) to stop the capture on.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "captureId": "1234",
              "network": {
                "id": "N_24329156",
                "name": "Main Office"
              },
              "device": {
                "name": "My AP",
                "serial": "Q234-ABCD-5678"
              },
              "admin": {
                "id": "1234",
                "name": "Miles Meraki"
              },
              "client": {
                "id": "k74272e",
                "mac": "22:33:44:55:66:77"
              },
              "details": [
                {
                  "name": "reason",
                  "value": "bad_password",
                  "productType": "wireless"
                }
              ],
              "name": "file_name",
              "startTs": "2018-02-11T00:00:00.090210Z",
              "ports": "1, 2",
              "status": "new",
              "errorMessage": "Some error message",
              "destination": "upload_to_cloud",
              "process": "manual",
              "file": {
                "size": 1066
              },
              "duration": 60,
              "filterExpression": "(icmp)",
              "counts": {
                "packets": {
                  "total": 10
                }
              },
              "interface": "wired"
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        capture_id = urllib.parse.quote(str(capture_id), safe="")
        path = f"/organizations/{organization_id}/devices/packetCapture/captures/{capture_id}/stop"

        payload: dict[str, Any] = {}
        if serials is not None:
            payload["serials"] = serials

        return self._session.post(
            scope="organizations",
            operation_id="stopOrganizationDevicesPacketCaptureCapture",
            path=path,
            json=payload,
            response_schema=StopOrganizationDevicesPacketCaptureCaptureResponse,
        )

    def get_organization_devices_packet_capture_schedules(
        self,
        organization_id: str,
        *,
        schedule_ids: list[str] | None = None,
        network_ids: list[str] | None = None,
        device_ids: list[str] | None = None,
    ) -> PaginatedResponse[GetOrganizationDevicesPacketCaptureSchedulesResponseItemsItem]:
        """List the Packet Capture Schedules.

        [API documentation: getOrganizationDevicesPacketCaptureSchedules](https://developer.cisco.com/meraki/api-v1/#!get-organization-devices-packet-capture-schedules)

        Args:
            organization_id: Organization ID.
            schedule_ids: Return the packet captures schedules of the specified packet capture
                schedule ids.
            network_ids: Return the scheduled packet captures of the specified network(s).
            device_ids: Return the scheduled packet captures of the specified device(s).

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            {
              "items": [
                {
                  "scheduleId": "1234",
                  "devices": [
                    {
                      "device": {
                        "serial": "Q234-ABCD-5678",
                        "switchports": "1-3, 9",
                        "interface": "GigabitEthernet1/0/1"
                      }
                    }
                  ],
                  "name": "pcap_file_name",
                  "admin": {
                    "id": "1234",
                    "name": "Miles Meraki"
                  },
                  "notes": "capture reason",
                  "duration": 60,
                  "filterExpression": "(icmp)",
                  "createdAt": "2018-02-11T00:00:00.090210Z",
                  "updatedAt": "2018-02-11T00:00:00.090210Z",
                  "captureCount": 2,
                  "lastCaptureId": "1234",
                  "enabled": true,
                  "priority": 1,
                  "schedule": {
                    "name": "schedule_name",
                    "startTs": "2018-02-11T00:00:00.090210Z",
                    "endTs": "2018-02-11T00:00:00.090210Z",
                    "frequency": "hour",
                    "weekdays": [
                      "Monday",
                      "Tuesday"
                    ],
                    "recurrence": 1,
                    "nextCaptureTs": "2018-02-11T00:00:00.090210Z"
                  },
                  "warnings": [
                    "This schedule conflicts with the schedule Test Schedule at the time 2025-01-28T18:25:06Z"
                  ]
                }
              ],
              "meta": {
                "counts": {
                  "items": {
                    "total": 100
                  }
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/devices/packetCapture/schedules"

        params: dict[str, Any] = {}
        if schedule_ids is not None:
            params["scheduleIds[]"] = schedule_ids
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if device_ids is not None:
            params["deviceIds[]"] = device_ids

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationDevicesPacketCaptureSchedules",
            path=path,
            params=params,
            item_schema=GetOrganizationDevicesPacketCaptureSchedulesResponseItemsItem,
        )

    def create_organization_devices_packet_capture_schedule(
        self,
        *,
        organization_id: str,
        devices: list[CreateOrganizationDevicesPacketCaptureScheduleDevicesItem],
        name: str | None = None,
        notes: str | None = None,
        duration: int | None = None,
        filter_expression: str | None = None,
        enabled: bool | None = None,
        schedule: CreateOrganizationDevicesPacketCaptureScheduleSchedule | None = None,
    ) -> CreateOrganizationDevicesPacketCaptureScheduleResponse:
        """Create a schedule for packet capture.

        [API documentation: createOrganizationDevicesPacketCaptureSchedule](https://developer.cisco.com/meraki/api-v1/#!create-organization-devices-packet-capture-schedule)

        Args:
            organization_id: Organization ID.
            devices: device details.
            name: Name of the packet capture file.
            notes: Reason for capture.
            duration: Duration of the capture in seconds.
            filter_expression: Filter expression for the capture.
            enabled: Enable or disable the schedule.
            schedule: Schedule details.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "scheduleId": "1234",
              "devices": [
                {
                  "device": {
                    "serial": "Q234-ABCD-5678",
                    "switchports": "1-3, 9",
                    "interface": "GigabitEthernet1/0/1"
                  }
                }
              ],
              "name": "pcap_file_name",
              "admin": {
                "id": "1234",
                "name": "Miles Meraki"
              },
              "notes": "capture reason",
              "duration": 60,
              "filterExpression": "(icmp)",
              "createdAt": "2018-02-11T00:00:00.090210Z",
              "updatedAt": "2018-02-11T00:00:00.090210Z",
              "captureCount": 2,
              "lastCaptureId": "1234",
              "enabled": true,
              "priority": 1,
              "schedule": {
                "name": "schedule_name",
                "startTs": "2018-02-11T00:00:00.090210Z",
                "endTs": "2018-02-11T00:00:00.090210Z",
                "frequency": "hour",
                "weekdays": [
                  "Monday",
                  "Tuesday"
                ],
                "recurrence": 1,
                "nextCaptureTs": "2018-02-11T00:00:00.090210Z"
              },
              "warnings": [
                "This schedule conflicts with the schedule Test Schedule at the time 2025-01-28T18:25:06Z"
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/devices/packetCapture/schedules"

        payload: dict[str, Any] = {}
        if devices is not None:
            payload["devices"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in devices
            ]
        if name is not None:
            payload["name"] = name
        if notes is not None:
            payload["notes"] = notes
        if duration is not None:
            payload["duration"] = duration
        if filter_expression is not None:
            payload["filterExpression"] = filter_expression
        if enabled is not None:
            payload["enabled"] = enabled
        if schedule is not None:
            payload["schedule"] = schedule.model_dump(by_alias=True, exclude_none=True)

        return self._session.post(
            scope="organizations",
            operation_id="createOrganizationDevicesPacketCaptureSchedule",
            path=path,
            json=payload,
            response_schema=CreateOrganizationDevicesPacketCaptureScheduleResponse,
        )

    def reorder_organization_devices_packet_capture_schedules(
        self,
        *,
        organization_id: str,
        order: list[ReorderOrganizationDevicesPacketCaptureSchedulesOrderItem],
    ) -> ReorderOrganizationDevicesPacketCaptureSchedulesResponse:
        """Bulk update priorities of pcap schedules.

        [API documentation: reorderOrganizationDevicesPacketCaptureSchedules](https://developer.cisco.com/meraki/api-v1/#!reorder-organization-devices-packet-capture-schedules)

        Args:
            organization_id: Organization ID.
            order: Array of schedule IDs and their priorities to reorder.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "updatedPriorities": [
                {
                  "scheduleId": "1234",
                  "priority": 1
                }
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/devices/packetCapture/schedules/reorder"

        payload: dict[str, Any] = {}
        if order is not None:
            payload["order"] = [item.model_dump(by_alias=True, exclude_none=True) for item in order]

        return self._session.post(
            scope="organizations",
            operation_id="reorderOrganizationDevicesPacketCaptureSchedules",
            path=path,
            json=payload,
            response_schema=ReorderOrganizationDevicesPacketCaptureSchedulesResponse,
        )

    def update_organization_devices_packet_capture_schedule(
        self,
        *,
        organization_id: str,
        schedule_id: str,
        devices: list[UpdateOrganizationDevicesPacketCaptureScheduleDevicesItem],
        name: str | None = None,
        notes: str | None = None,
        duration: int | None = None,
        filter_expression: str | None = None,
        enabled: bool | None = None,
        schedule: UpdateOrganizationDevicesPacketCaptureScheduleSchedule | None = None,
    ) -> UpdateOrganizationDevicesPacketCaptureScheduleResponse:
        """Update a schedule for packet capture.

        [API documentation: updateOrganizationDevicesPacketCaptureSchedule](https://developer.cisco.com/meraki/api-v1/#!update-organization-devices-packet-capture-schedule)

        Args:
            organization_id: Organization ID.
            schedule_id: Schedule ID.
            devices: device details.
            name: Name of the packet capture file.
            notes: Reason for capture.
            duration: Duration of the capture in seconds.
            filter_expression: Filter expression for the capture.
            enabled: Enable or disable the schedule.
            schedule: Schedule details.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "scheduleId": "1234",
              "devices": [
                {
                  "device": {
                    "serial": "Q234-ABCD-5678",
                    "switchports": "1-3, 9",
                    "interface": "GigabitEthernet1/0/1"
                  }
                }
              ],
              "name": "pcap_file_name",
              "admin": {
                "id": "1234",
                "name": "Miles Meraki"
              },
              "notes": "capture reason",
              "duration": 60,
              "filterExpression": "(icmp)",
              "createdAt": "2018-02-11T00:00:00.090210Z",
              "updatedAt": "2018-02-11T00:00:00.090210Z",
              "captureCount": 2,
              "lastCaptureId": "1234",
              "enabled": true,
              "priority": 1,
              "schedule": {
                "name": "schedule_name",
                "startTs": "2018-02-11T00:00:00.090210Z",
                "endTs": "2018-02-11T00:00:00.090210Z",
                "frequency": "hour",
                "weekdays": [
                  "Monday",
                  "Tuesday"
                ],
                "recurrence": 1,
                "nextCaptureTs": "2018-02-11T00:00:00.090210Z"
              },
              "warnings": [
                "This schedule conflicts with the schedule Test Schedule at the time 2025-01-28T18:25:06Z"
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        schedule_id = urllib.parse.quote(str(schedule_id), safe="")
        path = f"/organizations/{organization_id}/devices/packetCapture/schedules/{schedule_id}"

        payload: dict[str, Any] = {}
        if devices is not None:
            payload["devices"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in devices
            ]
        if name is not None:
            payload["name"] = name
        if notes is not None:
            payload["notes"] = notes
        if duration is not None:
            payload["duration"] = duration
        if filter_expression is not None:
            payload["filterExpression"] = filter_expression
        if enabled is not None:
            payload["enabled"] = enabled
        if schedule is not None:
            payload["schedule"] = schedule.model_dump(by_alias=True, exclude_none=True)

        return self._session.put(
            scope="organizations",
            operation_id="updateOrganizationDevicesPacketCaptureSchedule",
            path=path,
            json=payload,
            response_schema=UpdateOrganizationDevicesPacketCaptureScheduleResponse,
        )

    def delete_organization_devices_packet_capture_schedule(
        self, *, organization_id: str, schedule_id: str
    ) -> None:
        """Delete schedule from cloud.

        [API documentation: deleteOrganizationDevicesPacketCaptureSchedule](https://developer.cisco.com/meraki/api-v1/#!delete-organization-devices-packet-capture-schedule)

        Args:
            organization_id: Organization ID.
            schedule_id: Schedule ID.

        Returns:
            Successful operation.

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        schedule_id = urllib.parse.quote(str(schedule_id), safe="")
        path = f"/organizations/{organization_id}/devices/packetCapture/schedules/{schedule_id}"

        payload: dict[str, Any] = {}
        if schedule_id is not None:
            payload["scheduleId"] = schedule_id

        return self._session.delete(
            scope="organizations",
            operation_id="deleteOrganizationDevicesPacketCaptureSchedule",
            path=path,
        )

    def get_organization_devices_power_modules_statuses_by_device(
        self,
        organization_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        network_ids: list[str] | None = None,
        product_types: list[str] | None = None,
        serials: list[str] | None = None,
        tags: list[str] | None = None,
        tags_filter_type: GetOrganizationDevicesPowerModulesStatusesByDeviceTagsFilterType
        | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetOrganizationDevicesPowerModulesStatusesByDeviceResponseItem]:
        """List the most recent status information for power modules in rackmount MX and MS devices that support them.

        [API documentation: getOrganizationDevicesPowerModulesStatusesByDevice](https://developer.cisco.com/meraki/api-v1/#!get-organization-devices-power-modules-statuses-by-device)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            network_ids: Optional parameter to filter device availabilities by network ID. This
                filter uses multiple exact matches.
            product_types: Optional parameter to filter device availabilities by device product
                types. This filter uses multiple exact matches.
            serials: Optional parameter to filter device availabilities by device serial numbers.
                This filter uses multiple exact matches.
            tags: An optional parameter to filter devices by tags. The filtering is case-sensitive.
                If tags are included, 'tagsFilterType' should also be included (see
                below). This filter uses multiple exact matches.
            tags_filter_type: An optional parameter of value 'withAnyTags' or 'withAllTags' to
                indicate whether to return devices which contain ANY or ALL of the
                included tags. If no type is included, 'withAnyTags' will be selected.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "mac": "00:11:22:33:44:55",
                "name": "My AP",
                "network": {
                  "id": "N_24329156"
                },
                "productType": "switch",
                "serial": "Q234-ABCD-5678",
                "tags": [
                  "tag1",
                  "tag2"
                ],
                "slots": [
                  {
                    "number": 1,
                    "serial": "Q234-ABCD-5678",
                    "model": "PWR-C5-125WAC",
                    "status": "not connected"
                  }
                ]
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/devices/powerModules/statuses/byDevice"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if product_types is not None:
            params["productTypes[]"] = product_types
        if serials is not None:
            params["serials[]"] = serials
        if tags is not None:
            params["tags[]"] = tags
        if tags_filter_type is not None:
            params["tagsFilterType"] = tags_filter_type

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationDevicesPowerModulesStatusesByDevice",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationDevicesPowerModulesStatusesByDeviceResponseItem,
        )

    def get_organization_devices_provisioning_statuses(
        self,
        organization_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        network_ids: list[str] | None = None,
        product_types: list[str] | None = None,
        serials: list[str] | None = None,
        status: GetOrganizationDevicesProvisioningStatusesStatus | None = None,
        tags: list[str] | None = None,
        tags_filter_type: GetOrganizationDevicesProvisioningStatusesTagsFilterType | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetOrganizationDevicesProvisioningStatusesResponseItem]:
        """List the provisioning statuses information for devices in an organization.

        [API documentation: getOrganizationDevicesProvisioningStatuses](https://developer.cisco.com/meraki/api-v1/#!get-organization-devices-provisioning-statuses)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            network_ids: Optional parameter to filter device by network ID. This filter uses
                multiple exact matches.
            product_types: Optional parameter to filter device by device product types. This filter
                uses multiple exact matches.
            serials: Optional parameter to filter device by device serial numbers. This filter uses
                multiple exact matches.
            status: An optional parameter to filter devices by the provisioning status. Accepted
                statuses: unprovisioned, incomplete, complete.
            tags: An optional parameter to filter devices by tags. The filtering is case-sensitive.
                If tags are included, 'tagsFilterType' should also be included (see
                below). This filter uses multiple exact matches.
            tags_filter_type: An optional parameter of value 'withAnyTags' or 'withAllTags' to
                indicate whether to return devices which contain ANY or ALL of the
                included tags. If no type is included, 'withAnyTags' will be selected.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "mac": "00:11:22:33:44:55",
                "name": "My AP",
                "network": {
                  "id": "N_24329156"
                },
                "productType": "switch",
                "serial": "Q234-ABCD-5678",
                "status": "complete",
                "tags": [
                  "tag1",
                  "tag2"
                ]
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/devices/provisioning/statuses"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if product_types is not None:
            params["productTypes[]"] = product_types
        if serials is not None:
            params["serials[]"] = serials
        if status is not None:
            params["status"] = status
        if tags is not None:
            params["tags[]"] = tags
        if tags_filter_type is not None:
            params["tagsFilterType"] = tags_filter_type

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationDevicesProvisioningStatuses",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationDevicesProvisioningStatusesResponseItem,
        )

    def get_organization_devices_statuses(
        self,
        organization_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        network_ids: list[str] | None = None,
        serials: list[str] | None = None,
        statuses: GetOrganizationDevicesStatusesStatuses | None = None,
        product_types: GetOrganizationDevicesStatusesProductTypes | None = None,
        models: list[str] | None = None,
        tags: list[str] | None = None,
        tags_filter_type: GetOrganizationDevicesStatusesTagsFilterType | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetOrganizationDevicesStatusesResponseItem]:
        """List the status of every Meraki device in the organization.

        [API documentation: getOrganizationDevicesStatuses](https://developer.cisco.com/meraki/api-v1/#!get-organization-devices-statuses)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            network_ids: Optional parameter to filter devices by network ids.
            serials: Optional parameter to filter devices by serials.
            statuses: Optional parameter to filter devices by statuses. Valid statuses are
                ["online", "alerting", "offline", "dormant"].
            product_types: An optional parameter to filter device statuses by product type. Valid
                types are wireless, appliance, switch, systemsManager, camera,
                cellularGateway, sensor, wirelessController, campusGateway, and
                secureConnect.
            models: Optional parameter to filter devices by models.
            tags: An optional parameter to filter devices by tags. The filtering is case-sensitive.
                If tags are included, 'tagsFilterType' should also be included (see
                below).
            tags_filter_type: An optional parameter of value 'withAnyTags' or 'withAllTags' to
                indicate whether to return devices which contain ANY or ALL of the
                included tags. If no type is included, 'withAnyTags' will be selected.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "name": "My AP",
                "serial": "Q234-ABCD-5678",
                "mac": "00:11:22:33:44:55",
                "publicIp": "123.123.123.1",
                "networkId": "N_24329156",
                "status": "online",
                "lastReportedAt": "2018-02-11T00:00:00.090210Z",
                "lanIp": "1.2.3.4",
                "gateway": "1.2.3.5",
                "ipType": "dhcp",
                "primaryDns": "8.8.8.8",
                "secondaryDns": "8.8.4.4",
                "productType": "wireless",
                "components": {
                  "powerSupplies": [
                    {
                      "slot": 1,
                      "serial": "QABC-1234-5678",
                      "model": "PWR-MS320-1025WAC",
                      "status": "powering",
                      "poe": {
                        "unit": "watts",
                        "maximum": 740
                      }
                    }
                  ]
                },
                "model": "MR34",
                "tags": [
                  "tag1",
                  "tag2"
                ]
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/devices/statuses"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if serials is not None:
            params["serials[]"] = serials
        if statuses is not None:
            params["statuses[]"] = statuses
        if product_types is not None:
            params["productTypes[]"] = product_types
        if models is not None:
            params["models[]"] = models
        if tags is not None:
            params["tags[]"] = tags
        if tags_filter_type is not None:
            params["tagsFilterType"] = tags_filter_type

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationDevicesStatuses",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationDevicesStatusesResponseItem,
        )

    def get_organization_devices_statuses_overview(
        self,
        organization_id: str,
        *,
        product_types: GetOrganizationDevicesStatusesOverviewProductTypes | None = None,
        network_ids: list[str] | None = None,
    ) -> GetOrganizationDevicesStatusesOverviewResponse:
        """Return an overview of current device statuses.

        [API documentation: getOrganizationDevicesStatusesOverview](https://developer.cisco.com/meraki/api-v1/#!get-organization-devices-statuses-overview)

        Args:
            organization_id: Organization ID.
            product_types: An optional parameter to filter device statuses by product type. Valid
                types are wireless, appliance, switch, systemsManager, camera,
                cellularGateway, sensor, wirelessController, campusGateway, and
                secureConnect.
            network_ids: An optional parameter to filter device statuses by network.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "counts": {
                "byStatus": {
                  "online": 5,
                  "alerting": 4,
                  "offline": 2,
                  "dormant": 1
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/devices/statuses/overview"

        params: dict[str, Any] = {}
        if product_types is not None:
            params["productTypes[]"] = product_types
        if network_ids is not None:
            params["networkIds[]"] = network_ids

        return self._session.get(
            scope="organizations",
            operation_id="getOrganizationDevicesStatusesOverview",
            path=path,
            params=params,
            response_schema=GetOrganizationDevicesStatusesOverviewResponse,
        )

    def get_organization_devices_system_memory_usage_history_by_interval(
        self,
        organization_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        interval: int | None = None,
        network_ids: list[str] | None = None,
        serials: list[str] | None = None,
        product_types: GetOrganizationDevicesSystemMemoryUsageHistoryByIntervalProductTypes
        | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[
        GetOrganizationDevicesSystemMemoryUsageHistoryByIntervalResponseItemsItem
    ]:
        """Return the memory utilization history in kB for devices in the organization.

        [API documentation: getOrganizationDevicesSystemMemoryUsageHistoryByInterval](https://developer.cisco.com/meraki/api-v1/#!get-organization-devices-system-memory-usage-history-by-interval)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 20. Default
                is 10.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            t0: The beginning of the timespan for the data. The maximum lookback period is 31 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 31 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 31 days. The default is 2 hours. If
                interval is provided, the timespan will be autocalculated.
            interval: The time interval in seconds for returned data. The valid intervals are: 300,
                1200, 3600, 14400. The default is 300. Interval is calculated if time
                params are provided.
            network_ids: Optional parameter to filter the result set by the included set of network
                IDs.
            serials: Optional parameter to filter device availabilities history by device serial
                numbers.
            product_types: Optional parameter to filter device statuses by product type. Valid types
                are wireless, appliance, switch, systemsManager, camera,
                cellularGateway, sensor, wirelessController, campusGateway, and
                secureConnect.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            {
              "items": [
                {
                  "serial": "Q234-ABCD-0001",
                  "model": "MS",
                  "name": "My switch",
                  "mac": "00:11:22:33:44:55",
                  "tags": [
                    "tag1",
                    "tag2"
                  ],
                  "provisioned": 300,
                  "used": {
                    "median": 100
                  },
                  "free": {
                    "median": 150
                  },
                  "network": {
                    "id": "N_24329156",
                    "name": "Main Office",
                    "tags": [
                      "tag1",
                      "tag2"
                    ]
                  },
                  "intervals": [
                    {
                      "startTs": "2018-02-11T00:00:00.090210Z",
                      "endTs": "2018-02-11T00:00:00.090210Z",
                      "memory": {
                        "used": {
                          "minimum": 50,
                          "maximum": 150,
                          "median": 100,
                          "percentages": {
                            "maximum": 60
                          }
                        },
                        "free": {
                          "minimum": 100,
                          "maximum": 200,
                          "median": 150
                        }
                      }
                    }
                  ]
                }
              ],
              "meta": {
                "counts": {
                  "items": {
                    "total": 4,
                    "remaining": 2
                  }
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/devices/system/memory/usage/history/byInterval"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan
        if interval is not None:
            params["interval"] = interval
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if serials is not None:
            params["serials[]"] = serials
        if product_types is not None:
            params["productTypes[]"] = product_types

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationDevicesSystemMemoryUsageHistoryByInterval",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationDevicesSystemMemoryUsageHistoryByIntervalResponseItemsItem,
        )

    def get_organization_devices_uplinks_addresses_by_device(
        self,
        organization_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        network_ids: list[str] | None = None,
        product_types: list[str] | None = None,
        serials: list[str] | None = None,
        tags: list[str] | None = None,
        tags_filter_type: GetOrganizationDevicesUplinksAddressesByDeviceTagsFilterType
        | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetOrganizationDevicesUplinksAddressesByDeviceResponseItem]:
        """List the current uplink addresses for devices in an organization.

        [API documentation: getOrganizationDevicesUplinksAddressesByDevice](https://developer.cisco.com/meraki/api-v1/#!get-organization-devices-uplinks-addresses-by-device)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            network_ids: Optional parameter to filter device uplinks by network ID. This filter uses
                multiple exact matches.
            product_types: Optional parameter to filter device uplinks by device product types. This
                filter uses multiple exact matches.
            serials: Optional parameter to filter device availabilities by device serial numbers.
                This filter uses multiple exact matches.
            tags: An optional parameter to filter devices by tags. The filtering is case-sensitive.
                If tags are included, 'tagsFilterType' should also be included (see
                below). This filter uses multiple exact matches.
            tags_filter_type: An optional parameter of value 'withAnyTags' or 'withAllTags' to
                indicate whether to return devices which contain ANY or ALL of the
                included tags. If no type is included, 'withAnyTags' will be selected.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "mac": "00:11:22:33:44:55",
                "name": "My AP",
                "network": {
                  "id": "N_24329156"
                },
                "productType": "switch",
                "serial": "Q234-ABCD-5678",
                "tags": [
                  "tag1",
                  "tag2"
                ],
                "uplinks": [
                  {
                    "interface": "wan1",
                    "addresses": [
                      {
                        "protocol": "ipv6",
                        "assignmentMode": "static",
                        "address": "2001:db8:c15:c0:d0c::101:ca75",
                        "gateway": "fe80:db8:c15:c0:d0c::10ca:1d02",
                        "nameservers": {
                          "addresses": [
                            "8.8.8.8"
                          ]
                        },
                        "public": {
                          "address": "2001:db8:c15:c0:d0c:15e:15e:bab1"
                        },
                        "vlan": {
                          "id": "1"
                        }
                      }
                    ]
                  }
                ]
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/devices/uplinks/addresses/byDevice"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if product_types is not None:
            params["productTypes[]"] = product_types
        if serials is not None:
            params["serials[]"] = serials
        if tags is not None:
            params["tags[]"] = tags
        if tags_filter_type is not None:
            params["tagsFilterType"] = tags_filter_type

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationDevicesUplinksAddressesByDevice",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationDevicesUplinksAddressesByDeviceResponseItem,
        )

    def get_organization_devices_uplinks_loss_and_latency(
        self,
        organization_id: str,
        *,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        uplink: GetOrganizationDevicesUplinksLossAndLatencyUplink | None = None,
        ip: str | None = None,
    ) -> PaginatedResponse[GetOrganizationDevicesUplinksLossAndLatencyResponseItem]:
        """Return the uplink loss and latency for every MX in the organization from at latest 2 minutes ago.

        [API documentation: getOrganizationDevicesUplinksLossAndLatency](https://developer.cisco.com/meraki/api-v1/#!get-organization-devices-uplinks-loss-and-latency)

        Args:
            organization_id: Organization ID.
            t0: The beginning of the timespan for the data. The maximum lookback period is 60 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 5 minutes after t0. The
                latest possible time that t1 can be is 2 minutes into the past.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 5 minutes. The default is 5
                minutes.
            uplink: Optional filter for a specific WAN uplink. Valid uplinks are wan1, wan2, wan3,
                cellular. Default will return all uplinks.
            ip: Optional filter for a specific destination IP. Default will return all destination
                IPs.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "networkId": "N_24329156",
                "serial": "Q234-ABCD-5678",
                "uplink": "wan1",
                "ip": "1.2.3.4",
                "timeSeries": [
                  {
                    "ts": "2019-01-31T18:46:13Z",
                    "lossPercent": 5.3,
                    "latencyMs": 194.9
                  }
                ]
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/devices/uplinksLossAndLatency"

        params: dict[str, Any] = {}
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan
        if uplink is not None:
            params["uplink"] = uplink
        if ip is not None:
            params["ip"] = ip

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationDevicesUplinksLossAndLatency",
            path=path,
            params=params,
            item_schema=GetOrganizationDevicesUplinksLossAndLatencyResponseItem,
        )

    def get_organization_early_access_features(
        self, organization_id: str
    ) -> PaginatedResponse[GetOrganizationEarlyAccessFeaturesResponseItem]:
        """List the available early access features for organization.

        [API documentation: getOrganizationEarlyAccessFeatures](https://developer.cisco.com/meraki/api-v1/#!get-organization-early-access-features)

        Args:
            organization_id: Organization ID.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "shortName": "has_new_feature",
                "name": "New Feature Beta",
                "descriptions": {
                  "short": "New Feature Beta",
                  "long": "New Feature Beta long description. consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."
                },
                "topic": "Dashboard",
                "isOrgScopedOnly": true,
                "documentationLink": "https://documentation.meraki.com/",
                "supportLink": "https://community.meraki.com/",
                "privacyLink": "https://meraki.com/privacy"
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/earlyAccess/features"

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationEarlyAccessFeatures",
            path=path,
            item_schema=GetOrganizationEarlyAccessFeaturesResponseItem,
        )

    def get_organization_early_access_features_opt_ins(
        self, organization_id: str
    ) -> PaginatedResponse[OrganizationsPolicyObjectsItem]:
        """List the early access feature opt-ins for an organization.

        [API documentation: getOrganizationEarlyAccessFeaturesOptIns](https://developer.cisco.com/meraki/api-v1/#!get-organization-early-access-features-opt-ins)

        Args:
            organization_id: Organization ID.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            {
              "id": "1",
              "shortName": "has_new_feature",
              "limitScopeToNetworks": [
                {
                  "id": "L_1234",
                  "name": "My Network"
                }
              ],
              "optOutEligibility": {
                "eligible": false,
                "reason": "Please remove devices of type XYZ from your organization",
                "help": {
                  "label": "Read more",
                  "url": "http://meraki.com/my_help"
                }
              },
              "createdAt": "2022-05-01T04:07:15Z"
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/earlyAccess/features/optIns"

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationEarlyAccessFeaturesOptIns",
            path=path,
            item_schema=OrganizationsPolicyObjectsItem,
        )

    def create_organization_early_access_features_opt_in(
        self,
        *,
        organization_id: str,
        short_name: str,
        limit_scope_to_networks: list[str] | None = None,
    ) -> CreateOrganizationEarlyAccessFeaturesOptInResponse:
        """Create a new early access feature opt-in for an organization.

        [API documentation: createOrganizationEarlyAccessFeaturesOptIn](https://developer.cisco.com/meraki/api-v1/#!create-organization-early-access-features-opt-in)

        Args:
            organization_id: Organization ID.
            short_name: Short name of the early access feature.
            limit_scope_to_networks: A list of network IDs to apply the opt-in to.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "1",
              "shortName": "has_new_feature",
              "limitScopeToNetworks": [
                {
                  "id": "L_1234",
                  "name": "My Network"
                }
              ],
              "optOutEligibility": {
                "eligible": false,
                "reason": "Please remove devices of type XYZ from your organization",
                "help": {
                  "label": "Read more",
                  "url": "http://meraki.com/my_help"
                }
              },
              "createdAt": "2022-05-01T04:07:15Z"
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/earlyAccess/features/optIns"

        payload: dict[str, Any] = {}
        if short_name is not None:
            payload["shortName"] = short_name
        if limit_scope_to_networks is not None:
            payload["limitScopeToNetworks"] = limit_scope_to_networks

        return self._session.post(
            scope="organizations",
            operation_id="createOrganizationEarlyAccessFeaturesOptIn",
            path=path,
            json=payload,
            response_schema=CreateOrganizationEarlyAccessFeaturesOptInResponse,
        )

    def get_organization_early_access_features_opt_in(
        self, *, organization_id: str, opt_in_id: str
    ) -> GetOrganizationEarlyAccessFeaturesOptInResponse:
        """Show an early access feature opt-in for an organization.

        [API documentation: getOrganizationEarlyAccessFeaturesOptIn](https://developer.cisco.com/meraki/api-v1/#!get-organization-early-access-features-opt-in)

        Args:
            organization_id: Organization ID.
            opt_in_id: Opt in ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "1",
              "shortName": "has_new_feature",
              "limitScopeToNetworks": [
                {
                  "id": "L_1234",
                  "name": "My Network"
                }
              ],
              "optOutEligibility": {
                "eligible": false,
                "reason": "Please remove devices of type XYZ from your organization",
                "help": {
                  "label": "Read more",
                  "url": "http://meraki.com/my_help"
                }
              },
              "createdAt": "2022-05-01T04:07:15Z"
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        opt_in_id = urllib.parse.quote(str(opt_in_id), safe="")
        path = f"/organizations/{organization_id}/earlyAccess/features/optIns/{opt_in_id}"

        return self._session.get(
            scope="organizations",
            operation_id="getOrganizationEarlyAccessFeaturesOptIn",
            path=path,
            response_schema=GetOrganizationEarlyAccessFeaturesOptInResponse,
        )

    def update_organization_early_access_features_opt_in(
        self,
        *,
        organization_id: str,
        opt_in_id: str,
        limit_scope_to_networks: list[str] | None = None,
    ) -> UpdateOrganizationEarlyAccessFeaturesOptInResponse:
        """Update an early access feature opt-in for an organization.

        [API documentation: updateOrganizationEarlyAccessFeaturesOptIn](https://developer.cisco.com/meraki/api-v1/#!update-organization-early-access-features-opt-in)

        Args:
            organization_id: Organization ID.
            opt_in_id: Opt in ID.
            limit_scope_to_networks: A list of network IDs to apply the opt-in to.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "1",
              "shortName": "has_new_feature",
              "limitScopeToNetworks": [
                {
                  "id": "L_1234",
                  "name": "My Network"
                }
              ],
              "optOutEligibility": {
                "eligible": false,
                "reason": "Please remove devices of type XYZ from your organization",
                "help": {
                  "label": "Read more",
                  "url": "http://meraki.com/my_help"
                }
              },
              "createdAt": "2022-05-01T04:07:15Z"
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        opt_in_id = urllib.parse.quote(str(opt_in_id), safe="")
        path = f"/organizations/{organization_id}/earlyAccess/features/optIns/{opt_in_id}"

        payload: dict[str, Any] = {}
        if limit_scope_to_networks is not None:
            payload["limitScopeToNetworks"] = limit_scope_to_networks

        return self._session.put(
            scope="organizations",
            operation_id="updateOrganizationEarlyAccessFeaturesOptIn",
            path=path,
            json=payload,
            response_schema=UpdateOrganizationEarlyAccessFeaturesOptInResponse,
        )

    def delete_organization_early_access_features_opt_in(
        self, *, organization_id: str, opt_in_id: str
    ) -> None:
        """Delete an early access feature opt-in.

        [API documentation: deleteOrganizationEarlyAccessFeaturesOptIn](https://developer.cisco.com/meraki/api-v1/#!delete-organization-early-access-features-opt-in)

        Args:
            organization_id: Organization ID.
            opt_in_id: Opt in ID.

        Returns:
            Successful operation.

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        opt_in_id = urllib.parse.quote(str(opt_in_id), safe="")
        path = f"/organizations/{organization_id}/earlyAccess/features/optIns/{opt_in_id}"

        return self._session.delete(
            scope="organizations",
            operation_id="deleteOrganizationEarlyAccessFeaturesOptIn",
            path=path,
        )

    def get_organization_firmware_upgrades(
        self,
        organization_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        status: list[str] | None = None,
        product_types: list[str] | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetOrganizationFirmwareUpgradesResponseItem]:
        """Get firmware upgrade information for an organization.

        [API documentation: getOrganizationFirmwareUpgrades](https://developer.cisco.com/meraki/api-v1/#!get-organization-firmware-upgrades)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            status: Optional parameter to filter the upgrade by status.
            product_types: Optional parameter to filter the upgrade by product type.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "upgradeId": "1234",
                "upgradeBatchId": "5678",
                "network": {
                  "id": "L_1738",
                  "name": "Minions"
                },
                "status": "Completed",
                "time": "2022-11-01T00:00:00Z",
                "completedAt": "2020-11-05 15:50:05 UTC",
                "productTypes": "wireless",
                "toVersion": {
                  "id": "2888",
                  "shortName": "MR 11.2.1",
                  "firmware": "wireless-11-2-1",
                  "releaseType": "stable",
                  "releaseDate": "2022-03-17T17:22:52Z"
                },
                "fromVersion": {
                  "id": "2887",
                  "shortName": "MR 11.2.1",
                  "firmware": "wireless-11-2-1",
                  "releaseType": "stable",
                  "releaseDate": "2022-03-17T17:22:52Z"
                }
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/firmware/upgrades"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if status is not None:
            params["status[]"] = status
        if product_types is not None:
            params["productTypes[]"] = product_types

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationFirmwareUpgrades",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationFirmwareUpgradesResponseItem,
        )

    def get_organization_firmware_upgrades_by_device(
        self,
        organization_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        network_ids: list[str] | None = None,
        serials: list[str] | None = None,
        macs: list[str] | None = None,
        firmware_upgrade_batch_ids: list[str] | None = None,
        upgrade_statuses: GetOrganizationFirmwareUpgradesByDeviceUpgradeStatuses | None = None,
        current_upgrades_only: bool | None = None,
        limit_per_device: int | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetOrganizationFirmwareUpgradesByDeviceResponseItem]:
        """Get firmware upgrade status for the filtered devices.

        [API documentation: getOrganizationFirmwareUpgradesByDevice](https://developer.cisco.com/meraki/api-v1/#!get-organization-firmware-upgrades-by-device)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 50.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            network_ids: Optional parameter to filter by network.
            serials: Optional parameter to filter by serial number. All returned devices will have a
                serial number that is an exact match.
            macs: Optional parameter to filter by one or more MAC addresses belonging to devices.
                All devices returned belong to MAC addresses that are an exact match.
            firmware_upgrade_batch_ids: Optional parameter to filter by firmware upgrade batch ids.
            upgrade_statuses: Optional parameter to filter by firmware upgrade statuses.
            current_upgrades_only: Optional parameter to filter to only current or pending upgrade
                statuses.
            limit_per_device: Optional parameter to limit the number of upgrade statuses returned
                per device. If omitted, a value of 5 is used.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "serial": "Q234-ABCD-5678",
                "name": "My switch",
                "deviceStatus": "completed",
                "checkinFinishedAt": "2025-06-26T13:22:52Z",
                "checkinStartedAt": "2025-06-26T12:22:52Z",
                "detailedStatus": "upgrade-complete",
                "downloadFinishedAt": "2025-06-26T15:22:52Z",
                "downloadStartedAt": "2025-06-26T14:22:52Z",
                "downloadStatus": "complete",
                "installFinishedAt": "2025-06-26T17:22:52Z",
                "installStartedAt": "2025-06-26T16:22:52Z",
                "installStatus": "complete",
                "verifyFinishedAt": "2025-06-26T19:22:52Z",
                "verifyStartedAt": "2025-06-26T18:22:52Z",
                "verifyStatus": "complete",
                "upgrade": {
                  "time": "2018-02-11T00:00:00.090210Z",
                  "fromVersion": {
                    "id": "1234",
                    "shortName": "MS 16.7",
                    "releaseDate": "2018-02-11T00:00:00.090210Z"
                  },
                  "toVersion": {
                    "id": "1234",
                    "shortName": "MS 16.7.1",
                    "releaseDate": "2018-02-11T00:00:00.090210Z"
                  },
                  "status": "Completed",
                  "id": "1234",
                  "upgradeBatchId": "1234",
                  "staged": {
                    "group": {
                      "id": "1234"
                    }
                  }
                }
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/firmware/upgrades/byDevice"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if serials is not None:
            params["serials[]"] = serials
        if macs is not None:
            params["macs[]"] = macs
        if firmware_upgrade_batch_ids is not None:
            params["firmwareUpgradeBatchIds[]"] = firmware_upgrade_batch_ids
        if upgrade_statuses is not None:
            params["upgradeStatuses[]"] = upgrade_statuses
        if current_upgrades_only is not None:
            params["currentUpgradesOnly"] = current_upgrades_only
        if limit_per_device is not None:
            params["limitPerDevice"] = limit_per_device

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationFirmwareUpgradesByDevice",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationFirmwareUpgradesByDeviceResponseItem,
        )

    def get_organization_floor_plans_auto_locate_devices(
        self,
        organization_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        network_ids: list[str] | None = None,
        floor_plan_ids: list[str] | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetOrganizationFloorPlansAutoLocateDevicesResponseItem]:
        """List auto locate details for each device in your organization.

        [API documentation: getOrganizationFloorPlansAutoLocateDevices](https://developer.cisco.com/meraki/api-v1/#!get-organization-floor-plans-auto-locate-devices)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 10000.
                Default is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            network_ids: Optional parameter to filter devices by one or more network IDs.
            floor_plan_ids: Optional parameter to filter devices by one or more floorplan IDs.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "items": [
                  {
                    "name": "My AP",
                    "serial": "Q234-ABCD-5678",
                    "mac": "00:11:22:33:44:55",
                    "model": "MR34",
                    "tags": [
                      "tag1",
                      "tag2"
                    ],
                    "status": "online",
                    "network": {
                      "id": "N_24329156"
                    },
                    "floorPlan": {
                      "id": "g_2176982374",
                      "name": "My floor plan"
                    },
                    "lat": 37.4180951010362,
                    "lng": -122.098531723022,
                    "autoLocate": {
                      "lat": 13.23454243,
                      "lng": 18.12938123
                    },
                    "type": "user",
                    "isAnchor": true
                  }
                ],
                "meta": {
                  "counts": {
                    "items": {
                      "total": 50,
                      "remaining": 100
                    }
                  }
                }
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/floorPlans/autoLocate/devices"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if floor_plan_ids is not None:
            params["floorPlanIds[]"] = floor_plan_ids

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationFloorPlansAutoLocateDevices",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationFloorPlansAutoLocateDevicesResponseItem,
        )

    def get_organization_floor_plans_auto_locate_statuses(
        self,
        organization_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        network_ids: list[str] | None = None,
        floor_plan_ids: list[str] | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetOrganizationFloorPlansAutoLocateStatusesResponseItem]:
        """List the status of auto locate for each floorplan in your organization.

        [API documentation: getOrganizationFloorPlansAutoLocateStatuses](https://developer.cisco.com/meraki/api-v1/#!get-organization-floor-plans-auto-locate-statuses)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 10000.
                Default is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            network_ids: Optional parameter to filter floorplans by one or more network IDs.
            floor_plan_ids: Optional parameter to filter floorplans by one or more floorplan IDs.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "items": [
                  {
                    "network": {
                      "id": "N_24329156"
                    },
                    "floorPlanId": "g_2176982374",
                    "name": "My Floorplan",
                    "counts": {
                      "devices": {
                        "total": 120
                      }
                    },
                    "jobs": [
                      {
                        "id": "1234",
                        "status": "error",
                        "scheduledAt": "2018-02-11T00:00:00Z",
                        "completed": {
                          "percentage": 50
                        },
                        "ranging": {
                          "status": "in progress",
                          "completed": {
                            "percentage": 24
                          }
                        },
                        "gnss": {
                          "status": "in progress",
                          "completed": {
                            "percentage": 4
                          }
                        },
                        "errors": [
                          {
                            "source": "ranging",
                            "type": "missing anchors"
                          }
                        ]
                      }
                    ]
                  }
                ],
                "meta": {
                  "counts": {
                    "items": {
                      "total": 50,
                      "remaining": 100
                    }
                  }
                }
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/floorPlans/autoLocate/statuses"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if floor_plan_ids is not None:
            params["floorPlanIds[]"] = floor_plan_ids

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationFloorPlansAutoLocateStatuses",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationFloorPlansAutoLocateStatusesResponseItem,
        )

    def get_organization_integrations_xdr_networks(
        self,
        organization_id: str,
        *,
        network_ids: list[str] | None = None,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetOrganizationIntegrationsXdrNetworksResponseItemsItem]:
        """Returns the networks in the organization that have XDR enabled.

        [API documentation: getOrganizationIntegrationsXdrNetworks](https://developer.cisco.com/meraki/api-v1/#!get-organization-integrations-xdr-networks)

        Args:
            organization_id: Organization ID.
            network_ids: Optional parameter to filter the results by network IDs.
            per_page: The number of entries per page returned. Acceptable range is 3 - 100. Default
                is 20.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            {
              "items": [
                {
                  "networkId": "N_1234567",
                  "productTypes": [
                    "appliance"
                  ],
                  "name": "Test network",
                  "enabled": true,
                  "isEligible": true
                }
              ],
              "meta": {
                "counts": {
                  "items": {
                    "total": 10,
                    "remaining": 0
                  }
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/integrations/xdr/networks"

        params: dict[str, Any] = {}
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationIntegrationsXdrNetworks",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationIntegrationsXdrNetworksResponseItemsItem,
        )

    def disable_organization_integrations_xdr_networks(
        self,
        *,
        organization_id: str,
        networks: list[DisableOrganizationIntegrationsXdrNetworksNetworksItem],
    ) -> DisableOrganizationIntegrationsXdrNetworksResponse:
        """Disable XDR on networks.

        [API documentation: disableOrganizationIntegrationsXdrNetworks](https://developer.cisco.com/meraki/api-v1/#!disable-organization-integrations-xdr-networks)

        Args:
            organization_id: Organization ID.
            networks: List containing the network ID and the product type to disable XDR on.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "networks": [
                {
                  "networkId": "N_1234567",
                  "productTypes": [
                    "appliance"
                  ],
                  "name": "Test network",
                  "enabled": false,
                  "isEligible": true
                }
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/integrations/xdr/networks/disable"

        payload: dict[str, Any] = {}
        if networks is not None:
            payload["networks"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in networks
            ]

        return self._session.post(
            scope="organizations",
            operation_id="disableOrganizationIntegrationsXdrNetworks",
            path=path,
            json=payload,
            response_schema=DisableOrganizationIntegrationsXdrNetworksResponse,
        )

    def enable_organization_integrations_xdr_networks(
        self,
        *,
        organization_id: str,
        networks: list[EnableOrganizationIntegrationsXdrNetworksNetworksItem],
    ) -> EnableOrganizationIntegrationsXdrNetworksResponse:
        """Enable XDR on networks.

        [API documentation: enableOrganizationIntegrationsXdrNetworks](https://developer.cisco.com/meraki/api-v1/#!enable-organization-integrations-xdr-networks)

        Args:
            organization_id: Organization ID.
            networks: List containing the network ID and the product type to enable XDR on.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "networks": [
                {
                  "networkId": "N_1234567",
                  "productTypes": [
                    "appliance"
                  ],
                  "name": "Test network",
                  "enabled": true,
                  "isEligible": true
                }
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/integrations/xdr/networks/enable"

        payload: dict[str, Any] = {}
        if networks is not None:
            payload["networks"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in networks
            ]

        return self._session.post(
            scope="organizations",
            operation_id="enableOrganizationIntegrationsXdrNetworks",
            path=path,
            json=payload,
            response_schema=EnableOrganizationIntegrationsXdrNetworksResponse,
        )

    def claim_into_organization_inventory(
        self,
        organization_id: str,
        *,
        orders: list[str] | None = None,
        serials: list[str] | None = None,
        licenses: list[ClaimIntoOrganizationInventoryLicensesItem] | None = None,
    ) -> ClaimIntoOrganizationInventoryResponse:
        """Claim a list of devices, licenses, and/or orders into an organization inventory.

        [API documentation: claimIntoOrganizationInventory](https://developer.cisco.com/meraki/api-v1/#!claim-into-organization-inventory)

        Args:
            organization_id: Organization ID.
            orders: The numbers of the orders that should be claimed.
            serials: The serials of the devices that should be claimed.
            licenses: The licenses that should be claimed.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "orders": [
                "4CXXXXXXX"
              ],
              "serials": [
                "Q234-ABCD-5678"
              ],
              "licenses": [
                {
                  "key": "Z2XXXXXXXXXX",
                  "mode": "addDevices"
                }
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/inventory/claim"

        payload: dict[str, Any] = {}
        if orders is not None:
            payload["orders"] = orders
        if serials is not None:
            payload["serials"] = serials
        if licenses is not None:
            payload["licenses"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in licenses
            ]

        return self._session.post(
            scope="organizations",
            operation_id="claimIntoOrganizationInventory",
            path=path,
            json=payload,
            response_schema=ClaimIntoOrganizationInventoryResponse,
        )

    def get_organization_inventory_devices(
        self,
        organization_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        used_state: GetOrganizationInventoryDevicesUsedState | None = None,
        search: str | None = None,
        macs: list[str] | None = None,
        network_ids: list[str] | None = None,
        serials: list[str] | None = None,
        models: list[str] | None = None,
        order_numbers: list[str] | None = None,
        tags: list[str] | None = None,
        tags_filter_type: GetOrganizationInventoryDevicesTagsFilterType | None = None,
        product_types: GetOrganizationInventoryDevicesProductTypes | None = None,
        eox_statuses: GetOrganizationInventoryDevicesEoxStatuses | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetOrganizationInventoryDevicesResponseItem]:
        """Return the device inventory for an organization.

        [API documentation: getOrganizationInventoryDevices](https://developer.cisco.com/meraki/api-v1/#!get-organization-inventory-devices)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            used_state: Filter results by used or unused inventory. Accepted values are 'used' or
                'unused'.
            search: Search for devices in inventory based on serial number, mac address, or model.
            macs: Search for devices in inventory based on mac addresses.
            network_ids: Search for devices in inventory based on network ids. Use explicit 'null'
                value to get available devices only.
            serials: Search for devices in inventory based on serials.
            models: Search for devices in inventory based on model.
            order_numbers: Search for devices in inventory based on order numbers.
            tags: Filter devices by tags. The filtering is case-sensitive. If tags are included,
                'tagsFilterType' should also be included (see below).
            tags_filter_type: To use with 'tags' parameter, to filter devices which contain ANY or
                ALL given tags. Accepted values are 'withAnyTags' or 'withAllTags',
                default is 'withAnyTags'.
            product_types: Filter devices by product type. Accepted values are appliance, camera,
                campusGateway, cellularGateway, secureConnect, sensor, switch,
                systemsManager, wireless, and wirelessController.
            eox_statuses: Filter devices by EoX status. Accepted values are 'endOfSale',
                'endOfSupport', 'nearEndOfSupport', or 'null'. Use 'null' to filter for
                devices with no EOX data. Supports multiple values for multi-select
                filtering.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "mac": "00:11:22:33:44:55",
                "serial": "Q234-ABCD-5678",
                "name": "My AP",
                "model": "MR34",
                "networkId": "N_24329156",
                "orderNumber": "4C1234567",
                "claimedAt": "2018-02-11T00:00:00.090210Z",
                "licenseExpirationDate": "2020-05-02T10:52:44.012345Z",
                "tags": [
                  "tag1",
                  "tag2"
                ],
                "productType": "wireless",
                "countryCode": "US",
                "details": [
                  {
                    "name": "Catalyst serial",
                    "value": "FOC2234432B"
                  }
                ],
                "eox": {
                  "status": "endOfSale",
                  "endOfSaleAt": "2031-07-29T02:00:00Z",
                  "endOfSupportAt": "2032-07-29T02:00:00Z"
                }
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/inventory/devices"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if used_state is not None:
            params["usedState"] = used_state
        if search is not None:
            params["search"] = search
        if macs is not None:
            params["macs[]"] = macs
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if serials is not None:
            params["serials[]"] = serials
        if models is not None:
            params["models[]"] = models
        if order_numbers is not None:
            params["orderNumbers[]"] = order_numbers
        if tags is not None:
            params["tags[]"] = tags
        if tags_filter_type is not None:
            params["tagsFilterType"] = tags_filter_type
        if product_types is not None:
            params["productTypes[]"] = product_types
        if eox_statuses is not None:
            params["eoxStatuses[]"] = eox_statuses

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationInventoryDevices",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationInventoryDevicesResponseItem,
        )

    def get_organization_inventory_devices_eox_overview(
        self, organization_id: str
    ) -> GetOrganizationInventoryDevicesEoxOverviewResponse:
        """Fetch the EOX summary for an organization, including counts of devices that are end-of-sale, end-of-support, and end-of-support-soon.

        [API documentation: getOrganizationInventoryDevicesEoxOverview](https://developer.cisco.com/meraki/api-v1/#!get-organization-inventory-devices-eox-overview)

        Args:
            organization_id: Organization ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "counts": {
                "byStatus": {
                  "endOfSale": {
                    "total": 5
                  },
                  "endOfSupport": {
                    "total": 3
                  },
                  "nearEndOfSupport": {
                    "total": 7
                  }
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/inventory/devices/eox/overview"

        return self._session.get(
            scope="organizations",
            operation_id="getOrganizationInventoryDevicesEoxOverview",
            path=path,
            response_schema=GetOrganizationInventoryDevicesEoxOverviewResponse,
        )

    def create_organization_inventory_devices_swaps_bulk(
        self,
        *,
        organization_id: str,
        swaps: list[CreateOrganizationInventoryDevicesSwapsBulkSwapsItem],
    ) -> CreateOrganizationInventoryDevicesSwapsBulkResponse:
        """Swap the devices identified by devices.old with a devices.new, then perform the :afterAction on the devices.old.

        [API documentation: createOrganizationInventoryDevicesSwapsBulk](https://developer.cisco.com/meraki/api-v1/#!create-organization-inventory-devices-swaps-bulk)

        Args:
            organization_id: Organization ID.
            swaps: List of replacments to perform.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "jobId": "1284392014819",
              "swaps": [
                {
                  "id": "1284392014819",
                  "devices": {
                    "old": {
                      "mac": "00:11:22:33:44:55",
                      "serial": "Q234-ABCD-5678",
                      "model": "MR34",
                      "name": "My AP"
                    },
                    "new": {
                      "mac": "00:11:22:33:44:55",
                      "serial": "Q234-ABCD-5678",
                      "model": "MR34",
                      "name": "My AP"
                    }
                  },
                  "status": "complete",
                  "afterAction": "remove from network",
                  "createdAt": "2023-04-24T12:40:11Z",
                  "completedAt": "2023-04-24T12:40:12Z",
                  "errors": []
                }
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/inventory/devices/swaps/bulk"

        payload: dict[str, Any] = {}
        if swaps is not None:
            payload["swaps"] = [item.model_dump(by_alias=True, exclude_none=True) for item in swaps]

        return self._session.post(
            scope="organizations",
            operation_id="createOrganizationInventoryDevicesSwapsBulk",
            path=path,
            json=payload,
            response_schema=CreateOrganizationInventoryDevicesSwapsBulkResponse,
        )

    def get_organization_inventory_devices_swaps_bulk(
        self, *, organization_id: str, id: str
    ) -> GetOrganizationInventoryDevicesSwapsBulkResponse:
        """List of device swaps for a given request ID ({id}).

        [API documentation: getOrganizationInventoryDevicesSwapsBulk](https://developer.cisco.com/meraki/api-v1/#!get-organization-inventory-devices-swaps-bulk)

        Args:
            organization_id: Organization ID.
            id: ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "jobId": "1284392014819",
              "swaps": [
                {
                  "id": "1284392014819",
                  "devices": {
                    "old": {
                      "mac": "00:11:22:33:44:55",
                      "serial": "Q234-ABCD-5678",
                      "model": "MR34",
                      "name": "My AP"
                    },
                    "new": {
                      "mac": "00:11:22:33:44:55",
                      "serial": "Q234-ABCD-5678",
                      "model": "MR34",
                      "name": "My AP"
                    }
                  },
                  "status": "complete",
                  "afterAction": "remove from network",
                  "createdAt": "2023-04-24T12:40:11Z",
                  "completedAt": "2023-04-24T12:40:12Z",
                  "errors": []
                }
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        id = urllib.parse.quote(str(id), safe="")
        path = f"/organizations/{organization_id}/inventory/devices/swaps/bulk/{id}"

        return self._session.get(
            scope="organizations",
            operation_id="getOrganizationInventoryDevicesSwapsBulk",
            path=path,
            response_schema=GetOrganizationInventoryDevicesSwapsBulkResponse,
        )

    def get_organization_inventory_device(
        self, *, organization_id: str, serial: str
    ) -> GetOrganizationInventoryDeviceResponse:
        """Return a single device from the inventory of an organization.

        [API documentation: getOrganizationInventoryDevice](https://developer.cisco.com/meraki/api-v1/#!get-organization-inventory-device)

        Args:
            organization_id: Organization ID.
            serial: Serial.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "mac": "00:11:22:33:44:55",
              "serial": "Q234-ABCD-5678",
              "name": "My AP",
              "model": "MR34",
              "networkId": "N_24329156",
              "orderNumber": "4C1234567",
              "claimedAt": "2018-02-11T00:00:00.090210Z",
              "licenseExpirationDate": "2020-05-02T10:52:44.012345Z",
              "tags": [
                "tag1",
                "tag2"
              ],
              "productType": "wireless",
              "countryCode": "US",
              "details": [
                {
                  "name": "Catalyst serial",
                  "value": "FOC2234432B"
                }
              ],
              "eox": {
                "status": "endOfSale",
                "endOfSaleAt": "2031-07-29T02:00:00Z",
                "endOfSupportAt": "2032-07-29T02:00:00Z"
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        serial = urllib.parse.quote(str(serial), safe="")
        path = f"/organizations/{organization_id}/inventory/devices/{serial}"

        return self._session.get(
            scope="organizations",
            operation_id="getOrganizationInventoryDevice",
            path=path,
            response_schema=GetOrganizationInventoryDeviceResponse,
        )

    def create_organization_inventory_onboarding_cloud_monitoring_export_event(
        self,
        *,
        organization_id: str,
        log_event: str,
        timestamp: int,
        target_os: str | None = None,
        request: str | None = None,
    ) -> DictResponse:
        """Imports event logs related to the onboarding app into elastisearch.

        [API documentation: createOrganizationInventoryOnboardingCloudMonitoringExportEvent](https://developer.cisco.com/meraki/api-v1/#!create-organization-inventory-onboarding-cloud-monitoring-export-event)

        Args:
            organization_id: Organization ID.
            log_event: The type of log event this is recording, e.g. download or opening a banner.
            timestamp: A JavaScript UTC datetime stamp for when the even occurred.
            target_os: The name of the onboarding distro being downloaded.
            request: Used to describe if this event was the result of a redirect. E.g. a query param
                if an info banner is being used.

        Returns:
            Successful operation.

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/inventory/onboarding/cloudMonitoring/exportEvents"

        payload: dict[str, Any] = {}
        if log_event is not None:
            payload["logEvent"] = log_event
        if timestamp is not None:
            payload["timestamp"] = timestamp
        if target_os is not None:
            payload["targetOS"] = target_os
        if request is not None:
            payload["request"] = request

        return self._session.post(
            scope="organizations",
            operation_id="createOrganizationInventoryOnboardingCloudMonitoringExportEvent",
            path=path,
            json=payload,
            response_schema=DictResponse,
        )

    def get_organization_inventory_onboarding_cloud_monitoring_imports(
        self, *, organization_id: str, import_ids: list[str]
    ) -> PaginatedResponse[GetOrganizationInventoryOnboardingCloudMonitoringImportsResponseItem]:
        """Check the status of a committed Import operation.

        [API documentation: getOrganizationInventoryOnboardingCloudMonitoringImports](https://developer.cisco.com/meraki/api-v1/#!get-organization-inventory-onboarding-cloud-monitoring-imports)

        Args:
            organization_id: Organization ID.
            import_ids: import ids from an imports.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "importId": "0000000000000000",
                "device": {
                  "url": "https://n1.meraki.com//n//manage/nodes/new_list/000000000000",
                  "created": true,
                  "status": "SUCCESS"
                }
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/inventory/onboarding/cloudMonitoring/imports"

        params: dict[str, Any] = {}
        if import_ids is not None:
            params["importIds[]"] = import_ids

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationInventoryOnboardingCloudMonitoringImports",
            path=path,
            params=params,
            item_schema=GetOrganizationInventoryOnboardingCloudMonitoringImportsResponseItem,
        )

    def create_organization_inventory_onboarding_cloud_monitoring_import(
        self,
        *,
        organization_id: str,
        devices: list[CreateOrganizationInventoryOnboardingCloudMonitoringImportDevicesItem],
    ) -> CreateOrganizationInventoryOnboardingCloudMonitoringImportResponse:
        """Commits the import operation to complete the onboarding of a device into Dashboard for monitoring.

        [API documentation: createOrganizationInventoryOnboardingCloudMonitoringImport](https://developer.cisco.com/meraki/api-v1/#!create-organization-inventory-onboarding-cloud-monitoring-import)

        Args:
            organization_id: Organization ID.
            devices: A set of device imports to commit.

        Returns:
            Successful operation.

        Example API response:
            ```json
            [
              {
                "status": "IMPORT JOB SUCCESS",
                "importId": "1234",
                "message": "Import Started"
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/inventory/onboarding/cloudMonitoring/imports"

        payload: dict[str, Any] = {}
        if devices is not None:
            payload["devices"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in devices
            ]

        return self._session.post(
            scope="organizations",
            operation_id="createOrganizationInventoryOnboardingCloudMonitoringImport",
            path=path,
            json=payload,
            response_schema=CreateOrganizationInventoryOnboardingCloudMonitoringImportResponse,
        )

    def get_organization_inventory_onboarding_cloud_monitoring_networks(
        self,
        *,
        organization_id: str,
        device_type: GetOrganizationInventoryOnboardingCloudMonitoringNetworksDeviceType,
        search: str | None = None,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetOrganizationInventoryOnboardingCloudMonitoringNetworksResponseItem]:
        """Returns list of networks eligible for adding cloud monitored device.

        [API documentation: getOrganizationInventoryOnboardingCloudMonitoringNetworks](https://developer.cisco.com/meraki/api-v1/#!get-organization-inventory-onboarding-cloud-monitoring-networks)

        Args:
            organization_id: Organization ID.
            device_type: Device Type switch or wireless controller.
            search: Optional parameter to search on network name.
            per_page: The number of entries per page returned. Acceptable range is 3 - 100000.
                Default is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "id": "N_24329156",
                "organizationId": "2930418",
                "name": "Main Office",
                "productTypes": [
                  "appliance",
                  "switch",
                  "wireless"
                ],
                "timeZone": "America/Los_Angeles",
                "tags": [
                  "tag1",
                  "tag2"
                ],
                "enrollmentString": "my-enrollment-string",
                "url": "https://n1.meraki.com//n//manage/nodes/list",
                "notes": "Additional description of the network",
                "isBoundToConfigTemplate": false
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/inventory/onboarding/cloudMonitoring/networks"

        params: dict[str, Any] = {}
        if device_type is not None:
            params["deviceType"] = device_type
        if search is not None:
            params["search"] = search
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationInventoryOnboardingCloudMonitoringNetworks",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationInventoryOnboardingCloudMonitoringNetworksResponseItem,
        )

    def create_organization_inventory_onboarding_cloud_monitoring_prepare(
        self,
        *,
        organization_id: str,
        devices: list[CreateOrganizationInventoryOnboardingCloudMonitoringPrepareDevicesItem],
        options: CreateOrganizationInventoryOnboardingCloudMonitoringPrepareOptions | None = None,
    ) -> CreateOrganizationInventoryOnboardingCloudMonitoringPrepareResponse:
        """Initiates or updates an import session.

        [API documentation: createOrganizationInventoryOnboardingCloudMonitoringPrepare](https://developer.cisco.com/meraki/api-v1/#!create-organization-inventory-onboarding-cloud-monitoring-prepare)

        Args:
            organization_id: Organization ID.
            devices: A set of devices to import (or update).
            options: Additional options for the import.

        Returns:
            Successful operation.

        Example API response:
            ```json
            [
              {
                "message": "Existing import found",
                "udi": "PID:C9200L-24P-4G SN:JAE25220R2K",
                "deviceId": "161b2602-a713-4aac-b1eb-d9b55205353d",
                "status": "SUCCESS",
                "configParams": {
                  "tunnel": {
                    "mode": "443",
                    "port": "443",
                    "host": "secgw-int3.ciscocloudoffer.com",
                    "name": "MERAKI-PRIMARY",
                    "rootCertificate": {
                      "content": "",
                      "name": "MERAKI_TLSGW_CA"
                    }
                  },
                  "cloudStaticIp": "1.2.3.4",
                  "user": {
                    "publicKey": "",
                    "username": "MERAKI_USER",
                    "secret": {
                      "hash": ""
                    }
                  }
                }
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/inventory/onboarding/cloudMonitoring/prepare"

        payload: dict[str, Any] = {}
        if devices is not None:
            payload["devices"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in devices
            ]
        if options is not None:
            payload["options"] = options.model_dump(by_alias=True, exclude_none=True)

        return self._session.post(
            scope="organizations",
            operation_id="createOrganizationInventoryOnboardingCloudMonitoringPrepare",
            path=path,
            json=payload,
            response_schema=CreateOrganizationInventoryOnboardingCloudMonitoringPrepareResponse,
        )

    def claim_organization_inventory_orders(
        self,
        *,
        organization_id: str,
        claim_id: str,
        subscriptions: list[ClaimOrganizationInventoryOrdersSubscriptionsItem] | None = None,
    ) -> ClaimOrganizationInventoryOrdersResponse:
        """Claim an order by the secure unique order claim number, the order claim id.

        [API documentation: claimOrganizationInventoryOrders](https://developer.cisco.com/meraki/api-v1/#!claim-organization-inventory-orders)

        Args:
            organization_id: Organization ID.
            claim_id: The unique order claim id.
            subscriptions: The individual subscriptions to claim.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "claimId": "ABCDEFG12345",
              "number": "97001888",
              "serials": [
                "1234-ABCD-4567"
              ],
              "subscriptions": [
                {
                  "subscriptionId": "1234",
                  "name": "My UNX Subscription",
                  "description": "Wireless Networking Subscription",
                  "startDate": "2020-06-30T00:00:00Z",
                  "endDate": "2025-06-30T00:00:00Z",
                  "isClaimed": false,
                  "counts": {
                    "seats": {
                      "limit": 1
                    }
                  }
                }
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/inventory/orders/claim"

        payload: dict[str, Any] = {}
        if claim_id is not None:
            payload["claimId"] = claim_id
        if subscriptions is not None:
            payload["subscriptions"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in subscriptions
            ]

        return self._session.post(
            scope="organizations",
            operation_id="claimOrganizationInventoryOrders",
            path=path,
            json=payload,
            response_schema=ClaimOrganizationInventoryOrdersResponse,
        )

    def preview_organization_inventory_orders(
        self, *, organization_id: str, claim_id: str
    ) -> PreviewOrganizationInventoryOrdersResponse:
        """Preview the results and status of an order claim by the secure order id.

        [API documentation: previewOrganizationInventoryOrders](https://developer.cisco.com/meraki/api-v1/#!preview-organization-inventory-orders)

        Args:
            organization_id: Organization ID.
            claim_id: The unique order claim id.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "claimId": "ABCD1EFGH4IJ",
              "number": "97001888",
              "shipping": {
                "shipments": [
                  {
                    "shippedAt": "2024-06-30T00:00:00Z",
                    "number": 1,
                    "devices": [
                      {
                        "quantity": 5,
                        "sku": "MR70-HW",
                        "description": "Meraki MR70 Cloud Managed AP"
                      }
                    ]
                  }
                ],
                "pending": {
                  "devices": [
                    {
                      "quantity": 1,
                      "sku": "MR70-HW",
                      "description": "Meraki MX90 Cloud Managed Security Appliance"
                    }
                  ]
                }
              },
              "subscriptions": [
                {
                  "subscriptionId": "1234",
                  "name": "My UNX Subscription",
                  "description": "Wireless Networking Subscription",
                  "startDate": "2020-06-30T00:00:00Z",
                  "endDate": "2025-06-30T00:00:00Z",
                  "isClaimed": false,
                  "counts": {
                    "seats": {
                      "limit": 1
                    }
                  }
                }
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/inventory/orders/preview"

        payload: dict[str, Any] = {}
        if claim_id is not None:
            payload["claimId"] = claim_id

        return self._session.post(
            scope="organizations",
            operation_id="previewOrganizationInventoryOrders",
            path=path,
            json=payload,
            response_schema=PreviewOrganizationInventoryOrdersResponse,
        )

    def release_from_organization_inventory(
        self, organization_id: str, *, serials: list[str] | None = None
    ) -> ReleaseFromOrganizationInventoryResponse:
        """Release a list of claimed devices from an organization.

        [API documentation: releaseFromOrganizationInventory](https://developer.cisco.com/meraki/api-v1/#!release-from-organization-inventory)

        Args:
            organization_id: Organization ID.
            serials: Serials of the devices that should be released.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "serials": [
                "Q234-ABCD-5678"
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/inventory/release"

        payload: dict[str, Any] = {}
        if serials is not None:
            payload["serials"] = serials

        return self._session.post(
            scope="organizations",
            operation_id="releaseFromOrganizationInventory",
            path=path,
            json=payload,
            response_schema=ReleaseFromOrganizationInventoryResponse,
        )

    def get_organization_licenses(
        self,
        organization_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        device_serial: str | None = None,
        network_id: str | None = None,
        state: GetOrganizationLicensesState | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetOrganizationLicensesResponseItem]:
        """List the licenses for an organization.

        [API documentation: getOrganizationLicenses](https://developer.cisco.com/meraki/api-v1/#!get-organization-licenses)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            device_serial: Filter the licenses to those assigned to a particular device. Returned in
                the same order that they are queued to the device.
            network_id: Filter the licenses to those assigned in a particular network.
            state: Filter the licenses to those in a particular state. Can be one of 'active',
                'expired', 'expiring', 'recentlyQueued', 'unused' or 'unusedActive'.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "id": "1234",
                "licenseType": "MX64-ENT",
                "licenseKey": "Z21234567890",
                "orderNumber": "4C1234567",
                "deviceSerial": "Q234-ABCD-5678",
                "networkId": "N_24329156",
                "state": "active",
                "seatCount": 25,
                "totalDurationInDays": 425,
                "durationInDays": 365,
                "permanentlyQueuedLicenses": [
                  {
                    "id": "1234",
                    "licenseType": "MX64-ENT",
                    "licenseKey": "Z21234567890",
                    "orderNumber": "4C1234567",
                    "durationInDays": 60
                  }
                ],
                "claimDate": "2019-08-29T12:40:10Z",
                "activationDate": "2019-09-01T15:01:46Z",
                "expirationDate": "2020-10-30T15:01:46Z",
                "headLicenseId": "1234"
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/licenses"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if device_serial is not None:
            params["deviceSerial"] = device_serial
        if network_id is not None:
            params["networkId"] = network_id
        if state is not None:
            params["state"] = state

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationLicenses",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationLicensesResponseItem,
        )

    def assign_organization_licenses_seats(
        self, *, organization_id: str, license_id: str, network_id: str, seat_count: int
    ) -> AssignOrganizationLicensesSeatsResponse:
        """Assign SM seats to a network.

        [API documentation: assignOrganizationLicensesSeats](https://developer.cisco.com/meraki/api-v1/#!assign-organization-licenses-seats)

        Args:
            organization_id: Organization ID.
            license_id: The ID of the SM license to assign seats from.
            network_id: The ID of the SM network to assign the seats to.
            seat_count: The number of seats to assign to the SM network. Must be less than or equal
                to the total number of seats of the license.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "resultingLicenses": [
                {
                  "id": "1234",
                  "licenseType": "SME",
                  "licenseKey": "Z21234567890",
                  "orderNumber": "4C1234567",
                  "deviceSerial": "Q234-ABCD-5678",
                  "networkId": "N_24329156",
                  "state": "active",
                  "seatCount": 25,
                  "totalDurationInDays": 425,
                  "durationInDays": 365,
                  "permanentlyQueuedLicenses": [
                    {
                      "id": "1234",
                      "licenseType": "SME",
                      "licenseKey": "Z21234567890",
                      "orderNumber": "4C1234567",
                      "durationInDays": 60
                    }
                  ],
                  "claimDate": "2019-08-29T12:40:10Z",
                  "activationDate": "2019-09-01T15:01:46Z",
                  "expirationDate": "2020-10-30T15:01:46Z",
                  "headLicenseId": "1234"
                }
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/licenses/assignSeats"

        payload: dict[str, Any] = {}
        if license_id is not None:
            payload["licenseId"] = license_id
        if network_id is not None:
            payload["networkId"] = network_id
        if seat_count is not None:
            payload["seatCount"] = seat_count

        return self._session.post(
            scope="organizations",
            operation_id="assignOrganizationLicensesSeats",
            path=path,
            json=payload,
            response_schema=AssignOrganizationLicensesSeatsResponse,
        )

    def move_organization_licenses(
        self, *, organization_id: str, dest_organization_id: str, license_ids: list[str]
    ) -> MoveOrganizationLicensesResponse:
        """Move licenses to another organization.

        [API documentation: moveOrganizationLicenses](https://developer.cisco.com/meraki/api-v1/#!move-organization-licenses)

        Args:
            organization_id: Organization ID.
            dest_organization_id: The ID of the organization to move the licenses to.
            license_ids: A list of IDs of licenses to move to the new organization.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "destOrganizationId": "2930418",
              "licenseIds": [
                "123",
                "456"
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/licenses/move"

        payload: dict[str, Any] = {}
        if dest_organization_id is not None:
            payload["destOrganizationId"] = dest_organization_id
        if license_ids is not None:
            payload["licenseIds"] = license_ids

        return self._session.post(
            scope="organizations",
            operation_id="moveOrganizationLicenses",
            path=path,
            json=payload,
            response_schema=MoveOrganizationLicensesResponse,
        )

    def move_organization_licenses_seats(
        self, *, organization_id: str, dest_organization_id: str, license_id: str, seat_count: int
    ) -> MoveOrganizationLicensesSeatsResponse:
        """Move SM seats to another organization.

        [API documentation: moveOrganizationLicensesSeats](https://developer.cisco.com/meraki/api-v1/#!move-organization-licenses-seats)

        Args:
            organization_id: Organization ID.
            dest_organization_id: The ID of the organization to move the SM seats to.
            license_id: The ID of the SM license to move the seats from.
            seat_count: The number of seats to move to the new organization. Must be less than or
                equal to the total number of seats of the license.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "destOrganizationId": "2930418",
              "licenseId": "1234",
              "seatCount": 20
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/licenses/moveSeats"

        payload: dict[str, Any] = {}
        if dest_organization_id is not None:
            payload["destOrganizationId"] = dest_organization_id
        if license_id is not None:
            payload["licenseId"] = license_id
        if seat_count is not None:
            payload["seatCount"] = seat_count

        return self._session.post(
            scope="organizations",
            operation_id="moveOrganizationLicensesSeats",
            path=path,
            json=payload,
            response_schema=MoveOrganizationLicensesSeatsResponse,
        )

    def get_organization_licenses_overview(
        self, organization_id: str
    ) -> GetOrganizationLicensesOverviewResponse:
        """Return an overview of the license state for an organization.

        [API documentation: getOrganizationLicensesOverview](https://developer.cisco.com/meraki/api-v1/#!get-organization-licenses-overview)

        Args:
            organization_id: Organization ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "status": "OK",
              "expirationDate": "Feb 8, 2020 UTC",
              "licensedDeviceCounts": {
                "MS": 100
              },
              "licenseCount": 20,
              "states": {
                "active": {
                  "count": 10
                },
                "expired": {
                  "count": 2
                },
                "expiring": {
                  "count": 3,
                  "critical": {
                    "thresholdInDays": 14,
                    "expiringCount": 1
                  },
                  "warning": {
                    "thresholdInDays": 90,
                    "expiringCount": 2
                  }
                },
                "recentlyQueued": {
                  "count": 0
                },
                "unused": {
                  "count": 2,
                  "soonestActivation": {
                    "activationDate": "2020-10-30",
                    "toActivateCount": 1
                  }
                },
                "unusedActive": {
                  "count": 3,
                  "oldestActivation": {
                    "activationDate": "2019-09-01",
                    "activeCount": 2
                  }
                }
              },
              "licenseTypes": [
                {
                  "licenseType": "ENT",
                  "counts": {
                    "unassigned": 2
                  }
                }
              ],
              "systemsManager": {
                "counts": {
                  "totalSeats": 50,
                  "activeSeats": 10,
                  "unassignedSeats": 20,
                  "orgwideEnrolledDevices": 10
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/licenses/overview"

        return self._session.get(
            scope="organizations",
            operation_id="getOrganizationLicensesOverview",
            path=path,
            response_schema=GetOrganizationLicensesOverviewResponse,
        )

    def renew_organization_licenses_seats(
        self, *, organization_id: str, license_id_to_renew: str, unused_license_id: str
    ) -> RenewOrganizationLicensesSeatsResponse:
        """Renew SM seats of a license.

        [API documentation: renewOrganizationLicensesSeats](https://developer.cisco.com/meraki/api-v1/#!renew-organization-licenses-seats)

        Args:
            organization_id: Organization ID.
            license_id_to_renew: The ID of the SM license to renew. This license must already be
                assigned to an SM network.
            unused_license_id: The SM license to use to renew the seats on 'licenseIdToRenew'. This
                license must have at least as many seats available as there are seats on
                'licenseIdToRenew'.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "resultingLicenses": [
                {
                  "id": "1234",
                  "licenseType": "SME",
                  "licenseKey": "Z21234567890",
                  "orderNumber": "4C1234567",
                  "deviceSerial": "Q234-ABCD-5678",
                  "networkId": "N_24329156",
                  "state": "active",
                  "seatCount": 25,
                  "totalDurationInDays": 425,
                  "durationInDays": 365,
                  "permanentlyQueuedLicenses": [
                    {
                      "id": "1234",
                      "licenseType": "SME",
                      "licenseKey": "Z21234567890",
                      "orderNumber": "4C1234567",
                      "durationInDays": 60
                    }
                  ],
                  "claimDate": "2019-08-29T12:40:10Z",
                  "activationDate": "2019-09-01T15:01:46Z",
                  "expirationDate": "2020-10-30T15:01:46Z",
                  "headLicenseId": "1234"
                }
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/licenses/renewSeats"

        payload: dict[str, Any] = {}
        if license_id_to_renew is not None:
            payload["licenseIdToRenew"] = license_id_to_renew
        if unused_license_id is not None:
            payload["unusedLicenseId"] = unused_license_id

        return self._session.post(
            scope="organizations",
            operation_id="renewOrganizationLicensesSeats",
            path=path,
            json=payload,
            response_schema=RenewOrganizationLicensesSeatsResponse,
        )

    def get_organization_license(
        self, *, organization_id: str, license_id: str
    ) -> GetOrganizationLicenseResponse:
        """Display a license.

        [API documentation: getOrganizationLicense](https://developer.cisco.com/meraki/api-v1/#!get-organization-license)

        Args:
            organization_id: Organization ID.
            license_id: License ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "1234",
              "licenseType": "MX64-ENT",
              "licenseKey": "Z21234567890",
              "orderNumber": "4C1234567",
              "deviceSerial": "Q234-ABCD-5678",
              "networkId": "N_24329156",
              "state": "active",
              "seatCount": 25,
              "totalDurationInDays": 425,
              "durationInDays": 365,
              "permanentlyQueuedLicenses": [
                {
                  "id": "1234",
                  "licenseType": "MX64-ENT",
                  "licenseKey": "Z21234567890",
                  "orderNumber": "4C1234567",
                  "durationInDays": 60
                }
              ],
              "claimDate": "2019-08-29T12:40:10Z",
              "activationDate": "2019-09-01T15:01:46Z",
              "expirationDate": "2020-10-30T15:01:46Z",
              "headLicenseId": "1234"
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        license_id = urllib.parse.quote(str(license_id), safe="")
        path = f"/organizations/{organization_id}/licenses/{license_id}"

        return self._session.get(
            scope="organizations",
            operation_id="getOrganizationLicense",
            path=path,
            response_schema=GetOrganizationLicenseResponse,
        )

    def update_organization_license(
        self, *, organization_id: str, license_id: str, device_serial: str | None = None
    ) -> UpdateOrganizationLicenseResponse:
        """Update a license.

        [API documentation: updateOrganizationLicense](https://developer.cisco.com/meraki/api-v1/#!update-organization-license)

        Args:
            organization_id: Organization ID.
            license_id: License ID.
            device_serial: The serial number of the device to assign this license to. Set this to
                null to unassign the license. If a different license is already active
                on the device, this parameter will control queueing/dequeuing this
                license.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "1234",
              "licenseType": "MX64-ENT",
              "licenseKey": "Z21234567890",
              "orderNumber": "4C1234567",
              "deviceSerial": "Q234-ABCD-5678",
              "networkId": "N_24329156",
              "state": "active",
              "seatCount": 25,
              "totalDurationInDays": 425,
              "durationInDays": 365,
              "permanentlyQueuedLicenses": [
                {
                  "id": "1234",
                  "licenseType": "MX64-ENT",
                  "licenseKey": "Z21234567890",
                  "orderNumber": "4C1234567",
                  "durationInDays": 60
                }
              ],
              "claimDate": "2019-08-29T12:40:10Z",
              "activationDate": "2019-09-01T15:01:46Z",
              "expirationDate": "2020-10-30T15:01:46Z",
              "headLicenseId": "1234"
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        license_id = urllib.parse.quote(str(license_id), safe="")
        path = f"/organizations/{organization_id}/licenses/{license_id}"

        payload: dict[str, Any] = {}
        if device_serial is not None:
            payload["deviceSerial"] = device_serial

        return self._session.put(
            scope="organizations",
            operation_id="updateOrganizationLicense",
            path=path,
            json=payload,
            response_schema=UpdateOrganizationLicenseResponse,
        )

    def get_organization_login_security(
        self, organization_id: str
    ) -> GetOrganizationLoginSecurityResponse:
        """Returns the login security settings for an organization.

        [API documentation: getOrganizationLoginSecurity](https://developer.cisco.com/meraki/api-v1/#!get-organization-login-security)

        Args:
            organization_id: Organization ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "enforcePasswordExpiration": true,
              "passwordExpirationDays": 90,
              "enforceDifferentPasswords": true,
              "numDifferentPasswords": 3,
              "enforceStrongPasswords": true,
              "minimumPasswordLength": 12,
              "enforceAccountLockout": true,
              "accountLockoutAttempts": 3,
              "enforceIdleTimeout": true,
              "idleTimeoutMinutes": 30,
              "enforceTwoFactorAuth": true,
              "enforceLoginIpRanges": true,
              "loginIpRanges": [
                "192.195.83.1",
                "192.195.83.255"
              ],
              "apiAuthentication": {
                "ipRestrictionsForKeys": {
                  "enabled": true,
                  "ranges": [
                    "192.195.83.1",
                    "192.168.33.33"
                  ]
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/loginSecurity"

        return self._session.get(
            scope="organizations",
            operation_id="getOrganizationLoginSecurity",
            path=path,
            response_schema=GetOrganizationLoginSecurityResponse,
        )

    def update_organization_login_security(
        self,
        organization_id: str,
        *,
        enforce_password_expiration: bool | None = None,
        password_expiration_days: int | None = None,
        enforce_different_passwords: bool | None = None,
        num_different_passwords: int | None = None,
        enforce_strong_passwords: bool | None = None,
        minimum_password_length: int | None = None,
        enforce_account_lockout: bool | None = None,
        account_lockout_attempts: int | None = None,
        enforce_idle_timeout: bool | None = None,
        idle_timeout_minutes: int | None = None,
        enforce_two_factor_auth: bool | None = None,
        enforce_login_ip_ranges: bool | None = None,
        login_ip_ranges: list[str] | None = None,
        api_authentication: UpdateOrganizationLoginSecurityApiAuthentication | None = None,
    ) -> UpdateOrganizationLoginSecurityResponse:
        """Update the login security settings for an organization.

        [API documentation: updateOrganizationLoginSecurity](https://developer.cisco.com/meraki/api-v1/#!update-organization-login-security)

        Args:
            organization_id: Organization ID.
            enforce_password_expiration: Boolean indicating whether users are forced to change their
                password every X number of days.
            password_expiration_days: Number of days after which users will be forced to change
                their password.
            enforce_different_passwords: Boolean indicating whether users, when setting a new
                password, are forced to choose a new password that is different from any
                past passwords.
            num_different_passwords: Number of recent passwords that new password must be distinct
                from.
            enforce_strong_passwords: Deprecated. Values of 'false' are always ignored.
            minimum_password_length: Minimum number of characters required in admins' passwords.
            enforce_account_lockout: Boolean indicating whether users' Dashboard accounts will be
                locked out after a specified number of consecutive failed login
                attempts.
            account_lockout_attempts: Number of consecutive failed login attempts after which users'
                accounts will be locked.
            enforce_idle_timeout: Boolean indicating whether users will be logged out after being
                idle for the specified number of minutes.
            idle_timeout_minutes: Number of minutes users can remain idle before being logged out of
                their accounts.
            enforce_two_factor_auth: Boolean indicating whether users in this organization will be
                required to use an extra verification code when logging in to Dashboard.
                This code will be sent to their mobile phone via SMS, or can be
                generated by the authenticator application.
            enforce_login_ip_ranges: Boolean indicating whether organization will restrict access to
                Dashboard (including the API) from certain IP addresses.
            login_ip_ranges: List of acceptable IP ranges. Entries can be single IP addresses, IP
                address ranges, and CIDR subnets.
            api_authentication: Details for indicating whether organization will restrict access to
                API (but not Dashboard) to certain IP addresses.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "enforcePasswordExpiration": true,
              "passwordExpirationDays": 90,
              "enforceDifferentPasswords": true,
              "numDifferentPasswords": 3,
              "enforceStrongPasswords": true,
              "minimumPasswordLength": 12,
              "enforceAccountLockout": true,
              "accountLockoutAttempts": 3,
              "enforceIdleTimeout": true,
              "idleTimeoutMinutes": 30,
              "enforceTwoFactorAuth": true,
              "enforceLoginIpRanges": true,
              "loginIpRanges": [
                "192.195.83.1",
                "192.195.83.255"
              ],
              "apiAuthentication": {
                "ipRestrictionsForKeys": {
                  "enabled": true,
                  "ranges": [
                    "192.195.83.1",
                    "192.168.33.33"
                  ]
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/loginSecurity"

        payload: dict[str, Any] = {}
        if enforce_password_expiration is not None:
            payload["enforcePasswordExpiration"] = enforce_password_expiration
        if password_expiration_days is not None:
            payload["passwordExpirationDays"] = password_expiration_days
        if enforce_different_passwords is not None:
            payload["enforceDifferentPasswords"] = enforce_different_passwords
        if num_different_passwords is not None:
            payload["numDifferentPasswords"] = num_different_passwords
        if enforce_strong_passwords is not None:
            payload["enforceStrongPasswords"] = enforce_strong_passwords
        if minimum_password_length is not None:
            payload["minimumPasswordLength"] = minimum_password_length
        if enforce_account_lockout is not None:
            payload["enforceAccountLockout"] = enforce_account_lockout
        if account_lockout_attempts is not None:
            payload["accountLockoutAttempts"] = account_lockout_attempts
        if enforce_idle_timeout is not None:
            payload["enforceIdleTimeout"] = enforce_idle_timeout
        if idle_timeout_minutes is not None:
            payload["idleTimeoutMinutes"] = idle_timeout_minutes
        if enforce_two_factor_auth is not None:
            payload["enforceTwoFactorAuth"] = enforce_two_factor_auth
        if enforce_login_ip_ranges is not None:
            payload["enforceLoginIpRanges"] = enforce_login_ip_ranges
        if login_ip_ranges is not None:
            payload["loginIpRanges"] = login_ip_ranges
        if api_authentication is not None:
            payload["apiAuthentication"] = api_authentication.model_dump(
                by_alias=True, exclude_none=True
            )

        return self._session.put(
            scope="organizations",
            operation_id="updateOrganizationLoginSecurity",
            path=path,
            json=payload,
            response_schema=UpdateOrganizationLoginSecurityResponse,
        )

    def get_organization_networks(
        self,
        organization_id: str,
        *,
        config_template_id: str | None = None,
        is_bound_to_config_template: bool | None = None,
        tags: list[str] | None = None,
        tags_filter_type: GetOrganizationNetworksTagsFilterType | None = None,
        product_types: GetOrganizationNetworksProductTypes | None = None,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetOrganizationNetworksResponseItem]:
        """List the networks that the user has privileges on in an organization.

        [API documentation: getOrganizationNetworks](https://developer.cisco.com/meraki/api-v1/#!get-organization-networks)

        Args:
            organization_id: Organization ID.
            config_template_id: An optional parameter that is the ID of a config template. Will
                return all networks bound to that template.
            is_bound_to_config_template: An optional parameter to filter config template bound
                networks. If configTemplateId is set, this cannot be false.
            tags: An optional parameter to filter networks by tags. The filtering is case-sensitive.
                If tags are included, 'tagsFilterType' should also be included (see
                below).
            tags_filter_type: An optional parameter of value 'withAnyTags' or 'withAllTags' to
                indicate whether to return networks which contain ANY or ALL of the
                included tags. If no type is included, 'withAnyTags' will be selected.
            product_types: An optional parameter to filter networks by product type. Results will
                have at least one of the included product types.
            per_page: The number of entries per page returned. Acceptable range is 3 - 100000.
                Default is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "id": "N_24329156",
                "organizationId": "2930418",
                "name": "Main Office",
                "productTypes": [
                  "appliance",
                  "switch",
                  "wireless"
                ],
                "timeZone": "America/Los_Angeles",
                "tags": [
                  "tag1",
                  "tag2"
                ],
                "enrollmentString": "my-enrollment-string",
                "url": "https://n1.meraki.com//n//manage/nodes/list",
                "notes": "Additional description of the network",
                "isBoundToConfigTemplate": false
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/networks"

        params: dict[str, Any] = {}
        if config_template_id is not None:
            params["configTemplateId"] = config_template_id
        if is_bound_to_config_template is not None:
            params["isBoundToConfigTemplate"] = is_bound_to_config_template
        if tags is not None:
            params["tags[]"] = tags
        if tags_filter_type is not None:
            params["tagsFilterType"] = tags_filter_type
        if product_types is not None:
            params["productTypes[]"] = product_types
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationNetworks",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationNetworksResponseItem,
        )

    def create_organization_network(
        self,
        *,
        organization_id: str,
        name: str,
        product_types: CreateOrganizationNetworkProductTypes,
        tags: list[str] | None = None,
        time_zone: str | None = None,
        copy_from_network_id: str | None = None,
        notes: str | None = None,
    ) -> CreateOrganizationNetworkResponse:
        """Create a network.

        [API documentation: createOrganizationNetwork](https://developer.cisco.com/meraki/api-v1/#!create-organization-network)

        Args:
            organization_id: Organization ID.
            name: The name of the new network.
            product_types: The product type(s) of the new network. If more than one type is
                included, the network will be a combined network.
            tags: A list of tags to be applied to the network.
            time_zone: The timezone of the network. For a list of allowed timezones, please see the
                'TZ' column in the table in <a target='_blank'
                href='https://en.wikipedia.org/wiki/List_of_tz_database_time_zones'>this
                article.</a>.
            copy_from_network_id: The ID of the network to copy configuration from. Other provided
                parameters will override the copied configuration, except type which
                must match this network's type exactly.
            notes: Add any notes or additional information about this network here.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "N_24329156",
              "organizationId": "2930418",
              "name": "Main Office",
              "productTypes": [
                "appliance",
                "switch",
                "wireless"
              ],
              "timeZone": "America/Los_Angeles",
              "tags": [
                "tag1",
                "tag2"
              ],
              "enrollmentString": "my-enrollment-string",
              "url": "https://n1.meraki.com//n//manage/nodes/list",
              "notes": "Additional description of the network",
              "isBoundToConfigTemplate": false
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/networks"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if product_types is not None:
            payload["productTypes"] = product_types
        if tags is not None:
            payload["tags"] = tags
        if time_zone is not None:
            payload["timeZone"] = time_zone
        if copy_from_network_id is not None:
            payload["copyFromNetworkId"] = copy_from_network_id
        if notes is not None:
            payload["notes"] = notes

        return self._session.post(
            scope="organizations",
            operation_id="createOrganizationNetwork",
            path=path,
            json=payload,
            response_schema=CreateOrganizationNetworkResponse,
        )

    def combine_organization_networks(
        self,
        *,
        organization_id: str,
        name: str,
        network_ids: list[str],
        enrollment_string: str | None = None,
    ) -> CombineOrganizationNetworksResponse:
        """Combine multiple networks into a single network.

        [API documentation: combineOrganizationNetworks](https://developer.cisco.com/meraki/api-v1/#!combine-organization-networks)

        Args:
            organization_id: Organization ID.
            name: The name of the combined network.
            network_ids: A list of the network IDs that will be combined. If an ID of a combined
                network is included in this list, the other networks in the list will be
                grouped into that network.
            enrollment_string: A unique identifier which can be used for device enrollment or easy
                access through the Meraki SM Registration page or the Self Service
                Portal. Please note that changing this field may cause existing
                bookmarks to break. All networks that are part of this combined network
                will have their enrollment string appended by '-network_type'. If left
                empty, all exisitng enrollment strings will be deleted.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "resultingNetwork": {
                "id": "N_24329156",
                "organizationId": "2930418",
                "name": "Main Office",
                "productTypes": [
                  "appliance",
                  "switch",
                  "wireless"
                ],
                "timeZone": "America/Los_Angeles",
                "tags": [
                  "tag1",
                  "tag2"
                ],
                "enrollmentString": "my-enrollment-string",
                "url": "https://n1.meraki.com//n//manage/nodes/list",
                "notes": "Additional description of the network",
                "isBoundToConfigTemplate": false
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/networks/combine"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if network_ids is not None:
            payload["networkIds"] = network_ids
        if enrollment_string is not None:
            payload["enrollmentString"] = enrollment_string

        return self._session.post(
            scope="organizations",
            operation_id="combineOrganizationNetworks",
            path=path,
            json=payload,
            response_schema=CombineOrganizationNetworksResponse,
        )

    def get_network_moves(
        self,
        organization_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        move_ids: list[str] | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetNetworkMovesResponseItemsItem]:
        """Return a list of network move operations in the organization.

        [API documentation: getNetworkMoves](https://developer.cisco.com/meraki/api-v1/#!get-network-moves)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 10 - 100. Default
                is 50.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            move_ids: Array of network move operation IDs to include. If not specified, all network
                moves will be returned.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            {
              "items": [
                {
                  "moveId": "123456",
                  "initiator": {
                    "admin": {
                      "id": "8590064780"
                    }
                  },
                  "organizations": {
                    "source": {
                      "id": "146307"
                    },
                    "target": {
                      "id": "146308"
                    }
                  },
                  "network": {
                    "id": "N_569142402909112097"
                  },
                  "createdAt": "1970-01-20T15:57:36.000Z",
                  "lastUpdatedAt": "1970-01-20T15:57:36.000Z",
                  "result": {
                    "status": "failed",
                    "reason": "Cannot move network: Target organization is invalid or inaccessible."
                  }
                }
              ],
              "meta": {
                "counts": {
                  "items": {
                    "total": 42,
                    "remaining": 12
                  }
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/networks/moves"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if move_ids is not None:
            params["moveIds[]"] = move_ids

        return self._session.get_pages(
            scope="organizations",
            operation_id="getNetworkMoves",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetNetworkMovesResponseItemsItem,
        )

    def create_network_move(
        self,
        *,
        organization_id: str,
        network: CreateNetworkMoveNetwork,
        organizations: CreateNetworkMoveOrganizations,
        simulate: bool | None = None,
    ) -> CreateNetworkMoveResponse:
        """Move networks from one organization to another.

        [API documentation: createNetworkMove](https://developer.cisco.com/meraki/api-v1/#!create-network-move)

        Args:
            organization_id: Organization ID.
            network: Network to be moved.
            organizations: Organizations involved in the network move.
            simulate: If true, simulates the network move and validates the operation without
                committing changes. The network will remain in the source organization.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "moveId": "123456",
              "initiator": {
                "admin": {
                  "id": "8590064780"
                }
              },
              "organizations": {
                "source": {
                  "id": "146307"
                },
                "target": {
                  "id": "146308"
                }
              },
              "network": {
                "id": "N_569142402909112097"
              },
              "createdAt": "1970-01-20T15:57:36.000Z",
              "lastUpdatedAt": "1970-01-20T15:57:36.000Z",
              "result": {
                "status": "failed",
                "reason": "Cannot move network: Target organization is invalid or inaccessible."
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/networks/moves"

        payload: dict[str, Any] = {}
        if network is not None:
            payload["network"] = network.model_dump(by_alias=True, exclude_none=True)
        if organizations is not None:
            payload["organizations"] = organizations.model_dump(by_alias=True, exclude_none=True)
        if simulate is not None:
            payload["simulate"] = simulate

        return self._session.post(
            scope="organizations",
            operation_id="createNetworkMove",
            path=path,
            json=payload,
            response_schema=CreateNetworkMoveResponse,
        )

    def get_organization_openapi_spec(
        self, organization_id: str, *, version: GetOrganizationOpenapiSpecVersion | None = None
    ) -> DictResponse:
        """Return the OpenAPI Specification of the organization's API documentation in JSON.

        [API documentation: getOrganizationOpenapiSpec](https://developer.cisco.com/meraki/api-v1/#!get-organization-openapi-spec)

        Args:
            organization_id: Organization ID.
            version: OpenAPI Specification version to return. Default is 2.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "openapi": "3.0.1",
              "info": {
                "version": "v1",
                "title": "Meraki Dashboard API",
                "description": "This collection of API calls provides an easy way to manage and monitor Cisco Meraki networks at scale"
              },
              "paths": {
                "/organizations": {
                  "get": {
                    "description": "List the organizations that the user has privileges on",
                    "operationId": "getOrganizations",
                    "responses": {
                      "200": {
                        "description": "Successful operation",
                        "examples": {
                          "application/json": [
                            {
                              "id": "2930418",
                              "name": "My organization"
                            }
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/openapiSpec"

        params: dict[str, Any] = {}
        if version is not None:
            params["version"] = version

        return self._session.get(
            scope="organizations",
            operation_id="getOrganizationOpenapiSpec",
            path=path,
            params=params,
            response_schema=DictResponse,
        )

    def get_organization_policies_assignments_by_client(
        self,
        *,
        organization_id: str,
        network_ids: list[str],
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        t0: str | None = None,
        timespan: float | None = None,
        include_undetected_clients: bool | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetOrganizationPoliciesAssignmentsByClientResponseItem]:
        """Get policies for all clients with policies.

        [API documentation: getOrganizationPoliciesAssignmentsByClient](https://developer.cisco.com/meraki/api-v1/#!get-organization-policies-assignments-by-client)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 50.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            t0: The beginning of the timespan for the data. The maximum lookback period is 31 days
                from today.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameter t0. The value must be in seconds and
                be less than or equal to 31 days. The default is 1 day.
            include_undetected_clients: Include provisioned clients that have not associated to the
                network. Default: false.
            network_ids: Network Ids (minimum: 1, maximum: 30).
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "name": "Miles's phone",
                "clientId": "k74272e",
                "mac": "22:33:44:55:66:77",
                "networkId": "N_24329156",
                "assigned": [
                  {
                    "name": "My group policy",
                    "type": "Group",
                    "id": "102",
                    "limitTo": [
                      {
                        "appliance": false,
                        "ssids": [
                          {
                            "number": 1
                          }
                        ]
                      }
                    ]
                  }
                ]
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/policies/assignments/byClient"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if t0 is not None:
            params["t0"] = t0
        if timespan is not None:
            params["timespan"] = timespan
        if include_undetected_clients is not None:
            params["includeUndetectedClients"] = include_undetected_clients
        if network_ids is not None:
            params["networkIds[]"] = network_ids

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationPoliciesAssignmentsByClient",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationPoliciesAssignmentsByClientResponseItem,
        )

    def get_organization_policy_objects(
        self,
        organization_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetOrganizationPolicyObjectsResponseItem]:
        """Lists Policy Objects belonging to the organization.

        [API documentation: getOrganizationPolicyObjects](https://developer.cisco.com/meraki/api-v1/#!get-organization-policy-objects)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 10 - 5000.
                Default is 5000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "id": "1234",
                "name": "Web Servers - Datacenter 10",
                "category": "network",
                "type": "cidr",
                "cidr": "10.0.0.0/24",
                "createdAt": "2018-05-12T00:00:00Z",
                "updatedAt": "2018-05-12T00:00:00Z",
                "groupIds": [
                  "8"
                ],
                "networkIds": [
                  "L_12345",
                  "N_123456"
                ]
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/policyObjects"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationPolicyObjects",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationPolicyObjectsResponseItem,
        )

    def create_organization_policy_object(
        self,
        *,
        organization_id: str,
        name: str,
        category: str,
        type_: str,
        cidr: str | None = None,
        fqdn: str | None = None,
        mask: str | None = None,
        ip: str | None = None,
        group_ids: list[str] | None = None,
    ) -> CreateOrganizationPolicyObjectResponse:
        """Creates a new Policy Object.

        [API documentation: createOrganizationPolicyObject](https://developer.cisco.com/meraki/api-v1/#!create-organization-policy-object)

        Args:
            organization_id: Organization ID.
            name: Name of a policy object, unique within the organization (alphanumeric, space,
                dash, or underscore characters only).
            category: Category of a policy object (one of: adaptivePolicy, network).
            type_: Type of a policy object (one of: adaptivePolicyIpv4Cidr, cidr, fqdn, ipAndMask).
            cidr: CIDR Value of a policy object (e.g. 10.11.12.1/24").
            fqdn: Fully qualified domain name of policy object (e.g. "example.com").
            mask: Mask of a policy object (e.g. "255.255.0.0").
            ip: IP Address of a policy object (e.g. "1.2.3.4").
            group_ids: The IDs of policy object groups the policy object belongs to.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "1234",
              "name": "Web Servers - Datacenter 10",
              "category": "network",
              "type": "cidr",
              "cidr": "10.0.0.0/24",
              "createdAt": "2018-05-12T00:00:00Z",
              "updatedAt": "2018-05-12T00:00:00Z",
              "groupIds": [
                "8"
              ],
              "networkIds": [
                "L_12345",
                "N_123456"
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/policyObjects"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if category is not None:
            payload["category"] = category
        if type_ is not None:
            payload["type"] = type_
        if cidr is not None:
            payload["cidr"] = cidr
        if fqdn is not None:
            payload["fqdn"] = fqdn
        if mask is not None:
            payload["mask"] = mask
        if ip is not None:
            payload["ip"] = ip
        if group_ids is not None:
            payload["groupIds"] = group_ids

        return self._session.post(
            scope="organizations",
            operation_id="createOrganizationPolicyObject",
            path=path,
            json=payload,
            response_schema=CreateOrganizationPolicyObjectResponse,
        )

    def get_organization_policy_objects_groups(
        self,
        organization_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetOrganizationPolicyObjectsGroupsResponseItem]:
        """Lists Policy Object Groups belonging to the organization.

        [API documentation: getOrganizationPolicyObjectsGroups](https://developer.cisco.com/meraki/api-v1/#!get-organization-policy-objects-groups)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 10 - 1000.
                Default is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "id": "1234",
                "name": "Web Servers - Datacenter 10",
                "category": "NetworkObjectGroup",
                "createdAt": "2018-05-12T00:00:00Z",
                "updatedAt": "2018-05-12T00:00:00Z",
                "objectIds": [
                  100
                ],
                "networkIds": [
                  "L_12345",
                  "N_123456"
                ]
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/policyObjects/groups"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationPolicyObjectsGroups",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationPolicyObjectsGroupsResponseItem,
        )

    def create_organization_policy_objects_group(
        self,
        *,
        organization_id: str,
        name: str,
        category: str | None = None,
        object_ids: list[str] | None = None,
    ) -> CreateOrganizationPolicyObjectsGroupResponse:
        """Creates a new Policy Object Group.

        [API documentation: createOrganizationPolicyObjectsGroup](https://developer.cisco.com/meraki/api-v1/#!create-organization-policy-objects-group)

        Args:
            organization_id: Organization ID.
            name: A name for the group of network addresses, unique within the organization
                (alphanumeric, space, dash, or underscore characters only).
            category: Category of a policy object group (one of: NetworkObjectGroup,
                GeoLocationGroup, PortObjectGroup, ApplicationGroup).
            object_ids: A list of Policy Object ID's that this NetworkObjectGroup should be
                associated to (note: these ID's will replace the existing associated
                Policy Objects).

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "1234",
              "name": "Web Servers - Datacenter 10",
              "category": "NetworkObjectGroup",
              "createdAt": "2018-05-12T00:00:00Z",
              "updatedAt": "2018-05-12T00:00:00Z",
              "objectIds": [
                100
              ],
              "networkIds": [
                "L_12345",
                "N_123456"
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/policyObjects/groups"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if category is not None:
            payload["category"] = category
        if object_ids is not None:
            payload["objectIds"] = object_ids

        return self._session.post(
            scope="organizations",
            operation_id="createOrganizationPolicyObjectsGroup",
            path=path,
            json=payload,
            response_schema=CreateOrganizationPolicyObjectsGroupResponse,
        )

    def get_organization_policy_objects_group(
        self, *, organization_id: str, policy_object_group_id: str
    ) -> GetOrganizationPolicyObjectsGroupResponse:
        """Shows details of a Policy Object Group.

        [API documentation: getOrganizationPolicyObjectsGroup](https://developer.cisco.com/meraki/api-v1/#!get-organization-policy-objects-group)

        Args:
            organization_id: Organization ID.
            policy_object_group_id: Policy object group ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "1234",
              "name": "Web Servers - Datacenter 10",
              "category": "NetworkObjectGroup",
              "createdAt": "2018-05-12T00:00:00Z",
              "updatedAt": "2018-05-12T00:00:00Z",
              "objectIds": [
                100
              ],
              "networkIds": [
                "L_12345",
                "N_123456"
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        policy_object_group_id = urllib.parse.quote(str(policy_object_group_id), safe="")
        path = f"/organizations/{organization_id}/policyObjects/groups/{policy_object_group_id}"

        return self._session.get(
            scope="organizations",
            operation_id="getOrganizationPolicyObjectsGroup",
            path=path,
            response_schema=GetOrganizationPolicyObjectsGroupResponse,
        )

    def update_organization_policy_objects_group(
        self,
        *,
        organization_id: str,
        policy_object_group_id: str,
        name: str | None = None,
        object_ids: list[str] | None = None,
    ) -> UpdateOrganizationPolicyObjectsGroupResponse:
        """Updates a Policy Object Group.

        [API documentation: updateOrganizationPolicyObjectsGroup](https://developer.cisco.com/meraki/api-v1/#!update-organization-policy-objects-group)

        Args:
            organization_id: Organization ID.
            policy_object_group_id: Policy object group ID.
            name: A name for the group of network addresses, unique within the organization
                (alphanumeric, space, dash, or underscore characters only).
            object_ids: A list of Policy Object ID's that this NetworkObjectGroup should be
                associated to (note: these ID's will replace the existing associated
                Policy Objects).

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "1234",
              "name": "Web Servers - Datacenter 10",
              "category": "NetworkObjectGroup",
              "createdAt": "2018-05-12T00:00:00Z",
              "updatedAt": "2018-05-12T00:00:00Z",
              "objectIds": [
                100
              ],
              "networkIds": [
                "L_12345",
                "N_123456"
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        policy_object_group_id = urllib.parse.quote(str(policy_object_group_id), safe="")
        path = f"/organizations/{organization_id}/policyObjects/groups/{policy_object_group_id}"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if object_ids is not None:
            payload["objectIds"] = object_ids

        return self._session.put(
            scope="organizations",
            operation_id="updateOrganizationPolicyObjectsGroup",
            path=path,
            json=payload,
            response_schema=UpdateOrganizationPolicyObjectsGroupResponse,
        )

    def delete_organization_policy_objects_group(
        self, *, organization_id: str, policy_object_group_id: str
    ) -> None:
        """Deletes a Policy Object Group.

        [API documentation: deleteOrganizationPolicyObjectsGroup](https://developer.cisco.com/meraki/api-v1/#!delete-organization-policy-objects-group)

        Args:
            organization_id: Organization ID.
            policy_object_group_id: Policy object group ID.

        Returns:
            Successful operation.

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        policy_object_group_id = urllib.parse.quote(str(policy_object_group_id), safe="")
        path = f"/organizations/{organization_id}/policyObjects/groups/{policy_object_group_id}"

        return self._session.delete(
            scope="organizations", operation_id="deleteOrganizationPolicyObjectsGroup", path=path
        )

    def get_organization_policy_object(
        self, *, organization_id: str, policy_object_id: str
    ) -> GetOrganizationPolicyObjectResponse:
        """Shows details of a Policy Object.

        [API documentation: getOrganizationPolicyObject](https://developer.cisco.com/meraki/api-v1/#!get-organization-policy-object)

        Args:
            organization_id: Organization ID.
            policy_object_id: Policy object ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "1234",
              "name": "Web Servers - Datacenter 10",
              "category": "network",
              "type": "cidr",
              "cidr": "10.0.0.0/24",
              "createdAt": "2018-05-12T00:00:00Z",
              "updatedAt": "2018-05-12T00:00:00Z",
              "groupIds": [
                "8"
              ],
              "networkIds": [
                "L_12345",
                "N_123456"
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        policy_object_id = urllib.parse.quote(str(policy_object_id), safe="")
        path = f"/organizations/{organization_id}/policyObjects/{policy_object_id}"

        return self._session.get(
            scope="organizations",
            operation_id="getOrganizationPolicyObject",
            path=path,
            response_schema=GetOrganizationPolicyObjectResponse,
        )

    def update_organization_policy_object(
        self,
        *,
        organization_id: str,
        policy_object_id: str,
        name: str | None = None,
        cidr: str | None = None,
        fqdn: str | None = None,
        mask: str | None = None,
        ip: str | None = None,
        group_ids: list[str] | None = None,
    ) -> UpdateOrganizationPolicyObjectResponse:
        """Updates a Policy Object.

        [API documentation: updateOrganizationPolicyObject](https://developer.cisco.com/meraki/api-v1/#!update-organization-policy-object)

        Args:
            organization_id: Organization ID.
            policy_object_id: Policy object ID.
            name: Name of a policy object, unique within the organization (alphanumeric, space,
                dash, or underscore characters only).
            cidr: CIDR Value of a policy object (e.g. 10.11.12.1/24").
            fqdn: Fully qualified domain name of policy object (e.g. "example.com").
            mask: Mask of a policy object (e.g. "255.255.0.0").
            ip: IP Address of a policy object (e.g. "1.2.3.4").
            group_ids: The IDs of policy object groups the policy object belongs to.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "1234",
              "name": "Web Servers - Datacenter 10",
              "category": "network",
              "type": "cidr",
              "cidr": "10.0.0.0/24",
              "createdAt": "2018-05-12T00:00:00Z",
              "updatedAt": "2018-05-12T00:00:00Z",
              "groupIds": [
                "8"
              ],
              "networkIds": [
                "L_12345",
                "N_123456"
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        policy_object_id = urllib.parse.quote(str(policy_object_id), safe="")
        path = f"/organizations/{organization_id}/policyObjects/{policy_object_id}"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if cidr is not None:
            payload["cidr"] = cidr
        if fqdn is not None:
            payload["fqdn"] = fqdn
        if mask is not None:
            payload["mask"] = mask
        if ip is not None:
            payload["ip"] = ip
        if group_ids is not None:
            payload["groupIds"] = group_ids

        return self._session.put(
            scope="organizations",
            operation_id="updateOrganizationPolicyObject",
            path=path,
            json=payload,
            response_schema=UpdateOrganizationPolicyObjectResponse,
        )

    def delete_organization_policy_object(
        self, *, organization_id: str, policy_object_id: str
    ) -> None:
        """Deletes a Policy Object.

        [API documentation: deleteOrganizationPolicyObject](https://developer.cisco.com/meraki/api-v1/#!delete-organization-policy-object)

        Args:
            organization_id: Organization ID.
            policy_object_id: Policy object ID.

        Returns:
            Successful operation.

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        policy_object_id = urllib.parse.quote(str(policy_object_id), safe="")
        path = f"/organizations/{organization_id}/policyObjects/{policy_object_id}"

        return self._session.delete(
            scope="organizations", operation_id="deleteOrganizationPolicyObject", path=path
        )

    def get_organization_saml(self, organization_id: str) -> GetOrganizationSamlResponse:
        """Returns the SAML SSO enabled settings for an organization.

        [API documentation: getOrganizationSaml](https://developer.cisco.com/meraki/api-v1/#!get-organization-saml)

        Args:
            organization_id: Organization ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "enabled": true,
              "spInitiated": {
                "subdomain": "example_subdomain",
                "idpId": "uu3H_bx28Nnd"
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/saml"

        return self._session.get(
            scope="organizations",
            operation_id="getOrganizationSaml",
            path=path,
            response_schema=GetOrganizationSamlResponse,
        )

    def update_organization_saml(
        self,
        organization_id: str,
        *,
        enabled: bool | None = None,
        sp_initiated: UpdateOrganizationSamlSpInitiated | None = None,
    ) -> UpdateOrganizationSamlResponse:
        """Updates the SAML SSO enabled settings for an organization.

        [API documentation: updateOrganizationSaml](https://developer.cisco.com/meraki/api-v1/#!update-organization-saml)

        Args:
            organization_id: Organization ID.
            enabled: Boolean for updating SAML SSO enabled settings.
            sp_initiated: SP-Initiated SSO settings.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "enabled": true,
              "spInitiated": {
                "subdomain": "example_subdomain",
                "idpId": "uu3H_bx28Nnd"
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/saml"

        payload: dict[str, Any] = {}
        if enabled is not None:
            payload["enabled"] = enabled
        if sp_initiated is not None:
            payload["spInitiated"] = sp_initiated.model_dump(by_alias=True, exclude_none=True)

        return self._session.put(
            scope="organizations",
            operation_id="updateOrganizationSaml",
            path=path,
            json=payload,
            response_schema=UpdateOrganizationSamlResponse,
        )

    def get_organization_saml_idps(
        self, organization_id: str
    ) -> PaginatedResponse[GetOrganizationSamlIdpsResponseItem]:
        """List the SAML IdPs in your organization.

        [API documentation: getOrganizationSamlIdps](https://developer.cisco.com/meraki/api-v1/#!get-organization-saml-idps)

        Args:
            organization_id: Organization ID.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "idpId": "1284392014819",
                "consumerUrl": "https://n7.meraki.com/saml/login/XXX",
                "visionConsumerUrl": "https://n7.meraki.com/saml/login/XXX?appTarget=MerakiVision",
                "x509certSha1Fingerprint": "00:11:22:33:44:55:66:77:88:99:00:11:22:33:44:55:66:77:88:99",
                "ssoLoginUrl": "https://onelogin.com/trust/saml2/http-post/sso/3de5f942-e7b8-4cb9-94e3-85828111158b",
                "sloLogoutUrl": "https://onelogin.com/trust/saml2/http-redirect/slo/4155000"
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/saml/idps"

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationSamlIdps",
            path=path,
            item_schema=GetOrganizationSamlIdpsResponseItem,
        )

    def create_organization_saml_idp(
        self,
        *,
        organization_id: str,
        x509cert_sha1_fingerprint: str,
        sso_login_url: str | None = None,
        slo_logout_url: str | None = None,
    ) -> CreateOrganizationSamlIdpResponse:
        """Create a SAML IdP for your organization.

        [API documentation: createOrganizationSamlIdp](https://developer.cisco.com/meraki/api-v1/#!create-organization-saml-idp)

        Args:
            organization_id: Organization ID.
            x509cert_sha1_fingerprint: Fingerprint (SHA1) of the SAML certificate provided by your
                Identity Provider (IdP). This will be used for encryption / validation.
            sso_login_url: Dashboard will redirect users to this URL to log in again when their
                sessions expire.
            slo_logout_url: Dashboard will redirect users to this URL when they sign out.

        Returns:
            Successful operation.

        Example API response:
            ```json
            [
              {
                "idpId": "1284392014819",
                "consumerUrl": "https://n7.meraki.com/saml/login/XXX",
                "visionConsumerUrl": "https://n7.meraki.com/saml/login/XXX?appTarget=MerakiVision",
                "x509certSha1Fingerprint": "00:11:22:33:44:55:66:77:88:99:00:11:22:33:44:55:66:77:88:99",
                "ssoLoginUrl": "https://onelogin.com/trust/saml2/http-post/sso/3de5f942-e7b8-4cb9-94e3-85828111158b",
                "sloLogoutUrl": "https://onelogin.com/trust/saml2/http-redirect/slo/4155000"
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/saml/idps"

        payload: dict[str, Any] = {}
        if x509cert_sha1_fingerprint is not None:
            payload["x509certSha1Fingerprint"] = x509cert_sha1_fingerprint
        if sso_login_url is not None:
            payload["ssoLoginUrl"] = sso_login_url
        if slo_logout_url is not None:
            payload["sloLogoutUrl"] = slo_logout_url

        return self._session.post(
            scope="organizations",
            operation_id="createOrganizationSamlIdp",
            path=path,
            json=payload,
            response_schema=CreateOrganizationSamlIdpResponse,
        )

    def get_organization_saml_idp(
        self, *, organization_id: str, idp_id: str
    ) -> GetOrganizationSamlIdpResponse:
        """Get a SAML IdP from your organization.

        [API documentation: getOrganizationSamlIdp](https://developer.cisco.com/meraki/api-v1/#!get-organization-saml-idp)

        Args:
            organization_id: Organization ID.
            idp_id: Idp ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "idpId": "1284392014819",
              "consumerUrl": "https://n7.meraki.com/saml/login/XXX",
              "visionConsumerUrl": "https://n7.meraki.com/saml/login/XXX?appTarget=MerakiVision",
              "x509certSha1Fingerprint": "00:11:22:33:44:55:66:77:88:99:00:11:22:33:44:55:66:77:88:99",
              "ssoLoginUrl": "https://onelogin.com/trust/saml2/http-post/sso/3de5f942-e7b8-4cb9-94e3-85828111158b",
              "sloLogoutUrl": "https://onelogin.com/trust/saml2/http-redirect/slo/4155000"
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        idp_id = urllib.parse.quote(str(idp_id), safe="")
        path = f"/organizations/{organization_id}/saml/idps/{idp_id}"

        return self._session.get(
            scope="organizations",
            operation_id="getOrganizationSamlIdp",
            path=path,
            response_schema=GetOrganizationSamlIdpResponse,
        )

    def update_organization_saml_idp(
        self,
        *,
        organization_id: str,
        idp_id: str,
        x509cert_sha1_fingerprint: str | None = None,
        sso_login_url: str | None = None,
        slo_logout_url: str | None = None,
    ) -> UpdateOrganizationSamlIdpResponse:
        """Update a SAML IdP in your organization.

        [API documentation: updateOrganizationSamlIdp](https://developer.cisco.com/meraki/api-v1/#!update-organization-saml-idp)

        Args:
            organization_id: Organization ID.
            idp_id: Idp ID.
            x509cert_sha1_fingerprint: Fingerprint (SHA1) of the SAML certificate provided by your
                Identity Provider (IdP). This will be used for encryption / validation.
            sso_login_url: Dashboard will redirect users to this URL to log in again when their
                sessions expire.
            slo_logout_url: Dashboard will redirect users to this URL when they sign out.

        Returns:
            Successful operation.

        Example API response:
            ```json
            [
              {
                "idpId": "1284392014819",
                "consumerUrl": "https://n7.meraki.com/saml/login/XXX",
                "visionConsumerUrl": "https://n7.meraki.com/saml/login/XXX?appTarget=MerakiVision",
                "x509certSha1Fingerprint": "00:11:22:33:44:55:66:77:88:99:00:11:22:33:44:55:66:77:88:99",
                "ssoLoginUrl": "https://onelogin.com/trust/saml2/http-post/sso/3de5f942-e7b8-4cb9-94e3-85828111158b",
                "sloLogoutUrl": "https://onelogin.com/trust/saml2/http-redirect/slo/4155000"
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        idp_id = urllib.parse.quote(str(idp_id), safe="")
        path = f"/organizations/{organization_id}/saml/idps/{idp_id}"

        payload: dict[str, Any] = {}
        if x509cert_sha1_fingerprint is not None:
            payload["x509certSha1Fingerprint"] = x509cert_sha1_fingerprint
        if sso_login_url is not None:
            payload["ssoLoginUrl"] = sso_login_url
        if slo_logout_url is not None:
            payload["sloLogoutUrl"] = slo_logout_url

        return self._session.put(
            scope="organizations",
            operation_id="updateOrganizationSamlIdp",
            path=path,
            json=payload,
            response_schema=UpdateOrganizationSamlIdpResponse,
        )

    def delete_organization_saml_idp(self, *, organization_id: str, idp_id: str) -> None:
        """Remove a SAML IdP in your organization.

        [API documentation: deleteOrganizationSamlIdp](https://developer.cisco.com/meraki/api-v1/#!delete-organization-saml-idp)

        Args:
            organization_id: Organization ID.
            idp_id: Idp ID.

        Returns:
            Successful operation.

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        idp_id = urllib.parse.quote(str(idp_id), safe="")
        path = f"/organizations/{organization_id}/saml/idps/{idp_id}"

        return self._session.delete(
            scope="organizations", operation_id="deleteOrganizationSamlIdp", path=path
        )

    def get_organization_saml_roles(
        self, organization_id: str
    ) -> PaginatedResponse[GetOrganizationSamlRolesResponseItem]:
        """List the SAML roles for this organization.

        [API documentation: getOrganizationSamlRoles](https://developer.cisco.com/meraki/api-v1/#!get-organization-saml-roles)

        Args:
            organization_id: Organization ID.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "id": "1284392014819",
                "role": "myrole",
                "orgAccess": "none",
                "networks": [
                  {
                    "id": "N_24329156",
                    "access": "full"
                  }
                ],
                "tags": [
                  {
                    "tag": "west",
                    "access": "read-only"
                  }
                ],
                "camera": [
                  {
                    "orgWide": true,
                    "access": "viewAndExport"
                  }
                ]
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/samlRoles"

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationSamlRoles",
            path=path,
            item_schema=GetOrganizationSamlRolesResponseItem,
        )

    def create_organization_saml_role(
        self,
        *,
        organization_id: str,
        role: str,
        org_access: str,
        tags: list[CreateOrganizationSamlRoleTagsItem] | None = None,
        networks: list[CreateOrganizationSamlRoleNetworksItem] | None = None,
    ) -> CreateOrganizationSamlRoleResponse:
        """Create a SAML role.

        [API documentation: createOrganizationSamlRole](https://developer.cisco.com/meraki/api-v1/#!create-organization-saml-role)

        Args:
            organization_id: Organization ID.
            role: The role of the SAML administrator.
            org_access: The privilege of the SAML administrator on the organization. Can be one of
                'none', 'read-only', 'full' or 'enterprise' or a custom role in the
                format custom-role:ID:NAME.
            tags: The list of tags that the SAML administrator has privileges on.
            networks: The list of networks that the SAML administrator has privileges on.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "1284392014819",
              "role": "myrole",
              "orgAccess": "none",
              "networks": [
                {
                  "id": "N_24329156",
                  "access": "full"
                }
              ],
              "tags": [
                {
                  "tag": "west",
                  "access": "read-only"
                }
              ],
              "camera": [
                {
                  "orgWide": true,
                  "access": "viewAndExport"
                }
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/samlRoles"

        payload: dict[str, Any] = {}
        if role is not None:
            payload["role"] = role
        if org_access is not None:
            payload["orgAccess"] = org_access
        if tags is not None:
            payload["tags"] = [item.model_dump(by_alias=True, exclude_none=True) for item in tags]
        if networks is not None:
            payload["networks"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in networks
            ]

        return self._session.post(
            scope="organizations",
            operation_id="createOrganizationSamlRole",
            path=path,
            json=payload,
            response_schema=CreateOrganizationSamlRoleResponse,
        )

    def get_organization_saml_role(
        self, *, organization_id: str, saml_role_id: str
    ) -> GetOrganizationSamlRoleResponse:
        """Return a SAML role.

        [API documentation: getOrganizationSamlRole](https://developer.cisco.com/meraki/api-v1/#!get-organization-saml-role)

        Args:
            organization_id: Organization ID.
            saml_role_id: Saml role ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "1284392014819",
              "role": "myrole",
              "orgAccess": "none",
              "networks": [
                {
                  "id": "N_24329156",
                  "access": "full"
                }
              ],
              "tags": [
                {
                  "tag": "west",
                  "access": "read-only"
                }
              ],
              "camera": [
                {
                  "orgWide": true,
                  "access": "viewAndExport"
                }
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        saml_role_id = urllib.parse.quote(str(saml_role_id), safe="")
        path = f"/organizations/{organization_id}/samlRoles/{saml_role_id}"

        return self._session.get(
            scope="organizations",
            operation_id="getOrganizationSamlRole",
            path=path,
            response_schema=GetOrganizationSamlRoleResponse,
        )

    def update_organization_saml_role(
        self,
        *,
        organization_id: str,
        saml_role_id: str,
        role: str | None = None,
        org_access: str | None = None,
        tags: list[UpdateOrganizationSamlRoleTagsItem] | None = None,
        networks: list[UpdateOrganizationSamlRoleNetworksItem] | None = None,
    ) -> UpdateOrganizationSamlRoleResponse:
        """Update a SAML role.

        [API documentation: updateOrganizationSamlRole](https://developer.cisco.com/meraki/api-v1/#!update-organization-saml-role)

        Args:
            organization_id: Organization ID.
            saml_role_id: Saml role ID.
            role: The role of the SAML administrator.
            org_access: The privilege of the SAML administrator on the organization. Can be one of
                'none', 'read-only', 'full' or 'enterprise' or a custom role in the
                format custom-role:ID:NAME.
            tags: The list of tags that the SAML administrator has privileges on.
            networks: The list of networks that the SAML administrator has privileges on.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "1284392014819",
              "role": "myrole",
              "orgAccess": "none",
              "networks": [
                {
                  "id": "N_24329156",
                  "access": "full"
                }
              ],
              "tags": [
                {
                  "tag": "west",
                  "access": "read-only"
                }
              ],
              "camera": [
                {
                  "orgWide": true,
                  "access": "viewAndExport"
                }
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        saml_role_id = urllib.parse.quote(str(saml_role_id), safe="")
        path = f"/organizations/{organization_id}/samlRoles/{saml_role_id}"

        payload: dict[str, Any] = {}
        if role is not None:
            payload["role"] = role
        if org_access is not None:
            payload["orgAccess"] = org_access
        if tags is not None:
            payload["tags"] = [item.model_dump(by_alias=True, exclude_none=True) for item in tags]
        if networks is not None:
            payload["networks"] = [
                item.model_dump(by_alias=True, exclude_none=True) for item in networks
            ]

        return self._session.put(
            scope="organizations",
            operation_id="updateOrganizationSamlRole",
            path=path,
            json=payload,
            response_schema=UpdateOrganizationSamlRoleResponse,
        )

    def delete_organization_saml_role(self, *, organization_id: str, saml_role_id: str) -> None:
        """Remove a SAML role.

        [API documentation: deleteOrganizationSamlRole](https://developer.cisco.com/meraki/api-v1/#!delete-organization-saml-role)

        Args:
            organization_id: Organization ID.
            saml_role_id: Saml role ID.

        Returns:
            Successful operation.

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        saml_role_id = urllib.parse.quote(str(saml_role_id), safe="")
        path = f"/organizations/{organization_id}/samlRoles/{saml_role_id}"

        return self._session.delete(
            scope="organizations", operation_id="deleteOrganizationSamlRole", path=path
        )

    def get_organization_snmp(self, organization_id: str) -> GetOrganizationSnmpResponse:
        """Return the SNMP settings for an organization.

        [API documentation: getOrganizationSnmp](https://developer.cisco.com/meraki/api-v1/#!get-organization-snmp)

        Args:
            organization_id: Organization ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "v2cEnabled": false,
              "v2CommunityString": "o/ABCDEF",
              "v3Enabled": true,
              "v3User": "o/ABCDEF",
              "v3AuthMode": "SHA",
              "v3PrivMode": "AES128",
              "peerIps": [
                "123.123.123.1"
              ],
              "hostname": "snmp.meraki.com",
              "port": 443
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/snmp"

        return self._session.get(
            scope="organizations",
            operation_id="getOrganizationSnmp",
            path=path,
            response_schema=GetOrganizationSnmpResponse,
        )

    def update_organization_snmp(
        self,
        organization_id: str,
        *,
        v2c_enabled: bool | None = None,
        v3_enabled: bool | None = None,
        v3_auth_mode: UpdateOrganizationSnmpV3AuthMode | None = None,
        v3_auth_pass: str | None = None,
        v3_priv_mode: UpdateOrganizationSnmpV3PrivMode | None = None,
        v3_priv_pass: str | None = None,
        peer_ips: list[str] | None = None,
    ) -> UpdateOrganizationSnmpResponse:
        """Update the SNMP settings for an organization.

        [API documentation: updateOrganizationSnmp](https://developer.cisco.com/meraki/api-v1/#!update-organization-snmp)

        Args:
            organization_id: Organization ID.
            v2c_enabled: Boolean indicating whether SNMP version 2c is enabled for the organization.
            v3_enabled: Boolean indicating whether SNMP version 3 is enabled for the organization.
            v3_auth_mode: The SNMP version 3 authentication mode. Can be either 'MD5' or 'SHA'.
            v3_auth_pass: The SNMP version 3 authentication password. Must be at least 8 characters
                if specified.
            v3_priv_mode: The SNMP version 3 privacy mode. Can be either 'DES' or 'AES128'.
            v3_priv_pass: The SNMP version 3 privacy password. Must be at least 8 characters if
                specified.
            peer_ips: The list of IPv4 addresses that are allowed to access the SNMP server.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "v2cEnabled": false,
              "v2CommunityString": "o/ABCDEF",
              "v3Enabled": true,
              "v3User": "o/ABCDEF",
              "v3AuthMode": "SHA",
              "v3PrivMode": "AES128",
              "peerIps": [
                "123.123.123.1"
              ],
              "hostname": "snmp.meraki.com",
              "port": 443
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/snmp"

        payload: dict[str, Any] = {}
        if v2c_enabled is not None:
            payload["v2cEnabled"] = v2c_enabled
        if v3_enabled is not None:
            payload["v3Enabled"] = v3_enabled
        if v3_auth_mode is not None:
            payload["v3AuthMode"] = v3_auth_mode
        if v3_auth_pass is not None:
            payload["v3AuthPass"] = v3_auth_pass
        if v3_priv_mode is not None:
            payload["v3PrivMode"] = v3_priv_mode
        if v3_priv_pass is not None:
            payload["v3PrivPass"] = v3_priv_pass
        if peer_ips is not None:
            payload["peerIps"] = peer_ips

        return self._session.put(
            scope="organizations",
            operation_id="updateOrganizationSnmp",
            path=path,
            json=payload,
            response_schema=UpdateOrganizationSnmpResponse,
        )

    def get_organization_splash_asset(
        self, *, organization_id: str, id: str
    ) -> GetOrganizationSplashAssetResponse:
        r"""Get a Splash Theme Asset.

        [API documentation: getOrganizationSplashAsset](https://developer.cisco.com/meraki/api-v1/#!get-organization-splash-asset)

        Args:
            organization_id: Organization ID.
            id: ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "1284392014819",
              "name": "continue.html",
              "fileData": "PGh0bWw+PC9odG1sPg==\n"
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        id = urllib.parse.quote(str(id), safe="")
        path = f"/organizations/{organization_id}/splash/assets/{id}"

        return self._session.get(
            scope="organizations",
            operation_id="getOrganizationSplashAsset",
            path=path,
            response_schema=GetOrganizationSplashAssetResponse,
        )

    def delete_organization_splash_asset(self, *, organization_id: str, id: str) -> None:
        """Delete a Splash Theme Asset.

        [API documentation: deleteOrganizationSplashAsset](https://developer.cisco.com/meraki/api-v1/#!delete-organization-splash-asset)

        Args:
            organization_id: Organization ID.
            id: ID.

        Returns:
            Successful operation.

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        id = urllib.parse.quote(str(id), safe="")
        path = f"/organizations/{organization_id}/splash/assets/{id}"

        return self._session.delete(
            scope="organizations", operation_id="deleteOrganizationSplashAsset", path=path
        )

    def get_organization_splash_themes(
        self, organization_id: str
    ) -> PaginatedResponse[GetOrganizationSplashThemesResponseItem]:
        """List Splash Themes.

        [API documentation: getOrganizationSplashThemes](https://developer.cisco.com/meraki/api-v1/#!get-organization-splash-themes)

        Args:
            organization_id: Organization ID.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "id": "482367494044dbbb1d2cc8579d967cef5b4ce59f",
                "name": "My Custom Splash Theme",
                "themeAssets": [
                  {
                    "id": "1284392014819",
                    "name": "continue.html"
                  }
                ]
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/splash/themes"

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationSplashThemes",
            path=path,
            item_schema=GetOrganizationSplashThemesResponseItem,
        )

    def create_organization_splash_theme(
        self, organization_id: str, *, name: str | None = None, base_theme: str | None = None
    ) -> CreateOrganizationSplashThemeResponse:
        """Create a Splash Theme.

        [API documentation: createOrganizationSplashTheme](https://developer.cisco.com/meraki/api-v1/#!create-organization-splash-theme)

        Args:
            organization_id: Organization ID.
            name: theme name.
            base_theme: base theme id.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "482367494044dbbb1d2cc8579d967cef5b4ce59f",
              "name": "My Custom Splash Theme",
              "themeAssets": [
                {
                  "id": "1284392014819",
                  "name": "continue.html"
                }
              ]
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/splash/themes"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if base_theme is not None:
            payload["baseTheme"] = base_theme

        return self._session.post(
            scope="organizations",
            operation_id="createOrganizationSplashTheme",
            path=path,
            json=payload,
            response_schema=CreateOrganizationSplashThemeResponse,
        )

    def delete_organization_splash_theme(self, *, organization_id: str, id: str) -> None:
        """Delete a Splash Theme.

        [API documentation: deleteOrganizationSplashTheme](https://developer.cisco.com/meraki/api-v1/#!delete-organization-splash-theme)

        Args:
            organization_id: Organization ID.
            id: ID.

        Returns:
            Successful operation.

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        id = urllib.parse.quote(str(id), safe="")
        path = f"/organizations/{organization_id}/splash/themes/{id}"

        return self._session.delete(
            scope="organizations", operation_id="deleteOrganizationSplashTheme", path=path
        )

    def create_organization_splash_theme_asset(
        self,
        *,
        organization_id: str,
        theme_identifier: str,
        name: str | None = None,
        content: str | None = None,
    ) -> CreateOrganizationSplashThemeAssetResponse:
        r"""Create a Splash Theme Asset.

        [API documentation: createOrganizationSplashThemeAsset](https://developer.cisco.com/meraki/api-v1/#!create-organization-splash-theme-asset)

        Args:
            organization_id: Organization ID.
            theme_identifier: Theme identifier.
            name: File name. Will overwrite files with same name.
            content: a file containing the asset content.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "id": "1284392014819",
              "name": "continue.html",
              "fileData": "PGh0bWw+PC9odG1sPg==\n"
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        theme_identifier = urllib.parse.quote(str(theme_identifier), safe="")
        path = f"/organizations/{organization_id}/splash/themes/{theme_identifier}/assets"

        payload: dict[str, Any] = {}
        if name is not None:
            payload["name"] = name
        if content is not None:
            payload["content"] = content

        return self._session.post(
            scope="organizations",
            operation_id="createOrganizationSplashThemeAsset",
            path=path,
            json=payload,
            response_schema=CreateOrganizationSplashThemeAssetResponse,
        )

    def get_organization_summary_top_appliances_by_utilization(
        self,
        organization_id: str,
        *,
        network_tag: str | None = None,
        device_tag: str | None = None,
        quantity: int | None = None,
        ssid_name: str | None = None,
        usage_uplink: str | None = None,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
    ) -> PaginatedResponse[GetOrganizationSummaryTopAppliancesByUtilizationResponseItem]:
        """Return the top 10 appliances sorted by utilization over given time range.

        [API documentation: getOrganizationSummaryTopAppliancesByUtilization](https://developer.cisco.com/meraki/api-v1/#!get-organization-summary-top-appliances-by-utilization)

        Args:
            organization_id: Organization ID.
            network_tag: Match result to an exact network tag.
            device_tag: Match result to an exact device tag.
            quantity: Set number of desired results to return. Default is 10. Maximum is 50.
            ssid_name: Filter results by ssid name.
            usage_uplink: Filter results by usage uplink.
            t0: The beginning of the timespan for the data.
            t1: The end of the timespan for the data. t1 can be a maximum of 186 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be greater than or equal to 25 minutes and be less than or
                equal to 186 days. The default is 1 day.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "network": {
                  "name": "Main Office",
                  "id": "N_24329156"
                },
                "name": "My appliance",
                "mac": "00:11:22:33:44:55",
                "serial": "Q234-ABCD-5678",
                "model": "MX",
                "utilization": {
                  "average": {
                    "percentage": 7.3
                  }
                }
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/summary/top/appliances/byUtilization"

        params: dict[str, Any] = {}
        if network_tag is not None:
            params["networkTag"] = network_tag
        if device_tag is not None:
            params["deviceTag"] = device_tag
        if quantity is not None:
            params["quantity"] = quantity
        if ssid_name is not None:
            params["ssidName"] = ssid_name
        if usage_uplink is not None:
            params["usageUplink"] = usage_uplink
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationSummaryTopAppliancesByUtilization",
            path=path,
            params=params,
            item_schema=GetOrganizationSummaryTopAppliancesByUtilizationResponseItem,
        )

    def get_organization_summary_top_applications_by_usage(
        self,
        organization_id: str,
        *,
        network_tag: str | None = None,
        device: str | None = None,
        network_id: str | None = None,
        quantity: int | None = None,
        ssid_name: str | None = None,
        usage_uplink: str | None = None,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
    ) -> PaginatedResponse[GetOrganizationSummaryTopApplicationsByUsageResponseItem]:
        """Return the top applications sorted by data usage over given time range.

        [API documentation: getOrganizationSummaryTopApplicationsByUsage](https://developer.cisco.com/meraki/api-v1/#!get-organization-summary-top-applications-by-usage)

        Args:
            organization_id: Organization ID.
            network_tag: Match result to an exact network tag.
            device: Match result to an exact device tag.
            network_id: Match result to an exact network id.
            quantity: Set number of desired results to return. Default is 10. Maximum is 50.
            ssid_name: Filter results by ssid name.
            usage_uplink: Filter results by usage uplink.
            t0: The beginning of the timespan for the data.
            t1: The end of the timespan for the data. t1 can be a maximum of 186 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be greater than or equal to 25 minutes and be less than or
                equal to 186 days. The default is 1 day.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "application": "sample name",
                "total": 18000.0,
                "downstream": 10000.0,
                "upstream": 8000.0,
                "percentage": 80.223456789
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/summary/top/applications/byUsage"

        params: dict[str, Any] = {}
        if network_tag is not None:
            params["networkTag"] = network_tag
        if device is not None:
            params["device"] = device
        if network_id is not None:
            params["networkId"] = network_id
        if quantity is not None:
            params["quantity"] = quantity
        if ssid_name is not None:
            params["ssidName"] = ssid_name
        if usage_uplink is not None:
            params["usageUplink"] = usage_uplink
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationSummaryTopApplicationsByUsage",
            path=path,
            params=params,
            item_schema=GetOrganizationSummaryTopApplicationsByUsageResponseItem,
        )

    def get_organization_summary_top_applications_categories_by_usage(
        self,
        organization_id: str,
        *,
        network_tag: str | None = None,
        device_tag: str | None = None,
        network_id: str | None = None,
        quantity: int | None = None,
        ssid_name: str | None = None,
        usage_uplink: str | None = None,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
    ) -> PaginatedResponse[GetOrganizationSummaryTopApplicationsCategoriesByUsageResponseItem]:
        """Return the top application categories sorted by data usage over given time range.

        [API documentation: getOrganizationSummaryTopApplicationsCategoriesByUsage](https://developer.cisco.com/meraki/api-v1/#!get-organization-summary-top-applications-categories-by-usage)

        Args:
            organization_id: Organization ID.
            network_tag: Match result to an exact network tag.
            device_tag: Match result to an exact device tag.
            network_id: Match result to an exact network id.
            quantity: Set number of desired results to return. Default is 10. Maximum is 50.
            ssid_name: Filter results by ssid name.
            usage_uplink: Filter results by usage uplink.
            t0: The beginning of the timespan for the data.
            t1: The end of the timespan for the data. t1 can be a maximum of 186 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be greater than or equal to 25 minutes and be less than or
                equal to 186 days. The default is 1 day.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "category": "other",
                "total": 18000.0,
                "downstream": 10000.0,
                "upstream": 8000.0,
                "percentage": 80.223456789
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/summary/top/applications/categories/byUsage"

        params: dict[str, Any] = {}
        if network_tag is not None:
            params["networkTag"] = network_tag
        if device_tag is not None:
            params["deviceTag"] = device_tag
        if network_id is not None:
            params["networkId"] = network_id
        if quantity is not None:
            params["quantity"] = quantity
        if ssid_name is not None:
            params["ssidName"] = ssid_name
        if usage_uplink is not None:
            params["usageUplink"] = usage_uplink
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationSummaryTopApplicationsCategoriesByUsage",
            path=path,
            params=params,
            item_schema=GetOrganizationSummaryTopApplicationsCategoriesByUsageResponseItem,
        )

    def get_organization_summary_top_clients_by_usage(
        self,
        organization_id: str,
        *,
        network_tag: str | None = None,
        device_tag: str | None = None,
        quantity: int | None = None,
        ssid_name: str | None = None,
        usage_uplink: str | None = None,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
    ) -> PaginatedResponse[GetOrganizationSummaryTopClientsByUsageResponseItem]:
        """Return metrics for organization's top 10 clients by data usage (in mb) over given time range.

        [API documentation: getOrganizationSummaryTopClientsByUsage](https://developer.cisco.com/meraki/api-v1/#!get-organization-summary-top-clients-by-usage)

        Args:
            organization_id: Organization ID.
            network_tag: Match result to an exact network tag.
            device_tag: Match result to an exact device tag.
            quantity: Set number of desired results to return. Default is 10. Maximum is 50.
            ssid_name: Filter results by ssid name.
            usage_uplink: Filter results by usage uplink.
            t0: The beginning of the timespan for the data.
            t1: The end of the timespan for the data. t1 can be a maximum of 186 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be greater than or equal to 8 hours and be less than or
                equal to 186 days. The default is 1 day.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "name": "Office Switch",
                "mac": "22:33:44:55:66:77",
                "id": "k74272e",
                "network": {
                  "name": "Main Office",
                  "id": "N_24329156"
                },
                "usage": {
                  "total": 18000.0,
                  "upstream": 8000.0,
                  "downstream": 10000.0,
                  "percentage": 80.2
                }
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/summary/top/clients/byUsage"

        params: dict[str, Any] = {}
        if network_tag is not None:
            params["networkTag"] = network_tag
        if device_tag is not None:
            params["deviceTag"] = device_tag
        if quantity is not None:
            params["quantity"] = quantity
        if ssid_name is not None:
            params["ssidName"] = ssid_name
        if usage_uplink is not None:
            params["usageUplink"] = usage_uplink
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationSummaryTopClientsByUsage",
            path=path,
            params=params,
            item_schema=GetOrganizationSummaryTopClientsByUsageResponseItem,
        )

    def get_organization_summary_top_clients_manufacturers_by_usage(
        self,
        organization_id: str,
        *,
        network_tag: str | None = None,
        device_tag: str | None = None,
        quantity: int | None = None,
        ssid_name: str | None = None,
        usage_uplink: str | None = None,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
    ) -> PaginatedResponse[GetOrganizationSummaryTopClientsManufacturersByUsageResponseItem]:
        """Return metrics for organization's top clients by data usage (in mb) over given time range, grouped by manufacturer.

        [API documentation: getOrganizationSummaryTopClientsManufacturersByUsage](https://developer.cisco.com/meraki/api-v1/#!get-organization-summary-top-clients-manufacturers-by-usage)

        Args:
            organization_id: Organization ID.
            network_tag: Match result to an exact network tag.
            device_tag: Match result to an exact device tag.
            quantity: Set number of desired results to return. Default is 10. Maximum is 50.
            ssid_name: Filter results by ssid name.
            usage_uplink: Filter results by usage uplink.
            t0: The beginning of the timespan for the data.
            t1: The end of the timespan for the data. t1 can be a maximum of 186 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 186 days. The default is 1 day.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "name": "Manufacturer Name",
                "clients": {
                  "counts": {
                    "total": 3
                  }
                },
                "usage": {
                  "total": 9000.0,
                  "upstream": 1000.0,
                  "downstream": 8000.0
                }
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/summary/top/clients/manufacturers/byUsage"

        params: dict[str, Any] = {}
        if network_tag is not None:
            params["networkTag"] = network_tag
        if device_tag is not None:
            params["deviceTag"] = device_tag
        if quantity is not None:
            params["quantity"] = quantity
        if ssid_name is not None:
            params["ssidName"] = ssid_name
        if usage_uplink is not None:
            params["usageUplink"] = usage_uplink
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationSummaryTopClientsManufacturersByUsage",
            path=path,
            params=params,
            item_schema=GetOrganizationSummaryTopClientsManufacturersByUsageResponseItem,
        )

    def get_organization_summary_top_devices_by_usage(
        self,
        organization_id: str,
        *,
        network_tag: str | None = None,
        device_tag: str | None = None,
        quantity: int | None = None,
        ssid_name: str | None = None,
        usage_uplink: str | None = None,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
    ) -> PaginatedResponse[GetOrganizationSummaryTopDevicesByUsageResponseItem]:
        """Return metrics for organization's top 10 devices sorted by data usage over given time range.

        [API documentation: getOrganizationSummaryTopDevicesByUsage](https://developer.cisco.com/meraki/api-v1/#!get-organization-summary-top-devices-by-usage)

        Args:
            organization_id: Organization ID.
            network_tag: Match result to an exact network tag.
            device_tag: Match result to an exact device tag.
            quantity: Set number of desired results to return. Default is 10. Maximum is 50.
            ssid_name: Filter results by ssid name.
            usage_uplink: Filter results by usage uplink.
            t0: The beginning of the timespan for the data.
            t1: The end of the timespan for the data. t1 can be a maximum of 186 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be greater than or equal to 8 hours and be less than or
                equal to 186 days. The default is 1 day.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "name": "My AP",
                "model": "MR34",
                "serial": "Q234-ABCD-5678",
                "mac": "00:11:22:33:44:55",
                "productType": "switch",
                "network": {
                  "name": "Main Office",
                  "id": "N_24329156"
                },
                "usage": {
                  "total": 18000.111,
                  "percentage": 80.223456789
                },
                "clients": {
                  "counts": {
                    "total": 4
                  }
                }
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/summary/top/devices/byUsage"

        params: dict[str, Any] = {}
        if network_tag is not None:
            params["networkTag"] = network_tag
        if device_tag is not None:
            params["deviceTag"] = device_tag
        if quantity is not None:
            params["quantity"] = quantity
        if ssid_name is not None:
            params["ssidName"] = ssid_name
        if usage_uplink is not None:
            params["usageUplink"] = usage_uplink
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationSummaryTopDevicesByUsage",
            path=path,
            params=params,
            item_schema=GetOrganizationSummaryTopDevicesByUsageResponseItem,
        )

    def get_organization_summary_top_devices_models_by_usage(
        self,
        organization_id: str,
        *,
        network_tag: str | None = None,
        device_tag: str | None = None,
        quantity: int | None = None,
        ssid_name: str | None = None,
        usage_uplink: str | None = None,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
    ) -> PaginatedResponse[GetOrganizationSummaryTopDevicesModelsByUsageResponseItem]:
        """Return metrics for organization's top 10 device models sorted by data usage over given time range.

        [API documentation: getOrganizationSummaryTopDevicesModelsByUsage](https://developer.cisco.com/meraki/api-v1/#!get-organization-summary-top-devices-models-by-usage)

        Args:
            organization_id: Organization ID.
            network_tag: Match result to an exact network tag.
            device_tag: Match result to an exact device tag.
            quantity: Set number of desired results to return. Default is 10. Maximum is 50.
            ssid_name: Filter results by ssid name.
            usage_uplink: Filter results by usage uplink.
            t0: The beginning of the timespan for the data.
            t1: The end of the timespan for the data. t1 can be a maximum of 186 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be greater than or equal to 8 hours and be less than or
                equal to 186 days. The default is 1 day.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "model": "MR34",
                "count": 2,
                "usage": {
                  "total": 2000.0,
                  "average": 1000.0
                }
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/summary/top/devices/models/byUsage"

        params: dict[str, Any] = {}
        if network_tag is not None:
            params["networkTag"] = network_tag
        if device_tag is not None:
            params["deviceTag"] = device_tag
        if quantity is not None:
            params["quantity"] = quantity
        if ssid_name is not None:
            params["ssidName"] = ssid_name
        if usage_uplink is not None:
            params["usageUplink"] = usage_uplink
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationSummaryTopDevicesModelsByUsage",
            path=path,
            params=params,
            item_schema=GetOrganizationSummaryTopDevicesModelsByUsageResponseItem,
        )

    def get_organization_summary_top_networks_by_status(
        self,
        organization_id: str,
        *,
        network_tag: str | None = None,
        device_tag: str | None = None,
        quantity: int | None = None,
        ssid_name: str | None = None,
        usage_uplink: str | None = None,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetOrganizationSummaryTopNetworksByStatusResponseItem]:
        """List the client and status overview information for the networks in an organization.

        [API documentation: getOrganizationSummaryTopNetworksByStatus](https://developer.cisco.com/meraki/api-v1/#!get-organization-summary-top-networks-by-status)

        Args:
            organization_id: Organization ID.
            network_tag: Match result to an exact network tag.
            device_tag: Match result to an exact device tag.
            quantity: Set number of desired results to return. Default is 10. Maximum is 50.
            ssid_name: Filter results by ssid name.
            usage_uplink: Filter results by usage uplink.
            per_page: The number of entries per page returned. Acceptable range is 3 - 5000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "networkId": "N_24329156",
                "name": "Main Office",
                "url": "https://n1.meraki.com//n//manage/nodes/list",
                "tags": [
                  "tag1",
                  "tag2"
                ],
                "clients": {
                  "counts": {
                    "total": 72
                  },
                  "usage": {
                    "upstream": 3732658.44,
                    "downstream": 983732658.87
                  }
                },
                "statuses": {
                  "overall": "online",
                  "byProductType": [
                    {
                      "productType": "wireless",
                      "counts": {
                        "online": 2,
                        "offline": 1,
                        "alerting": 0,
                        "dormant": 3
                      }
                    }
                  ]
                },
                "devices": {
                  "byProductType": [
                    {
                      "productType": "wireless",
                      "url": "https://n1.meraki.com//n//manage/nodes/new_list/000000000000"
                    }
                  ]
                },
                "productTypes": [
                  "appliance",
                  "switch",
                  "wireless"
                ]
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/summary/top/networks/byStatus"

        params: dict[str, Any] = {}
        if network_tag is not None:
            params["networkTag"] = network_tag
        if device_tag is not None:
            params["deviceTag"] = device_tag
        if quantity is not None:
            params["quantity"] = quantity
        if ssid_name is not None:
            params["ssidName"] = ssid_name
        if usage_uplink is not None:
            params["usageUplink"] = usage_uplink
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationSummaryTopNetworksByStatus",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationSummaryTopNetworksByStatusResponseItem,
        )

    def get_organization_summary_top_ssids_by_usage(
        self,
        organization_id: str,
        *,
        network_tag: str | None = None,
        device_tag: str | None = None,
        quantity: int | None = None,
        ssid_name: str | None = None,
        usage_uplink: str | None = None,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
    ) -> PaginatedResponse[GetOrganizationSummaryTopSsidsByUsageResponseItem]:
        """Return metrics for organization's top 10 ssids by data usage over given time range.

        [API documentation: getOrganizationSummaryTopSsidsByUsage](https://developer.cisco.com/meraki/api-v1/#!get-organization-summary-top-ssids-by-usage)

        Args:
            organization_id: Organization ID.
            network_tag: Match result to an exact network tag.
            device_tag: Match result to an exact device tag.
            quantity: Set number of desired results to return. Default is 10. Maximum is 50.
            ssid_name: Filter results by ssid name.
            usage_uplink: Filter results by usage uplink.
            t0: The beginning of the timespan for the data.
            t1: The end of the timespan for the data. t1 can be a maximum of 186 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be greater than or equal to 8 hours and be less than or
                equal to 186 days. The default is 1 day.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "name": "My SSID",
                "usage": {
                  "total": 18000.0,
                  "downstream": 10000.0,
                  "upstream": 8000.0,
                  "percentage": 80.223456789
                },
                "clients": {
                  "counts": {
                    "total": 4
                  }
                }
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/summary/top/ssids/byUsage"

        params: dict[str, Any] = {}
        if network_tag is not None:
            params["networkTag"] = network_tag
        if device_tag is not None:
            params["deviceTag"] = device_tag
        if quantity is not None:
            params["quantity"] = quantity
        if ssid_name is not None:
            params["ssidName"] = ssid_name
        if usage_uplink is not None:
            params["usageUplink"] = usage_uplink
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationSummaryTopSsidsByUsage",
            path=path,
            params=params,
            item_schema=GetOrganizationSummaryTopSsidsByUsageResponseItem,
        )

    def get_organization_summary_top_switches_by_energy_usage(
        self,
        organization_id: str,
        *,
        network_tag: str | None = None,
        device_tag: str | None = None,
        quantity: int | None = None,
        ssid_name: str | None = None,
        usage_uplink: str | None = None,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
    ) -> PaginatedResponse[GetOrganizationSummaryTopSwitchesByEnergyUsageResponseItem]:
        """Return metrics for organization's top 10 switches by energy usage over given time range.

        [API documentation: getOrganizationSummaryTopSwitchesByEnergyUsage](https://developer.cisco.com/meraki/api-v1/#!get-organization-summary-top-switches-by-energy-usage)

        Args:
            organization_id: Organization ID.
            network_tag: Match result to an exact network tag.
            device_tag: Match result to an exact device tag.
            quantity: Set number of desired results to return. Default is 10. Maximum is 50.
            ssid_name: Filter results by ssid name.
            usage_uplink: Filter results by usage uplink.
            t0: The beginning of the timespan for the data.
            t1: The end of the timespan for the data. t1 can be a maximum of 186 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be greater than or equal to 25 minutes and be less than or
                equal to 186 days. The default is 1 day.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "network": {
                  "name": "Main Office",
                  "id": "N_24329156"
                },
                "name": "My switch",
                "mac": "00:11:22:33:44:55",
                "model": "MS",
                "usage": {
                  "total": 800.021
                }
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/summary/top/switches/byEnergyUsage"

        params: dict[str, Any] = {}
        if network_tag is not None:
            params["networkTag"] = network_tag
        if device_tag is not None:
            params["deviceTag"] = device_tag
        if quantity is not None:
            params["quantity"] = quantity
        if ssid_name is not None:
            params["ssidName"] = ssid_name
        if usage_uplink is not None:
            params["usageUplink"] = usage_uplink
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationSummaryTopSwitchesByEnergyUsage",
            path=path,
            params=params,
            item_schema=GetOrganizationSummaryTopSwitchesByEnergyUsageResponseItem,
        )

    def get_organization_uplinks_statuses(
        self,
        organization_id: str,
        *,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        network_ids: list[str] | None = None,
        serials: list[str] | None = None,
        iccids: list[str] | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetOrganizationUplinksStatusesResponseItem]:
        """List the uplink status of every Meraki MX, MG and Z series devices in the organization.

        [API documentation: getOrganizationUplinksStatuses](https://developer.cisco.com/meraki/api-v1/#!get-organization-uplinks-statuses)

        Args:
            organization_id: Organization ID.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 1000.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            network_ids: A list of network IDs. The returned devices will be filtered to only
                include these networks.
            serials: A list of serial numbers. The returned devices will be filtered to only include
                these serials.
            iccids: A list of ICCIDs. The returned devices will be filtered to only include these
                ICCIDs.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "networkId": "N_24329156",
                "serial": "Q234-ABCD-5678",
                "model": "MX68C",
                "lastReportedAt": "2018-02-11T00:00:00Z",
                "highAvailability": {
                  "enabled": true,
                  "role": "primary"
                },
                "uplinks": [
                  {
                    "interface": "wan1",
                    "status": "active",
                    "ip": "1.2.3.4",
                    "gateway": "1.2.3.5",
                    "publicIp": "123.123.123.1",
                    "primaryDns": "8.8.8.8",
                    "secondaryDns": "8.8.4.4",
                    "ipAssignedBy": "static",
                    "provider": "at&t",
                    "signalStat": {
                      "rsrp": "-120",
                      "rsrq": "-13"
                    },
                    "mcc": "123",
                    "mnc": "123",
                    "roaming": {
                      "status": "home"
                    },
                    "connectionType": "4g",
                    "apn": "internet",
                    "dns1": "111.111.111.111",
                    "dns2": "222.222.222.222",
                    "signalType": "4G",
                    "mtu": 1500,
                    "iccid": "123456789",
                    "imsi": "123456789012345",
                    "msisdn": "123456789012345"
                  }
                ]
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/uplinks/statuses"

        params: dict[str, Any] = {}
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if network_ids is not None:
            params["networkIds[]"] = network_ids
        if serials is not None:
            params["serials[]"] = serials
        if iccids is not None:
            params["iccids[]"] = iccids

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationUplinksStatuses",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationUplinksStatusesResponseItem,
        )

    def get_organization_webhooks_alert_types(
        self,
        organization_id: str,
        *,
        product_type: GetOrganizationWebhooksAlertTypesProductType | None = None,
    ) -> PaginatedResponse[GetOrganizationWebhooksAlertTypesResponse]:
        """Return a list of alert types to be used with managing webhook alerts.

        [API documentation: getOrganizationWebhooksAlertTypes](https://developer.cisco.com/meraki/api-v1/#!get-organization-webhooks-alert-types)

        Args:
            organization_id: Organization ID.
            product_type: Filter sample alerts to a specific product type.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            {
              "alertTypeId": "stopped_reporting",
              "alertType": "APs went down",
              "example": {
                "version": "0.1",
                "sharedSecret": "secret",
                "sentAt": "2018-02-11T00:00:00.090210Z",
                "alertId": "0000000000000000",
                "alertLevel": "warning",
                "occurredAt": "2018-02-11T00:00:00.090210Z",
                "organizationId": "2930418",
                "organizationName": "My organization",
                "organizationUrl": "https://dashboard.meraki.com/o/VjjsAd/manage/organization/overview",
                "deviceSerial": "Q234-ABCD-5678",
                "deviceMac": "00:11:22:33:44:55",
                "deviceName": "My AP",
                "deviceUrl": "https://n1.meraki.com//n//manage/nodes/new_list/000000000000",
                "deviceTags": [
                  "tag1",
                  "tag2"
                ],
                "deviceModel": "MR34",
                "networkId": "N_24329156",
                "networkName": "Main Office",
                "networkUrl": "https://n1.meraki.com//n//manage/nodes/list",
                "enrollmentString": "my-enrollment-string",
                "notes": "Additional description of the network",
                "productTypes": [
                  "appliance",
                  "switch",
                  "wireless"
                ],
                "encryptedId": "6GREra"
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/webhooks/alertTypes"

        params: dict[str, Any] = {}
        if product_type is not None:
            params["productType"] = product_type

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationWebhooksAlertTypes",
            path=path,
            params=params,
            item_schema=GetOrganizationWebhooksAlertTypesResponse,
        )

    def get_organization_webhooks_callbacks_status(
        self, *, organization_id: str, callback_id: str
    ) -> GetOrganizationWebhooksCallbacksStatusResponse:
        """Return the status of an API callback.

        [API documentation: getOrganizationWebhooksCallbacksStatus](https://developer.cisco.com/meraki/api-v1/#!get-organization-webhooks-callbacks-status)

        Args:
            organization_id: Organization ID.
            callback_id: Callback ID.

        Returns:
            Successful operation.

        Example API response:
            ```json
            {
              "callbackId": "1284392014819",
              "status": "completed",
              "errors": [
                "Callback failed"
              ],
              "createdBy": {
                "adminId": "212406"
              },
              "webhook": {
                "url": "https://webhook.site/28efa24e-f830-4d9f-a12b-fbb9e5035031",
                "httpServer": {
                  "id": "aHR0cHM6Ly93d3cuZXhhbXBsZS5jb20vd2ViaG9va3M="
                },
                "payloadTemplate": {
                  "id": "wpt_2100"
                },
                "sentAt": "2018-02-11T00:00:00.090210Z"
              }
            }
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        callback_id = urllib.parse.quote(str(callback_id), safe="")
        path = f"/organizations/{organization_id}/webhooks/callbacks/statuses/{callback_id}"

        return self._session.get(
            scope="organizations",
            operation_id="getOrganizationWebhooksCallbacksStatus",
            path=path,
            response_schema=GetOrganizationWebhooksCallbacksStatusResponse,
        )

    def get_organization_webhooks_logs(
        self,
        organization_id: str,
        *,
        t0: str | None = None,
        t1: str | None = None,
        timespan: float | None = None,
        per_page: int | None = None,
        starting_after: str | None = None,
        ending_before: str | None = None,
        url: str | None = None,
        total_pages: int | Literal["all"] = "all",
        direction: Literal["prev", "next"] = "next",
    ) -> PaginatedResponse[GetOrganizationWebhooksLogsResponseItem]:
        """Return the log of webhook POSTs sent.

        [API documentation: getOrganizationWebhooksLogs](https://developer.cisco.com/meraki/api-v1/#!get-organization-webhooks-logs)

        Args:
            organization_id: Organization ID.
            t0: The beginning of the timespan for the data. The maximum lookback period is 90 days
                from today.
            t1: The end of the timespan for the data. t1 can be a maximum of 31 days after t0.
            timespan: The timespan for which the information will be fetched. If specifying
                timespan, do not specify parameters t0 and t1. The value must be in
                seconds and be less than or equal to 31 days. The default is 1 day.
            per_page: The number of entries per page returned. Acceptable range is 3 - 1000. Default
                is 50.
            starting_after: A token used by the server to indicate the start of the page. Often this
                is a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            ending_before: A token used by the server to indicate the end of the page. Often this is
                a timestamp or an ID but it is not limited to those. This parameter
                should not be defined by client applications. The link for the first,
                last, prev, or next page in the HTTP Link header should define it.
            url: The URL the webhook was sent to.
            total_pages: use with per_page to get total results up to total_pages * per_page; -1 or
                "all" for all pages.
            direction: direction to paginate, either "next" (default) or "prev" page.

        Returns:
            Successful operation.

        Note:
            Returns a lazy PaginatedResponse
            that can be iterated or collected with `.collect()`.
            Page metadata is available on `.meta` and `.meta_pages`.

        Example API response:
            ```json
            [
              {
                "alertType": "Settings changed",
                "loggedAt": "2019-01-01T13:37:28.423456Z",
                "networkId": "N_24329156",
                "organizationId": "2930418",
                "responseCode": 200,
                "responseDuration": 244,
                "sentAt": "2019-01-01T13:37:28.123456Z",
                "url": "https://www.example.com/path"
              }
            ]
            ```

        """
        organization_id = urllib.parse.quote(str(organization_id), safe="")
        path = f"/organizations/{organization_id}/webhooks/logs"

        params: dict[str, Any] = {}
        if t0 is not None:
            params["t0"] = t0
        if t1 is not None:
            params["t1"] = t1
        if timespan is not None:
            params["timespan"] = timespan
        if per_page is not None:
            params["perPage"] = per_page
        if starting_after is not None:
            params["startingAfter"] = starting_after
        if ending_before is not None:
            params["endingBefore"] = ending_before
        if url is not None:
            params["url"] = url

        return self._session.get_pages(
            scope="organizations",
            operation_id="getOrganizationWebhooksLogs",
            path=path,
            params=params,
            total_pages=total_pages,
            direction=direction,
            item_schema=GetOrganizationWebhooksLogsResponseItem,
        )
