diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 19c0e9cc..f371d275 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.104.0"
+ ".": "0.106.0"
}
\ No newline at end of file
diff --git a/.stats.yml b/.stats.yml
index a0ee50ed..88ce9db5 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1 +1 @@
-configured_endpoints: 163
+configured_endpoints: 164
diff --git a/CHANGELOG.md b/CHANGELOG.md
index eb98375c..cb10a2df 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,16 @@
# Changelog
+## 0.106.0 (2026-09-16)
+
+Full Changelog: [v0.104.0...v0.106.0](https://github.com/kernel/kernel-python-sdk/compare/v0.104.0...v0.106.0)
+
+### Features
+
+* Add processor-bound AgentCard preparation contracts ([37d5e9c](https://github.com/kernel/kernel-python-sdk/commit/37d5e9c3d5db76bece8f8ba8d5358b939bc79315))
+* Add start_url to browser session updates ([82a475d](https://github.com/kernel/kernel-python-sdk/commit/82a475dae250abce535476386be88033a5314656))
+* Polish and publish the Config Registry API ([afe2fea](https://github.com/kernel/kernel-python-sdk/commit/afe2feaf2dcea1f4fc160d66cfe9f3711b61a447))
+* Square UKP and Hypeman placement load factors ([76dee03](https://github.com/kernel/kernel-python-sdk/commit/76dee03d215481de6ee42b2cba631b5f5893c1a3))
+
## [0.104.0](https://github.com/kernel/kernel-python-sdk/compare/v0.103.0...v0.104.0) (2026-09-15)
diff --git a/api.md b/api.md
index fdb9696b..0679de62 100644
--- a/api.md
+++ b/api.md
@@ -109,6 +109,7 @@ Methods:
- client.config_registry.analyses.retrieve(id) -> ConfigRegistryResponse
- client.config_registry.analyses.list(\*\*params) -> SyncOffsetPagination[AnalysisSummary]
+- client.config_registry.analyses.cancel(id) -> ConfigRegistryResponse
# Browsers
@@ -526,6 +527,7 @@ Types:
from kernel.types.vaults import (
AgentcardCheckoutAuthorization,
AgentcardCheckoutPreparation,
+ AgentcardPreparedProcessor,
AuthorizeVaultItemOperationRequest,
CardVaultItemSpec,
CardVaultItemState,
diff --git a/pyproject.toml b/pyproject.toml
index 6b6ca1ef..a89b3709 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "kernel"
-version = "0.104.0"
+version = "0.106.0"
description = "The official Python library for the kernel API"
dynamic = ["readme"]
license = "Apache-2.0"
diff --git a/src/kernel/_version.py b/src/kernel/_version.py
index 0a7fea06..66f10fd8 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.104.0" # x-release-please-version
+__version__ = "0.106.0" # x-release-please-version
diff --git a/src/kernel/resources/browsers/browsers.py b/src/kernel/resources/browsers/browsers.py
index 219dd462..49dc4063 100644
--- a/src/kernel/resources/browsers/browsers.py
+++ b/src/kernel/resources/browsers/browsers.py
@@ -394,6 +394,7 @@ def update(
profile: BrowserProfile | Omit = omit,
proxy: BrowserProxyConfigParam | Omit = omit,
proxy_id: Optional[str] | Omit = omit,
+ start_url: str | Omit = omit,
tags: Optional[TagsParam] | Omit = omit,
telemetry: Optional[browser_update_params.Telemetry] | Omit = omit,
viewport: browser_update_params.Viewport | Omit = omit,
@@ -428,6 +429,11 @@ def update(
proxy_id: ID of the proxy to use. Omit to leave unchanged, set to empty string to remove
proxy. Deprecated in favor of proxy.
+ start_url: Optional URL to navigate the browser to after applying this update. When a
+ profile is loaded in the same update, this overrides the profile's restored
+ tabs. Navigation is best-effort, so failures do not fail the update. Omit or set
+ to an empty string to leave the current page unchanged.
+
tags: User-defined key-value tags for the browser session. Omit to leave unchanged.
Provide a map to replace the entire tag set (full replace, not a merge). Set to
an empty object ({}) to clear all tags. Up to 50 pairs.
@@ -459,6 +465,7 @@ def update(
"profile": profile,
"proxy": proxy,
"proxy_id": proxy_id,
+ "start_url": start_url,
"tags": tags,
"telemetry": telemetry,
"viewport": viewport,
@@ -1024,6 +1031,7 @@ async def update(
profile: BrowserProfile | Omit = omit,
proxy: BrowserProxyConfigParam | Omit = omit,
proxy_id: Optional[str] | Omit = omit,
+ start_url: str | Omit = omit,
tags: Optional[TagsParam] | Omit = omit,
telemetry: Optional[browser_update_params.Telemetry] | Omit = omit,
viewport: browser_update_params.Viewport | Omit = omit,
@@ -1058,6 +1066,11 @@ async def update(
proxy_id: ID of the proxy to use. Omit to leave unchanged, set to empty string to remove
proxy. Deprecated in favor of proxy.
+ start_url: Optional URL to navigate the browser to after applying this update. When a
+ profile is loaded in the same update, this overrides the profile's restored
+ tabs. Navigation is best-effort, so failures do not fail the update. Omit or set
+ to an empty string to leave the current page unchanged.
+
tags: User-defined key-value tags for the browser session. Omit to leave unchanged.
Provide a map to replace the entire tag set (full replace, not a merge). Set to
an empty object ({}) to clear all tags. Up to 50 pairs.
@@ -1089,6 +1102,7 @@ async def update(
"profile": profile,
"proxy": proxy,
"proxy_id": proxy_id,
+ "start_url": start_url,
"tags": tags,
"telemetry": telemetry,
"viewport": viewport,
diff --git a/src/kernel/resources/config_registry/analyses.py b/src/kernel/resources/config_registry/analyses.py
index c0cbd2c7..3d975f32 100644
--- a/src/kernel/resources/config_registry/analyses.py
+++ b/src/kernel/resources/config_registry/analyses.py
@@ -126,6 +126,43 @@ def list(
model=AnalysisSummary,
)
+ def cancel(
+ self,
+ id: str,
+ *,
+ # 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,
+ ) -> ConfigRegistryResponse:
+ """Requests cancellation of a running project-scoped analysis.
+
+ Cancellation is
+ asynchronous; poll the analysis until its status becomes canceled. Repeating the
+ request after the analysis reaches a terminal state returns the existing
+ outcome.
+
+ Args:
+ 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
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return self._post(
+ path_template("/config-registry/analyses/{id}/cancel", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ConfigRegistryResponse,
+ )
+
class AsyncAnalysesResource(AsyncAPIResource):
"""Resolve browser and proxy recommendations for bot-protected sites."""
@@ -230,6 +267,43 @@ def list(
model=AnalysisSummary,
)
+ async def cancel(
+ self,
+ id: str,
+ *,
+ # 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,
+ ) -> ConfigRegistryResponse:
+ """Requests cancellation of a running project-scoped analysis.
+
+ Cancellation is
+ asynchronous; poll the analysis until its status becomes canceled. Repeating the
+ request after the analysis reaches a terminal state returns the existing
+ outcome.
+
+ Args:
+ 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
+ """
+ if not id:
+ raise ValueError(f"Expected a non-empty value for `id` but received {id!r}")
+ return await self._post(
+ path_template("/config-registry/analyses/{id}/cancel", id=id),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ConfigRegistryResponse,
+ )
+
class AnalysesResourceWithRawResponse:
def __init__(self, analyses: AnalysesResource) -> None:
@@ -241,6 +315,9 @@ def __init__(self, analyses: AnalysesResource) -> None:
self.list = to_raw_response_wrapper(
analyses.list,
)
+ self.cancel = to_raw_response_wrapper(
+ analyses.cancel,
+ )
class AsyncAnalysesResourceWithRawResponse:
@@ -253,6 +330,9 @@ def __init__(self, analyses: AsyncAnalysesResource) -> None:
self.list = async_to_raw_response_wrapper(
analyses.list,
)
+ self.cancel = async_to_raw_response_wrapper(
+ analyses.cancel,
+ )
class AnalysesResourceWithStreamingResponse:
@@ -265,6 +345,9 @@ def __init__(self, analyses: AnalysesResource) -> None:
self.list = to_streamed_response_wrapper(
analyses.list,
)
+ self.cancel = to_streamed_response_wrapper(
+ analyses.cancel,
+ )
class AsyncAnalysesResourceWithStreamingResponse:
@@ -277,3 +360,6 @@ def __init__(self, analyses: AsyncAnalysesResource) -> None:
self.list = async_to_streamed_response_wrapper(
analyses.list,
)
+ self.cancel = async_to_streamed_response_wrapper(
+ analyses.cancel,
+ )
diff --git a/src/kernel/resources/config_registry/config_registry.py b/src/kernel/resources/config_registry/config_registry.py
index 27a8766c..39faa9f5 100644
--- a/src/kernel/resources/config_registry/config_registry.py
+++ b/src/kernel/resources/config_registry/config_registry.py
@@ -190,8 +190,9 @@ def resolve(
any non-HTTPS destination as off-site and will not drive an http one. Kernel
uses it to drive the browser further into the site, where it can observe
protections that only appear once a session interacts. When this target already
- has a verified configuration, the run confirms that one instead of re-deriving
- the whole matrix, so supplying an intent narrows what can be recommended.
+ has a recommended configuration, the run confirms that one instead of
+ re-deriving the whole matrix, so supplying an intent narrows what can be
+ recommended.
extra_headers: Send extra headers
@@ -374,8 +375,9 @@ async def resolve(
any non-HTTPS destination as off-site and will not drive an http one. Kernel
uses it to drive the browser further into the site, where it can observe
protections that only appear once a session interacts. When this target already
- has a verified configuration, the run confirms that one instead of re-deriving
- the whole matrix, so supplying an intent narrows what can be recommended.
+ has a recommended configuration, the run confirms that one instead of
+ re-deriving the whole matrix, so supplying an intent narrows what can be
+ recommended.
extra_headers: Send extra headers
diff --git a/src/kernel/resources/vaults/items.py b/src/kernel/resources/vaults/items.py
index ea0fbf83..cd53e796 100644
--- a/src/kernel/resources/vaults/items.py
+++ b/src/kernel/resources/vaults/items.py
@@ -511,11 +511,11 @@ def perform_operation(
leave the outcome unknown; do not automatically retry.
Args:
- checkout: Required when preparing an unused AgentCard card for Square. Consent is bound to
- this browser and declared merchant origin, not a tab. Wait for the item's
- ready_to_submit status before native Pay and submit within its readiness
- deadline. Unused preparations expire automatically; every preparation is
- single-use, including after failure or expiry.
+ checkout: Required when preparing an unused AgentCard card for a supported tokenization
+ processor. Consent is bound to this browser and declared merchant origin, not a
+ tab. Wait for the item's ready_to_submit status before native Pay and submit
+ within its readiness deadline. Unused preparations expire automatically; every
+ preparation is single-use, including after failure or expiry.
extra_headers: Send extra headers
@@ -1274,11 +1274,11 @@ async def perform_operation(
leave the outcome unknown; do not automatically retry.
Args:
- checkout: Required when preparing an unused AgentCard card for Square. Consent is bound to
- this browser and declared merchant origin, not a tab. Wait for the item's
- ready_to_submit status before native Pay and submit within its readiness
- deadline. Unused preparations expire automatically; every preparation is
- single-use, including after failure or expiry.
+ checkout: Required when preparing an unused AgentCard card for a supported tokenization
+ processor. Consent is bound to this browser and declared merchant origin, not a
+ tab. Wait for the item's ready_to_submit status before native Pay and submit
+ within its readiness deadline. Unused preparations expire automatically; every
+ preparation is single-use, including after failure or expiry.
extra_headers: Send extra headers
diff --git a/src/kernel/types/analysis.py b/src/kernel/types/analysis.py
index 34184ae4..6ce7c3b1 100644
--- a/src/kernel/types/analysis.py
+++ b/src/kernel/types/analysis.py
@@ -31,3 +31,9 @@ class Analysis(BaseModel):
status: Literal["running", "completed", "failed", "canceled", "expired"]
"""Lifecycle status of a background analysis."""
+
+ intent: Optional[str] = None
+ """The workload description supplied for this analysis.
+
+ Null when the analysis only tested connectivity.
+ """
diff --git a/src/kernel/types/browser_create_response.py b/src/kernel/types/browser_create_response.py
index 678bcbcb..a5e674f7 100644
--- a/src/kernel/types/browser_create_response.py
+++ b/src/kernel/types/browser_create_response.py
@@ -106,7 +106,7 @@ class BrowserCreateResponse(BaseModel):
"""
start_url: Optional[str] = None
- """URL the session was asked to navigate to on creation, if any.
+ """URL the session was most recently asked to navigate to, if any.
Recorded for debugging. Navigation is fire-and-forget — the URL is dispatched to
the browser without waiting for it to load, and any errors (DNS failure, bad
diff --git a/src/kernel/types/browser_list_response.py b/src/kernel/types/browser_list_response.py
index aa281a39..3cc62ebe 100644
--- a/src/kernel/types/browser_list_response.py
+++ b/src/kernel/types/browser_list_response.py
@@ -106,7 +106,7 @@ class BrowserListResponse(BaseModel):
"""
start_url: Optional[str] = None
- """URL the session was asked to navigate to on creation, if any.
+ """URL the session was most recently asked to navigate to, if any.
Recorded for debugging. Navigation is fire-and-forget — the URL is dispatched to
the browser without waiting for it to load, and any errors (DNS failure, bad
diff --git a/src/kernel/types/browser_pool_acquire_response.py b/src/kernel/types/browser_pool_acquire_response.py
index d472b5e0..c223c927 100644
--- a/src/kernel/types/browser_pool_acquire_response.py
+++ b/src/kernel/types/browser_pool_acquire_response.py
@@ -106,7 +106,7 @@ class BrowserPoolAcquireResponse(BaseModel):
"""
start_url: Optional[str] = None
- """URL the session was asked to navigate to on creation, if any.
+ """URL the session was most recently asked to navigate to, if any.
Recorded for debugging. Navigation is fire-and-forget — the URL is dispatched to
the browser without waiting for it to load, and any errors (DNS failure, bad
diff --git a/src/kernel/types/browser_retrieve_response.py b/src/kernel/types/browser_retrieve_response.py
index e6881ab1..936b41c6 100644
--- a/src/kernel/types/browser_retrieve_response.py
+++ b/src/kernel/types/browser_retrieve_response.py
@@ -106,7 +106,7 @@ class BrowserRetrieveResponse(BaseModel):
"""
start_url: Optional[str] = None
- """URL the session was asked to navigate to on creation, if any.
+ """URL the session was most recently asked to navigate to, if any.
Recorded for debugging. Navigation is fire-and-forget — the URL is dispatched to
the browser without waiting for it to load, and any errors (DNS failure, bad
diff --git a/src/kernel/types/browser_update_params.py b/src/kernel/types/browser_update_params.py
index e7769e61..c0592e28 100644
--- a/src/kernel/types/browser_update_params.py
+++ b/src/kernel/types/browser_update_params.py
@@ -59,6 +59,14 @@ class BrowserUpdateParams(TypedDict, total=False):
favor of proxy.
"""
+ start_url: str
+ """Optional URL to navigate the browser to after applying this update.
+
+ When a profile is loaded in the same update, this overrides the profile's
+ restored tabs. Navigation is best-effort, so failures do not fail the update.
+ Omit or set to an empty string to leave the current page unchanged.
+ """
+
tags: Optional[TagsParam]
"""User-defined key-value tags for the browser session.
diff --git a/src/kernel/types/browser_update_response.py b/src/kernel/types/browser_update_response.py
index 65be1ba3..d2296c21 100644
--- a/src/kernel/types/browser_update_response.py
+++ b/src/kernel/types/browser_update_response.py
@@ -106,7 +106,7 @@ class BrowserUpdateResponse(BaseModel):
"""
start_url: Optional[str] = None
- """URL the session was asked to navigate to on creation, if any.
+ """URL the session was most recently asked to navigate to, if any.
Recorded for debugging. Navigation is fire-and-forget — the URL is dispatched to
the browser without waiting for it to load, and any errors (DNS failure, bad
diff --git a/src/kernel/types/config_registry_resolve_params.py b/src/kernel/types/config_registry_resolve_params.py
index 2c0ecc00..e1a063dc 100644
--- a/src/kernel/types/config_registry_resolve_params.py
+++ b/src/kernel/types/config_registry_resolve_params.py
@@ -27,6 +27,7 @@ class ConfigRegistryResolveParams(TypedDict, total=False):
any non-HTTPS destination as off-site and will not drive an http one. Kernel
uses it to drive the browser further into the site, where it can observe
protections that only appear once a session interacts. When this target already
- has a verified configuration, the run confirms that one instead of re-deriving
- the whole matrix, so supplying an intent narrows what can be recommended.
+ has a recommended configuration, the run confirms that one instead of
+ re-deriving the whole matrix, so supplying an intent narrows what can be
+ recommended.
"""
diff --git a/src/kernel/types/evidence.py b/src/kernel/types/evidence.py
index 1a777de9..c53f2842 100644
--- a/src/kernel/types/evidence.py
+++ b/src/kernel/types/evidence.py
@@ -30,9 +30,9 @@ class Evidence(BaseModel):
success_rate: float
"""Accessed trials divided by judged trials. Inconclusive trials are excluded."""
- last_verified_at: Optional[datetime] = None
- """Most recent contributing run where this config met the success threshold.
-
- Omitted for knowledge assembled from runs that did not independently meet the
- threshold.
+ last_supported_at: Optional[datetime] = None
+ """
+ Most recent contributing run whose evidence supported recommending this
+ configuration. Omitted when no individual run independently met the
+ recommendation threshold.
"""
diff --git a/src/kernel/types/invocation_list_browsers_response.py b/src/kernel/types/invocation_list_browsers_response.py
index bb9d423d..a88f33f9 100644
--- a/src/kernel/types/invocation_list_browsers_response.py
+++ b/src/kernel/types/invocation_list_browsers_response.py
@@ -106,7 +106,7 @@ class Browser(BaseModel):
"""
start_url: Optional[str] = None
- """URL the session was asked to navigate to on creation, if any.
+ """URL the session was most recently asked to navigate to, if any.
Recorded for debugging. Navigation is fire-and-forget — the URL is dispatched to
the browser without waiting for it to load, and any errors (DNS failure, bad
diff --git a/src/kernel/types/recommendation.py b/src/kernel/types/recommendation.py
index 74b1761a..e7d21b8e 100644
--- a/src/kernel/types/recommendation.py
+++ b/src/kernel/types/recommendation.py
@@ -17,7 +17,11 @@ class Recommendation(BaseModel):
evidence: Evidence
match_scope: Literal["exact", "host", "domain"]
- """Specificity of knowledge matched for this recommendation."""
+ """Specificity of knowledge matched for this recommendation.
+
+ Exact matches use knowledge for the requested target; host and domain matches
+ use broader fallback knowledge.
+ """
matched_target: str
"""Target value that supplied the recommendation."""
@@ -26,10 +30,3 @@ class Recommendation(BaseModel):
"""Proxy recipe for the recommended browser."""
type: Literal["recommendation"]
-
- verification: Literal["verified", "inferred"]
- """
- Exact matches meet the evidence threshold; host and domain fallbacks are
- inferred. Check evidence.last_verified_at for successful verification age and
- last_observed_at for the latest evidence.
- """
diff --git a/src/kernel/types/vaults/__init__.py b/src/kernel/types/vaults/__init__.py
index 9188791e..e2dd28eb 100644
--- a/src/kernel/types/vaults/__init__.py
+++ b/src/kernel/types/vaults/__init__.py
@@ -24,6 +24,7 @@
from .credential_vault_item_spec import CredentialVaultItemSpec as CredentialVaultItemSpec
from .credential_vault_field_type import CredentialVaultFieldType as CredentialVaultFieldType
from .credential_vault_item_state import CredentialVaultItemState as CredentialVaultItemState
+from .agentcard_prepared_processor import AgentcardPreparedProcessor as AgentcardPreparedProcessor
from .credential_collection_action import CredentialCollectionAction as CredentialCollectionAction
from .credential_vault_field_state import CredentialVaultFieldState as CredentialVaultFieldState
from .vault_checkout_context_param import VaultCheckoutContextParam as VaultCheckoutContextParam
diff --git a/src/kernel/types/vaults/agentcard_checkout_preparation.py b/src/kernel/types/vaults/agentcard_checkout_preparation.py
index 8296b2fd..7f9da71f 100644
--- a/src/kernel/types/vaults/agentcard_checkout_preparation.py
+++ b/src/kernel/types/vaults/agentcard_checkout_preparation.py
@@ -5,12 +5,13 @@
from typing_extensions import Literal
from ..._models import BaseModel
+from .agentcard_prepared_processor import AgentcardPreparedProcessor
__all__ = ["AgentcardCheckoutPreparation"]
class AgentcardCheckoutPreparation(BaseModel):
- """One-use Square checkout preparation.
+ """One-use processor-bound checkout preparation.
Keep the approval page open through token handoff. The amount is display-only and does not constrain the merchant's eventual charge.
"""
@@ -19,10 +20,12 @@ class AgentcardCheckoutPreparation(BaseModel):
created_at: datetime
- environment: Literal["production", "sandbox"]
+ environment: Literal["production", "sandbox", "shared"]
merchant_origin: str
+ psp: AgentcardPreparedProcessor
+
status: Literal["creating", "awaiting_approval", "ready", "consumed", "cancelled", "expired", "unknown"]
"""
Preparation consumed means egress claimed the preparation and it cannot be
diff --git a/src/kernel/types/vaults/agentcard_prepared_processor.py b/src/kernel/types/vaults/agentcard_prepared_processor.py
new file mode 100644
index 00000000..ebf94c86
--- /dev/null
+++ b/src/kernel/types/vaults/agentcard_prepared_processor.py
@@ -0,0 +1,7 @@
+# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+from typing_extensions import Literal, TypeAlias
+
+__all__ = ["AgentcardPreparedProcessor"]
+
+AgentcardPreparedProcessor: TypeAlias = Literal["square", "braintree", "worldpay", "bambora", "mercado_pago"]
diff --git a/src/kernel/types/vaults/card_vault_item_state.py b/src/kernel/types/vaults/card_vault_item_state.py
index 98459762..a1cb0b68 100644
--- a/src/kernel/types/vaults/card_vault_item_state.py
+++ b/src/kernel/types/vaults/card_vault_item_state.py
@@ -33,6 +33,11 @@ def __getattr__(self, attr: str) -> str: ...
class LinkCardState(BaseModel):
+ """Issued Link cards retain encrypted card material for the fill operation.
+
+ Link cards do not expose aliases or support egress substitution.
+ """
+
provider: Literal["link"]
status: Literal[
@@ -47,8 +52,6 @@ class LinkCardState(BaseModel):
caller-asserted reconciliation operation.
"""
- aliases: Optional[VaultCardAliases] = None
-
domains: Optional[List[str]] = None
masks: Optional[LinkCardStateMasks] = None
@@ -112,7 +115,7 @@ class AgentCardCardState(BaseModel):
masks: Optional[AgentCardCardStateMasks] = None
preparation: Optional[AgentcardCheckoutPreparation] = None
- """One-use Square checkout preparation.
+ """One-use processor-bound checkout preparation.
Keep the approval page open through token handoff. The amount is display-only
and does not constrain the merchant's eventual charge.
diff --git a/src/kernel/types/vaults/fill_vault_item_operation_request_param.py b/src/kernel/types/vaults/fill_vault_item_operation_request_param.py
index 1d8fc8be..012ec2b9 100644
--- a/src/kernel/types/vaults/fill_vault_item_operation_request_param.py
+++ b/src/kernel/types/vaults/fill_vault_item_operation_request_param.py
@@ -34,10 +34,9 @@ class FillVaultItemOperationRequestParam(TypedDict, total=False):
Fill in request order and stop on the first failure. This operation is
not atomic: previously filled fields are not rolled back. Never submit
the form or click buttons, though input/change events may trigger site
- behavior. Fill is the preferred browser-checkout path. Aliases remain an
- alternative for explicitly chosen egress-substitution integrations. Do not
- automatically retry or fall back to aliases after a failed or indeterminate
- operation.
+ behavior. Link cards use fill for browser checkout and do not expose
+ aliases or support egress substitution. Do not automatically retry a
+ failed or indeterminate operation.
Secret values are never returned or included in operation logs, traces,
audit events, or error details. This does not prevent an agent with
diff --git a/src/kernel/types/vaults/item_perform_operation_params.py b/src/kernel/types/vaults/item_perform_operation_params.py
index 33c38043..c1fb80c9 100644
--- a/src/kernel/types/vaults/item_perform_operation_params.py
+++ b/src/kernel/types/vaults/item_perform_operation_params.py
@@ -33,12 +33,12 @@ class PrepareCheckoutVaultItemOperationRequest(TypedDict, total=False):
id_or_name: Required[str]
checkout: Required[VaultCheckoutContextParam]
- """Required when preparing an unused AgentCard card for Square.
-
- Consent is bound to this browser and declared merchant origin, not a tab. Wait
- for the item's ready_to_submit status before native Pay and submit within its
- readiness deadline. Unused preparations expire automatically; every preparation
- is single-use, including after failure or expiry.
+ """
+ Required when preparing an unused AgentCard card for a supported tokenization
+ processor. Consent is bound to this browser and declared merchant origin, not a
+ tab. Wait for the item's ready_to_submit status before native Pay and submit
+ within its readiness deadline. Unused preparations expire automatically; every
+ preparation is single-use, including after failure or expiry.
"""
type: Required[Literal["prepare_checkout"]]
diff --git a/src/kernel/types/vaults/prepare_checkout_vault_item_operation_request_param.py b/src/kernel/types/vaults/prepare_checkout_vault_item_operation_request_param.py
index 9900c513..72fdb4d2 100644
--- a/src/kernel/types/vaults/prepare_checkout_vault_item_operation_request_param.py
+++ b/src/kernel/types/vaults/prepare_checkout_vault_item_operation_request_param.py
@@ -10,18 +10,18 @@
class PrepareCheckoutVaultItemOperationRequestParam(TypedDict, total=False):
- """Prepare an unused AgentCard card for Square checkout.
+ """Prepare an unused AgentCard card for a supported tokenization checkout.
Deliver the returned approval URL and keep the approval page open. Poll the item until ready_to_submit, then submit native Pay before preparation.expires_at. Readiness lasts at most 30 seconds. Unused preparations expire automatically. Preparations are single-use even after failure or expiry; do not automatically retry and reconcile uncertain outcomes with the merchant.
"""
checkout: Required[VaultCheckoutContextParam]
- """Required when preparing an unused AgentCard card for Square.
-
- Consent is bound to this browser and declared merchant origin, not a tab. Wait
- for the item's ready_to_submit status before native Pay and submit within its
- readiness deadline. Unused preparations expire automatically; every preparation
- is single-use, including after failure or expiry.
+ """
+ Required when preparing an unused AgentCard card for a supported tokenization
+ processor. Consent is bound to this browser and declared merchant origin, not a
+ tab. Wait for the item's ready_to_submit status before native Pay and submit
+ within its readiness deadline. Unused preparations expire automatically; every
+ preparation is single-use, including after failure or expiry.
"""
type: Required[Literal["prepare_checkout"]]
diff --git a/src/kernel/types/vaults/vault_checkout_context_param.py b/src/kernel/types/vaults/vault_checkout_context_param.py
index 8b08c40c..f5fda5db 100644
--- a/src/kernel/types/vaults/vault_checkout_context_param.py
+++ b/src/kernel/types/vaults/vault_checkout_context_param.py
@@ -4,24 +4,36 @@
from typing_extensions import Literal, Required, TypedDict
+from .agentcard_prepared_processor import AgentcardPreparedProcessor
+
__all__ = ["VaultCheckoutContextParam"]
class VaultCheckoutContextParam(TypedDict, total=False):
- """Required when preparing an unused AgentCard card for Square.
-
- Consent is bound to this browser and declared merchant origin, not a tab. Wait for the item's ready_to_submit status before native Pay and submit within its readiness deadline. Unused preparations expire automatically; every preparation is single-use, including after failure or expiry.
+ """
+ Required when preparing an unused AgentCard card for a supported tokenization processor. Consent is bound to this browser and declared merchant origin, not a tab. Wait for the item's ready_to_submit status before native Pay and submit within its readiness deadline. Unused preparations expire automatically; every preparation is single-use, including after failure or expiry.
"""
browser_id: Required[str]
"""Active browser session with this vault bound to it."""
- environment: Required[Literal["production", "sandbox"]]
- """Square environment, independent of the AgentCard credential mode."""
+ environment: Required[Literal["production", "sandbox", "shared"]]
+ """
+ Use production or sandbox for Square, Braintree and Worldpay; shared for Bambora
+ and Mercado Pago. Shared endpoints do not establish test mode. Merchant
+ credentials/configuration determine processor test mode, independently of the
+ AgentCard credential mode.
+ """
merchant_origin: Required[str]
- """Canonical HTTPS origin of the top-level merchant document, not the Square
- iframe.
+ """
+ Canonical HTTPS origin of the top-level merchant document, not a processor
+ iframe. HTTP localhost is accepted for tests.
+ """
+
+ psp: AgentcardPreparedProcessor
+ """Tokenization processor.
- HTTP localhost is accepted for tests.
+ Omit for Square compatibility. Non-Square processors require multi-processor
+ preparation enablement.
"""
diff --git a/src/kernel/types/vaults/vault_item.py b/src/kernel/types/vaults/vault_item.py
index 07253ea4..b9723f4a 100644
--- a/src/kernel/types/vaults/vault_item.py
+++ b/src/kernel/types/vaults/vault_item.py
@@ -127,6 +127,10 @@ class CardVaultItem(BaseModel):
"""Live payment card. Test-mode card creation is not supported."""
state: CardVaultItemState
+ """Issued Link cards retain encrypted card material for the fill operation.
+
+ Link cards do not expose aliases or support egress substitution.
+ """
type: Literal["card"]
diff --git a/src/kernel/types/vaults/vault_item_operation_response.py b/src/kernel/types/vaults/vault_item_operation_response.py
index 163f73a7..33dcd8b3 100644
--- a/src/kernel/types/vaults/vault_item_operation_response.py
+++ b/src/kernel/types/vaults/vault_item_operation_response.py
@@ -127,6 +127,10 @@ class CardVaultItem(BaseModel):
"""Live payment card. Test-mode card creation is not supported."""
state: CardVaultItemState
+ """Issued Link cards retain encrypted card material for the fill operation.
+
+ Link cards do not expose aliases or support egress substitution.
+ """
type: Literal["card"]
diff --git a/tests/api_resources/config_registry/test_analyses.py b/tests/api_resources/config_registry/test_analyses.py
index 50b608df..0a9c8607 100644
--- a/tests/api_resources/config_registry/test_analyses.py
+++ b/tests/api_resources/config_registry/test_analyses.py
@@ -98,6 +98,48 @@ def test_streaming_response_list(self, client: Kernel) -> None:
assert cast(Any, response.is_closed) is True
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_cancel(self, client: Kernel) -> None:
+ analysis = client.config_registry.analyses.cancel(
+ "id",
+ )
+ assert_matches_type(ConfigRegistryResponse, analysis, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_raw_response_cancel(self, client: Kernel) -> None:
+ response = client.config_registry.analyses.with_raw_response.cancel(
+ "id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ analysis = response.parse()
+ assert_matches_type(ConfigRegistryResponse, analysis, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_streaming_response_cancel(self, client: Kernel) -> None:
+ with client.config_registry.analyses.with_streaming_response.cancel(
+ "id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ analysis = response.parse()
+ assert_matches_type(ConfigRegistryResponse, analysis, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_path_params_cancel(self, client: Kernel) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ client.config_registry.analyses.with_raw_response.cancel(
+ "",
+ )
+
class TestAsyncAnalyses:
parametrize = pytest.mark.parametrize(
@@ -183,3 +225,45 @@ async def test_streaming_response_list(self, async_client: AsyncKernel) -> None:
assert_matches_type(AsyncOffsetPagination[AnalysisSummary], analysis, path=["response"])
assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_cancel(self, async_client: AsyncKernel) -> None:
+ analysis = await async_client.config_registry.analyses.cancel(
+ "id",
+ )
+ assert_matches_type(ConfigRegistryResponse, analysis, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_raw_response_cancel(self, async_client: AsyncKernel) -> None:
+ response = await async_client.config_registry.analyses.with_raw_response.cancel(
+ "id",
+ )
+
+ assert response.is_closed is True
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ analysis = await response.parse()
+ assert_matches_type(ConfigRegistryResponse, analysis, path=["response"])
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_streaming_response_cancel(self, async_client: AsyncKernel) -> None:
+ async with async_client.config_registry.analyses.with_streaming_response.cancel(
+ "id",
+ ) as response:
+ assert not response.is_closed
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+
+ analysis = await response.parse()
+ assert_matches_type(ConfigRegistryResponse, analysis, path=["response"])
+
+ assert cast(Any, response.is_closed) is True
+
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_path_params_cancel(self, async_client: AsyncKernel) -> None:
+ with pytest.raises(ValueError, match=r"Expected a non-empty value for `id` but received ''"):
+ await async_client.config_registry.analyses.with_raw_response.cancel(
+ "",
+ )
diff --git a/tests/api_resources/test_browsers.py b/tests/api_resources/test_browsers.py
index 406b0ce8..28189f15 100644
--- a/tests/api_resources/test_browsers.py
+++ b/tests/api_resources/test_browsers.py
@@ -207,6 +207,7 @@ def test_method_update_with_all_params(self, client: Kernel) -> None:
"name": "x",
},
proxy_id="proxy_id",
+ start_url="https://example.com",
tags={
"team": "backend",
"env": "staging",
@@ -680,6 +681,7 @@ async def test_method_update_with_all_params(self, async_client: AsyncKernel) ->
"name": "x",
},
proxy_id="proxy_id",
+ start_url="https://example.com",
tags={
"team": "backend",
"env": "staging",
diff --git a/tests/api_resources/vaults/test_items.py b/tests/api_resources/vaults/test_items.py
index 1eeb98e3..b80631eb 100644
--- a/tests/api_resources/vaults/test_items.py
+++ b/tests/api_resources/vaults/test_items.py
@@ -604,6 +604,22 @@ def test_method_perform_operation_overload_3(self, client: Kernel) -> None:
)
assert_matches_type(VaultItemOperationResponse, item, path=["response"])
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ def test_method_perform_operation_with_all_params_overload_3(self, client: Kernel) -> None:
+ item = client.vaults.items.perform_operation(
+ key="key",
+ id_or_name="id_or_name",
+ checkout={
+ "browser_id": "browser_id",
+ "environment": "production",
+ "merchant_origin": "merchant_origin",
+ "psp": "square",
+ },
+ type="prepare_checkout",
+ )
+ assert_matches_type(VaultItemOperationResponse, item, path=["response"])
+
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
def test_raw_response_perform_operation_overload_3(self, client: Kernel) -> None:
@@ -1793,6 +1809,22 @@ async def test_method_perform_operation_overload_3(self, async_client: AsyncKern
)
assert_matches_type(VaultItemOperationResponse, item, path=["response"])
+ @pytest.mark.skip(reason="Mock server tests are disabled")
+ @parametrize
+ async def test_method_perform_operation_with_all_params_overload_3(self, async_client: AsyncKernel) -> None:
+ item = await async_client.vaults.items.perform_operation(
+ key="key",
+ id_or_name="id_or_name",
+ checkout={
+ "browser_id": "browser_id",
+ "environment": "production",
+ "merchant_origin": "merchant_origin",
+ "psp": "square",
+ },
+ type="prepare_checkout",
+ )
+ assert_matches_type(VaultItemOperationResponse, item, path=["response"])
+
@pytest.mark.skip(reason="Mock server tests are disabled")
@parametrize
async def test_raw_response_perform_operation_overload_3(self, async_client: AsyncKernel) -> None: