diff --git a/.stats.yml b/.stats.yml
index e16f1ad2..966331a1 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1 +1 @@
-configured_endpoints: 24
+configured_endpoints: 34
diff --git a/api.md b/api.md
index b920447c..0529d9d2 100644
--- a/api.md
+++ b/api.md
@@ -1,7 +1,12 @@
# Shared Types
```python
-from finch.types import OperationSupport, OperationSupportMatrix, Paging
+from finch.types import (
+ IntrospectResponseConnectionStatus,
+ OperationSupport,
+ OperationSupportMatrix,
+ Paging,
+)
```
# Finch
@@ -223,3 +228,111 @@ from finch.types.jobs import ManualAsyncJob
Methods:
- client.jobs.manual.retrieve(job_id) -> ManualAsyncJob
+
+# Auth
+
+Methods:
+
+- client.auth.create_token(\*\*params) -> CreateAccessTokenResponse
+
+# Sandbox
+
+## Connections
+
+Types:
+
+```python
+from finch.types.sandbox import ConnectionCreateResponse
+```
+
+Methods:
+
+- client.sandbox.connections.create(\*\*params) -> ConnectionCreateResponse
+
+### Accounts
+
+Types:
+
+```python
+from finch.types.sandbox.connections import AccountCreateResponse, AccountUpdateResponse
+```
+
+Methods:
+
+- client.sandbox.connections.accounts.create(\*\*params) -> AccountCreateResponse
+- client.sandbox.connections.accounts.update(\*\*params) -> AccountUpdateResponse
+
+## Company
+
+Types:
+
+```python
+from finch.types.sandbox import CompanyUpdateResponse
+```
+
+Methods:
+
+- client.sandbox.company.update(\*\*params) -> CompanyUpdateResponse
+
+## Directory
+
+Types:
+
+```python
+from finch.types.sandbox import DirectoryCreateResponse
+```
+
+Methods:
+
+- client.sandbox.directory.create(\*\*params) -> DirectoryCreateResponse
+
+## Individual
+
+Types:
+
+```python
+from finch.types.sandbox import IndividualUpdateResponse
+```
+
+Methods:
+
+- client.sandbox.individual.update(individual_id, \*\*params) -> IndividualUpdateResponse
+
+## Employment
+
+Types:
+
+```python
+from finch.types.sandbox import EmploymentUpdateResponse
+```
+
+Methods:
+
+- client.sandbox.employment.update(individual_id, \*\*params) -> EmploymentUpdateResponse
+
+## Payment
+
+Types:
+
+```python
+from finch.types.sandbox import PaymentCreateResponse
+```
+
+Methods:
+
+- client.sandbox.payment.create(\*\*params) -> PaymentCreateResponse
+
+## Jobs
+
+### Configuration
+
+Types:
+
+```python
+from finch.types.sandbox.jobs import SandboxJobConfiguration, ConfigurationRetrieveResponse
+```
+
+Methods:
+
+- client.sandbox.jobs.configuration.retrieve() -> ConfigurationRetrieveResponse
+- client.sandbox.jobs.configuration.update(\*\*params) -> SandboxJobConfiguration
diff --git a/src/finch/_client.py b/src/finch/_client.py
index d6e88d57..6e220ad4 100644
--- a/src/finch/_client.py
+++ b/src/finch/_client.py
@@ -58,6 +58,8 @@ class Finch(SyncAPIClient):
webhooks: resources.Webhooks
request_forwarding: resources.RequestForwarding
jobs: resources.Jobs
+ auth: resources.Auth
+ sandbox: resources.Sandbox
with_raw_response: FinchWithRawResponse
# client options
@@ -143,6 +145,8 @@ def __init__(
self.webhooks = resources.Webhooks(self)
self.request_forwarding = resources.RequestForwarding(self)
self.jobs = resources.Jobs(self)
+ self.auth = resources.Auth(self)
+ self.sandbox = resources.Sandbox(self)
self.with_raw_response = FinchWithRawResponse(self)
@property
@@ -365,6 +369,8 @@ class AsyncFinch(AsyncAPIClient):
webhooks: resources.AsyncWebhooks
request_forwarding: resources.AsyncRequestForwarding
jobs: resources.AsyncJobs
+ auth: resources.AsyncAuth
+ sandbox: resources.AsyncSandbox
with_raw_response: AsyncFinchWithRawResponse
# client options
@@ -450,6 +456,8 @@ def __init__(
self.webhooks = resources.AsyncWebhooks(self)
self.request_forwarding = resources.AsyncRequestForwarding(self)
self.jobs = resources.AsyncJobs(self)
+ self.auth = resources.AsyncAuth(self)
+ self.sandbox = resources.AsyncSandbox(self)
self.with_raw_response = AsyncFinchWithRawResponse(self)
@property
@@ -672,6 +680,8 @@ def __init__(self, client: Finch) -> None:
self.account = resources.AccountWithRawResponse(client.account)
self.request_forwarding = resources.RequestForwardingWithRawResponse(client.request_forwarding)
self.jobs = resources.JobsWithRawResponse(client.jobs)
+ self.auth = resources.AuthWithRawResponse(client.auth)
+ self.sandbox = resources.SandboxWithRawResponse(client.sandbox)
class AsyncFinchWithRawResponse:
@@ -682,6 +692,8 @@ def __init__(self, client: AsyncFinch) -> None:
self.account = resources.AsyncAccountWithRawResponse(client.account)
self.request_forwarding = resources.AsyncRequestForwardingWithRawResponse(client.request_forwarding)
self.jobs = resources.AsyncJobsWithRawResponse(client.jobs)
+ self.auth = resources.AsyncAuthWithRawResponse(client.auth)
+ self.sandbox = resources.AsyncSandboxWithRawResponse(client.sandbox)
Client = Finch
diff --git a/src/finch/resources/__init__.py b/src/finch/resources/__init__.py
index 152e5776..f5912eb0 100644
--- a/src/finch/resources/__init__.py
+++ b/src/finch/resources/__init__.py
@@ -1,8 +1,10 @@
# File generated from our OpenAPI spec by Stainless.
+from .auth import Auth, AsyncAuth, AuthWithRawResponse, AsyncAuthWithRawResponse
from .hris import HRIS, AsyncHRIS, HRISWithRawResponse, AsyncHRISWithRawResponse
from .jobs import Jobs, AsyncJobs, JobsWithRawResponse, AsyncJobsWithRawResponse
from .account import Account, AsyncAccount, AccountWithRawResponse, AsyncAccountWithRawResponse
+from .sandbox import Sandbox, AsyncSandbox, SandboxWithRawResponse, AsyncSandboxWithRawResponse
from .webhooks import Webhooks, AsyncWebhooks
from .providers import Providers, AsyncProviders, ProvidersWithRawResponse, AsyncProvidersWithRawResponse
from .access_tokens import (
@@ -45,4 +47,12 @@
"AsyncJobs",
"JobsWithRawResponse",
"AsyncJobsWithRawResponse",
+ "Auth",
+ "AsyncAuth",
+ "AuthWithRawResponse",
+ "AsyncAuthWithRawResponse",
+ "Sandbox",
+ "AsyncSandbox",
+ "SandboxWithRawResponse",
+ "AsyncSandboxWithRawResponse",
]
diff --git a/src/finch/resources/auth.py b/src/finch/resources/auth.py
new file mode 100644
index 00000000..1a7bd991
--- /dev/null
+++ b/src/finch/resources/auth.py
@@ -0,0 +1,129 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+import httpx
+
+from ..types import CreateAccessTokenResponse, auth_create_token_params
+from .._types import NOT_GIVEN, Body, Query, Headers, NotGiven
+from .._utils import maybe_transform
+from .._compat import cached_property
+from .._resource import SyncAPIResource, AsyncAPIResource
+from .._response import to_raw_response_wrapper, async_to_raw_response_wrapper
+from .._base_client import (
+ make_request_options,
+)
+
+__all__ = ["Auth", "AsyncAuth"]
+
+
+class Auth(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AuthWithRawResponse:
+ return AuthWithRawResponse(self)
+
+ def create_token(
+ self,
+ *,
+ client_id: str,
+ client_secret: str,
+ code: str,
+ redirect_uri: 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,
+ ) -> CreateAccessTokenResponse:
+ """
+ Exchange the authorization code for an access token
+
+ 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
+ """
+ return self._post(
+ "/auth/token",
+ body=maybe_transform(
+ {
+ "client_id": client_id,
+ "client_secret": client_secret,
+ "code": code,
+ "redirect_uri": redirect_uri,
+ },
+ auth_create_token_params.AuthCreateTokenParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=CreateAccessTokenResponse,
+ )
+
+
+class AsyncAuth(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncAuthWithRawResponse:
+ return AsyncAuthWithRawResponse(self)
+
+ async def create_token(
+ self,
+ *,
+ client_id: str,
+ client_secret: str,
+ code: str,
+ redirect_uri: 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,
+ ) -> CreateAccessTokenResponse:
+ """
+ Exchange the authorization code for an access token
+
+ 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
+ """
+ return await self._post(
+ "/auth/token",
+ body=maybe_transform(
+ {
+ "client_id": client_id,
+ "client_secret": client_secret,
+ "code": code,
+ "redirect_uri": redirect_uri,
+ },
+ auth_create_token_params.AuthCreateTokenParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=CreateAccessTokenResponse,
+ )
+
+
+class AuthWithRawResponse:
+ def __init__(self, auth: Auth) -> None:
+ self.create_token = to_raw_response_wrapper(
+ auth.create_token,
+ )
+
+
+class AsyncAuthWithRawResponse:
+ def __init__(self, auth: AsyncAuth) -> None:
+ self.create_token = async_to_raw_response_wrapper(
+ auth.create_token,
+ )
diff --git a/src/finch/resources/sandbox/__init__.py b/src/finch/resources/sandbox/__init__.py
new file mode 100644
index 00000000..41f27f60
--- /dev/null
+++ b/src/finch/resources/sandbox/__init__.py
@@ -0,0 +1,45 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from .jobs import Jobs, AsyncJobs, JobsWithRawResponse, AsyncJobsWithRawResponse
+from .company import Company, AsyncCompany, CompanyWithRawResponse, AsyncCompanyWithRawResponse
+from .payment import Payment, AsyncPayment, PaymentWithRawResponse, AsyncPaymentWithRawResponse
+from .sandbox import Sandbox, AsyncSandbox, SandboxWithRawResponse, AsyncSandboxWithRawResponse
+from .directory import Directory, AsyncDirectory, DirectoryWithRawResponse, AsyncDirectoryWithRawResponse
+from .employment import Employment, AsyncEmployment, EmploymentWithRawResponse, AsyncEmploymentWithRawResponse
+from .individual import Individual, AsyncIndividual, IndividualWithRawResponse, AsyncIndividualWithRawResponse
+from .connections import Connections, AsyncConnections, ConnectionsWithRawResponse, AsyncConnectionsWithRawResponse
+
+__all__ = [
+ "Connections",
+ "AsyncConnections",
+ "ConnectionsWithRawResponse",
+ "AsyncConnectionsWithRawResponse",
+ "Company",
+ "AsyncCompany",
+ "CompanyWithRawResponse",
+ "AsyncCompanyWithRawResponse",
+ "Directory",
+ "AsyncDirectory",
+ "DirectoryWithRawResponse",
+ "AsyncDirectoryWithRawResponse",
+ "Individual",
+ "AsyncIndividual",
+ "IndividualWithRawResponse",
+ "AsyncIndividualWithRawResponse",
+ "Employment",
+ "AsyncEmployment",
+ "EmploymentWithRawResponse",
+ "AsyncEmploymentWithRawResponse",
+ "Payment",
+ "AsyncPayment",
+ "PaymentWithRawResponse",
+ "AsyncPaymentWithRawResponse",
+ "Jobs",
+ "AsyncJobs",
+ "JobsWithRawResponse",
+ "AsyncJobsWithRawResponse",
+ "Sandbox",
+ "AsyncSandbox",
+ "SandboxWithRawResponse",
+ "AsyncSandboxWithRawResponse",
+]
diff --git a/src/finch/resources/sandbox/company.py b/src/finch/resources/sandbox/company.py
new file mode 100644
index 00000000..82bb0239
--- /dev/null
+++ b/src/finch/resources/sandbox/company.py
@@ -0,0 +1,176 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from typing import List, Optional
+
+import httpx
+
+from ...types import LocationParam
+from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven
+from ..._utils import maybe_transform
+from ..._compat import cached_property
+from ..._resource import SyncAPIResource, AsyncAPIResource
+from ..._response import to_raw_response_wrapper, async_to_raw_response_wrapper
+from ..._base_client import (
+ make_request_options,
+)
+from ...types.sandbox import CompanyUpdateResponse, company_update_params
+
+__all__ = ["Company", "AsyncCompany"]
+
+
+class Company(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> CompanyWithRawResponse:
+ return CompanyWithRawResponse(self)
+
+ def update(
+ self,
+ *,
+ accounts: Optional[List[company_update_params.Account]],
+ departments: Optional[List[Optional[company_update_params.Department]]],
+ ein: Optional[str],
+ entity: Optional[company_update_params.Entity],
+ legal_name: Optional[str],
+ locations: Optional[List[Optional[LocationParam]]],
+ primary_email: Optional[str],
+ primary_phone_number: Optional[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,
+ ) -> CompanyUpdateResponse:
+ """
+ Update a sandbox company's data
+
+ Args:
+ accounts: An array of bank account objects associated with the payroll/HRIS system.
+
+ departments: The array of company departments.
+
+ ein: The employer identification number.
+
+ entity: The entity type object.
+
+ legal_name: The legal name of the company.
+
+ primary_email: The email of the main administrator on the account.
+
+ primary_phone_number: The phone number of the main administrator on the account. Format: `XXXXXXXXXX`
+
+ 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._put(
+ "/sandbox/company",
+ body=maybe_transform(
+ {
+ "accounts": accounts,
+ "departments": departments,
+ "ein": ein,
+ "entity": entity,
+ "legal_name": legal_name,
+ "locations": locations,
+ "primary_email": primary_email,
+ "primary_phone_number": primary_phone_number,
+ },
+ company_update_params.CompanyUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=CompanyUpdateResponse,
+ )
+
+
+class AsyncCompany(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncCompanyWithRawResponse:
+ return AsyncCompanyWithRawResponse(self)
+
+ async def update(
+ self,
+ *,
+ accounts: Optional[List[company_update_params.Account]],
+ departments: Optional[List[Optional[company_update_params.Department]]],
+ ein: Optional[str],
+ entity: Optional[company_update_params.Entity],
+ legal_name: Optional[str],
+ locations: Optional[List[Optional[LocationParam]]],
+ primary_email: Optional[str],
+ primary_phone_number: Optional[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,
+ ) -> CompanyUpdateResponse:
+ """
+ Update a sandbox company's data
+
+ Args:
+ accounts: An array of bank account objects associated with the payroll/HRIS system.
+
+ departments: The array of company departments.
+
+ ein: The employer identification number.
+
+ entity: The entity type object.
+
+ legal_name: The legal name of the company.
+
+ primary_email: The email of the main administrator on the account.
+
+ primary_phone_number: The phone number of the main administrator on the account. Format: `XXXXXXXXXX`
+
+ 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._put(
+ "/sandbox/company",
+ body=maybe_transform(
+ {
+ "accounts": accounts,
+ "departments": departments,
+ "ein": ein,
+ "entity": entity,
+ "legal_name": legal_name,
+ "locations": locations,
+ "primary_email": primary_email,
+ "primary_phone_number": primary_phone_number,
+ },
+ company_update_params.CompanyUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=CompanyUpdateResponse,
+ )
+
+
+class CompanyWithRawResponse:
+ def __init__(self, company: Company) -> None:
+ self.update = to_raw_response_wrapper(
+ company.update,
+ )
+
+
+class AsyncCompanyWithRawResponse:
+ def __init__(self, company: AsyncCompany) -> None:
+ self.update = async_to_raw_response_wrapper(
+ company.update,
+ )
diff --git a/src/finch/resources/sandbox/connections/__init__.py b/src/finch/resources/sandbox/connections/__init__.py
new file mode 100644
index 00000000..747635e9
--- /dev/null
+++ b/src/finch/resources/sandbox/connections/__init__.py
@@ -0,0 +1,15 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from .accounts import Accounts, AsyncAccounts, AccountsWithRawResponse, AsyncAccountsWithRawResponse
+from .connections import Connections, AsyncConnections, ConnectionsWithRawResponse, AsyncConnectionsWithRawResponse
+
+__all__ = [
+ "Accounts",
+ "AsyncAccounts",
+ "AccountsWithRawResponse",
+ "AsyncAccountsWithRawResponse",
+ "Connections",
+ "AsyncConnections",
+ "ConnectionsWithRawResponse",
+ "AsyncConnectionsWithRawResponse",
+]
diff --git a/src/finch/resources/sandbox/connections/accounts.py b/src/finch/resources/sandbox/connections/accounts.py
new file mode 100644
index 00000000..c685e92a
--- /dev/null
+++ b/src/finch/resources/sandbox/connections/accounts.py
@@ -0,0 +1,218 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from typing import List
+from typing_extensions import Literal
+
+import httpx
+
+from ...._types import NOT_GIVEN, Body, Query, Headers, NotGiven
+from ...._utils import maybe_transform
+from ...._compat import cached_property
+from ...._resource import SyncAPIResource, AsyncAPIResource
+from ...._response import to_raw_response_wrapper, async_to_raw_response_wrapper
+from ...._base_client import (
+ make_request_options,
+)
+from ....types.shared import IntrospectResponseConnectionStatus
+from ....types.sandbox.connections import (
+ AccountCreateResponse,
+ AccountUpdateResponse,
+ account_create_params,
+ account_update_params,
+)
+
+__all__ = ["Accounts", "AsyncAccounts"]
+
+
+class Accounts(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AccountsWithRawResponse:
+ return AccountsWithRawResponse(self)
+
+ def create(
+ self,
+ *,
+ company_id: str,
+ provider_id: str,
+ authentication_type: Literal["credentials", "api_token", "oauth", "assisted"] | NotGiven = NOT_GIVEN,
+ products: List[str] | NotGiven = NOT_GIVEN,
+ # 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,
+ ) -> AccountCreateResponse:
+ """
+ Create a new account for an existing connection (company/provider pair)
+
+ Args:
+ products: Optional, defaults to Organization products (`company`, `directory`,
+ `employment`, `individual`)
+
+ 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._post(
+ "/sandbox/connections/accounts",
+ body=maybe_transform(
+ {
+ "company_id": company_id,
+ "provider_id": provider_id,
+ "authentication_type": authentication_type,
+ "products": products,
+ },
+ account_create_params.AccountCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=AccountCreateResponse,
+ )
+
+ def update(
+ self,
+ *,
+ connection_status: IntrospectResponseConnectionStatus | NotGiven = NOT_GIVEN,
+ # 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,
+ ) -> AccountUpdateResponse:
+ """Update an existing sandbox account.
+
+ Change the connection status to understand
+ how the Finch API responds.
+
+ 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
+ """
+ return self._put(
+ "/sandbox/connections/accounts",
+ body=maybe_transform({"connection_status": connection_status}, account_update_params.AccountUpdateParams),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=AccountUpdateResponse,
+ )
+
+
+class AsyncAccounts(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncAccountsWithRawResponse:
+ return AsyncAccountsWithRawResponse(self)
+
+ async def create(
+ self,
+ *,
+ company_id: str,
+ provider_id: str,
+ authentication_type: Literal["credentials", "api_token", "oauth", "assisted"] | NotGiven = NOT_GIVEN,
+ products: List[str] | NotGiven = NOT_GIVEN,
+ # 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,
+ ) -> AccountCreateResponse:
+ """
+ Create a new account for an existing connection (company/provider pair)
+
+ Args:
+ products: Optional, defaults to Organization products (`company`, `directory`,
+ `employment`, `individual`)
+
+ 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._post(
+ "/sandbox/connections/accounts",
+ body=maybe_transform(
+ {
+ "company_id": company_id,
+ "provider_id": provider_id,
+ "authentication_type": authentication_type,
+ "products": products,
+ },
+ account_create_params.AccountCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=AccountCreateResponse,
+ )
+
+ async def update(
+ self,
+ *,
+ connection_status: IntrospectResponseConnectionStatus | NotGiven = NOT_GIVEN,
+ # 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,
+ ) -> AccountUpdateResponse:
+ """Update an existing sandbox account.
+
+ Change the connection status to understand
+ how the Finch API responds.
+
+ 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
+ """
+ return await self._put(
+ "/sandbox/connections/accounts",
+ body=maybe_transform({"connection_status": connection_status}, account_update_params.AccountUpdateParams),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=AccountUpdateResponse,
+ )
+
+
+class AccountsWithRawResponse:
+ def __init__(self, accounts: Accounts) -> None:
+ self.create = to_raw_response_wrapper(
+ accounts.create,
+ )
+ self.update = to_raw_response_wrapper(
+ accounts.update,
+ )
+
+
+class AsyncAccountsWithRawResponse:
+ def __init__(self, accounts: AsyncAccounts) -> None:
+ self.create = async_to_raw_response_wrapper(
+ accounts.create,
+ )
+ self.update = async_to_raw_response_wrapper(
+ accounts.update,
+ )
diff --git a/src/finch/resources/sandbox/connections/connections.py b/src/finch/resources/sandbox/connections/connections.py
new file mode 100644
index 00000000..b3b522bc
--- /dev/null
+++ b/src/finch/resources/sandbox/connections/connections.py
@@ -0,0 +1,151 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from typing import List
+from typing_extensions import Literal
+
+import httpx
+
+from .accounts import Accounts, AsyncAccounts, AccountsWithRawResponse, AsyncAccountsWithRawResponse
+from ...._types import NOT_GIVEN, Body, Query, Headers, NotGiven
+from ...._utils import maybe_transform
+from ...._compat import cached_property
+from ...._resource import SyncAPIResource, AsyncAPIResource
+from ...._response import to_raw_response_wrapper, async_to_raw_response_wrapper
+from ...._base_client import (
+ make_request_options,
+)
+from ....types.sandbox import ConnectionCreateResponse, connection_create_params
+
+__all__ = ["Connections", "AsyncConnections"]
+
+
+class Connections(SyncAPIResource):
+ @cached_property
+ def accounts(self) -> Accounts:
+ return Accounts(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> ConnectionsWithRawResponse:
+ return ConnectionsWithRawResponse(self)
+
+ def create(
+ self,
+ *,
+ provider_id: str,
+ authentication_type: Literal["credentials", "api_token", "oauth", "assisted"] | NotGiven = NOT_GIVEN,
+ employer_size: int | NotGiven = NOT_GIVEN,
+ products: List[str] | NotGiven = NOT_GIVEN,
+ # 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,
+ ) -> ConnectionCreateResponse:
+ """
+ Create a new connection (new company/provider pair) with a new account
+
+ Args:
+ employer_size: Optional: the size of the employer to be created with this connection. Defaults
+ to 20
+
+ 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._post(
+ "/sandbox/connections",
+ body=maybe_transform(
+ {
+ "provider_id": provider_id,
+ "authentication_type": authentication_type,
+ "employer_size": employer_size,
+ "products": products,
+ },
+ connection_create_params.ConnectionCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ConnectionCreateResponse,
+ )
+
+
+class AsyncConnections(AsyncAPIResource):
+ @cached_property
+ def accounts(self) -> AsyncAccounts:
+ return AsyncAccounts(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> AsyncConnectionsWithRawResponse:
+ return AsyncConnectionsWithRawResponse(self)
+
+ async def create(
+ self,
+ *,
+ provider_id: str,
+ authentication_type: Literal["credentials", "api_token", "oauth", "assisted"] | NotGiven = NOT_GIVEN,
+ employer_size: int | NotGiven = NOT_GIVEN,
+ products: List[str] | NotGiven = NOT_GIVEN,
+ # 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,
+ ) -> ConnectionCreateResponse:
+ """
+ Create a new connection (new company/provider pair) with a new account
+
+ Args:
+ employer_size: Optional: the size of the employer to be created with this connection. Defaults
+ to 20
+
+ 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._post(
+ "/sandbox/connections",
+ body=maybe_transform(
+ {
+ "provider_id": provider_id,
+ "authentication_type": authentication_type,
+ "employer_size": employer_size,
+ "products": products,
+ },
+ connection_create_params.ConnectionCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ConnectionCreateResponse,
+ )
+
+
+class ConnectionsWithRawResponse:
+ def __init__(self, connections: Connections) -> None:
+ self.accounts = AccountsWithRawResponse(connections.accounts)
+
+ self.create = to_raw_response_wrapper(
+ connections.create,
+ )
+
+
+class AsyncConnectionsWithRawResponse:
+ def __init__(self, connections: AsyncConnections) -> None:
+ self.accounts = AsyncAccountsWithRawResponse(connections.accounts)
+
+ self.create = async_to_raw_response_wrapper(
+ connections.create,
+ )
diff --git a/src/finch/resources/sandbox/directory.py b/src/finch/resources/sandbox/directory.py
new file mode 100644
index 00000000..3249c71e
--- /dev/null
+++ b/src/finch/resources/sandbox/directory.py
@@ -0,0 +1,115 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from typing import List
+
+import httpx
+
+from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven
+from ..._utils import maybe_transform
+from ..._compat import cached_property
+from ..._resource import SyncAPIResource, AsyncAPIResource
+from ..._response import to_raw_response_wrapper, async_to_raw_response_wrapper
+from ..._base_client import (
+ make_request_options,
+)
+from ...types.sandbox import DirectoryCreateResponse, directory_create_params
+
+__all__ = ["Directory", "AsyncDirectory"]
+
+
+class Directory(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> DirectoryWithRawResponse:
+ return DirectoryWithRawResponse(self)
+
+ def create(
+ self,
+ *,
+ body: List[directory_create_params.Body],
+ # 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,
+ ) -> DirectoryCreateResponse:
+ """
+ Add new individuals to a sandbox company
+
+ Args:
+ body: Array of individuals to create. Takes all combined fields from `/individual` and
+ `/employment` endpoints. All fields are optional.
+
+ 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._post(
+ "/sandbox/directory",
+ body=maybe_transform(body, directory_create_params.DirectoryCreateParams),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DirectoryCreateResponse,
+ )
+
+
+class AsyncDirectory(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncDirectoryWithRawResponse:
+ return AsyncDirectoryWithRawResponse(self)
+
+ async def create(
+ self,
+ *,
+ body: List[directory_create_params.Body],
+ # 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,
+ ) -> DirectoryCreateResponse:
+ """
+ Add new individuals to a sandbox company
+
+ Args:
+ body: Array of individuals to create. Takes all combined fields from `/individual` and
+ `/employment` endpoints. All fields are optional.
+
+ 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._post(
+ "/sandbox/directory",
+ body=maybe_transform(body, directory_create_params.DirectoryCreateParams),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=DirectoryCreateResponse,
+ )
+
+
+class DirectoryWithRawResponse:
+ def __init__(self, directory: Directory) -> None:
+ self.create = to_raw_response_wrapper(
+ directory.create,
+ )
+
+
+class AsyncDirectoryWithRawResponse:
+ def __init__(self, directory: AsyncDirectory) -> None:
+ self.create = async_to_raw_response_wrapper(
+ directory.create,
+ )
diff --git a/src/finch/resources/sandbox/employment.py b/src/finch/resources/sandbox/employment.py
new file mode 100644
index 00000000..b38757b4
--- /dev/null
+++ b/src/finch/resources/sandbox/employment.py
@@ -0,0 +1,246 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from typing import List, Optional
+
+import httpx
+
+from ...types import IncomeParam, LocationParam
+from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven
+from ..._utils import maybe_transform
+from ..._compat import cached_property
+from ..._resource import SyncAPIResource, AsyncAPIResource
+from ..._response import to_raw_response_wrapper, async_to_raw_response_wrapper
+from ..._base_client import (
+ make_request_options,
+)
+from ...types.sandbox import EmploymentUpdateResponse, employment_update_params
+
+__all__ = ["Employment", "AsyncEmployment"]
+
+
+class Employment(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> EmploymentWithRawResponse:
+ return EmploymentWithRawResponse(self)
+
+ def update(
+ self,
+ individual_id: str,
+ *,
+ class_code: Optional[str] | NotGiven = NOT_GIVEN,
+ custom_fields: List[employment_update_params.CustomField] | NotGiven = NOT_GIVEN,
+ department: Optional[employment_update_params.Department] | NotGiven = NOT_GIVEN,
+ employment: Optional[employment_update_params.Employment] | NotGiven = NOT_GIVEN,
+ end_date: Optional[str] | NotGiven = NOT_GIVEN,
+ first_name: Optional[str] | NotGiven = NOT_GIVEN,
+ income: Optional[IncomeParam] | NotGiven = NOT_GIVEN,
+ income_history: Optional[List[Optional[IncomeParam]]] | NotGiven = NOT_GIVEN,
+ is_active: Optional[bool] | NotGiven = NOT_GIVEN,
+ last_name: Optional[str] | NotGiven = NOT_GIVEN,
+ location: Optional[LocationParam] | NotGiven = NOT_GIVEN,
+ manager: Optional[employment_update_params.Manager] | NotGiven = NOT_GIVEN,
+ middle_name: Optional[str] | NotGiven = NOT_GIVEN,
+ source_id: str | NotGiven = NOT_GIVEN,
+ start_date: Optional[str] | NotGiven = NOT_GIVEN,
+ title: Optional[str] | NotGiven = NOT_GIVEN,
+ # 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,
+ ) -> EmploymentUpdateResponse:
+ """
+ Update sandbox employment
+
+ Args:
+ class_code: Worker's compensation classification code for this employee
+
+ custom_fields: Custom fields for the individual. These are fields which are defined by the
+ employer in the system. Custom fields are not currently supported for assisted
+ connections.
+
+ department: The department object.
+
+ employment: The employment object.
+
+ first_name: The legal first name of the individual.
+
+ income: The employee's income as reported by the provider. This may not always be
+ annualized income, but may be in units of bi-weekly, semi-monthly, daily, etc,
+ depending on what information the provider returns.
+
+ income_history: The array of income history.
+
+ is_active: `true` if the individual an an active employee or contractor at the company.
+
+ last_name: The legal last name of the individual.
+
+ location
+
+ manager: The manager object representing the manager of the individual within the org.
+
+ middle_name: The legal middle name of the individual.
+
+ source_id: The source system's unique employment identifier for this individual
+
+ title: The current title of the individual.
+
+ 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._put(
+ f"/sandbox/employment/{individual_id}",
+ body=maybe_transform(
+ {
+ "class_code": class_code,
+ "custom_fields": custom_fields,
+ "department": department,
+ "employment": employment,
+ "end_date": end_date,
+ "first_name": first_name,
+ "income": income,
+ "income_history": income_history,
+ "is_active": is_active,
+ "last_name": last_name,
+ "location": location,
+ "manager": manager,
+ "middle_name": middle_name,
+ "source_id": source_id,
+ "start_date": start_date,
+ "title": title,
+ },
+ employment_update_params.EmploymentUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=EmploymentUpdateResponse,
+ )
+
+
+class AsyncEmployment(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncEmploymentWithRawResponse:
+ return AsyncEmploymentWithRawResponse(self)
+
+ async def update(
+ self,
+ individual_id: str,
+ *,
+ class_code: Optional[str] | NotGiven = NOT_GIVEN,
+ custom_fields: List[employment_update_params.CustomField] | NotGiven = NOT_GIVEN,
+ department: Optional[employment_update_params.Department] | NotGiven = NOT_GIVEN,
+ employment: Optional[employment_update_params.Employment] | NotGiven = NOT_GIVEN,
+ end_date: Optional[str] | NotGiven = NOT_GIVEN,
+ first_name: Optional[str] | NotGiven = NOT_GIVEN,
+ income: Optional[IncomeParam] | NotGiven = NOT_GIVEN,
+ income_history: Optional[List[Optional[IncomeParam]]] | NotGiven = NOT_GIVEN,
+ is_active: Optional[bool] | NotGiven = NOT_GIVEN,
+ last_name: Optional[str] | NotGiven = NOT_GIVEN,
+ location: Optional[LocationParam] | NotGiven = NOT_GIVEN,
+ manager: Optional[employment_update_params.Manager] | NotGiven = NOT_GIVEN,
+ middle_name: Optional[str] | NotGiven = NOT_GIVEN,
+ source_id: str | NotGiven = NOT_GIVEN,
+ start_date: Optional[str] | NotGiven = NOT_GIVEN,
+ title: Optional[str] | NotGiven = NOT_GIVEN,
+ # 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,
+ ) -> EmploymentUpdateResponse:
+ """
+ Update sandbox employment
+
+ Args:
+ class_code: Worker's compensation classification code for this employee
+
+ custom_fields: Custom fields for the individual. These are fields which are defined by the
+ employer in the system. Custom fields are not currently supported for assisted
+ connections.
+
+ department: The department object.
+
+ employment: The employment object.
+
+ first_name: The legal first name of the individual.
+
+ income: The employee's income as reported by the provider. This may not always be
+ annualized income, but may be in units of bi-weekly, semi-monthly, daily, etc,
+ depending on what information the provider returns.
+
+ income_history: The array of income history.
+
+ is_active: `true` if the individual an an active employee or contractor at the company.
+
+ last_name: The legal last name of the individual.
+
+ location
+
+ manager: The manager object representing the manager of the individual within the org.
+
+ middle_name: The legal middle name of the individual.
+
+ source_id: The source system's unique employment identifier for this individual
+
+ title: The current title of the individual.
+
+ 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._put(
+ f"/sandbox/employment/{individual_id}",
+ body=maybe_transform(
+ {
+ "class_code": class_code,
+ "custom_fields": custom_fields,
+ "department": department,
+ "employment": employment,
+ "end_date": end_date,
+ "first_name": first_name,
+ "income": income,
+ "income_history": income_history,
+ "is_active": is_active,
+ "last_name": last_name,
+ "location": location,
+ "manager": manager,
+ "middle_name": middle_name,
+ "source_id": source_id,
+ "start_date": start_date,
+ "title": title,
+ },
+ employment_update_params.EmploymentUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=EmploymentUpdateResponse,
+ )
+
+
+class EmploymentWithRawResponse:
+ def __init__(self, employment: Employment) -> None:
+ self.update = to_raw_response_wrapper(
+ employment.update,
+ )
+
+
+class AsyncEmploymentWithRawResponse:
+ def __init__(self, employment: AsyncEmployment) -> None:
+ self.update = async_to_raw_response_wrapper(
+ employment.update,
+ )
diff --git a/src/finch/resources/sandbox/individual.py b/src/finch/resources/sandbox/individual.py
new file mode 100644
index 00000000..d0da230a
--- /dev/null
+++ b/src/finch/resources/sandbox/individual.py
@@ -0,0 +1,235 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from typing import List, Optional
+from typing_extensions import Literal
+
+import httpx
+
+from ...types import LocationParam
+from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven
+from ..._utils import maybe_transform
+from ..._compat import cached_property
+from ..._resource import SyncAPIResource, AsyncAPIResource
+from ..._response import to_raw_response_wrapper, async_to_raw_response_wrapper
+from ..._base_client import (
+ make_request_options,
+)
+from ...types.sandbox import IndividualUpdateResponse, individual_update_params
+
+__all__ = ["Individual", "AsyncIndividual"]
+
+
+class Individual(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> IndividualWithRawResponse:
+ return IndividualWithRawResponse(self)
+
+ def update(
+ self,
+ individual_id: str,
+ *,
+ dob: Optional[str] | NotGiven = NOT_GIVEN,
+ emails: Optional[List[individual_update_params.Email]] | NotGiven = NOT_GIVEN,
+ encrypted_ssn: Optional[str] | NotGiven = NOT_GIVEN,
+ ethnicity: Optional[
+ Literal[
+ "asian",
+ "white",
+ "black_or_african_american",
+ "native_hawaiian_or_pacific_islander",
+ "american_indian_or_alaska_native",
+ "hispanic_or_latino",
+ "two_or_more_races",
+ "decline_to_specify",
+ ]
+ ]
+ | NotGiven = NOT_GIVEN,
+ first_name: Optional[str] | NotGiven = NOT_GIVEN,
+ gender: Optional[Literal["female", "male", "other", "decline_to_specify"]] | NotGiven = NOT_GIVEN,
+ last_name: Optional[str] | NotGiven = NOT_GIVEN,
+ middle_name: Optional[str] | NotGiven = NOT_GIVEN,
+ phone_numbers: Optional[List[Optional[individual_update_params.PhoneNumber]]] | NotGiven = NOT_GIVEN,
+ preferred_name: Optional[str] | NotGiven = NOT_GIVEN,
+ residence: Optional[LocationParam] | NotGiven = NOT_GIVEN,
+ ssn: Optional[str] | NotGiven = NOT_GIVEN,
+ # 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,
+ ) -> IndividualUpdateResponse:
+ """
+ Update sandbox individual
+
+ Args:
+ encrypted_ssn: Social Security Number of the individual in **encrypted** format. This field is
+ only available with the `ssn` scope enabled and the
+ `options: { include: ['ssn'] }` param set in the body.
+
+ ethnicity: The EEOC-defined ethnicity of the individual.
+
+ first_name: The legal first name of the individual.
+
+ gender: The gender of the individual.
+
+ last_name: The legal last name of the individual.
+
+ middle_name: The legal middle name of the individual.
+
+ preferred_name: The preferred name of the individual.
+
+ residence
+
+ ssn: Social Security Number of the individual. This field is only available with the
+ `ssn` scope enabled and the `options: { include: ['ssn'] }` param set in the
+ body.
+
+ 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._put(
+ f"/sandbox/individual/{individual_id}",
+ body=maybe_transform(
+ {
+ "dob": dob,
+ "emails": emails,
+ "encrypted_ssn": encrypted_ssn,
+ "ethnicity": ethnicity,
+ "first_name": first_name,
+ "gender": gender,
+ "last_name": last_name,
+ "middle_name": middle_name,
+ "phone_numbers": phone_numbers,
+ "preferred_name": preferred_name,
+ "residence": residence,
+ "ssn": ssn,
+ },
+ individual_update_params.IndividualUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=IndividualUpdateResponse,
+ )
+
+
+class AsyncIndividual(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncIndividualWithRawResponse:
+ return AsyncIndividualWithRawResponse(self)
+
+ async def update(
+ self,
+ individual_id: str,
+ *,
+ dob: Optional[str] | NotGiven = NOT_GIVEN,
+ emails: Optional[List[individual_update_params.Email]] | NotGiven = NOT_GIVEN,
+ encrypted_ssn: Optional[str] | NotGiven = NOT_GIVEN,
+ ethnicity: Optional[
+ Literal[
+ "asian",
+ "white",
+ "black_or_african_american",
+ "native_hawaiian_or_pacific_islander",
+ "american_indian_or_alaska_native",
+ "hispanic_or_latino",
+ "two_or_more_races",
+ "decline_to_specify",
+ ]
+ ]
+ | NotGiven = NOT_GIVEN,
+ first_name: Optional[str] | NotGiven = NOT_GIVEN,
+ gender: Optional[Literal["female", "male", "other", "decline_to_specify"]] | NotGiven = NOT_GIVEN,
+ last_name: Optional[str] | NotGiven = NOT_GIVEN,
+ middle_name: Optional[str] | NotGiven = NOT_GIVEN,
+ phone_numbers: Optional[List[Optional[individual_update_params.PhoneNumber]]] | NotGiven = NOT_GIVEN,
+ preferred_name: Optional[str] | NotGiven = NOT_GIVEN,
+ residence: Optional[LocationParam] | NotGiven = NOT_GIVEN,
+ ssn: Optional[str] | NotGiven = NOT_GIVEN,
+ # 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,
+ ) -> IndividualUpdateResponse:
+ """
+ Update sandbox individual
+
+ Args:
+ encrypted_ssn: Social Security Number of the individual in **encrypted** format. This field is
+ only available with the `ssn` scope enabled and the
+ `options: { include: ['ssn'] }` param set in the body.
+
+ ethnicity: The EEOC-defined ethnicity of the individual.
+
+ first_name: The legal first name of the individual.
+
+ gender: The gender of the individual.
+
+ last_name: The legal last name of the individual.
+
+ middle_name: The legal middle name of the individual.
+
+ preferred_name: The preferred name of the individual.
+
+ residence
+
+ ssn: Social Security Number of the individual. This field is only available with the
+ `ssn` scope enabled and the `options: { include: ['ssn'] }` param set in the
+ body.
+
+ 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._put(
+ f"/sandbox/individual/{individual_id}",
+ body=maybe_transform(
+ {
+ "dob": dob,
+ "emails": emails,
+ "encrypted_ssn": encrypted_ssn,
+ "ethnicity": ethnicity,
+ "first_name": first_name,
+ "gender": gender,
+ "last_name": last_name,
+ "middle_name": middle_name,
+ "phone_numbers": phone_numbers,
+ "preferred_name": preferred_name,
+ "residence": residence,
+ "ssn": ssn,
+ },
+ individual_update_params.IndividualUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=IndividualUpdateResponse,
+ )
+
+
+class IndividualWithRawResponse:
+ def __init__(self, individual: Individual) -> None:
+ self.update = to_raw_response_wrapper(
+ individual.update,
+ )
+
+
+class AsyncIndividualWithRawResponse:
+ def __init__(self, individual: AsyncIndividual) -> None:
+ self.update = async_to_raw_response_wrapper(
+ individual.update,
+ )
diff --git a/src/finch/resources/sandbox/jobs/__init__.py b/src/finch/resources/sandbox/jobs/__init__.py
new file mode 100644
index 00000000..1a21f174
--- /dev/null
+++ b/src/finch/resources/sandbox/jobs/__init__.py
@@ -0,0 +1,20 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from .jobs import Jobs, AsyncJobs, JobsWithRawResponse, AsyncJobsWithRawResponse
+from .configuration import (
+ Configuration,
+ AsyncConfiguration,
+ ConfigurationWithRawResponse,
+ AsyncConfigurationWithRawResponse,
+)
+
+__all__ = [
+ "Configuration",
+ "AsyncConfiguration",
+ "ConfigurationWithRawResponse",
+ "AsyncConfigurationWithRawResponse",
+ "Jobs",
+ "AsyncJobs",
+ "JobsWithRawResponse",
+ "AsyncJobsWithRawResponse",
+]
diff --git a/src/finch/resources/sandbox/jobs/configuration.py b/src/finch/resources/sandbox/jobs/configuration.py
new file mode 100644
index 00000000..f3e8d6ab
--- /dev/null
+++ b/src/finch/resources/sandbox/jobs/configuration.py
@@ -0,0 +1,167 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from typing_extensions import Literal
+
+import httpx
+
+from ...._types import NOT_GIVEN, Body, Query, Headers, NotGiven
+from ...._utils import maybe_transform
+from ...._compat import cached_property
+from ...._resource import SyncAPIResource, AsyncAPIResource
+from ...._response import to_raw_response_wrapper, async_to_raw_response_wrapper
+from ...._base_client import (
+ make_request_options,
+)
+from ....types.sandbox.jobs import SandboxJobConfiguration, ConfigurationRetrieveResponse, configuration_update_params
+
+__all__ = ["Configuration", "AsyncConfiguration"]
+
+
+class Configuration(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> ConfigurationWithRawResponse:
+ return ConfigurationWithRawResponse(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,
+ ) -> ConfigurationRetrieveResponse:
+ """Get configurations for sandbox jobs"""
+ return self._get(
+ "/sandbox/jobs/configuration",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ConfigurationRetrieveResponse,
+ )
+
+ def update(
+ self,
+ *,
+ completion_status: Literal["complete", "reauth_error", "permissions_error", "error"],
+ type: Literal["data_sync_all"],
+ # 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,
+ ) -> SandboxJobConfiguration:
+ """
+ Update configurations for sandbox jobs
+
+ 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
+ """
+ return self._put(
+ "/sandbox/jobs/configuration",
+ body=maybe_transform(
+ {
+ "completion_status": completion_status,
+ "type": type,
+ },
+ configuration_update_params.ConfigurationUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=SandboxJobConfiguration,
+ )
+
+
+class AsyncConfiguration(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncConfigurationWithRawResponse:
+ return AsyncConfigurationWithRawResponse(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,
+ ) -> ConfigurationRetrieveResponse:
+ """Get configurations for sandbox jobs"""
+ return await self._get(
+ "/sandbox/jobs/configuration",
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=ConfigurationRetrieveResponse,
+ )
+
+ async def update(
+ self,
+ *,
+ completion_status: Literal["complete", "reauth_error", "permissions_error", "error"],
+ type: Literal["data_sync_all"],
+ # 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,
+ ) -> SandboxJobConfiguration:
+ """
+ Update configurations for sandbox jobs
+
+ 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
+ """
+ return await self._put(
+ "/sandbox/jobs/configuration",
+ body=maybe_transform(
+ {
+ "completion_status": completion_status,
+ "type": type,
+ },
+ configuration_update_params.ConfigurationUpdateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=SandboxJobConfiguration,
+ )
+
+
+class ConfigurationWithRawResponse:
+ def __init__(self, configuration: Configuration) -> None:
+ self.retrieve = to_raw_response_wrapper(
+ configuration.retrieve,
+ )
+ self.update = to_raw_response_wrapper(
+ configuration.update,
+ )
+
+
+class AsyncConfigurationWithRawResponse:
+ def __init__(self, configuration: AsyncConfiguration) -> None:
+ self.retrieve = async_to_raw_response_wrapper(
+ configuration.retrieve,
+ )
+ self.update = async_to_raw_response_wrapper(
+ configuration.update,
+ )
diff --git a/src/finch/resources/sandbox/jobs/jobs.py b/src/finch/resources/sandbox/jobs/jobs.py
new file mode 100644
index 00000000..3f45e345
--- /dev/null
+++ b/src/finch/resources/sandbox/jobs/jobs.py
@@ -0,0 +1,44 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from ...._compat import cached_property
+from ...._resource import SyncAPIResource, AsyncAPIResource
+from .configuration import (
+ Configuration,
+ AsyncConfiguration,
+ ConfigurationWithRawResponse,
+ AsyncConfigurationWithRawResponse,
+)
+
+__all__ = ["Jobs", "AsyncJobs"]
+
+
+class Jobs(SyncAPIResource):
+ @cached_property
+ def configuration(self) -> Configuration:
+ return Configuration(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> JobsWithRawResponse:
+ return JobsWithRawResponse(self)
+
+
+class AsyncJobs(AsyncAPIResource):
+ @cached_property
+ def configuration(self) -> AsyncConfiguration:
+ return AsyncConfiguration(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> AsyncJobsWithRawResponse:
+ return AsyncJobsWithRawResponse(self)
+
+
+class JobsWithRawResponse:
+ def __init__(self, jobs: Jobs) -> None:
+ self.configuration = ConfigurationWithRawResponse(jobs.configuration)
+
+
+class AsyncJobsWithRawResponse:
+ def __init__(self, jobs: AsyncJobs) -> None:
+ self.configuration = AsyncConfigurationWithRawResponse(jobs.configuration)
diff --git a/src/finch/resources/sandbox/payment.py b/src/finch/resources/sandbox/payment.py
new file mode 100644
index 00000000..18753bd6
--- /dev/null
+++ b/src/finch/resources/sandbox/payment.py
@@ -0,0 +1,127 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from typing import List
+
+import httpx
+
+from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven
+from ..._utils import maybe_transform
+from ..._compat import cached_property
+from ..._resource import SyncAPIResource, AsyncAPIResource
+from ..._response import to_raw_response_wrapper, async_to_raw_response_wrapper
+from ..._base_client import (
+ make_request_options,
+)
+from ...types.sandbox import PaymentCreateResponse, payment_create_params
+
+__all__ = ["Payment", "AsyncPayment"]
+
+
+class Payment(SyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> PaymentWithRawResponse:
+ return PaymentWithRawResponse(self)
+
+ def create(
+ self,
+ *,
+ end_date: str | NotGiven = NOT_GIVEN,
+ pay_statements: List[payment_create_params.PayStatement] | NotGiven = NOT_GIVEN,
+ start_date: str | NotGiven = NOT_GIVEN,
+ # 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,
+ ) -> PaymentCreateResponse:
+ """
+ Add a new sandbox payment
+
+ 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
+ """
+ return self._post(
+ "/sandbox/payment",
+ body=maybe_transform(
+ {
+ "end_date": end_date,
+ "pay_statements": pay_statements,
+ "start_date": start_date,
+ },
+ payment_create_params.PaymentCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=PaymentCreateResponse,
+ )
+
+
+class AsyncPayment(AsyncAPIResource):
+ @cached_property
+ def with_raw_response(self) -> AsyncPaymentWithRawResponse:
+ return AsyncPaymentWithRawResponse(self)
+
+ async def create(
+ self,
+ *,
+ end_date: str | NotGiven = NOT_GIVEN,
+ pay_statements: List[payment_create_params.PayStatement] | NotGiven = NOT_GIVEN,
+ start_date: str | NotGiven = NOT_GIVEN,
+ # 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,
+ ) -> PaymentCreateResponse:
+ """
+ Add a new sandbox payment
+
+ 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
+ """
+ return await self._post(
+ "/sandbox/payment",
+ body=maybe_transform(
+ {
+ "end_date": end_date,
+ "pay_statements": pay_statements,
+ "start_date": start_date,
+ },
+ payment_create_params.PaymentCreateParams,
+ ),
+ options=make_request_options(
+ extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout
+ ),
+ cast_to=PaymentCreateResponse,
+ )
+
+
+class PaymentWithRawResponse:
+ def __init__(self, payment: Payment) -> None:
+ self.create = to_raw_response_wrapper(
+ payment.create,
+ )
+
+
+class AsyncPaymentWithRawResponse:
+ def __init__(self, payment: AsyncPayment) -> None:
+ self.create = async_to_raw_response_wrapper(
+ payment.create,
+ )
diff --git a/src/finch/resources/sandbox/sandbox.py b/src/finch/resources/sandbox/sandbox.py
new file mode 100644
index 00000000..23b1994d
--- /dev/null
+++ b/src/finch/resources/sandbox/sandbox.py
@@ -0,0 +1,107 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from .jobs import Jobs, AsyncJobs, JobsWithRawResponse, AsyncJobsWithRawResponse
+from .company import Company, AsyncCompany, CompanyWithRawResponse, AsyncCompanyWithRawResponse
+from .payment import Payment, AsyncPayment, PaymentWithRawResponse, AsyncPaymentWithRawResponse
+from ..._compat import cached_property
+from .directory import Directory, AsyncDirectory, DirectoryWithRawResponse, AsyncDirectoryWithRawResponse
+from .jobs.jobs import Jobs, AsyncJobs
+from .employment import Employment, AsyncEmployment, EmploymentWithRawResponse, AsyncEmploymentWithRawResponse
+from .individual import Individual, AsyncIndividual, IndividualWithRawResponse, AsyncIndividualWithRawResponse
+from ..._resource import SyncAPIResource, AsyncAPIResource
+from .connections import Connections, AsyncConnections, ConnectionsWithRawResponse, AsyncConnectionsWithRawResponse
+from .connections.connections import Connections, AsyncConnections
+
+__all__ = ["Sandbox", "AsyncSandbox"]
+
+
+class Sandbox(SyncAPIResource):
+ @cached_property
+ def connections(self) -> Connections:
+ return Connections(self._client)
+
+ @cached_property
+ def company(self) -> Company:
+ return Company(self._client)
+
+ @cached_property
+ def directory(self) -> Directory:
+ return Directory(self._client)
+
+ @cached_property
+ def individual(self) -> Individual:
+ return Individual(self._client)
+
+ @cached_property
+ def employment(self) -> Employment:
+ return Employment(self._client)
+
+ @cached_property
+ def payment(self) -> Payment:
+ return Payment(self._client)
+
+ @cached_property
+ def jobs(self) -> Jobs:
+ return Jobs(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> SandboxWithRawResponse:
+ return SandboxWithRawResponse(self)
+
+
+class AsyncSandbox(AsyncAPIResource):
+ @cached_property
+ def connections(self) -> AsyncConnections:
+ return AsyncConnections(self._client)
+
+ @cached_property
+ def company(self) -> AsyncCompany:
+ return AsyncCompany(self._client)
+
+ @cached_property
+ def directory(self) -> AsyncDirectory:
+ return AsyncDirectory(self._client)
+
+ @cached_property
+ def individual(self) -> AsyncIndividual:
+ return AsyncIndividual(self._client)
+
+ @cached_property
+ def employment(self) -> AsyncEmployment:
+ return AsyncEmployment(self._client)
+
+ @cached_property
+ def payment(self) -> AsyncPayment:
+ return AsyncPayment(self._client)
+
+ @cached_property
+ def jobs(self) -> AsyncJobs:
+ return AsyncJobs(self._client)
+
+ @cached_property
+ def with_raw_response(self) -> AsyncSandboxWithRawResponse:
+ return AsyncSandboxWithRawResponse(self)
+
+
+class SandboxWithRawResponse:
+ def __init__(self, sandbox: Sandbox) -> None:
+ self.connections = ConnectionsWithRawResponse(sandbox.connections)
+ self.company = CompanyWithRawResponse(sandbox.company)
+ self.directory = DirectoryWithRawResponse(sandbox.directory)
+ self.individual = IndividualWithRawResponse(sandbox.individual)
+ self.employment = EmploymentWithRawResponse(sandbox.employment)
+ self.payment = PaymentWithRawResponse(sandbox.payment)
+ self.jobs = JobsWithRawResponse(sandbox.jobs)
+
+
+class AsyncSandboxWithRawResponse:
+ def __init__(self, sandbox: AsyncSandbox) -> None:
+ self.connections = AsyncConnectionsWithRawResponse(sandbox.connections)
+ self.company = AsyncCompanyWithRawResponse(sandbox.company)
+ self.directory = AsyncDirectoryWithRawResponse(sandbox.directory)
+ self.individual = AsyncIndividualWithRawResponse(sandbox.individual)
+ self.employment = AsyncEmploymentWithRawResponse(sandbox.employment)
+ self.payment = AsyncPaymentWithRawResponse(sandbox.payment)
+ self.jobs = AsyncJobsWithRawResponse(sandbox.jobs)
diff --git a/src/finch/types/__init__.py b/src/finch/types/__init__.py
index e8b6a6dd..aaa3cad1 100644
--- a/src/finch/types/__init__.py
+++ b/src/finch/types/__init__.py
@@ -8,11 +8,16 @@
Paging as Paging,
OperationSupport as OperationSupport,
OperationSupportMatrix as OperationSupportMatrix,
+ IntrospectResponseConnectionStatus as IntrospectResponseConnectionStatus,
)
from .location import Location as Location
from .provider import Provider as Provider
+from .money_param import MoneyParam as MoneyParam
+from .income_param import IncomeParam as IncomeParam
from .introspection import Introspection as Introspection
+from .location_param import LocationParam as LocationParam
from .disconnect_response import DisconnectResponse as DisconnectResponse
+from .auth_create_token_params import AuthCreateTokenParams as AuthCreateTokenParams
from .access_token_create_params import AccessTokenCreateParams as AccessTokenCreateParams
from .create_access_token_response import CreateAccessTokenResponse as CreateAccessTokenResponse
from .request_forwarding_forward_params import RequestForwardingForwardParams as RequestForwardingForwardParams
diff --git a/src/finch/types/auth_create_token_params.py b/src/finch/types/auth_create_token_params.py
new file mode 100644
index 00000000..9cce752f
--- /dev/null
+++ b/src/finch/types/auth_create_token_params.py
@@ -0,0 +1,17 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from typing_extensions import Required, TypedDict
+
+__all__ = ["AuthCreateTokenParams"]
+
+
+class AuthCreateTokenParams(TypedDict, total=False):
+ client_id: Required[str]
+
+ client_secret: Required[str]
+
+ code: Required[str]
+
+ redirect_uri: Required[str]
diff --git a/src/finch/types/income_param.py b/src/finch/types/income_param.py
new file mode 100644
index 00000000..5c378edd
--- /dev/null
+++ b/src/finch/types/income_param.py
@@ -0,0 +1,28 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from typing import Optional
+from typing_extensions import Literal, TypedDict
+
+__all__ = ["IncomeParam"]
+
+
+class IncomeParam(TypedDict, total=False):
+ amount: Optional[int]
+ """The income amount in cents."""
+
+ currency: Optional[str]
+ """The currency code."""
+
+ effective_date: Optional[str]
+ """The date the income amount went into effect."""
+
+ unit: Optional[
+ Literal["yearly", "quarterly", "monthly", "semi_monthly", "bi_weekly", "weekly", "daily", "hourly", "fixed"]
+ ]
+ """The income unit of payment.
+
+ Options: `yearly`, `quarterly`, `monthly`, `semi_monthly`, `bi_weekly`,
+ `weekly`, `daily`, `hourly`, and `fixed`.
+ """
diff --git a/src/finch/types/introspection.py b/src/finch/types/introspection.py
index 41ad1f6c..bdf99fa7 100644
--- a/src/finch/types/introspection.py
+++ b/src/finch/types/introspection.py
@@ -1,17 +1,32 @@
# File generated from our OpenAPI spec by Stainless.
-from typing import List
+from typing import List, Optional
from typing_extensions import Literal
+from .shared import IntrospectResponseConnectionStatus
from .._models import BaseModel
-__all__ = ["Introspection"]
+__all__ = ["Introspection", "AuthenticationMethods", "AuthenticationMethodsConnectionStatus"]
+
+
+class AuthenticationMethodsConnectionStatus(BaseModel):
+ message: Optional[str] = None
+
+ status: Optional[IntrospectResponseConnectionStatus] = None
+
+
+class AuthenticationMethods(BaseModel):
+ connection_status: Optional[AuthenticationMethodsConnectionStatus] = None
+
+ type: Optional[str] = None
class Introspection(BaseModel):
account_id: str
"""The Finch uuid of the account used to connect this company."""
+ authentication_methods: AuthenticationMethods
+
client_id: str
"""The client id of the application associated with the `access_token`."""
diff --git a/src/finch/types/location_param.py b/src/finch/types/location_param.py
new file mode 100644
index 00000000..11f4e33e
--- /dev/null
+++ b/src/finch/types/location_param.py
@@ -0,0 +1,32 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from typing import Optional
+from typing_extensions import TypedDict
+
+__all__ = ["LocationParam"]
+
+
+class LocationParam(TypedDict, total=False):
+ city: Optional[str]
+ """City, district, suburb, town, or village."""
+
+ country: Optional[str]
+ """The 2-letter ISO 3166 country code."""
+
+ line1: Optional[str]
+ """Street address or PO box."""
+
+ line2: Optional[str]
+ """Apartment, suite, unit, or building."""
+
+ name: Optional[str]
+
+ postal_code: Optional[str]
+ """The postal code or zip code."""
+
+ source_id: Optional[str]
+
+ state: Optional[str]
+ """The state code."""
diff --git a/src/finch/types/money_param.py b/src/finch/types/money_param.py
new file mode 100644
index 00000000..6d86df6c
--- /dev/null
+++ b/src/finch/types/money_param.py
@@ -0,0 +1,15 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from typing import Optional
+from typing_extensions import TypedDict
+
+__all__ = ["MoneyParam"]
+
+
+class MoneyParam(TypedDict, total=False):
+ amount: Optional[int]
+ """Amount for money object (in cents)"""
+
+ currency: str
diff --git a/src/finch/types/sandbox/__init__.py b/src/finch/types/sandbox/__init__.py
new file mode 100644
index 00000000..74361b09
--- /dev/null
+++ b/src/finch/types/sandbox/__init__.py
@@ -0,0 +1,16 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from .company_update_params import CompanyUpdateParams as CompanyUpdateParams
+from .payment_create_params import PaymentCreateParams as PaymentCreateParams
+from .company_update_response import CompanyUpdateResponse as CompanyUpdateResponse
+from .directory_create_params import DirectoryCreateParams as DirectoryCreateParams
+from .payment_create_response import PaymentCreateResponse as PaymentCreateResponse
+from .connection_create_params import ConnectionCreateParams as ConnectionCreateParams
+from .employment_update_params import EmploymentUpdateParams as EmploymentUpdateParams
+from .individual_update_params import IndividualUpdateParams as IndividualUpdateParams
+from .directory_create_response import DirectoryCreateResponse as DirectoryCreateResponse
+from .connection_create_response import ConnectionCreateResponse as ConnectionCreateResponse
+from .employment_update_response import EmploymentUpdateResponse as EmploymentUpdateResponse
+from .individual_update_response import IndividualUpdateResponse as IndividualUpdateResponse
diff --git a/src/finch/types/sandbox/company_update_params.py b/src/finch/types/sandbox/company_update_params.py
new file mode 100644
index 00000000..1141ca6a
--- /dev/null
+++ b/src/finch/types/sandbox/company_update_params.py
@@ -0,0 +1,76 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from typing import List, Optional
+from typing_extensions import Literal, Required, TypedDict
+
+from ..location_param import LocationParam
+
+__all__ = ["CompanyUpdateParams", "Account", "Department", "DepartmentParent", "Entity"]
+
+
+class CompanyUpdateParams(TypedDict, total=False):
+ accounts: Required[Optional[List[Account]]]
+ """An array of bank account objects associated with the payroll/HRIS system."""
+
+ departments: Required[Optional[List[Optional[Department]]]]
+ """The array of company departments."""
+
+ ein: Required[Optional[str]]
+ """The employer identification number."""
+
+ entity: Required[Optional[Entity]]
+ """The entity type object."""
+
+ legal_name: Required[Optional[str]]
+ """The legal name of the company."""
+
+ locations: Required[Optional[List[Optional[LocationParam]]]]
+
+ primary_email: Required[Optional[str]]
+ """The email of the main administrator on the account."""
+
+ primary_phone_number: Required[Optional[str]]
+ """The phone number of the main administrator on the account. Format: `XXXXXXXXXX`"""
+
+
+class Account(TypedDict, total=False):
+ account_name: Optional[str]
+ """The name of the bank associated in the payroll/HRIS system."""
+
+ account_number: Optional[str]
+ """10-12 digit number to specify the bank account"""
+
+ account_type: Optional[Literal["checking", "savings"]]
+ """The type of bank account."""
+
+ institution_name: Optional[str]
+ """Name of the banking institution."""
+
+ routing_number: Optional[str]
+ """A nine-digit code that's based on the U.S.
+
+ Bank location where your account was opened.
+ """
+
+
+class DepartmentParent(TypedDict, total=False):
+ name: Optional[str]
+ """The parent department's name."""
+
+
+class Department(TypedDict, total=False):
+ name: Optional[str]
+ """The department name."""
+
+ parent: Optional[DepartmentParent]
+ """The parent department, if present."""
+
+
+class Entity(TypedDict, total=False):
+ subtype: Optional[Literal["s_corporation", "c_corporation", "b_corporation"]]
+ """The tax payer subtype of the company."""
+
+ type: Optional[Literal["llc", "lp", "corporation", "sole_proprietor", "non_profit", "partnership", "cooperative"]]
+ """The tax payer type of the company."""
diff --git a/src/finch/types/sandbox/company_update_response.py b/src/finch/types/sandbox/company_update_response.py
new file mode 100644
index 00000000..e5a4d2d6
--- /dev/null
+++ b/src/finch/types/sandbox/company_update_response.py
@@ -0,0 +1,77 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from typing import List, Optional
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+from ..location import Location
+
+__all__ = ["CompanyUpdateResponse", "Account", "Department", "DepartmentParent", "Entity"]
+
+
+class Account(BaseModel):
+ account_name: Optional[str] = None
+ """The name of the bank associated in the payroll/HRIS system."""
+
+ account_number: Optional[str] = None
+ """10-12 digit number to specify the bank account"""
+
+ account_type: Optional[Literal["checking", "savings"]] = None
+ """The type of bank account."""
+
+ institution_name: Optional[str] = None
+ """Name of the banking institution."""
+
+ routing_number: Optional[str] = None
+ """A nine-digit code that's based on the U.S.
+
+ Bank location where your account was opened.
+ """
+
+
+class DepartmentParent(BaseModel):
+ name: Optional[str] = None
+ """The parent department's name."""
+
+
+class Department(BaseModel):
+ name: Optional[str] = None
+ """The department name."""
+
+ parent: Optional[DepartmentParent] = None
+ """The parent department, if present."""
+
+
+class Entity(BaseModel):
+ subtype: Optional[Literal["s_corporation", "c_corporation", "b_corporation"]] = None
+ """The tax payer subtype of the company."""
+
+ type: Optional[
+ Literal["llc", "lp", "corporation", "sole_proprietor", "non_profit", "partnership", "cooperative"]
+ ] = None
+ """The tax payer type of the company."""
+
+
+class CompanyUpdateResponse(BaseModel):
+ accounts: Optional[List[Account]] = None
+ """An array of bank account objects associated with the payroll/HRIS system."""
+
+ departments: Optional[List[Optional[Department]]] = None
+ """The array of company departments."""
+
+ ein: Optional[str] = None
+ """The employer identification number."""
+
+ entity: Optional[Entity] = None
+ """The entity type object."""
+
+ legal_name: Optional[str] = None
+ """The legal name of the company."""
+
+ locations: Optional[List[Optional[Location]]] = None
+
+ primary_email: Optional[str] = None
+ """The email of the main administrator on the account."""
+
+ primary_phone_number: Optional[str] = None
+ """The phone number of the main administrator on the account. Format: `XXXXXXXXXX`"""
diff --git a/src/finch/types/sandbox/connection_create_params.py b/src/finch/types/sandbox/connection_create_params.py
new file mode 100644
index 00000000..bd2908e8
--- /dev/null
+++ b/src/finch/types/sandbox/connection_create_params.py
@@ -0,0 +1,22 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from typing import List
+from typing_extensions import Literal, Required, TypedDict
+
+__all__ = ["ConnectionCreateParams"]
+
+
+class ConnectionCreateParams(TypedDict, total=False):
+ provider_id: Required[str]
+
+ authentication_type: Literal["credentials", "api_token", "oauth", "assisted"]
+
+ employer_size: int
+ """Optional: the size of the employer to be created with this connection.
+
+ Defaults to 20
+ """
+
+ products: List[str]
diff --git a/src/finch/types/sandbox/connection_create_response.py b/src/finch/types/sandbox/connection_create_response.py
new file mode 100644
index 00000000..bc31f5b5
--- /dev/null
+++ b/src/finch/types/sandbox/connection_create_response.py
@@ -0,0 +1,22 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from typing import List
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+
+__all__ = ["ConnectionCreateResponse"]
+
+
+class ConnectionCreateResponse(BaseModel):
+ access_token: str
+
+ account_id: str
+
+ authentication_type: Literal["credentials", "api_token", "oauth", "assisted"]
+
+ company_id: str
+
+ products: List[str]
+
+ provider_id: str
diff --git a/src/finch/types/sandbox/connections/__init__.py b/src/finch/types/sandbox/connections/__init__.py
new file mode 100644
index 00000000..7d68eabb
--- /dev/null
+++ b/src/finch/types/sandbox/connections/__init__.py
@@ -0,0 +1,8 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from .account_create_params import AccountCreateParams as AccountCreateParams
+from .account_update_params import AccountUpdateParams as AccountUpdateParams
+from .account_create_response import AccountCreateResponse as AccountCreateResponse
+from .account_update_response import AccountUpdateResponse as AccountUpdateResponse
diff --git a/src/finch/types/sandbox/connections/account_create_params.py b/src/finch/types/sandbox/connections/account_create_params.py
new file mode 100644
index 00000000..bc6e5bf4
--- /dev/null
+++ b/src/finch/types/sandbox/connections/account_create_params.py
@@ -0,0 +1,22 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from typing import List
+from typing_extensions import Literal, Required, TypedDict
+
+__all__ = ["AccountCreateParams"]
+
+
+class AccountCreateParams(TypedDict, total=False):
+ company_id: Required[str]
+
+ provider_id: Required[str]
+
+ authentication_type: Literal["credentials", "api_token", "oauth", "assisted"]
+
+ products: List[str]
+ """
+ Optional, defaults to Organization products (`company`, `directory`,
+ `employment`, `individual`)
+ """
diff --git a/src/finch/types/sandbox/connections/account_create_response.py b/src/finch/types/sandbox/connections/account_create_response.py
new file mode 100644
index 00000000..5bb2c84f
--- /dev/null
+++ b/src/finch/types/sandbox/connections/account_create_response.py
@@ -0,0 +1,22 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from typing import List
+from typing_extensions import Literal
+
+from ...._models import BaseModel
+
+__all__ = ["AccountCreateResponse"]
+
+
+class AccountCreateResponse(BaseModel):
+ access_token: str
+
+ account_id: str
+
+ authentication_type: Literal["credentials", "api_token", "oauth", "assisted"]
+
+ company_id: str
+
+ products: List[str]
+
+ provider_id: str
diff --git a/src/finch/types/sandbox/connections/account_update_params.py b/src/finch/types/sandbox/connections/account_update_params.py
new file mode 100644
index 00000000..c7af5455
--- /dev/null
+++ b/src/finch/types/sandbox/connections/account_update_params.py
@@ -0,0 +1,13 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from typing_extensions import TypedDict
+
+from ...shared import IntrospectResponseConnectionStatus
+
+__all__ = ["AccountUpdateParams"]
+
+
+class AccountUpdateParams(TypedDict, total=False):
+ connection_status: IntrospectResponseConnectionStatus
diff --git a/src/finch/types/sandbox/connections/account_update_response.py b/src/finch/types/sandbox/connections/account_update_response.py
new file mode 100644
index 00000000..2e8cae7e
--- /dev/null
+++ b/src/finch/types/sandbox/connections/account_update_response.py
@@ -0,0 +1,20 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from typing import List
+from typing_extensions import Literal
+
+from ...._models import BaseModel
+
+__all__ = ["AccountUpdateResponse"]
+
+
+class AccountUpdateResponse(BaseModel):
+ account_id: str
+
+ authentication_type: Literal["credentials", "api_token", "oauth", "assisted"]
+
+ company_id: str
+
+ products: List[str]
+
+ provider_id: str
diff --git a/src/finch/types/sandbox/directory_create_params.py b/src/finch/types/sandbox/directory_create_params.py
new file mode 100644
index 00000000..a1e949fd
--- /dev/null
+++ b/src/finch/types/sandbox/directory_create_params.py
@@ -0,0 +1,166 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from typing import List, Optional
+from typing_extensions import Literal, Required, TypedDict
+
+from ..income_param import IncomeParam
+from ..location_param import LocationParam
+
+__all__ = [
+ "DirectoryCreateParams",
+ "Body",
+ "BodyCustomField",
+ "BodyDepartment",
+ "BodyEmail",
+ "BodyEmployment",
+ "BodyManager",
+ "BodyPhoneNumber",
+]
+
+
+class DirectoryCreateParams(TypedDict, total=False):
+ body: Required[List[Body]]
+ """Array of individuals to create.
+
+ Takes all combined fields from `/individual` and `/employment` endpoints. All
+ fields are optional.
+ """
+
+
+class BodyCustomField(TypedDict, total=False):
+ name: Optional[str]
+
+ value: object
+
+
+class BodyDepartment(TypedDict, total=False):
+ name: Optional[str]
+ """The name of the department associated with the individual."""
+
+
+class BodyEmail(TypedDict, total=False):
+ data: str
+
+ type: Literal["work", "personal"]
+
+
+class BodyEmployment(TypedDict, total=False):
+ subtype: Optional[Literal["full_time", "intern", "part_time", "temp", "seasonal", "individual_contractor"]]
+ """The secondary employment type of the individual.
+
+ Options: `full_time`, `part_time`, `intern`, `temp`, `seasonal` and
+ `individual_contractor`.
+ """
+
+ type: Optional[Literal["employee", "contractor"]]
+ """The main employment type of the individual."""
+
+
+class BodyManager(TypedDict, total=False):
+ id: str
+ """A stable Finch `id` (UUID v4) for an individual in the company."""
+
+
+class BodyPhoneNumber(TypedDict, total=False):
+ data: str
+
+ type: Literal["work", "personal"]
+
+
+class Body(TypedDict, total=False):
+ class_code: Optional[str]
+ """Worker's compensation classification code for this employee"""
+
+ custom_fields: List[BodyCustomField]
+ """Custom fields for the individual.
+
+ These are fields which are defined by the employer in the system. Custom fields
+ are not currently supported for assisted connections.
+ """
+
+ department: Optional[BodyDepartment]
+ """The department object."""
+
+ dob: Optional[str]
+
+ emails: Optional[List[BodyEmail]]
+
+ employment: Optional[BodyEmployment]
+ """The employment object."""
+
+ encrypted_ssn: Optional[str]
+ """Social Security Number of the individual in **encrypted** format.
+
+ This field is only available with the `ssn` scope enabled and the
+ `options: { include: ['ssn'] }` param set in the body.
+ """
+
+ end_date: Optional[str]
+
+ ethnicity: Optional[
+ Literal[
+ "asian",
+ "white",
+ "black_or_african_american",
+ "native_hawaiian_or_pacific_islander",
+ "american_indian_or_alaska_native",
+ "hispanic_or_latino",
+ "two_or_more_races",
+ "decline_to_specify",
+ ]
+ ]
+ """The EEOC-defined ethnicity of the individual."""
+
+ first_name: Optional[str]
+ """The legal first name of the individual."""
+
+ gender: Optional[Literal["female", "male", "other", "decline_to_specify"]]
+ """The gender of the individual."""
+
+ income: Optional[IncomeParam]
+ """The employee's income as reported by the provider.
+
+ This may not always be annualized income, but may be in units of bi-weekly,
+ semi-monthly, daily, etc, depending on what information the provider returns.
+ """
+
+ income_history: Optional[List[Optional[IncomeParam]]]
+ """The array of income history."""
+
+ is_active: Optional[bool]
+ """`true` if the individual an an active employee or contractor at the company."""
+
+ last_name: Optional[str]
+ """The legal last name of the individual."""
+
+ location: Optional[LocationParam]
+
+ manager: Optional[BodyManager]
+ """The manager object representing the manager of the individual within the org."""
+
+ middle_name: Optional[str]
+ """The legal middle name of the individual."""
+
+ phone_numbers: Optional[List[Optional[BodyPhoneNumber]]]
+
+ preferred_name: Optional[str]
+ """The preferred name of the individual."""
+
+ residence: Optional[LocationParam]
+
+ source_id: str
+ """The source system's unique employment identifier for this individual"""
+
+ ssn: Optional[str]
+ """Social Security Number of the individual.
+
+ This field is only available with the `ssn` scope enabled and the
+ `options: { include: ['ssn'] }` param set in the body.
+ """
+
+ start_date: Optional[str]
+
+ title: Optional[str]
+ """The current title of the individual."""
diff --git a/src/finch/types/sandbox/directory_create_response.py b/src/finch/types/sandbox/directory_create_response.py
new file mode 100644
index 00000000..6a0a4025
--- /dev/null
+++ b/src/finch/types/sandbox/directory_create_response.py
@@ -0,0 +1,7 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from typing import List
+
+__all__ = ["DirectoryCreateResponse"]
+
+DirectoryCreateResponse = List[object]
diff --git a/src/finch/types/sandbox/employment_update_params.py b/src/finch/types/sandbox/employment_update_params.py
new file mode 100644
index 00000000..be90cca6
--- /dev/null
+++ b/src/finch/types/sandbox/employment_update_params.py
@@ -0,0 +1,94 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from typing import List, Optional
+from typing_extensions import Literal, TypedDict
+
+from ..income_param import IncomeParam
+from ..location_param import LocationParam
+
+__all__ = ["EmploymentUpdateParams", "CustomField", "Department", "Employment", "Manager"]
+
+
+class EmploymentUpdateParams(TypedDict, total=False):
+ class_code: Optional[str]
+ """Worker's compensation classification code for this employee"""
+
+ custom_fields: List[CustomField]
+ """Custom fields for the individual.
+
+ These are fields which are defined by the employer in the system. Custom fields
+ are not currently supported for assisted connections.
+ """
+
+ department: Optional[Department]
+ """The department object."""
+
+ employment: Optional[Employment]
+ """The employment object."""
+
+ end_date: Optional[str]
+
+ first_name: Optional[str]
+ """The legal first name of the individual."""
+
+ income: Optional[IncomeParam]
+ """The employee's income as reported by the provider.
+
+ This may not always be annualized income, but may be in units of bi-weekly,
+ semi-monthly, daily, etc, depending on what information the provider returns.
+ """
+
+ income_history: Optional[List[Optional[IncomeParam]]]
+ """The array of income history."""
+
+ is_active: Optional[bool]
+ """`true` if the individual an an active employee or contractor at the company."""
+
+ last_name: Optional[str]
+ """The legal last name of the individual."""
+
+ location: Optional[LocationParam]
+
+ manager: Optional[Manager]
+ """The manager object representing the manager of the individual within the org."""
+
+ middle_name: Optional[str]
+ """The legal middle name of the individual."""
+
+ source_id: str
+ """The source system's unique employment identifier for this individual"""
+
+ start_date: Optional[str]
+
+ title: Optional[str]
+ """The current title of the individual."""
+
+
+class CustomField(TypedDict, total=False):
+ name: Optional[str]
+
+ value: object
+
+
+class Department(TypedDict, total=False):
+ name: Optional[str]
+ """The name of the department associated with the individual."""
+
+
+class Employment(TypedDict, total=False):
+ subtype: Optional[Literal["full_time", "intern", "part_time", "temp", "seasonal", "individual_contractor"]]
+ """The secondary employment type of the individual.
+
+ Options: `full_time`, `part_time`, `intern`, `temp`, `seasonal` and
+ `individual_contractor`.
+ """
+
+ type: Optional[Literal["employee", "contractor"]]
+ """The main employment type of the individual."""
+
+
+class Manager(TypedDict, total=False):
+ id: str
+ """A stable Finch `id` (UUID v4) for an individual in the company."""
diff --git a/src/finch/types/sandbox/employment_update_response.py b/src/finch/types/sandbox/employment_update_response.py
new file mode 100644
index 00000000..796aa25d
--- /dev/null
+++ b/src/finch/types/sandbox/employment_update_response.py
@@ -0,0 +1,96 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from typing import List, Optional
+from typing_extensions import Literal
+
+from ..income import Income
+from ..._models import BaseModel
+from ..location import Location
+
+__all__ = ["EmploymentUpdateResponse", "CustomField", "Department", "Employment", "Manager"]
+
+
+class CustomField(BaseModel):
+ name: Optional[str] = None
+
+ value: Optional[object] = None
+
+
+class Department(BaseModel):
+ name: Optional[str] = None
+ """The name of the department associated with the individual."""
+
+
+class Employment(BaseModel):
+ subtype: Optional[Literal["full_time", "intern", "part_time", "temp", "seasonal", "individual_contractor"]] = None
+ """The secondary employment type of the individual.
+
+ Options: `full_time`, `part_time`, `intern`, `temp`, `seasonal` and
+ `individual_contractor`.
+ """
+
+ type: Optional[Literal["employee", "contractor"]] = None
+ """The main employment type of the individual."""
+
+
+class Manager(BaseModel):
+ id: Optional[str] = None
+ """A stable Finch `id` (UUID v4) for an individual in the company."""
+
+
+class EmploymentUpdateResponse(BaseModel):
+ id: Optional[str] = None
+ """A stable Finch `id` (UUID v4) for an individual in the company."""
+
+ class_code: Optional[str] = None
+ """Worker's compensation classification code for this employee"""
+
+ custom_fields: Optional[List[CustomField]] = None
+ """Custom fields for the individual.
+
+ These are fields which are defined by the employer in the system. Custom fields
+ are not currently supported for assisted connections.
+ """
+
+ department: Optional[Department] = None
+ """The department object."""
+
+ employment: Optional[Employment] = None
+ """The employment object."""
+
+ end_date: Optional[str] = None
+
+ first_name: Optional[str] = None
+ """The legal first name of the individual."""
+
+ income_history: Optional[List[Optional[Income]]] = None
+ """The array of income history."""
+
+ income: Optional[Income] = None
+ """The employee's income as reported by the provider.
+
+ This may not always be annualized income, but may be in units of bi-weekly,
+ semi-monthly, daily, etc, depending on what information the provider returns.
+ """
+
+ is_active: Optional[bool] = None
+ """`true` if the individual an an active employee or contractor at the company."""
+
+ last_name: Optional[str] = None
+ """The legal last name of the individual."""
+
+ location: Optional[Location] = None
+
+ manager: Optional[Manager] = None
+ """The manager object representing the manager of the individual within the org."""
+
+ middle_name: Optional[str] = None
+ """The legal middle name of the individual."""
+
+ source_id: Optional[str] = None
+ """The source system's unique employment identifier for this individual"""
+
+ start_date: Optional[str] = None
+
+ title: Optional[str] = None
+ """The current title of the individual."""
diff --git a/src/finch/types/sandbox/individual_update_params.py b/src/finch/types/sandbox/individual_update_params.py
new file mode 100644
index 00000000..8e40198e
--- /dev/null
+++ b/src/finch/types/sandbox/individual_update_params.py
@@ -0,0 +1,75 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from typing import List, Optional
+from typing_extensions import Literal, TypedDict
+
+from ..location_param import LocationParam
+
+__all__ = ["IndividualUpdateParams", "Email", "PhoneNumber"]
+
+
+class IndividualUpdateParams(TypedDict, total=False):
+ dob: Optional[str]
+
+ emails: Optional[List[Email]]
+
+ encrypted_ssn: Optional[str]
+ """Social Security Number of the individual in **encrypted** format.
+
+ This field is only available with the `ssn` scope enabled and the
+ `options: { include: ['ssn'] }` param set in the body.
+ """
+
+ ethnicity: Optional[
+ Literal[
+ "asian",
+ "white",
+ "black_or_african_american",
+ "native_hawaiian_or_pacific_islander",
+ "american_indian_or_alaska_native",
+ "hispanic_or_latino",
+ "two_or_more_races",
+ "decline_to_specify",
+ ]
+ ]
+ """The EEOC-defined ethnicity of the individual."""
+
+ first_name: Optional[str]
+ """The legal first name of the individual."""
+
+ gender: Optional[Literal["female", "male", "other", "decline_to_specify"]]
+ """The gender of the individual."""
+
+ last_name: Optional[str]
+ """The legal last name of the individual."""
+
+ middle_name: Optional[str]
+ """The legal middle name of the individual."""
+
+ phone_numbers: Optional[List[Optional[PhoneNumber]]]
+
+ preferred_name: Optional[str]
+ """The preferred name of the individual."""
+
+ residence: Optional[LocationParam]
+
+ ssn: Optional[str]
+ """Social Security Number of the individual.
+
+ This field is only available with the `ssn` scope enabled and the
+ `options: { include: ['ssn'] }` param set in the body.
+ """
+
+
+class Email(TypedDict, total=False):
+ data: str
+
+ type: Literal["work", "personal"]
+
+
+class PhoneNumber(TypedDict, total=False):
+ data: str
+
+ type: Literal["work", "personal"]
diff --git a/src/finch/types/sandbox/individual_update_response.py b/src/finch/types/sandbox/individual_update_response.py
new file mode 100644
index 00000000..4db655e1
--- /dev/null
+++ b/src/finch/types/sandbox/individual_update_response.py
@@ -0,0 +1,77 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from typing import List, Optional
+from typing_extensions import Literal
+
+from ..._models import BaseModel
+from ..location import Location
+
+__all__ = ["IndividualUpdateResponse", "Email", "PhoneNumber"]
+
+
+class Email(BaseModel):
+ data: Optional[str] = None
+
+ type: Optional[Literal["work", "personal"]] = None
+
+
+class PhoneNumber(BaseModel):
+ data: Optional[str] = None
+
+ type: Optional[Literal["work", "personal"]] = None
+
+
+class IndividualUpdateResponse(BaseModel):
+ id: Optional[str] = None
+ """A stable Finch `id` (UUID v4) for an individual in the company."""
+
+ dob: Optional[str] = None
+
+ emails: Optional[List[Email]] = None
+
+ encrypted_ssn: Optional[str] = None
+ """Social Security Number of the individual in **encrypted** format.
+
+ This field is only available with the `ssn` scope enabled and the
+ `options: { include: ['ssn'] }` param set in the body.
+ """
+
+ ethnicity: Optional[
+ Literal[
+ "asian",
+ "white",
+ "black_or_african_american",
+ "native_hawaiian_or_pacific_islander",
+ "american_indian_or_alaska_native",
+ "hispanic_or_latino",
+ "two_or_more_races",
+ "decline_to_specify",
+ ]
+ ] = None
+ """The EEOC-defined ethnicity of the individual."""
+
+ first_name: Optional[str] = None
+ """The legal first name of the individual."""
+
+ gender: Optional[Literal["female", "male", "other", "decline_to_specify"]] = None
+ """The gender of the individual."""
+
+ last_name: Optional[str] = None
+ """The legal last name of the individual."""
+
+ middle_name: Optional[str] = None
+ """The legal middle name of the individual."""
+
+ phone_numbers: Optional[List[Optional[PhoneNumber]]] = None
+
+ preferred_name: Optional[str] = None
+ """The preferred name of the individual."""
+
+ residence: Optional[Location] = None
+
+ ssn: Optional[str] = None
+ """Social Security Number of the individual.
+
+ This field is only available with the `ssn` scope enabled and the
+ `options: { include: ['ssn'] }` param set in the body.
+ """
diff --git a/src/finch/types/sandbox/jobs/__init__.py b/src/finch/types/sandbox/jobs/__init__.py
new file mode 100644
index 00000000..cec01f2e
--- /dev/null
+++ b/src/finch/types/sandbox/jobs/__init__.py
@@ -0,0 +1,7 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from .sandbox_job_configuration import SandboxJobConfiguration as SandboxJobConfiguration
+from .configuration_update_params import ConfigurationUpdateParams as ConfigurationUpdateParams
+from .configuration_retrieve_response import ConfigurationRetrieveResponse as ConfigurationRetrieveResponse
diff --git a/src/finch/types/sandbox/jobs/configuration_retrieve_response.py b/src/finch/types/sandbox/jobs/configuration_retrieve_response.py
new file mode 100644
index 00000000..e46121ab
--- /dev/null
+++ b/src/finch/types/sandbox/jobs/configuration_retrieve_response.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from typing import List
+
+from .sandbox_job_configuration import SandboxJobConfiguration
+
+__all__ = ["ConfigurationRetrieveResponse"]
+
+ConfigurationRetrieveResponse = List[SandboxJobConfiguration]
diff --git a/src/finch/types/sandbox/jobs/configuration_update_params.py b/src/finch/types/sandbox/jobs/configuration_update_params.py
new file mode 100644
index 00000000..5a4955e6
--- /dev/null
+++ b/src/finch/types/sandbox/jobs/configuration_update_params.py
@@ -0,0 +1,13 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from typing_extensions import Literal, Required, TypedDict
+
+__all__ = ["ConfigurationUpdateParams"]
+
+
+class ConfigurationUpdateParams(TypedDict, total=False):
+ completion_status: Required[Literal["complete", "reauth_error", "permissions_error", "error"]]
+
+ type: Required[Literal["data_sync_all"]]
diff --git a/src/finch/types/sandbox/jobs/sandbox_job_configuration.py b/src/finch/types/sandbox/jobs/sandbox_job_configuration.py
new file mode 100644
index 00000000..ff1be519
--- /dev/null
+++ b/src/finch/types/sandbox/jobs/sandbox_job_configuration.py
@@ -0,0 +1,13 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from typing_extensions import Literal
+
+from ...._models import BaseModel
+
+__all__ = ["SandboxJobConfiguration"]
+
+
+class SandboxJobConfiguration(BaseModel):
+ completion_status: Literal["complete", "reauth_error", "permissions_error", "error"]
+
+ type: Literal["data_sync_all"]
diff --git a/src/finch/types/sandbox/payment_create_params.py b/src/finch/types/sandbox/payment_create_params.py
new file mode 100644
index 00000000..47587206
--- /dev/null
+++ b/src/finch/types/sandbox/payment_create_params.py
@@ -0,0 +1,140 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from typing import List, Optional
+from typing_extensions import Literal, TypedDict
+
+from ..hris import BenefitType
+from ..money_param import MoneyParam
+
+__all__ = [
+ "PaymentCreateParams",
+ "PayStatement",
+ "PayStatementEarning",
+ "PayStatementEmployeeDeduction",
+ "PayStatementEmployerContribution",
+ "PayStatementTax",
+]
+
+
+class PaymentCreateParams(TypedDict, total=False):
+ end_date: str
+
+ pay_statements: List[PayStatement]
+
+ start_date: str
+
+
+class PayStatementEarning(TypedDict, total=False):
+ amount: Optional[int]
+ """The earnings amount in cents."""
+
+ currency: Optional[str]
+ """The earnings currency code."""
+
+ hours: Optional[float]
+ """The number of hours associated with this earning.
+
+ (For salaried employees, this could be hours per pay period, `0` or `null`,
+ depending on the provider).
+ """
+
+ name: Optional[str]
+ """The exact name of the deduction from the pay statement."""
+
+ type: Optional[
+ Literal[
+ "salary",
+ "wage",
+ "reimbursement",
+ "overtime",
+ "severance",
+ "double_overtime",
+ "pto",
+ "sick",
+ "bonus",
+ "commission",
+ "tips",
+ "1099",
+ "other",
+ ]
+ ]
+ """The type of earning."""
+
+
+class PayStatementEmployeeDeduction(TypedDict, total=False):
+ amount: Optional[int]
+ """The deduction amount in cents."""
+
+ currency: Optional[str]
+ """The deduction currency."""
+
+ name: Optional[str]
+ """The deduction name from the pay statement."""
+
+ pre_tax: Optional[bool]
+ """Boolean indicating if the deduction is pre-tax."""
+
+ type: Optional[BenefitType]
+ """Type of benefit."""
+
+
+class PayStatementEmployerContribution(TypedDict, total=False):
+ amount: Optional[int]
+ """The contribution amount in cents."""
+
+ currency: Optional[str]
+ """The contribution currency."""
+
+ name: Optional[str]
+ """The contribution name from the pay statement."""
+
+ type: Optional[BenefitType]
+ """Type of benefit."""
+
+
+class PayStatementTax(TypedDict, total=False):
+ amount: Optional[int]
+ """The tax amount in cents."""
+
+ currency: Optional[str]
+ """The currency code."""
+
+ employer: Optional[bool]
+ """`true` if the amount is paid by the employers."""
+
+ name: Optional[str]
+ """The exact name of tax from the pay statement."""
+
+ type: Optional[Literal["state", "federal", "local", "fica"]]
+ """The type of taxes."""
+
+
+class PayStatement(TypedDict, total=False):
+ earnings: Optional[List[Optional[PayStatementEarning]]]
+ """The array of earnings objects associated with this pay statement"""
+
+ employee_deductions: Optional[List[Optional[PayStatementEmployeeDeduction]]]
+ """The array of deductions objects associated with this pay statement."""
+
+ employer_contributions: Optional[List[Optional[PayStatementEmployerContribution]]]
+
+ gross_pay: Optional[MoneyParam]
+
+ individual_id: str
+ """A stable Finch `id` (UUID v4) for an individual in the company"""
+
+ net_pay: Optional[MoneyParam]
+
+ payment_method: Optional[Literal["check", "direct_deposit"]]
+ """The payment method."""
+
+ taxes: Optional[List[Optional[PayStatementTax]]]
+ """The array of taxes objects associated with this pay statement."""
+
+ total_hours: Optional[float]
+ """The number of hours worked for this pay period"""
+
+ type: Optional[Literal["regular_payroll", "off_cycle_payroll", "one_time_payment"]]
+ """The type of the payment associated with the pay statement."""
diff --git a/src/finch/types/sandbox/payment_create_response.py b/src/finch/types/sandbox/payment_create_response.py
new file mode 100644
index 00000000..4e3bcf57
--- /dev/null
+++ b/src/finch/types/sandbox/payment_create_response.py
@@ -0,0 +1,13 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from ..._models import BaseModel
+
+__all__ = ["PaymentCreateResponse"]
+
+
+class PaymentCreateResponse(BaseModel):
+ pay_date: str
+ """The date of the payment."""
+
+ payment_id: str
+ """The ID of the payment."""
diff --git a/src/finch/types/shared/__init__.py b/src/finch/types/shared/__init__.py
index 6c699bd7..8aada49c 100644
--- a/src/finch/types/shared/__init__.py
+++ b/src/finch/types/shared/__init__.py
@@ -3,3 +3,6 @@
from .paging import Paging as Paging
from .operation_support import OperationSupport as OperationSupport
from .operation_support_matrix import OperationSupportMatrix as OperationSupportMatrix
+from .introspect_response_connection_status import (
+ IntrospectResponseConnectionStatus as IntrospectResponseConnectionStatus,
+)
diff --git a/src/finch/types/shared/introspect_response_connection_status.py b/src/finch/types/shared/introspect_response_connection_status.py
new file mode 100644
index 00000000..bd418208
--- /dev/null
+++ b/src/finch/types/shared/introspect_response_connection_status.py
@@ -0,0 +1,9 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from typing_extensions import Literal
+
+__all__ = ["IntrospectResponseConnectionStatus"]
+
+IntrospectResponseConnectionStatus = Literal[
+ "pending", "processing", "connected", "error_no_account_setup", "error_permissions", "reauth"
+]
diff --git a/src/finch/types/shared_params/__init__.py b/src/finch/types/shared_params/__init__.py
new file mode 100644
index 00000000..aa9fdc38
--- /dev/null
+++ b/src/finch/types/shared_params/__init__.py
@@ -0,0 +1,5 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from .introspect_response_connection_status import (
+ IntrospectResponseConnectionStatus as IntrospectResponseConnectionStatus,
+)
diff --git a/src/finch/types/shared_params/introspect_response_connection_status.py b/src/finch/types/shared_params/introspect_response_connection_status.py
new file mode 100644
index 00000000..02ca322c
--- /dev/null
+++ b/src/finch/types/shared_params/introspect_response_connection_status.py
@@ -0,0 +1,11 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+from typing_extensions import Literal
+
+__all__ = ["IntrospectResponseConnectionStatus"]
+
+IntrospectResponseConnectionStatus = Literal[
+ "pending", "processing", "connected", "error_no_account_setup", "error_permissions", "reauth"
+]
diff --git a/tests/api_resources/hris/test_pay_statements.py b/tests/api_resources/hris/test_pay_statements.py
index bc6b3d39..ec2cac24 100644
--- a/tests/api_resources/hris/test_pay_statements.py
+++ b/tests/api_resources/hris/test_pay_statements.py
@@ -24,22 +24,14 @@ class TestPayStatements:
@parametrize
def test_method_retrieve_many(self, client: Finch) -> None:
pay_statement = client.hris.pay_statements.retrieve_many(
- requests=[
- {"payment_id": "e8b90071-0c11-471c-86e8-e303ef2f6782"},
- {"payment_id": "e8b90071-0c11-471c-86e8-e303ef2f6782"},
- {"payment_id": "e8b90071-0c11-471c-86e8-e303ef2f6782"},
- ],
+ requests=[{"payment_id": "string"}],
)
assert_matches_type(SyncResponsesPage[PayStatementResponse], pay_statement, path=["response"])
@parametrize
def test_raw_response_retrieve_many(self, client: Finch) -> None:
response = client.hris.pay_statements.with_raw_response.retrieve_many(
- requests=[
- {"payment_id": "e8b90071-0c11-471c-86e8-e303ef2f6782"},
- {"payment_id": "e8b90071-0c11-471c-86e8-e303ef2f6782"},
- {"payment_id": "e8b90071-0c11-471c-86e8-e303ef2f6782"},
- ],
+ requests=[{"payment_id": "string"}],
)
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
pay_statement = response.parse()
@@ -54,22 +46,14 @@ class TestAsyncPayStatements:
@parametrize
async def test_method_retrieve_many(self, client: AsyncFinch) -> None:
pay_statement = await client.hris.pay_statements.retrieve_many(
- requests=[
- {"payment_id": "e8b90071-0c11-471c-86e8-e303ef2f6782"},
- {"payment_id": "e8b90071-0c11-471c-86e8-e303ef2f6782"},
- {"payment_id": "e8b90071-0c11-471c-86e8-e303ef2f6782"},
- ],
+ requests=[{"payment_id": "string"}],
)
assert_matches_type(AsyncResponsesPage[PayStatementResponse], pay_statement, path=["response"])
@parametrize
async def test_raw_response_retrieve_many(self, client: AsyncFinch) -> None:
response = await client.hris.pay_statements.with_raw_response.retrieve_many(
- requests=[
- {"payment_id": "e8b90071-0c11-471c-86e8-e303ef2f6782"},
- {"payment_id": "e8b90071-0c11-471c-86e8-e303ef2f6782"},
- {"payment_id": "e8b90071-0c11-471c-86e8-e303ef2f6782"},
- ],
+ requests=[{"payment_id": "string"}],
)
assert response.http_request.headers.get("X-Stainless-Lang") == "python"
pay_statement = response.parse()
diff --git a/tests/api_resources/sandbox/__init__.py b/tests/api_resources/sandbox/__init__.py
new file mode 100644
index 00000000..1016754e
--- /dev/null
+++ b/tests/api_resources/sandbox/__init__.py
@@ -0,0 +1 @@
+# File generated from our OpenAPI spec by Stainless.
diff --git a/tests/api_resources/sandbox/connections/__init__.py b/tests/api_resources/sandbox/connections/__init__.py
new file mode 100644
index 00000000..1016754e
--- /dev/null
+++ b/tests/api_resources/sandbox/connections/__init__.py
@@ -0,0 +1 @@
+# File generated from our OpenAPI spec by Stainless.
diff --git a/tests/api_resources/sandbox/connections/test_accounts.py b/tests/api_resources/sandbox/connections/test_accounts.py
new file mode 100644
index 00000000..e61edc81
--- /dev/null
+++ b/tests/api_resources/sandbox/connections/test_accounts.py
@@ -0,0 +1,124 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+import os
+
+import pytest
+
+from finch import Finch, AsyncFinch
+from tests.utils import assert_matches_type
+from finch._client import Finch, AsyncFinch
+from finch.types.sandbox.connections import (
+ AccountCreateResponse,
+ AccountUpdateResponse,
+)
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+access_token = "My Access Token"
+
+
+class TestAccounts:
+ strict_client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=True)
+ loose_client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=False)
+ parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"])
+
+ @parametrize
+ def test_method_create(self, client: Finch) -> None:
+ account = client.sandbox.connections.accounts.create(
+ company_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ provider_id="string",
+ )
+ assert_matches_type(AccountCreateResponse, account, path=["response"])
+
+ @parametrize
+ def test_method_create_with_all_params(self, client: Finch) -> None:
+ account = client.sandbox.connections.accounts.create(
+ company_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ provider_id="string",
+ authentication_type="credentials",
+ products=["string", "string", "string"],
+ )
+ assert_matches_type(AccountCreateResponse, account, path=["response"])
+
+ @parametrize
+ def test_raw_response_create(self, client: Finch) -> None:
+ response = client.sandbox.connections.accounts.with_raw_response.create(
+ company_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ provider_id="string",
+ )
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ account = response.parse()
+ assert_matches_type(AccountCreateResponse, account, path=["response"])
+
+ @parametrize
+ def test_method_update(self, client: Finch) -> None:
+ account = client.sandbox.connections.accounts.update()
+ assert_matches_type(AccountUpdateResponse, account, path=["response"])
+
+ @parametrize
+ def test_method_update_with_all_params(self, client: Finch) -> None:
+ account = client.sandbox.connections.accounts.update(
+ connection_status="reauth",
+ )
+ assert_matches_type(AccountUpdateResponse, account, path=["response"])
+
+ @parametrize
+ def test_raw_response_update(self, client: Finch) -> None:
+ response = client.sandbox.connections.accounts.with_raw_response.update()
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ account = response.parse()
+ assert_matches_type(AccountUpdateResponse, account, path=["response"])
+
+
+class TestAsyncAccounts:
+ strict_client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=True)
+ loose_client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=False)
+ parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"])
+
+ @parametrize
+ async def test_method_create(self, client: AsyncFinch) -> None:
+ account = await client.sandbox.connections.accounts.create(
+ company_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ provider_id="string",
+ )
+ assert_matches_type(AccountCreateResponse, account, path=["response"])
+
+ @parametrize
+ async def test_method_create_with_all_params(self, client: AsyncFinch) -> None:
+ account = await client.sandbox.connections.accounts.create(
+ company_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ provider_id="string",
+ authentication_type="credentials",
+ products=["string", "string", "string"],
+ )
+ assert_matches_type(AccountCreateResponse, account, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create(self, client: AsyncFinch) -> None:
+ response = await client.sandbox.connections.accounts.with_raw_response.create(
+ company_id="182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e",
+ provider_id="string",
+ )
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ account = response.parse()
+ assert_matches_type(AccountCreateResponse, account, path=["response"])
+
+ @parametrize
+ async def test_method_update(self, client: AsyncFinch) -> None:
+ account = await client.sandbox.connections.accounts.update()
+ assert_matches_type(AccountUpdateResponse, account, path=["response"])
+
+ @parametrize
+ async def test_method_update_with_all_params(self, client: AsyncFinch) -> None:
+ account = await client.sandbox.connections.accounts.update(
+ connection_status="reauth",
+ )
+ assert_matches_type(AccountUpdateResponse, account, path=["response"])
+
+ @parametrize
+ async def test_raw_response_update(self, client: AsyncFinch) -> None:
+ response = await client.sandbox.connections.accounts.with_raw_response.update()
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ account = response.parse()
+ assert_matches_type(AccountUpdateResponse, account, path=["response"])
diff --git a/tests/api_resources/sandbox/jobs/__init__.py b/tests/api_resources/sandbox/jobs/__init__.py
new file mode 100644
index 00000000..1016754e
--- /dev/null
+++ b/tests/api_resources/sandbox/jobs/__init__.py
@@ -0,0 +1 @@
+# File generated from our OpenAPI spec by Stainless.
diff --git a/tests/api_resources/sandbox/jobs/test_configuration.py b/tests/api_resources/sandbox/jobs/test_configuration.py
new file mode 100644
index 00000000..c9a6f5e2
--- /dev/null
+++ b/tests/api_resources/sandbox/jobs/test_configuration.py
@@ -0,0 +1,87 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+import os
+
+import pytest
+
+from finch import Finch, AsyncFinch
+from tests.utils import assert_matches_type
+from finch._client import Finch, AsyncFinch
+from finch.types.sandbox.jobs import SandboxJobConfiguration, ConfigurationRetrieveResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+access_token = "My Access Token"
+
+
+class TestConfiguration:
+ strict_client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=True)
+ loose_client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=False)
+ parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"])
+
+ @parametrize
+ def test_method_retrieve(self, client: Finch) -> None:
+ configuration = client.sandbox.jobs.configuration.retrieve()
+ assert_matches_type(ConfigurationRetrieveResponse, configuration, path=["response"])
+
+ @parametrize
+ def test_raw_response_retrieve(self, client: Finch) -> None:
+ response = client.sandbox.jobs.configuration.with_raw_response.retrieve()
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ configuration = response.parse()
+ assert_matches_type(ConfigurationRetrieveResponse, configuration, path=["response"])
+
+ @parametrize
+ def test_method_update(self, client: Finch) -> None:
+ configuration = client.sandbox.jobs.configuration.update(
+ completion_status="complete",
+ type="data_sync_all",
+ )
+ assert_matches_type(SandboxJobConfiguration, configuration, path=["response"])
+
+ @parametrize
+ def test_raw_response_update(self, client: Finch) -> None:
+ response = client.sandbox.jobs.configuration.with_raw_response.update(
+ completion_status="complete",
+ type="data_sync_all",
+ )
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ configuration = response.parse()
+ assert_matches_type(SandboxJobConfiguration, configuration, path=["response"])
+
+
+class TestAsyncConfiguration:
+ strict_client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=True)
+ loose_client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=False)
+ parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"])
+
+ @parametrize
+ async def test_method_retrieve(self, client: AsyncFinch) -> None:
+ configuration = await client.sandbox.jobs.configuration.retrieve()
+ assert_matches_type(ConfigurationRetrieveResponse, configuration, path=["response"])
+
+ @parametrize
+ async def test_raw_response_retrieve(self, client: AsyncFinch) -> None:
+ response = await client.sandbox.jobs.configuration.with_raw_response.retrieve()
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ configuration = response.parse()
+ assert_matches_type(ConfigurationRetrieveResponse, configuration, path=["response"])
+
+ @parametrize
+ async def test_method_update(self, client: AsyncFinch) -> None:
+ configuration = await client.sandbox.jobs.configuration.update(
+ completion_status="complete",
+ type="data_sync_all",
+ )
+ assert_matches_type(SandboxJobConfiguration, configuration, path=["response"])
+
+ @parametrize
+ async def test_raw_response_update(self, client: AsyncFinch) -> None:
+ response = await client.sandbox.jobs.configuration.with_raw_response.update(
+ completion_status="complete",
+ type="data_sync_all",
+ )
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ configuration = response.parse()
+ assert_matches_type(SandboxJobConfiguration, configuration, path=["response"])
diff --git a/tests/api_resources/sandbox/test_company.py b/tests/api_resources/sandbox/test_company.py
new file mode 100644
index 00000000..23a76f9c
--- /dev/null
+++ b/tests/api_resources/sandbox/test_company.py
@@ -0,0 +1,253 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+import os
+
+import pytest
+
+from finch import Finch, AsyncFinch
+from tests.utils import assert_matches_type
+from finch._client import Finch, AsyncFinch
+from finch.types.sandbox import CompanyUpdateResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+access_token = "My Access Token"
+
+
+class TestCompany:
+ strict_client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=True)
+ loose_client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=False)
+ parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"])
+
+ @parametrize
+ def test_method_update(self, client: Finch) -> None:
+ company = client.sandbox.company.update(
+ accounts=[{}, {}, {}],
+ departments=[{}, {}, {}],
+ ein="string",
+ entity={},
+ legal_name="string",
+ locations=[{}, {}, {}],
+ primary_email="string",
+ primary_phone_number="string",
+ )
+ assert_matches_type(CompanyUpdateResponse, company, path=["response"])
+
+ @parametrize
+ def test_method_update_with_all_params(self, client: Finch) -> None:
+ company = client.sandbox.company.update(
+ accounts=[
+ {
+ "routing_number": "string",
+ "account_name": "string",
+ "institution_name": "string",
+ "account_type": "checking",
+ "account_number": "string",
+ },
+ {
+ "routing_number": "string",
+ "account_name": "string",
+ "institution_name": "string",
+ "account_type": "checking",
+ "account_number": "string",
+ },
+ {
+ "routing_number": "string",
+ "account_name": "string",
+ "institution_name": "string",
+ "account_type": "checking",
+ "account_number": "string",
+ },
+ ],
+ departments=[
+ {
+ "name": "string",
+ "parent": {"name": "string"},
+ },
+ {
+ "name": "string",
+ "parent": {"name": "string"},
+ },
+ {
+ "name": "string",
+ "parent": {"name": "string"},
+ },
+ ],
+ ein="string",
+ entity={
+ "type": "llc",
+ "subtype": "s_corporation",
+ },
+ legal_name="string",
+ locations=[
+ {
+ "line1": "string",
+ "line2": "string",
+ "city": "string",
+ "state": "string",
+ "postal_code": "string",
+ "country": "string",
+ "name": "string",
+ "source_id": "string",
+ },
+ {
+ "line1": "string",
+ "line2": "string",
+ "city": "string",
+ "state": "string",
+ "postal_code": "string",
+ "country": "string",
+ "name": "string",
+ "source_id": "string",
+ },
+ {
+ "line1": "string",
+ "line2": "string",
+ "city": "string",
+ "state": "string",
+ "postal_code": "string",
+ "country": "string",
+ "name": "string",
+ "source_id": "string",
+ },
+ ],
+ primary_email="string",
+ primary_phone_number="string",
+ )
+ assert_matches_type(CompanyUpdateResponse, company, path=["response"])
+
+ @parametrize
+ def test_raw_response_update(self, client: Finch) -> None:
+ response = client.sandbox.company.with_raw_response.update(
+ accounts=[{}, {}, {}],
+ departments=[{}, {}, {}],
+ ein="string",
+ entity={},
+ legal_name="string",
+ locations=[{}, {}, {}],
+ primary_email="string",
+ primary_phone_number="string",
+ )
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ company = response.parse()
+ assert_matches_type(CompanyUpdateResponse, company, path=["response"])
+
+
+class TestAsyncCompany:
+ strict_client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=True)
+ loose_client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=False)
+ parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"])
+
+ @parametrize
+ async def test_method_update(self, client: AsyncFinch) -> None:
+ company = await client.sandbox.company.update(
+ accounts=[{}, {}, {}],
+ departments=[{}, {}, {}],
+ ein="string",
+ entity={},
+ legal_name="string",
+ locations=[{}, {}, {}],
+ primary_email="string",
+ primary_phone_number="string",
+ )
+ assert_matches_type(CompanyUpdateResponse, company, path=["response"])
+
+ @parametrize
+ async def test_method_update_with_all_params(self, client: AsyncFinch) -> None:
+ company = await client.sandbox.company.update(
+ accounts=[
+ {
+ "routing_number": "string",
+ "account_name": "string",
+ "institution_name": "string",
+ "account_type": "checking",
+ "account_number": "string",
+ },
+ {
+ "routing_number": "string",
+ "account_name": "string",
+ "institution_name": "string",
+ "account_type": "checking",
+ "account_number": "string",
+ },
+ {
+ "routing_number": "string",
+ "account_name": "string",
+ "institution_name": "string",
+ "account_type": "checking",
+ "account_number": "string",
+ },
+ ],
+ departments=[
+ {
+ "name": "string",
+ "parent": {"name": "string"},
+ },
+ {
+ "name": "string",
+ "parent": {"name": "string"},
+ },
+ {
+ "name": "string",
+ "parent": {"name": "string"},
+ },
+ ],
+ ein="string",
+ entity={
+ "type": "llc",
+ "subtype": "s_corporation",
+ },
+ legal_name="string",
+ locations=[
+ {
+ "line1": "string",
+ "line2": "string",
+ "city": "string",
+ "state": "string",
+ "postal_code": "string",
+ "country": "string",
+ "name": "string",
+ "source_id": "string",
+ },
+ {
+ "line1": "string",
+ "line2": "string",
+ "city": "string",
+ "state": "string",
+ "postal_code": "string",
+ "country": "string",
+ "name": "string",
+ "source_id": "string",
+ },
+ {
+ "line1": "string",
+ "line2": "string",
+ "city": "string",
+ "state": "string",
+ "postal_code": "string",
+ "country": "string",
+ "name": "string",
+ "source_id": "string",
+ },
+ ],
+ primary_email="string",
+ primary_phone_number="string",
+ )
+ assert_matches_type(CompanyUpdateResponse, company, path=["response"])
+
+ @parametrize
+ async def test_raw_response_update(self, client: AsyncFinch) -> None:
+ response = await client.sandbox.company.with_raw_response.update(
+ accounts=[{}, {}, {}],
+ departments=[{}, {}, {}],
+ ein="string",
+ entity={},
+ legal_name="string",
+ locations=[{}, {}, {}],
+ primary_email="string",
+ primary_phone_number="string",
+ )
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ company = response.parse()
+ assert_matches_type(CompanyUpdateResponse, company, path=["response"])
diff --git a/tests/api_resources/sandbox/test_connections.py b/tests/api_resources/sandbox/test_connections.py
new file mode 100644
index 00000000..160c0ad5
--- /dev/null
+++ b/tests/api_resources/sandbox/test_connections.py
@@ -0,0 +1,79 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+import os
+
+import pytest
+
+from finch import Finch, AsyncFinch
+from tests.utils import assert_matches_type
+from finch._client import Finch, AsyncFinch
+from finch.types.sandbox import ConnectionCreateResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+access_token = "My Access Token"
+
+
+class TestConnections:
+ strict_client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=True)
+ loose_client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=False)
+ parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"])
+
+ @parametrize
+ def test_method_create(self, client: Finch) -> None:
+ connection = client.sandbox.connections.create(
+ provider_id="string",
+ )
+ assert_matches_type(ConnectionCreateResponse, connection, path=["response"])
+
+ @parametrize
+ def test_method_create_with_all_params(self, client: Finch) -> None:
+ connection = client.sandbox.connections.create(
+ provider_id="string",
+ authentication_type="credentials",
+ employer_size=0,
+ products=["string", "string", "string"],
+ )
+ assert_matches_type(ConnectionCreateResponse, connection, path=["response"])
+
+ @parametrize
+ def test_raw_response_create(self, client: Finch) -> None:
+ response = client.sandbox.connections.with_raw_response.create(
+ provider_id="string",
+ )
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ connection = response.parse()
+ assert_matches_type(ConnectionCreateResponse, connection, path=["response"])
+
+
+class TestAsyncConnections:
+ strict_client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=True)
+ loose_client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=False)
+ parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"])
+
+ @parametrize
+ async def test_method_create(self, client: AsyncFinch) -> None:
+ connection = await client.sandbox.connections.create(
+ provider_id="string",
+ )
+ assert_matches_type(ConnectionCreateResponse, connection, path=["response"])
+
+ @parametrize
+ async def test_method_create_with_all_params(self, client: AsyncFinch) -> None:
+ connection = await client.sandbox.connections.create(
+ provider_id="string",
+ authentication_type="credentials",
+ employer_size=0,
+ products=["string", "string", "string"],
+ )
+ assert_matches_type(ConnectionCreateResponse, connection, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create(self, client: AsyncFinch) -> None:
+ response = await client.sandbox.connections.with_raw_response.create(
+ provider_id="string",
+ )
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ connection = response.parse()
+ assert_matches_type(ConnectionCreateResponse, connection, path=["response"])
diff --git a/tests/api_resources/sandbox/test_directory.py b/tests/api_resources/sandbox/test_directory.py
new file mode 100644
index 00000000..3d6ba5f3
--- /dev/null
+++ b/tests/api_resources/sandbox/test_directory.py
@@ -0,0 +1,59 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+import os
+
+import pytest
+
+from finch import Finch, AsyncFinch
+from tests.utils import assert_matches_type
+from finch._client import Finch, AsyncFinch
+from finch.types.sandbox import DirectoryCreateResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+access_token = "My Access Token"
+
+
+class TestDirectory:
+ strict_client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=True)
+ loose_client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=False)
+ parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"])
+
+ @parametrize
+ def test_method_create(self, client: Finch) -> None:
+ directory = client.sandbox.directory.create(
+ body=[{}, {}, {}],
+ )
+ assert_matches_type(DirectoryCreateResponse, directory, path=["response"])
+
+ @parametrize
+ def test_raw_response_create(self, client: Finch) -> None:
+ response = client.sandbox.directory.with_raw_response.create(
+ body=[{}, {}, {}],
+ )
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ directory = response.parse()
+ assert_matches_type(DirectoryCreateResponse, directory, path=["response"])
+
+
+class TestAsyncDirectory:
+ strict_client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=True)
+ loose_client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=False)
+ parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"])
+
+ @parametrize
+ async def test_method_create(self, client: AsyncFinch) -> None:
+ directory = await client.sandbox.directory.create(
+ body=[{}, {}, {}],
+ )
+ assert_matches_type(DirectoryCreateResponse, directory, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create(self, client: AsyncFinch) -> None:
+ response = await client.sandbox.directory.with_raw_response.create(
+ body=[{}, {}, {}],
+ )
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ directory = response.parse()
+ assert_matches_type(DirectoryCreateResponse, directory, path=["response"])
diff --git a/tests/api_resources/sandbox/test_employment.py b/tests/api_resources/sandbox/test_employment.py
new file mode 100644
index 00000000..3995c21a
--- /dev/null
+++ b/tests/api_resources/sandbox/test_employment.py
@@ -0,0 +1,203 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+import os
+
+import pytest
+
+from finch import Finch, AsyncFinch
+from tests.utils import assert_matches_type
+from finch._client import Finch, AsyncFinch
+from finch.types.sandbox import EmploymentUpdateResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+access_token = "My Access Token"
+
+
+class TestEmployment:
+ strict_client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=True)
+ loose_client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=False)
+ parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"])
+
+ @parametrize
+ def test_method_update(self, client: Finch) -> None:
+ employment = client.sandbox.employment.update(
+ "string",
+ )
+ assert_matches_type(EmploymentUpdateResponse, employment, path=["response"])
+
+ @parametrize
+ def test_method_update_with_all_params(self, client: Finch) -> None:
+ employment = client.sandbox.employment.update(
+ "string",
+ class_code="string",
+ custom_fields=[
+ {
+ "name": "string",
+ "value": {},
+ },
+ {
+ "name": "string",
+ "value": {},
+ },
+ {
+ "name": "string",
+ "value": {},
+ },
+ ],
+ department={"name": "string"},
+ employment={
+ "type": "employee",
+ "subtype": "full_time",
+ },
+ end_date="string",
+ first_name="string",
+ income={
+ "unit": "yearly",
+ "amount": 0,
+ "currency": "string",
+ "effective_date": "string",
+ },
+ income_history=[
+ {
+ "unit": "yearly",
+ "amount": 0,
+ "currency": "string",
+ "effective_date": "string",
+ },
+ {
+ "unit": "yearly",
+ "amount": 0,
+ "currency": "string",
+ "effective_date": "string",
+ },
+ {
+ "unit": "yearly",
+ "amount": 0,
+ "currency": "string",
+ "effective_date": "string",
+ },
+ ],
+ is_active=True,
+ last_name="string",
+ location={
+ "line1": "string",
+ "line2": "string",
+ "city": "string",
+ "state": "string",
+ "postal_code": "string",
+ "country": "string",
+ "name": "string",
+ "source_id": "string",
+ },
+ manager={"id": "string"},
+ middle_name="string",
+ source_id="string",
+ start_date="string",
+ title="string",
+ )
+ assert_matches_type(EmploymentUpdateResponse, employment, path=["response"])
+
+ @parametrize
+ def test_raw_response_update(self, client: Finch) -> None:
+ response = client.sandbox.employment.with_raw_response.update(
+ "string",
+ )
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ employment = response.parse()
+ assert_matches_type(EmploymentUpdateResponse, employment, path=["response"])
+
+
+class TestAsyncEmployment:
+ strict_client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=True)
+ loose_client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=False)
+ parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"])
+
+ @parametrize
+ async def test_method_update(self, client: AsyncFinch) -> None:
+ employment = await client.sandbox.employment.update(
+ "string",
+ )
+ assert_matches_type(EmploymentUpdateResponse, employment, path=["response"])
+
+ @parametrize
+ async def test_method_update_with_all_params(self, client: AsyncFinch) -> None:
+ employment = await client.sandbox.employment.update(
+ "string",
+ class_code="string",
+ custom_fields=[
+ {
+ "name": "string",
+ "value": {},
+ },
+ {
+ "name": "string",
+ "value": {},
+ },
+ {
+ "name": "string",
+ "value": {},
+ },
+ ],
+ department={"name": "string"},
+ employment={
+ "type": "employee",
+ "subtype": "full_time",
+ },
+ end_date="string",
+ first_name="string",
+ income={
+ "unit": "yearly",
+ "amount": 0,
+ "currency": "string",
+ "effective_date": "string",
+ },
+ income_history=[
+ {
+ "unit": "yearly",
+ "amount": 0,
+ "currency": "string",
+ "effective_date": "string",
+ },
+ {
+ "unit": "yearly",
+ "amount": 0,
+ "currency": "string",
+ "effective_date": "string",
+ },
+ {
+ "unit": "yearly",
+ "amount": 0,
+ "currency": "string",
+ "effective_date": "string",
+ },
+ ],
+ is_active=True,
+ last_name="string",
+ location={
+ "line1": "string",
+ "line2": "string",
+ "city": "string",
+ "state": "string",
+ "postal_code": "string",
+ "country": "string",
+ "name": "string",
+ "source_id": "string",
+ },
+ manager={"id": "string"},
+ middle_name="string",
+ source_id="string",
+ start_date="string",
+ title="string",
+ )
+ assert_matches_type(EmploymentUpdateResponse, employment, path=["response"])
+
+ @parametrize
+ async def test_raw_response_update(self, client: AsyncFinch) -> None:
+ response = await client.sandbox.employment.with_raw_response.update(
+ "string",
+ )
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ employment = response.parse()
+ assert_matches_type(EmploymentUpdateResponse, employment, path=["response"])
diff --git a/tests/api_resources/sandbox/test_individual.py b/tests/api_resources/sandbox/test_individual.py
new file mode 100644
index 00000000..21f4affc
--- /dev/null
+++ b/tests/api_resources/sandbox/test_individual.py
@@ -0,0 +1,167 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+import os
+
+import pytest
+
+from finch import Finch, AsyncFinch
+from tests.utils import assert_matches_type
+from finch._client import Finch, AsyncFinch
+from finch.types.sandbox import IndividualUpdateResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+access_token = "My Access Token"
+
+
+class TestIndividual:
+ strict_client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=True)
+ loose_client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=False)
+ parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"])
+
+ @parametrize
+ def test_method_update(self, client: Finch) -> None:
+ individual = client.sandbox.individual.update(
+ "string",
+ )
+ assert_matches_type(IndividualUpdateResponse, individual, path=["response"])
+
+ @parametrize
+ def test_method_update_with_all_params(self, client: Finch) -> None:
+ individual = client.sandbox.individual.update(
+ "string",
+ dob="string",
+ emails=[
+ {
+ "data": "string",
+ "type": "work",
+ },
+ {
+ "data": "string",
+ "type": "work",
+ },
+ {
+ "data": "string",
+ "type": "work",
+ },
+ ],
+ encrypted_ssn="string",
+ ethnicity="asian",
+ first_name="string",
+ gender="female",
+ last_name="string",
+ middle_name="string",
+ phone_numbers=[
+ {
+ "data": "string",
+ "type": "work",
+ },
+ {
+ "data": "string",
+ "type": "work",
+ },
+ {
+ "data": "string",
+ "type": "work",
+ },
+ ],
+ preferred_name="string",
+ residence={
+ "line1": "string",
+ "line2": "string",
+ "city": "string",
+ "state": "string",
+ "postal_code": "string",
+ "country": "string",
+ "name": "string",
+ "source_id": "string",
+ },
+ ssn="string",
+ )
+ assert_matches_type(IndividualUpdateResponse, individual, path=["response"])
+
+ @parametrize
+ def test_raw_response_update(self, client: Finch) -> None:
+ response = client.sandbox.individual.with_raw_response.update(
+ "string",
+ )
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ individual = response.parse()
+ assert_matches_type(IndividualUpdateResponse, individual, path=["response"])
+
+
+class TestAsyncIndividual:
+ strict_client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=True)
+ loose_client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=False)
+ parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"])
+
+ @parametrize
+ async def test_method_update(self, client: AsyncFinch) -> None:
+ individual = await client.sandbox.individual.update(
+ "string",
+ )
+ assert_matches_type(IndividualUpdateResponse, individual, path=["response"])
+
+ @parametrize
+ async def test_method_update_with_all_params(self, client: AsyncFinch) -> None:
+ individual = await client.sandbox.individual.update(
+ "string",
+ dob="string",
+ emails=[
+ {
+ "data": "string",
+ "type": "work",
+ },
+ {
+ "data": "string",
+ "type": "work",
+ },
+ {
+ "data": "string",
+ "type": "work",
+ },
+ ],
+ encrypted_ssn="string",
+ ethnicity="asian",
+ first_name="string",
+ gender="female",
+ last_name="string",
+ middle_name="string",
+ phone_numbers=[
+ {
+ "data": "string",
+ "type": "work",
+ },
+ {
+ "data": "string",
+ "type": "work",
+ },
+ {
+ "data": "string",
+ "type": "work",
+ },
+ ],
+ preferred_name="string",
+ residence={
+ "line1": "string",
+ "line2": "string",
+ "city": "string",
+ "state": "string",
+ "postal_code": "string",
+ "country": "string",
+ "name": "string",
+ "source_id": "string",
+ },
+ ssn="string",
+ )
+ assert_matches_type(IndividualUpdateResponse, individual, path=["response"])
+
+ @parametrize
+ async def test_raw_response_update(self, client: AsyncFinch) -> None:
+ response = await client.sandbox.individual.with_raw_response.update(
+ "string",
+ )
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ individual = response.parse()
+ assert_matches_type(IndividualUpdateResponse, individual, path=["response"])
diff --git a/tests/api_resources/sandbox/test_payment.py b/tests/api_resources/sandbox/test_payment.py
new file mode 100644
index 00000000..ee4a2a1d
--- /dev/null
+++ b/tests/api_resources/sandbox/test_payment.py
@@ -0,0 +1,249 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+import os
+
+import pytest
+
+from finch import Finch, AsyncFinch
+from tests.utils import assert_matches_type
+from finch._client import Finch, AsyncFinch
+from finch.types.sandbox import PaymentCreateResponse
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+access_token = "My Access Token"
+
+
+class TestPayment:
+ strict_client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=True)
+ loose_client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=False)
+ parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"])
+
+ @parametrize
+ def test_method_create(self, client: Finch) -> None:
+ payment = client.sandbox.payment.create()
+ assert_matches_type(PaymentCreateResponse, payment, path=["response"])
+
+ @parametrize
+ def test_method_create_with_all_params(self, client: Finch) -> None:
+ payment = client.sandbox.payment.create(
+ end_date="string",
+ pay_statements=[
+ {
+ "individual_id": "b2338cfb-472f-4f72-9faa-e028c083144a",
+ "type": "regular_payroll",
+ "payment_method": "check",
+ "total_hours": 0,
+ "gross_pay": {
+ "amount": 0,
+ "currency": "string",
+ },
+ "net_pay": {
+ "amount": 0,
+ "currency": "string",
+ },
+ "earnings": [
+ {
+ "type": "salary",
+ "name": "string",
+ "amount": 0,
+ "currency": "string",
+ "hours": 0,
+ },
+ {
+ "type": "salary",
+ "name": "string",
+ "amount": 0,
+ "currency": "string",
+ "hours": 0,
+ },
+ {
+ "type": "salary",
+ "name": "string",
+ "amount": 0,
+ "currency": "string",
+ "hours": 0,
+ },
+ ],
+ "taxes": [
+ {
+ "type": "state",
+ "name": "string",
+ "employer": True,
+ "amount": 0,
+ "currency": "string",
+ },
+ {
+ "type": "state",
+ "name": "string",
+ "employer": True,
+ "amount": 0,
+ "currency": "string",
+ },
+ {
+ "type": "state",
+ "name": "string",
+ "employer": True,
+ "amount": 0,
+ "currency": "string",
+ },
+ ],
+ "employee_deductions": [
+ {
+ "name": "401k test",
+ "amount": 2000,
+ "currency": "usd",
+ "pre_tax": True,
+ "type": "401k",
+ }
+ ],
+ "employer_contributions": [
+ {
+ "name": "string",
+ "amount": 0,
+ "currency": "string",
+ "type": "401k",
+ },
+ {
+ "name": "string",
+ "amount": 0,
+ "currency": "string",
+ "type": "401k",
+ },
+ {
+ "name": "string",
+ "amount": 0,
+ "currency": "string",
+ "type": "401k",
+ },
+ ],
+ }
+ ],
+ start_date="string",
+ )
+ assert_matches_type(PaymentCreateResponse, payment, path=["response"])
+
+ @parametrize
+ def test_raw_response_create(self, client: Finch) -> None:
+ response = client.sandbox.payment.with_raw_response.create()
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ payment = response.parse()
+ assert_matches_type(PaymentCreateResponse, payment, path=["response"])
+
+
+class TestAsyncPayment:
+ strict_client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=True)
+ loose_client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=False)
+ parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"])
+
+ @parametrize
+ async def test_method_create(self, client: AsyncFinch) -> None:
+ payment = await client.sandbox.payment.create()
+ assert_matches_type(PaymentCreateResponse, payment, path=["response"])
+
+ @parametrize
+ async def test_method_create_with_all_params(self, client: AsyncFinch) -> None:
+ payment = await client.sandbox.payment.create(
+ end_date="string",
+ pay_statements=[
+ {
+ "individual_id": "b2338cfb-472f-4f72-9faa-e028c083144a",
+ "type": "regular_payroll",
+ "payment_method": "check",
+ "total_hours": 0,
+ "gross_pay": {
+ "amount": 0,
+ "currency": "string",
+ },
+ "net_pay": {
+ "amount": 0,
+ "currency": "string",
+ },
+ "earnings": [
+ {
+ "type": "salary",
+ "name": "string",
+ "amount": 0,
+ "currency": "string",
+ "hours": 0,
+ },
+ {
+ "type": "salary",
+ "name": "string",
+ "amount": 0,
+ "currency": "string",
+ "hours": 0,
+ },
+ {
+ "type": "salary",
+ "name": "string",
+ "amount": 0,
+ "currency": "string",
+ "hours": 0,
+ },
+ ],
+ "taxes": [
+ {
+ "type": "state",
+ "name": "string",
+ "employer": True,
+ "amount": 0,
+ "currency": "string",
+ },
+ {
+ "type": "state",
+ "name": "string",
+ "employer": True,
+ "amount": 0,
+ "currency": "string",
+ },
+ {
+ "type": "state",
+ "name": "string",
+ "employer": True,
+ "amount": 0,
+ "currency": "string",
+ },
+ ],
+ "employee_deductions": [
+ {
+ "name": "401k test",
+ "amount": 2000,
+ "currency": "usd",
+ "pre_tax": True,
+ "type": "401k",
+ }
+ ],
+ "employer_contributions": [
+ {
+ "name": "string",
+ "amount": 0,
+ "currency": "string",
+ "type": "401k",
+ },
+ {
+ "name": "string",
+ "amount": 0,
+ "currency": "string",
+ "type": "401k",
+ },
+ {
+ "name": "string",
+ "amount": 0,
+ "currency": "string",
+ "type": "401k",
+ },
+ ],
+ }
+ ],
+ start_date="string",
+ )
+ assert_matches_type(PaymentCreateResponse, payment, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create(self, client: AsyncFinch) -> None:
+ response = await client.sandbox.payment.with_raw_response.create()
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ payment = response.parse()
+ assert_matches_type(PaymentCreateResponse, payment, path=["response"])
diff --git a/tests/api_resources/test_auth.py b/tests/api_resources/test_auth.py
new file mode 100644
index 00000000..f826ee79
--- /dev/null
+++ b/tests/api_resources/test_auth.py
@@ -0,0 +1,71 @@
+# File generated from our OpenAPI spec by Stainless.
+
+from __future__ import annotations
+
+import os
+
+import pytest
+
+from finch import Finch, AsyncFinch
+from finch.types import CreateAccessTokenResponse
+from tests.utils import assert_matches_type
+from finch._client import Finch, AsyncFinch
+
+base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010")
+access_token = "My Access Token"
+
+
+class TestAuth:
+ strict_client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=True)
+ loose_client = Finch(base_url=base_url, access_token=access_token, _strict_response_validation=False)
+ parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"])
+
+ @parametrize
+ def test_method_create_token(self, client: Finch) -> None:
+ auth = client.auth.create_token(
+ client_id="",
+ client_secret="",
+ code="",
+ redirect_uri="https://example.com",
+ )
+ assert_matches_type(CreateAccessTokenResponse, auth, path=["response"])
+
+ @parametrize
+ def test_raw_response_create_token(self, client: Finch) -> None:
+ response = client.auth.with_raw_response.create_token(
+ client_id="",
+ client_secret="",
+ code="",
+ redirect_uri="https://example.com",
+ )
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ auth = response.parse()
+ assert_matches_type(CreateAccessTokenResponse, auth, path=["response"])
+
+
+class TestAsyncAuth:
+ strict_client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=True)
+ loose_client = AsyncFinch(base_url=base_url, access_token=access_token, _strict_response_validation=False)
+ parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"])
+
+ @parametrize
+ async def test_method_create_token(self, client: AsyncFinch) -> None:
+ auth = await client.auth.create_token(
+ client_id="",
+ client_secret="",
+ code="",
+ redirect_uri="https://example.com",
+ )
+ assert_matches_type(CreateAccessTokenResponse, auth, path=["response"])
+
+ @parametrize
+ async def test_raw_response_create_token(self, client: AsyncFinch) -> None:
+ response = await client.auth.with_raw_response.create_token(
+ client_id="",
+ client_secret="",
+ code="",
+ redirect_uri="https://example.com",
+ )
+ assert response.http_request.headers.get("X-Stainless-Lang") == "python"
+ auth = response.parse()
+ assert_matches_type(CreateAccessTokenResponse, auth, path=["response"])