diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 57726a4f..b429f966 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.65.0"
+ ".": "0.66.0"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index dcde96de..17293bfb 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 117
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-08c2d6a44f4cdcbfb6803a3043fdc1a3e33911dec4652cb3a870f01bc584421f.yml
-openapi_spec_hash: c816491451347eb93b793cddf6a78648
-config_hash: 9e45c27425021d49b5391f5cc980b046
+configured_endpoints: 119
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-f9a96fe14f0b3c93230a26f9b64827a35a19a28d4e7cd2719315c4d76cce78fc.yml
+openapi_spec_hash: 852e2a64b850f759ccbcf81b1579497a
+config_hash: 80eef1b592110714ea55cd26c470fabb
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 18792366..601f4010 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
# Changelog
+## 0.66.0 (2026-06-09)
+
+Full Changelog: [v0.65.0...v0.66.0](https://github.com/kernel/kernel-python-sdk/compare/v0.65.0...v0.66.0)
+
+### Features
+
+* Add org-level default per-project concurrency cap ([2de4525](https://github.com/kernel/kernel-python-sdk/commit/2de45255a1f5ed003ec0492461ee967bf961db2e))
+
## 0.65.0 (2026-06-08)
Full Changelog: [v0.64.0...v0.65.0](https://github.com/kernel/kernel-python-sdk/compare/v0.64.0...v0.65.0)
diff --git a/api.md b/api.md
index 2d311077..4b24f102 100644
--- a/api.md
+++ b/api.md
@@ -423,6 +423,21 @@ Methods:
- client.projects.limits.retrieve(id) -> ProjectLimits
- client.projects.limits.update(id, \*\*params) -> ProjectLimits
+# Organization
+
+## Limits
+
+Types:
+
+```python
+from kernel.types.organization import OrgLimits, UpdateOrgLimitsRequest
+```
+
+Methods:
+
+- client.organization.limits.retrieve() -> OrgLimits
+- client.organization.limits.update(\*\*params) -> OrgLimits
+
# APIKeys
Types:
diff --git a/pyproject.toml b/pyproject.toml
index 75d7d508..c9fef2a6 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "kernel"
-version = "0.65.0"
+version = "0.66.0"
description = "The official Python library for the kernel API"
dynamic = ["readme"]
license = "Apache-2.0"
diff --git a/src/kernel/_client.py b/src/kernel/_client.py
index 537d1598..5e7e5e0d 100644
--- a/src/kernel/_client.py
+++ b/src/kernel/_client.py
@@ -58,6 +58,7 @@
credentials,
deployments,
invocations,
+ organization,
browser_pools,
credential_providers,
)
@@ -74,6 +75,7 @@
from .resources.browsers.browsers import BrowsersResource, AsyncBrowsersResource
from .resources.projects.projects import ProjectsResource, AsyncProjectsResource
from .resources.credential_providers import CredentialProvidersResource, AsyncCredentialProvidersResource
+ from .resources.organization.organization import OrganizationResource, AsyncOrganizationResource
__all__ = [
"ENVIRONMENTS",
@@ -262,6 +264,12 @@ def projects(self) -> ProjectsResource:
return ProjectsResource(self)
+ @cached_property
+ def organization(self) -> OrganizationResource:
+ from .resources.organization import OrganizationResource
+
+ return OrganizationResource(self)
+
@cached_property
def api_keys(self) -> APIKeysResource:
"""Create and manage API keys for organization and project-scoped access."""
@@ -593,6 +601,12 @@ def projects(self) -> AsyncProjectsResource:
return AsyncProjectsResource(self)
+ @cached_property
+ def organization(self) -> AsyncOrganizationResource:
+ from .resources.organization import AsyncOrganizationResource
+
+ return AsyncOrganizationResource(self)
+
@cached_property
def api_keys(self) -> AsyncAPIKeysResource:
"""Create and manage API keys for organization and project-scoped access."""
@@ -837,6 +851,12 @@ def projects(self) -> projects.ProjectsResourceWithRawResponse:
return ProjectsResourceWithRawResponse(self._client.projects)
+ @cached_property
+ def organization(self) -> organization.OrganizationResourceWithRawResponse:
+ from .resources.organization import OrganizationResourceWithRawResponse
+
+ return OrganizationResourceWithRawResponse(self._client.organization)
+
@cached_property
def api_keys(self) -> api_keys.APIKeysResourceWithRawResponse:
"""Create and manage API keys for organization and project-scoped access."""
@@ -934,6 +954,12 @@ def projects(self) -> projects.AsyncProjectsResourceWithRawResponse:
return AsyncProjectsResourceWithRawResponse(self._client.projects)
+ @cached_property
+ def organization(self) -> organization.AsyncOrganizationResourceWithRawResponse:
+ from .resources.organization import AsyncOrganizationResourceWithRawResponse
+
+ return AsyncOrganizationResourceWithRawResponse(self._client.organization)
+
@cached_property
def api_keys(self) -> api_keys.AsyncAPIKeysResourceWithRawResponse:
"""Create and manage API keys for organization and project-scoped access."""
@@ -1031,6 +1057,12 @@ def projects(self) -> projects.ProjectsResourceWithStreamingResponse:
return ProjectsResourceWithStreamingResponse(self._client.projects)
+ @cached_property
+ def organization(self) -> organization.OrganizationResourceWithStreamingResponse:
+ from .resources.organization import OrganizationResourceWithStreamingResponse
+
+ return OrganizationResourceWithStreamingResponse(self._client.organization)
+
@cached_property
def api_keys(self) -> api_keys.APIKeysResourceWithStreamingResponse:
"""Create and manage API keys for organization and project-scoped access."""
@@ -1128,6 +1160,12 @@ def projects(self) -> projects.AsyncProjectsResourceWithStreamingResponse:
return AsyncProjectsResourceWithStreamingResponse(self._client.projects)
+ @cached_property
+ def organization(self) -> organization.AsyncOrganizationResourceWithStreamingResponse:
+ from .resources.organization import AsyncOrganizationResourceWithStreamingResponse
+
+ return AsyncOrganizationResourceWithStreamingResponse(self._client.organization)
+
@cached_property
def api_keys(self) -> api_keys.AsyncAPIKeysResourceWithStreamingResponse:
"""Create and manage API keys for organization and project-scoped access."""
diff --git a/src/kernel/_version.py b/src/kernel/_version.py
index 7a6f830a..eda0bdfb 100644
--- a/src/kernel/_version.py
+++ b/src/kernel/_version.py
@@ -1,4 +1,4 @@
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
__title__ = "kernel"
-__version__ = "0.65.0" # x-release-please-version
+__version__ = "0.66.0" # x-release-please-version
diff --git a/src/kernel/resources/__init__.py b/src/kernel/resources/__init__.py
index 64b98338..1497ad67 100644
--- a/src/kernel/resources/__init__.py
+++ b/src/kernel/resources/__init__.py
@@ -88,6 +88,14 @@
InvocationsResourceWithStreamingResponse,
AsyncInvocationsResourceWithStreamingResponse,
)
+from .organization import (
+ OrganizationResource,
+ AsyncOrganizationResource,
+ OrganizationResourceWithRawResponse,
+ AsyncOrganizationResourceWithRawResponse,
+ OrganizationResourceWithStreamingResponse,
+ AsyncOrganizationResourceWithStreamingResponse,
+)
from .browser_pools import (
BrowserPoolsResource,
AsyncBrowserPoolsResource,
@@ -172,6 +180,12 @@
"AsyncProjectsResourceWithRawResponse",
"ProjectsResourceWithStreamingResponse",
"AsyncProjectsResourceWithStreamingResponse",
+ "OrganizationResource",
+ "AsyncOrganizationResource",
+ "OrganizationResourceWithRawResponse",
+ "AsyncOrganizationResourceWithRawResponse",
+ "OrganizationResourceWithStreamingResponse",
+ "AsyncOrganizationResourceWithStreamingResponse",
"APIKeysResource",
"AsyncAPIKeysResource",
"APIKeysResourceWithRawResponse",
diff --git a/src/kernel/resources/organization/__init__.py b/src/kernel/resources/organization/__init__.py
new file mode 100644
index 00000000..68c28d60
--- /dev/null
+++ b/src/kernel/resources/organization/__init__.py
@@ -0,0 +1,33 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from .limits import (
+ LimitsResource,
+ AsyncLimitsResource,
+ LimitsResourceWithRawResponse,
+ AsyncLimitsResourceWithRawResponse,
+ LimitsResourceWithStreamingResponse,
+ AsyncLimitsResourceWithStreamingResponse,
+)
+from .organization import (
+ OrganizationResource,
+ AsyncOrganizationResource,
+ OrganizationResourceWithRawResponse,
+ AsyncOrganizationResourceWithRawResponse,
+ OrganizationResourceWithStreamingResponse,
+ AsyncOrganizationResourceWithStreamingResponse,
+)
+
+__all__ = [
+ "LimitsResource",
+ "AsyncLimitsResource",
+ "LimitsResourceWithRawResponse",
+ "AsyncLimitsResourceWithRawResponse",
+ "LimitsResourceWithStreamingResponse",
+ "AsyncLimitsResourceWithStreamingResponse",
+ "OrganizationResource",
+ "AsyncOrganizationResource",
+ "OrganizationResourceWithRawResponse",
+ "AsyncOrganizationResourceWithRawResponse",
+ "OrganizationResourceWithStreamingResponse",
+ "AsyncOrganizationResourceWithStreamingResponse",
+]
diff --git a/src/kernel/resources/organization/limits.py b/src/kernel/resources/organization/limits.py
new file mode 100644
index 00000000..4bf68845
--- /dev/null
+++ b/src/kernel/resources/organization/limits.py
@@ -0,0 +1,245 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Optional
+
+import httpx
+
+from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given
+from ..._utils import maybe_transform, async_maybe_transform
+from ..._compat import cached_property
+from ..._resource import SyncAPIResource, AsyncAPIResource
+from ..._response import (
+ to_raw_response_wrapper,
+ to_streamed_response_wrapper,
+ async_to_raw_response_wrapper,
+ async_to_streamed_response_wrapper,
+)
+from ..._base_client import make_request_options
+from ...types.organization import limit_update_params
+from ...types.organization.org_limits import OrgLimits
+
+__all__ = ["LimitsResource", "AsyncLimitsResource"]
+
+
+class LimitsResource(SyncAPIResource):
+ """Read and manage organization-level limits."""
+
+ @cached_property
+ def with_raw_response(self) -> LimitsResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/kernel/kernel-python-sdk#accessing-raw-response-data-eg-headers
+ """
+ return LimitsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> LimitsResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/kernel/kernel-python-sdk#with_streaming_response
+ """
+ return LimitsResourceWithStreamingResponse(self)
+
+ def retrieve(
+ self,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> OrgLimits:
+ """
+ Get the organization's concurrent session ceiling and the default per-project
+ concurrency cap applied to projects without an explicit override.
+ """
+ return self._get(
+ "/org/limits",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=OrgLimits,
+ )
+
+ def update(
+ self,
+ *,
+ default_project_max_concurrent_sessions: Optional[int] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> OrgLimits:
+ """
+ Set the default per-project concurrency cap applied to projects without an
+ explicit override. Set the value to 0 to remove the default; omit to leave it
+ unchanged. The default cannot exceed the organization's concurrent session
+ ceiling.
+
+ Args:
+ default_project_max_concurrent_sessions: Default maximum concurrent browser sessions for projects without an explicit
+ override. Set to 0 to remove the default; omit to leave unchanged. Cannot exceed
+ the organization's concurrent session ceiling.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return self._patch(
+ "/org/limits",
+ body=maybe_transform(
+ {"default_project_max_concurrent_sessions": default_project_max_concurrent_sessions},
+ limit_update_params.LimitUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=OrgLimits,
+ )
+
+
+class AsyncLimitsResource(AsyncAPIResource):
+ """Read and manage organization-level limits."""
+
+ @cached_property
+ def with_raw_response(self) -> AsyncLimitsResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/kernel/kernel-python-sdk#accessing-raw-response-data-eg-headers
+ """
+ return AsyncLimitsResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncLimitsResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/kernel/kernel-python-sdk#with_streaming_response
+ """
+ return AsyncLimitsResourceWithStreamingResponse(self)
+
+ async def retrieve(
+ self,
+ *,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> OrgLimits:
+ """
+ Get the organization's concurrent session ceiling and the default per-project
+ concurrency cap applied to projects without an explicit override.
+ """
+ return await self._get(
+ "/org/limits",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=OrgLimits,
+ )
+
+ async def update(
+ self,
+ *,
+ default_project_max_concurrent_sessions: Optional[int] | Omit = omit,
+ # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs.
+ # The extra values given here take precedence over values defined on the client or passed to this method.
+ extra_headers: Headers | None = None,
+ extra_query: Query | None = None,
+ extra_body: Body | None = None,
+ timeout: float | httpx.Timeout | None | NotGiven = not_given,
+ ) -> OrgLimits:
+ """
+ Set the default per-project concurrency cap applied to projects without an
+ explicit override. Set the value to 0 to remove the default; omit to leave it
+ unchanged. The default cannot exceed the organization's concurrent session
+ ceiling.
+
+ Args:
+ default_project_max_concurrent_sessions: Default maximum concurrent browser sessions for projects without an explicit
+ override. Set to 0 to remove the default; omit to leave unchanged. Cannot exceed
+ the organization's concurrent session ceiling.
+
+ extra_headers: Send extra headers
+
+ extra_query: Add additional query parameters to the request
+
+ extra_body: Add additional JSON properties to the request
+
+ timeout: Override the client-level default timeout for this request, in seconds
+ """
+ return await self._patch(
+ "/org/limits",
+ body=await async_maybe_transform(
+ {"default_project_max_concurrent_sessions": default_project_max_concurrent_sessions},
+ limit_update_params.LimitUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=OrgLimits,
+ )
+
+
+class LimitsResourceWithRawResponse:
+ def __init__(self, limits: LimitsResource) -> None:
+ self._limits = limits
+
+ self.retrieve = to_raw_response_wrapper(
+ limits.retrieve,
+ )
+ self.update = to_raw_response_wrapper(
+ limits.update,
+ )
+
+
+class AsyncLimitsResourceWithRawResponse:
+ def __init__(self, limits: AsyncLimitsResource) -> None:
+ self._limits = limits
+
+ self.retrieve = async_to_raw_response_wrapper(
+ limits.retrieve,
+ )
+ self.update = async_to_raw_response_wrapper(
+ limits.update,
+ )
+
+
+class LimitsResourceWithStreamingResponse:
+ def __init__(self, limits: LimitsResource) -> None:
+ self._limits = limits
+
+ self.retrieve = to_streamed_response_wrapper(
+ limits.retrieve,
+ )
+ self.update = to_streamed_response_wrapper(
+ limits.update,
+ )
+
+
+class AsyncLimitsResourceWithStreamingResponse:
+ def __init__(self, limits: AsyncLimitsResource) -> None:
+ self._limits = limits
+
+ self.retrieve = async_to_streamed_response_wrapper(
+ limits.retrieve,
+ )
+ self.update = async_to_streamed_response_wrapper(
+ limits.update,
+ )
diff --git a/src/kernel/resources/organization/organization.py b/src/kernel/resources/organization/organization.py
new file mode 100644
index 00000000..21163122
--- /dev/null
+++ b/src/kernel/resources/organization/organization.py
@@ -0,0 +1,108 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .limits import (
+ LimitsResource,
+ AsyncLimitsResource,
+ LimitsResourceWithRawResponse,
+ AsyncLimitsResourceWithRawResponse,
+ LimitsResourceWithStreamingResponse,
+ AsyncLimitsResourceWithStreamingResponse,
+)
+from ..._compat import cached_property
+from ..._resource import SyncAPIResource, AsyncAPIResource
+
+__all__ = ["OrganizationResource", "AsyncOrganizationResource"]
+
+
+class OrganizationResource(SyncAPIResource):
+ @cached_property
+ def limits(self) -> LimitsResource:
+ """Read and manage organization-level limits."""
+ return LimitsResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> OrganizationResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/kernel/kernel-python-sdk#accessing-raw-response-data-eg-headers
+ """
+ return OrganizationResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> OrganizationResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/kernel/kernel-python-sdk#with_streaming_response
+ """
+ return OrganizationResourceWithStreamingResponse(self)
+
+
+class AsyncOrganizationResource(AsyncAPIResource):
+ @cached_property
+ def limits(self) -> AsyncLimitsResource:
+ """Read and manage organization-level limits."""
+ return AsyncLimitsResource(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> AsyncOrganizationResourceWithRawResponse:
+ """
+ This property can be used as a prefix for any HTTP method call to return
+ the raw response object instead of the parsed content.
+
+ For more information, see https://www.github.com/kernel/kernel-python-sdk#accessing-raw-response-data-eg-headers
+ """
+ return AsyncOrganizationResourceWithRawResponse(self)
+
+ @cached_property
+ def with_streaming_response(self) -> AsyncOrganizationResourceWithStreamingResponse:
+ """
+ An alternative to `.with_raw_response` that doesn't eagerly read the response body.
+
+ For more information, see https://www.github.com/kernel/kernel-python-sdk#with_streaming_response
+ """
+ return AsyncOrganizationResourceWithStreamingResponse(self)
+
+
+class OrganizationResourceWithRawResponse:
+ def __init__(self, organization: OrganizationResource) -> None:
+ self._organization = organization
+
+ @cached_property
+ def limits(self) -> LimitsResourceWithRawResponse:
+ """Read and manage organization-level limits."""
+ return LimitsResourceWithRawResponse(self._organization.limits)
+
+
+class AsyncOrganizationResourceWithRawResponse:
+ def __init__(self, organization: AsyncOrganizationResource) -> None:
+ self._organization = organization
+
+ @cached_property
+ def limits(self) -> AsyncLimitsResourceWithRawResponse:
+ """Read and manage organization-level limits."""
+ return AsyncLimitsResourceWithRawResponse(self._organization.limits)
+
+
+class OrganizationResourceWithStreamingResponse:
+ def __init__(self, organization: OrganizationResource) -> None:
+ self._organization = organization
+
+ @cached_property
+ def limits(self) -> LimitsResourceWithStreamingResponse:
+ """Read and manage organization-level limits."""
+ return LimitsResourceWithStreamingResponse(self._organization.limits)
+
+
+class AsyncOrganizationResourceWithStreamingResponse:
+ def __init__(self, organization: AsyncOrganizationResource) -> None:
+ self._organization = organization
+
+ @cached_property
+ def limits(self) -> AsyncLimitsResourceWithStreamingResponse:
+ """Read and manage organization-level limits."""
+ return AsyncLimitsResourceWithStreamingResponse(self._organization.limits)
diff --git a/src/kernel/types/organization/__init__.py b/src/kernel/types/organization/__init__.py
new file mode 100644
index 00000000..d2411f9a
--- /dev/null
+++ b/src/kernel/types/organization/__init__.py
@@ -0,0 +1,6 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from .org_limits import OrgLimits as OrgLimits
+from .limit_update_params import LimitUpdateParams as LimitUpdateParams
diff --git a/src/kernel/types/organization/limit_update_params.py b/src/kernel/types/organization/limit_update_params.py
new file mode 100644
index 00000000..619eae91
--- /dev/null
+++ b/src/kernel/types/organization/limit_update_params.py
@@ -0,0 +1,17 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+from typing import Optional
+from typing_extensions import TypedDict
+
+__all__ = ["LimitUpdateParams"]
+
+
+class LimitUpdateParams(TypedDict, total=False):
+ default_project_max_concurrent_sessions: Optional[int]
+ """
+ Default maximum concurrent browser sessions for projects without an explicit
+ override. Set to 0 to remove the default; omit to leave unchanged. Cannot exceed
+ the organization's concurrent session ceiling.
+ """
diff --git a/src/kernel/types/organization/org_limits.py b/src/kernel/types/organization/org_limits.py
new file mode 100644
index 00000000..da9153c1
--- /dev/null
+++ b/src/kernel/types/organization/org_limits.py
@@ -0,0 +1,24 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing import Optional
+
+from ..._models import BaseModel
+
+__all__ = ["OrgLimits"]
+
+
+class OrgLimits(BaseModel):
+ default_project_max_concurrent_sessions: Optional[int] = None
+ """
+ Default maximum concurrent browser sessions applied to every project that has no
+ explicit per-project override. Null means no org-level default, so such projects
+ are uncapped (only the org-wide limit applies). Applies to existing and newly
+ created projects.
+ """
+
+ max_concurrent_sessions: Optional[int] = None
+ """
+ The organization's effective concurrent browser session ceiling, from its plan
+ or an override. Read-only and shared across all projects in the org; a
+ per-project default cannot exceed it.
+ """
diff --git a/tests/api_resources/organization/__init__.py b/tests/api_resources/organization/__init__.py
new file mode 100644
index 00000000..fd8019a9
--- /dev/null
+++ b/tests/api_resources/organization/__init__.py
@@ -0,0 +1 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
diff --git a/tests/api_resources/organization/test_limits.py b/tests/api_resources/organization/test_limits.py
new file mode 100644
index 00000000..a9dca6d0
--- /dev/null
+++ b/tests/api_resources/organization/test_limits.py
@@ -0,0 +1,152 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from __future__ import annotations
+
+import os
+from typing import Any, cast
+
+import pytest
+
+from kernel import Kernel, AsyncKernel
+from tests.utils import assert_matches_type
+from kernel.types.organization import OrgLimits
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+
+
+class TestLimits:
+ parametrize = pytest.mark.parametrize("client", [False, True], indirect=True, ids=["loose", "strict"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_retrieve(self, client: Kernel) -> None:
+ limit = client.organization.limits.retrieve()
+ assert_matches_type(OrgLimits, limit, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_retrieve(self, client: Kernel) -> None:
+ response = client.organization.limits.with_raw_response.retrieve()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ limit = response.parse()
+ assert_matches_type(OrgLimits, limit, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_retrieve(self, client: Kernel) -> None:
+ with client.organization.limits.with_streaming_response.retrieve() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ limit = response.parse()
+ assert_matches_type(OrgLimits, limit, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_update(self, client: Kernel) -> None:
+ limit = client.organization.limits.update()
+ assert_matches_type(OrgLimits, limit, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_update_with_all_params(self, client: Kernel) -> None:
+ limit = client.organization.limits.update(
+ default_project_max_concurrent_sessions=0,
+ )
+ assert_matches_type(OrgLimits, limit, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_update(self, client: Kernel) -> None:
+ response = client.organization.limits.with_raw_response.update()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ limit = response.parse()
+ assert_matches_type(OrgLimits, limit, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_update(self, client: Kernel) -> None:
+ with client.organization.limits.with_streaming_response.update() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ limit = response.parse()
+ assert_matches_type(OrgLimits, limit, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+
+class TestAsyncLimits:
+ parametrize = pytest.mark.parametrize(
+ "async_client", [False, True, {"http_client": "aiohttp"}], indirect=True, ids=["loose", "strict", "aiohttp"]
+ )
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_retrieve(self, async_client: AsyncKernel) -> None:
+ limit = await async_client.organization.limits.retrieve()
+ assert_matches_type(OrgLimits, limit, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_retrieve(self, async_client: AsyncKernel) -> None:
+ response = await async_client.organization.limits.with_raw_response.retrieve()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ limit = await response.parse()
+ assert_matches_type(OrgLimits, limit, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_retrieve(self, async_client: AsyncKernel) -> None:
+ async with async_client.organization.limits.with_streaming_response.retrieve() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ limit = await response.parse()
+ assert_matches_type(OrgLimits, limit, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_update(self, async_client: AsyncKernel) -> None:
+ limit = await async_client.organization.limits.update()
+ assert_matches_type(OrgLimits, limit, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_update_with_all_params(self, async_client: AsyncKernel) -> None:
+ limit = await async_client.organization.limits.update(
+ default_project_max_concurrent_sessions=0,
+ )
+ assert_matches_type(OrgLimits, limit, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_update(self, async_client: AsyncKernel) -> None:
+ response = await async_client.organization.limits.with_raw_response.update()
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ limit = await response.parse()
+ assert_matches_type(OrgLimits, limit, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_update(self, async_client: AsyncKernel) -> None:
+ async with async_client.organization.limits.with_streaming_response.update() as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ limit = await response.parse()
+ assert_matches_type(OrgLimits, limit, path=["response"])
+
+ assert cast(Any, response.is_closed) is True