diff --git a/api_reference.md b/api_reference.md
new file mode 100644
index 0000000..f8f2aae
--- /dev/null
+++ b/api_reference.md
@@ -0,0 +1,1949 @@
+# Table of Contents
+
+* [kwork\_api](#kwork_api)
+ * [KworkClient](#kwork_api.KworkClient)
+ * [KworkError](#kwork_api.KworkError)
+ * [KworkAuthError](#kwork_api.KworkAuthError)
+ * [KworkApiError](#kwork_api.KworkApiError)
+ * [\_\_version\_\_](#kwork_api.__version__)
+ * [\_\_all\_\_](#kwork_api.__all__)
+* [kwork\_api.client](#kwork_api.client)
+ * [logging](#kwork_api.client.logging)
+ * [Any](#kwork_api.client.Any)
+ * [Optional](#kwork_api.client.Optional)
+ * [httpx](#kwork_api.client.httpx)
+ * [HttpUrl](#kwork_api.client.HttpUrl)
+ * [KworkApiError](#kwork_api.client.KworkApiError)
+ * [KworkAuthError](#kwork_api.client.KworkAuthError)
+ * [KworkError](#kwork_api.client.KworkError)
+ * [KworkNetworkError](#kwork_api.client.KworkNetworkError)
+ * [KworkNotFoundError](#kwork_api.client.KworkNotFoundError)
+ * [KworkRateLimitError](#kwork_api.client.KworkRateLimitError)
+ * [KworkValidationError](#kwork_api.client.KworkValidationError)
+ * [APIErrorResponse](#kwork_api.client.APIErrorResponse)
+ * [AuthResponse](#kwork_api.client.AuthResponse)
+ * [Badge](#kwork_api.client.Badge)
+ * [CatalogResponse](#kwork_api.client.CatalogResponse)
+ * [City](#kwork_api.client.City)
+ * [Country](#kwork_api.client.Country)
+ * [DataResponse](#kwork_api.client.DataResponse)
+ * [Dialog](#kwork_api.client.Dialog)
+ * [Feature](#kwork_api.client.Feature)
+ * [Kwork](#kwork_api.client.Kwork)
+ * [KworkDetails](#kwork_api.client.KworkDetails)
+ * [NotificationsResponse](#kwork_api.client.NotificationsResponse)
+ * [Project](#kwork_api.client.Project)
+ * [ProjectsResponse](#kwork_api.client.ProjectsResponse)
+ * [Review](#kwork_api.client.Review)
+ * [ReviewsResponse](#kwork_api.client.ReviewsResponse)
+ * [TimeZone](#kwork_api.client.TimeZone)
+ * [logger](#kwork_api.client.logger)
+ * [KworkClient](#kwork_api.client.KworkClient)
+ * [BASE\_URL](#kwork_api.client.KworkClient.BASE_URL)
+ * [LOGIN\_URL](#kwork_api.client.KworkClient.LOGIN_URL)
+ * [TOKEN\_URL](#kwork_api.client.KworkClient.TOKEN_URL)
+ * [\_\_init\_\_](#kwork_api.client.KworkClient.__init__)
+ * [login](#kwork_api.client.KworkClient.login)
+ * [close](#kwork_api.client.KworkClient.close)
+ * [\_\_aenter\_\_](#kwork_api.client.KworkClient.__aenter__)
+ * [\_\_aexit\_\_](#kwork_api.client.KworkClient.__aexit__)
+ * [CatalogAPI](#kwork_api.client.KworkClient.CatalogAPI)
+ * [ProjectsAPI](#kwork_api.client.KworkClient.ProjectsAPI)
+ * [UserAPI](#kwork_api.client.KworkClient.UserAPI)
+ * [ReferenceAPI](#kwork_api.client.KworkClient.ReferenceAPI)
+ * [NotificationsAPI](#kwork_api.client.KworkClient.NotificationsAPI)
+ * [OtherAPI](#kwork_api.client.KworkClient.OtherAPI)
+ * [catalog](#kwork_api.client.KworkClient.catalog)
+ * [projects](#kwork_api.client.KworkClient.projects)
+ * [user](#kwork_api.client.KworkClient.user)
+ * [reference](#kwork_api.client.KworkClient.reference)
+ * [notifications](#kwork_api.client.KworkClient.notifications)
+ * [other](#kwork_api.client.KworkClient.other)
+* [kwork\_api.models](#kwork_api.models)
+ * [datetime](#kwork_api.models.datetime)
+ * [Any](#kwork_api.models.Any)
+ * [Optional](#kwork_api.models.Optional)
+ * [BaseModel](#kwork_api.models.BaseModel)
+ * [Field](#kwork_api.models.Field)
+ * [KworkUser](#kwork_api.models.KworkUser)
+ * [id](#kwork_api.models.KworkUser.id)
+ * [username](#kwork_api.models.KworkUser.username)
+ * [avatar\_url](#kwork_api.models.KworkUser.avatar_url)
+ * [is\_online](#kwork_api.models.KworkUser.is_online)
+ * [rating](#kwork_api.models.KworkUser.rating)
+ * [KworkCategory](#kwork_api.models.KworkCategory)
+ * [id](#kwork_api.models.KworkCategory.id)
+ * [name](#kwork_api.models.KworkCategory.name)
+ * [slug](#kwork_api.models.KworkCategory.slug)
+ * [parent\_id](#kwork_api.models.KworkCategory.parent_id)
+ * [Kwork](#kwork_api.models.Kwork)
+ * [id](#kwork_api.models.Kwork.id)
+ * [title](#kwork_api.models.Kwork.title)
+ * [description](#kwork_api.models.Kwork.description)
+ * [price](#kwork_api.models.Kwork.price)
+ * [currency](#kwork_api.models.Kwork.currency)
+ * [category\_id](#kwork_api.models.Kwork.category_id)
+ * [seller](#kwork_api.models.Kwork.seller)
+ * [images](#kwork_api.models.Kwork.images)
+ * [rating](#kwork_api.models.Kwork.rating)
+ * [reviews\_count](#kwork_api.models.Kwork.reviews_count)
+ * [created\_at](#kwork_api.models.Kwork.created_at)
+ * [updated\_at](#kwork_api.models.Kwork.updated_at)
+ * [KworkDetails](#kwork_api.models.KworkDetails)
+ * [full\_description](#kwork_api.models.KworkDetails.full_description)
+ * [requirements](#kwork_api.models.KworkDetails.requirements)
+ * [delivery\_time](#kwork_api.models.KworkDetails.delivery_time)
+ * [revisions](#kwork_api.models.KworkDetails.revisions)
+ * [features](#kwork_api.models.KworkDetails.features)
+ * [faq](#kwork_api.models.KworkDetails.faq)
+ * [PaginationInfo](#kwork_api.models.PaginationInfo)
+ * [current\_page](#kwork_api.models.PaginationInfo.current_page)
+ * [total\_pages](#kwork_api.models.PaginationInfo.total_pages)
+ * [total\_items](#kwork_api.models.PaginationInfo.total_items)
+ * [items\_per\_page](#kwork_api.models.PaginationInfo.items_per_page)
+ * [has\_next](#kwork_api.models.PaginationInfo.has_next)
+ * [has\_prev](#kwork_api.models.PaginationInfo.has_prev)
+ * [CatalogResponse](#kwork_api.models.CatalogResponse)
+ * [kworks](#kwork_api.models.CatalogResponse.kworks)
+ * [pagination](#kwork_api.models.CatalogResponse.pagination)
+ * [filters](#kwork_api.models.CatalogResponse.filters)
+ * [sort\_options](#kwork_api.models.CatalogResponse.sort_options)
+ * [Project](#kwork_api.models.Project)
+ * [id](#kwork_api.models.Project.id)
+ * [title](#kwork_api.models.Project.title)
+ * [description](#kwork_api.models.Project.description)
+ * [budget](#kwork_api.models.Project.budget)
+ * [budget\_type](#kwork_api.models.Project.budget_type)
+ * [category\_id](#kwork_api.models.Project.category_id)
+ * [customer](#kwork_api.models.Project.customer)
+ * [status](#kwork_api.models.Project.status)
+ * [created\_at](#kwork_api.models.Project.created_at)
+ * [updated\_at](#kwork_api.models.Project.updated_at)
+ * [bids\_count](#kwork_api.models.Project.bids_count)
+ * [skills](#kwork_api.models.Project.skills)
+ * [ProjectsResponse](#kwork_api.models.ProjectsResponse)
+ * [projects](#kwork_api.models.ProjectsResponse.projects)
+ * [pagination](#kwork_api.models.ProjectsResponse.pagination)
+ * [Review](#kwork_api.models.Review)
+ * [id](#kwork_api.models.Review.id)
+ * [rating](#kwork_api.models.Review.rating)
+ * [comment](#kwork_api.models.Review.comment)
+ * [author](#kwork_api.models.Review.author)
+ * [kwork\_id](#kwork_api.models.Review.kwork_id)
+ * [created\_at](#kwork_api.models.Review.created_at)
+ * [ReviewsResponse](#kwork_api.models.ReviewsResponse)
+ * [reviews](#kwork_api.models.ReviewsResponse.reviews)
+ * [pagination](#kwork_api.models.ReviewsResponse.pagination)
+ * [average\_rating](#kwork_api.models.ReviewsResponse.average_rating)
+ * [Notification](#kwork_api.models.Notification)
+ * [id](#kwork_api.models.Notification.id)
+ * [type](#kwork_api.models.Notification.type)
+ * [title](#kwork_api.models.Notification.title)
+ * [message](#kwork_api.models.Notification.message)
+ * [is\_read](#kwork_api.models.Notification.is_read)
+ * [created\_at](#kwork_api.models.Notification.created_at)
+ * [link](#kwork_api.models.Notification.link)
+ * [NotificationsResponse](#kwork_api.models.NotificationsResponse)
+ * [notifications](#kwork_api.models.NotificationsResponse.notifications)
+ * [unread\_count](#kwork_api.models.NotificationsResponse.unread_count)
+ * [Dialog](#kwork_api.models.Dialog)
+ * [id](#kwork_api.models.Dialog.id)
+ * [participant](#kwork_api.models.Dialog.participant)
+ * [last\_message](#kwork_api.models.Dialog.last_message)
+ * [unread\_count](#kwork_api.models.Dialog.unread_count)
+ * [updated\_at](#kwork_api.models.Dialog.updated_at)
+ * [AuthResponse](#kwork_api.models.AuthResponse)
+ * [success](#kwork_api.models.AuthResponse.success)
+ * [user\_id](#kwork_api.models.AuthResponse.user_id)
+ * [username](#kwork_api.models.AuthResponse.username)
+ * [web\_auth\_token](#kwork_api.models.AuthResponse.web_auth_token)
+ * [message](#kwork_api.models.AuthResponse.message)
+ * [ErrorDetail](#kwork_api.models.ErrorDetail)
+ * [code](#kwork_api.models.ErrorDetail.code)
+ * [message](#kwork_api.models.ErrorDetail.message)
+ * [field](#kwork_api.models.ErrorDetail.field)
+ * [APIErrorResponse](#kwork_api.models.APIErrorResponse)
+ * [success](#kwork_api.models.APIErrorResponse.success)
+ * [errors](#kwork_api.models.APIErrorResponse.errors)
+ * [message](#kwork_api.models.APIErrorResponse.message)
+ * [City](#kwork_api.models.City)
+ * [id](#kwork_api.models.City.id)
+ * [name](#kwork_api.models.City.name)
+ * [country\_id](#kwork_api.models.City.country_id)
+ * [Country](#kwork_api.models.Country)
+ * [id](#kwork_api.models.Country.id)
+ * [name](#kwork_api.models.Country.name)
+ * [code](#kwork_api.models.Country.code)
+ * [cities](#kwork_api.models.Country.cities)
+ * [TimeZone](#kwork_api.models.TimeZone)
+ * [id](#kwork_api.models.TimeZone.id)
+ * [name](#kwork_api.models.TimeZone.name)
+ * [offset](#kwork_api.models.TimeZone.offset)
+ * [Feature](#kwork_api.models.Feature)
+ * [id](#kwork_api.models.Feature.id)
+ * [name](#kwork_api.models.Feature.name)
+ * [description](#kwork_api.models.Feature.description)
+ * [price](#kwork_api.models.Feature.price)
+ * [type](#kwork_api.models.Feature.type)
+ * [Badge](#kwork_api.models.Badge)
+ * [id](#kwork_api.models.Badge.id)
+ * [name](#kwork_api.models.Badge.name)
+ * [description](#kwork_api.models.Badge.description)
+ * [icon\_url](#kwork_api.models.Badge.icon_url)
+ * [DataResponse](#kwork_api.models.DataResponse)
+ * [success](#kwork_api.models.DataResponse.success)
+ * [data](#kwork_api.models.DataResponse.data)
+ * [message](#kwork_api.models.DataResponse.message)
+* [kwork\_api.errors](#kwork_api.errors)
+ * [Any](#kwork_api.errors.Any)
+ * [Optional](#kwork_api.errors.Optional)
+ * [KworkError](#kwork_api.errors.KworkError)
+ * [\_\_init\_\_](#kwork_api.errors.KworkError.__init__)
+ * [\_\_str\_\_](#kwork_api.errors.KworkError.__str__)
+ * [KworkAuthError](#kwork_api.errors.KworkAuthError)
+ * [\_\_init\_\_](#kwork_api.errors.KworkAuthError.__init__)
+ * [\_\_str\_\_](#kwork_api.errors.KworkAuthError.__str__)
+ * [KworkApiError](#kwork_api.errors.KworkApiError)
+ * [\_\_init\_\_](#kwork_api.errors.KworkApiError.__init__)
+ * [\_\_str\_\_](#kwork_api.errors.KworkApiError.__str__)
+ * [KworkNotFoundError](#kwork_api.errors.KworkNotFoundError)
+ * [\_\_init\_\_](#kwork_api.errors.KworkNotFoundError.__init__)
+ * [KworkRateLimitError](#kwork_api.errors.KworkRateLimitError)
+ * [\_\_init\_\_](#kwork_api.errors.KworkRateLimitError.__init__)
+ * [KworkValidationError](#kwork_api.errors.KworkValidationError)
+ * [\_\_init\_\_](#kwork_api.errors.KworkValidationError.__init__)
+ * [\_\_str\_\_](#kwork_api.errors.KworkValidationError.__str__)
+ * [KworkNetworkError](#kwork_api.errors.KworkNetworkError)
+ * [\_\_init\_\_](#kwork_api.errors.KworkNetworkError.__init__)
+ * [\_\_str\_\_](#kwork_api.errors.KworkNetworkError.__str__)
+
+
+
+# Module kwork\_api
+
+Kwork.ru API Client
+
+Unofficial Python client for Kwork.ru API.
+
+**Example**:
+
+ from kwork_api import KworkClient
+
+ # Login with credentials
+ client = await KworkClient.login("username", "password")
+
+ # Or restore from token
+ client = KworkClient(token="your_web_auth_token")
+
+ # Get catalog
+ catalog = await client.catalog.get_list(page=1)
+
+
+
+## KworkClient
+
+
+
+## KworkError
+
+
+
+## KworkAuthError
+
+
+
+## KworkApiError
+
+
+
+#### \_\_version\_\_
+
+
+
+#### \_\_all\_\_
+
+
+
+# Module kwork\_api.client
+
+Kwork API Client.
+
+Main client class with authentication and all API endpoints.
+
+
+
+## logging
+
+
+
+## Any
+
+
+
+## Optional
+
+
+
+## httpx
+
+
+
+## HttpUrl
+
+
+
+## KworkApiError
+
+
+
+## KworkAuthError
+
+
+
+## KworkError
+
+
+
+## KworkNetworkError
+
+
+
+## KworkNotFoundError
+
+
+
+## KworkRateLimitError
+
+
+
+## KworkValidationError
+
+
+
+## APIErrorResponse
+
+
+
+## AuthResponse
+
+
+
+## Badge
+
+
+
+## CatalogResponse
+
+
+
+## City
+
+
+
+## Country
+
+
+
+## DataResponse
+
+
+
+## Dialog
+
+
+
+## Feature
+
+
+
+## Kwork
+
+
+
+## KworkDetails
+
+
+
+## NotificationsResponse
+
+
+
+## Project
+
+
+
+## ProjectsResponse
+
+
+
+## Review
+
+
+
+## ReviewsResponse
+
+
+
+## TimeZone
+
+
+
+#### logger
+
+
+
+## KworkClient
+
+```python
+class KworkClient()
+```
+
+Kwork.ru API client.
+
+Usage:
+ # Login with credentials
+ client = await KworkClient.login("username", "password")
+
+ # Or restore from token
+ client = KworkClient(token="your_web_auth_token")
+
+ # Make requests
+ catalog = await client.catalog.get_list(page=1)
+
+
+
+#### BASE\_URL
+
+
+
+#### LOGIN\_URL
+
+
+
+#### TOKEN\_URL
+
+
+
+#### KworkClient.\_\_init\_\_
+
+```python
+def __init__(token: Optional[str] = None,
+ cookies: Optional[dict[str, str]] = None,
+ timeout: float = 30.0,
+ base_url: Optional[str] = None)
+```
+
+Initialize client.
+
+**Arguments**:
+
+- `token` - Web auth token (from getWebAuthToken)
+- `cookies` - Session cookies (optional, will be set from token)
+- `timeout` - Request timeout in seconds
+- `base_url` - Custom base URL (for testing)
+
+
+
+#### KworkClient.login
+
+```python
+@classmethod
+async def login(cls,
+ username: str,
+ password: str,
+ timeout: float = 30.0) -> "KworkClient"
+```
+
+Login with username and password.
+
+**Arguments**:
+
+- `username` - Kwork username or email
+- `password` - Kwork password
+- `timeout` - Request timeout
+
+
+**Returns**:
+
+ Authenticated KworkClient instance
+
+
+**Raises**:
+
+- `KworkAuthError` - If login fails
+
+
+
+#### KworkClient.close
+
+```python
+async def close() -> None
+```
+
+Close HTTP client.
+
+
+
+#### KworkClient.\_\_aenter\_\_
+
+```python
+async def __aenter__() -> "KworkClient"
+```
+
+
+
+#### KworkClient.\_\_aexit\_\_
+
+```python
+async def __aexit__(*args: Any) -> None
+```
+
+
+
+## CatalogAPI
+
+```python
+class CatalogAPI()
+```
+
+Catalog/Kworks API endpoints.
+
+
+
+#### CatalogAPI.\_\_init\_\_
+
+```python
+def __init__(client: "KworkClient")
+```
+
+
+
+#### CatalogAPI.get\_list
+
+```python
+async def get_list(page: int = 1,
+ category_id: Optional[int] = None,
+ sort: str = "recommend") -> CatalogResponse
+```
+
+Get kworks catalog.
+
+**Arguments**:
+
+- `page` - Page number
+- `category_id` - Category filter
+- `sort` - Sort option (recommend, price_asc, price_desc, etc.)
+
+
+**Returns**:
+
+ CatalogResponse with kworks and pagination
+
+
+
+#### CatalogAPI.get\_details
+
+```python
+async def get_details(kwork_id: int) -> KworkDetails
+```
+
+Get kwork details.
+
+**Arguments**:
+
+- `kwork_id` - Kwork ID
+
+
+**Returns**:
+
+ KworkDetails with full information
+
+
+
+#### CatalogAPI.get\_details\_extra
+
+```python
+async def get_details_extra(kwork_id: int) -> dict[str, Any]
+```
+
+Get additional kwork details.
+
+**Arguments**:
+
+- `kwork_id` - Kwork ID
+
+
+**Returns**:
+
+ Extra details dict
+
+
+
+## ProjectsAPI
+
+```python
+class ProjectsAPI()
+```
+
+Projects (freelance orders) API endpoints.
+
+
+
+#### ProjectsAPI.\_\_init\_\_
+
+```python
+def __init__(client: "KworkClient")
+```
+
+
+
+#### ProjectsAPI.get\_list
+
+```python
+async def get_list(page: int = 1,
+ category_id: Optional[int] = None) -> ProjectsResponse
+```
+
+Get projects list.
+
+**Arguments**:
+
+- `page` - Page number
+- `category_id` - Category filter
+
+
+**Returns**:
+
+ ProjectsResponse with projects and pagination
+
+
+
+#### ProjectsAPI.get\_payer\_orders
+
+```python
+async def get_payer_orders() -> list[Project]
+```
+
+Get orders where user is customer.
+
+**Returns**:
+
+ List of projects
+
+
+
+#### ProjectsAPI.get\_worker\_orders
+
+```python
+async def get_worker_orders() -> list[Project]
+```
+
+Get orders where user is performer.
+
+**Returns**:
+
+ List of projects
+
+
+
+## UserAPI
+
+```python
+class UserAPI()
+```
+
+User API endpoints.
+
+
+
+#### UserAPI.\_\_init\_\_
+
+```python
+def __init__(client: "KworkClient")
+```
+
+
+
+#### UserAPI.get\_info
+
+```python
+async def get_info() -> dict[str, Any]
+```
+
+Get current user info.
+
+**Returns**:
+
+ User info dict
+
+
+
+#### UserAPI.get\_reviews
+
+```python
+async def get_reviews(user_id: Optional[int] = None,
+ page: int = 1) -> ReviewsResponse
+```
+
+Get user reviews.
+
+**Arguments**:
+
+- `user_id` - User ID (None for current user)
+- `page` - Page number
+
+
+**Returns**:
+
+ ReviewsResponse
+
+
+
+#### UserAPI.get\_favorite\_kworks
+
+```python
+async def get_favorite_kworks() -> list[Kwork]
+```
+
+Get favorite kworks.
+
+**Returns**:
+
+ List of kworks
+
+
+
+## ReferenceAPI
+
+```python
+class ReferenceAPI()
+```
+
+Reference data (cities, countries, etc.) endpoints.
+
+
+
+#### ReferenceAPI.\_\_init\_\_
+
+```python
+def __init__(client: "KworkClient")
+```
+
+
+
+#### ReferenceAPI.get\_cities
+
+```python
+async def get_cities() -> list[City]
+```
+
+Get all cities.
+
+
+
+#### ReferenceAPI.get\_countries
+
+```python
+async def get_countries() -> list[Country]
+```
+
+Get all countries.
+
+
+
+#### ReferenceAPI.get\_timezones
+
+```python
+async def get_timezones() -> list[TimeZone]
+```
+
+Get all timezones.
+
+
+
+#### ReferenceAPI.get\_features
+
+```python
+async def get_features() -> list[Feature]
+```
+
+Get available features.
+
+
+
+#### ReferenceAPI.get\_public\_features
+
+```python
+async def get_public_features() -> list[Feature]
+```
+
+Get public features.
+
+
+
+#### ReferenceAPI.get\_badges\_info
+
+```python
+async def get_badges_info() -> list[Badge]
+```
+
+Get badges info.
+
+
+
+## NotificationsAPI
+
+```python
+class NotificationsAPI()
+```
+
+Notifications and messages endpoints.
+
+
+
+#### NotificationsAPI.\_\_init\_\_
+
+```python
+def __init__(client: "KworkClient")
+```
+
+
+
+#### NotificationsAPI.get\_list
+
+```python
+async def get_list() -> NotificationsResponse
+```
+
+Get notifications list.
+
+
+
+#### NotificationsAPI.fetch
+
+```python
+async def fetch() -> NotificationsResponse
+```
+
+Fetch new notifications.
+
+
+
+#### NotificationsAPI.get\_dialogs
+
+```python
+async def get_dialogs() -> list[Dialog]
+```
+
+Get dialogs list.
+
+
+
+#### NotificationsAPI.get\_blocked\_dialogs
+
+```python
+async def get_blocked_dialogs() -> list[Dialog]
+```
+
+Get blocked dialogs.
+
+
+
+## OtherAPI
+
+```python
+class OtherAPI()
+```
+
+Other API endpoints.
+
+
+
+#### OtherAPI.\_\_init\_\_
+
+```python
+def __init__(client: "KworkClient")
+```
+
+
+
+#### OtherAPI.get\_wants
+
+```python
+async def get_wants() -> dict[str, Any]
+```
+
+Get user wants.
+
+
+
+#### OtherAPI.get\_wants\_status
+
+```python
+async def get_wants_status() -> dict[str, Any]
+```
+
+Get wants status.
+
+
+
+#### OtherAPI.get\_kworks\_status
+
+```python
+async def get_kworks_status() -> dict[str, Any]
+```
+
+Get kworks status.
+
+
+
+#### OtherAPI.get\_offers
+
+```python
+async def get_offers() -> dict[str, Any]
+```
+
+Get offers.
+
+
+
+#### OtherAPI.get\_exchange\_info
+
+```python
+async def get_exchange_info() -> dict[str, Any]
+```
+
+Get exchange info.
+
+
+
+#### OtherAPI.get\_channel
+
+```python
+async def get_channel() -> dict[str, Any]
+```
+
+Get channel info.
+
+
+
+#### OtherAPI.get\_in\_app\_notification
+
+```python
+async def get_in_app_notification() -> dict[str, Any]
+```
+
+Get in-app notification.
+
+
+
+#### OtherAPI.get\_security\_user\_data
+
+```python
+async def get_security_user_data() -> dict[str, Any]
+```
+
+Get security user data.
+
+
+
+#### OtherAPI.is\_dialog\_allow
+
+```python
+async def is_dialog_allow(user_id: int) -> bool
+```
+
+Check if dialog is allowed.
+
+
+
+#### OtherAPI.get\_viewed\_kworks
+
+```python
+async def get_viewed_kworks() -> list[Kwork]
+```
+
+Get viewed kworks.
+
+
+
+#### OtherAPI.get\_favorite\_categories
+
+```python
+async def get_favorite_categories() -> list[int]
+```
+
+Get favorite categories.
+
+
+
+#### OtherAPI.update\_settings
+
+```python
+async def update_settings(settings: dict[str, Any]) -> dict[str, Any]
+```
+
+Update user settings.
+
+
+
+#### OtherAPI.go\_offline
+
+```python
+async def go_offline() -> dict[str, Any]
+```
+
+Set user status to offline.
+
+
+
+#### OtherAPI.get\_actor
+
+```python
+async def get_actor() -> dict[str, Any]
+```
+
+Get actor info.
+
+
+
+#### KworkClient.catalog
+
+```python
+@property
+def catalog() -> CatalogAPI
+```
+
+Catalog API.
+
+
+
+#### KworkClient.projects
+
+```python
+@property
+def projects() -> ProjectsAPI
+```
+
+Projects API.
+
+
+
+#### KworkClient.user
+
+```python
+@property
+def user() -> UserAPI
+```
+
+User API.
+
+
+
+#### KworkClient.reference
+
+```python
+@property
+def reference() -> ReferenceAPI
+```
+
+Reference data API.
+
+
+
+#### KworkClient.notifications
+
+```python
+@property
+def notifications() -> NotificationsAPI
+```
+
+Notifications API.
+
+
+
+#### KworkClient.other
+
+```python
+@property
+def other() -> OtherAPI
+```
+
+Other endpoints.
+
+
+
+# Module kwork\_api.models
+
+Pydantic models for Kwork API responses.
+
+All models follow the structure found in the HAR dump analysis.
+
+
+
+## datetime
+
+
+
+## Any
+
+
+
+## Optional
+
+
+
+## BaseModel
+
+
+
+## Field
+
+
+
+## KworkUser
+
+```python
+class KworkUser(BaseModel)
+```
+
+User information.
+
+
+
+#### id
+
+
+
+#### username
+
+
+
+#### avatar\_url
+
+
+
+#### is\_online
+
+
+
+#### rating
+
+
+
+## KworkCategory
+
+```python
+class KworkCategory(BaseModel)
+```
+
+Category information.
+
+
+
+#### id
+
+
+
+#### name
+
+
+
+#### slug
+
+
+
+#### parent\_id
+
+
+
+## Kwork
+
+```python
+class Kwork(BaseModel)
+```
+
+Kwork (service) information.
+
+
+
+#### id
+
+
+
+#### title
+
+
+
+#### description
+
+
+
+#### price
+
+
+
+#### currency
+
+
+
+#### category\_id
+
+
+
+#### seller
+
+
+
+#### images
+
+
+
+#### rating
+
+
+
+#### reviews\_count
+
+
+
+#### created\_at
+
+
+
+#### updated\_at
+
+
+
+## KworkDetails
+
+```python
+class KworkDetails(Kwork)
+```
+
+Extended kwork details.
+
+
+
+#### full\_description
+
+
+
+#### requirements
+
+
+
+#### delivery\_time
+
+in days
+
+
+
+#### revisions
+
+
+
+#### features
+
+
+
+#### faq
+
+
+
+## PaginationInfo
+
+```python
+class PaginationInfo(BaseModel)
+```
+
+Pagination metadata.
+
+
+
+#### current\_page
+
+
+
+#### total\_pages
+
+
+
+#### total\_items
+
+
+
+#### items\_per\_page
+
+
+
+#### has\_next
+
+
+
+#### has\_prev
+
+
+
+## CatalogResponse
+
+```python
+class CatalogResponse(BaseModel)
+```
+
+Catalog response with kworks and pagination.
+
+
+
+#### kworks
+
+
+
+#### pagination
+
+
+
+#### filters
+
+
+
+#### sort\_options
+
+
+
+## Project
+
+```python
+class Project(BaseModel)
+```
+
+Project (freelance order) information.
+
+
+
+#### id
+
+
+
+#### title
+
+
+
+#### description
+
+
+
+#### budget
+
+
+
+#### budget\_type
+
+fixed, hourly
+
+
+
+#### category\_id
+
+
+
+#### customer
+
+
+
+#### status
+
+open, in_progress, completed, cancelled
+
+
+
+#### created\_at
+
+
+
+#### updated\_at
+
+
+
+#### bids\_count
+
+
+
+#### skills
+
+
+
+## ProjectsResponse
+
+```python
+class ProjectsResponse(BaseModel)
+```
+
+Projects list response.
+
+
+
+#### projects
+
+
+
+#### pagination
+
+
+
+## Review
+
+```python
+class Review(BaseModel)
+```
+
+Review information.
+
+
+
+#### id
+
+
+
+#### rating
+
+
+
+#### comment
+
+
+
+#### author
+
+
+
+#### kwork\_id
+
+
+
+#### created\_at
+
+
+
+## ReviewsResponse
+
+```python
+class ReviewsResponse(BaseModel)
+```
+
+Reviews list response.
+
+
+
+#### reviews
+
+
+
+#### pagination
+
+
+
+#### average\_rating
+
+
+
+## Notification
+
+```python
+class Notification(BaseModel)
+```
+
+Notification information.
+
+
+
+#### id
+
+
+
+#### type
+
+message, order, system, etc.
+
+
+
+#### title
+
+
+
+#### message
+
+
+
+#### is\_read
+
+
+
+#### created\_at
+
+
+
+#### link
+
+
+
+## NotificationsResponse
+
+```python
+class NotificationsResponse(BaseModel)
+```
+
+Notifications list response.
+
+
+
+#### notifications
+
+
+
+#### unread\_count
+
+
+
+## Dialog
+
+```python
+class Dialog(BaseModel)
+```
+
+Dialog (chat) information.
+
+
+
+#### id
+
+
+
+#### participant
+
+
+
+#### last\_message
+
+
+
+#### unread\_count
+
+
+
+#### updated\_at
+
+
+
+## AuthResponse
+
+```python
+class AuthResponse(BaseModel)
+```
+
+Authentication response.
+
+
+
+#### success
+
+
+
+#### user\_id
+
+
+
+#### username
+
+
+
+#### web\_auth\_token
+
+
+
+#### message
+
+
+
+## ErrorDetail
+
+```python
+class ErrorDetail(BaseModel)
+```
+
+Error detail from API.
+
+
+
+#### code
+
+
+
+#### message
+
+
+
+#### field
+
+
+
+## APIErrorResponse
+
+```python
+class APIErrorResponse(BaseModel)
+```
+
+Standard API error response.
+
+
+
+#### success
+
+
+
+#### errors
+
+
+
+#### message
+
+
+
+## City
+
+```python
+class City(BaseModel)
+```
+
+City information.
+
+
+
+#### id
+
+
+
+#### name
+
+
+
+#### country\_id
+
+
+
+## Country
+
+```python
+class Country(BaseModel)
+```
+
+Country information.
+
+
+
+#### id
+
+
+
+#### name
+
+
+
+#### code
+
+
+
+#### cities
+
+
+
+## TimeZone
+
+```python
+class TimeZone(BaseModel)
+```
+
+Timezone information.
+
+
+
+#### id
+
+
+
+#### name
+
+
+
+#### offset
+
+e.g., "+03:00"
+
+
+
+## Feature
+
+```python
+class Feature(BaseModel)
+```
+
+Feature/addon information.
+
+
+
+#### id
+
+
+
+#### name
+
+
+
+#### description
+
+
+
+#### price
+
+
+
+#### type
+
+extra, premium, etc.
+
+
+
+## Badge
+
+```python
+class Badge(BaseModel)
+```
+
+User badge information.
+
+
+
+#### id
+
+
+
+#### name
+
+
+
+#### description
+
+
+
+#### icon\_url
+
+
+
+## DataResponse
+
+```python
+class DataResponse(BaseModel)
+```
+
+Generic data response wrapper.
+
+
+
+#### success
+
+
+
+#### data
+
+
+
+#### message
+
+
+
+# Module kwork\_api.errors
+
+Kwork API exceptions.
+
+All exceptions provide clear error messages for debugging.
+
+
+
+## Any
+
+
+
+## Optional
+
+
+
+## KworkError
+
+```python
+class KworkError(Exception)
+```
+
+Base exception for all Kwork API errors.
+
+
+
+#### KworkError.\_\_init\_\_
+
+```python
+def __init__(message: str, response: Optional[Any] = None)
+```
+
+
+
+#### KworkError.\_\_str\_\_
+
+```python
+def __str__() -> str
+```
+
+
+
+## KworkAuthError
+
+```python
+class KworkAuthError(KworkError)
+```
+
+Authentication/authorization error.
+
+
+
+#### KworkAuthError.\_\_init\_\_
+
+```python
+def __init__(message: str = "Authentication failed",
+ response: Optional[Any] = None)
+```
+
+
+
+#### KworkAuthError.\_\_str\_\_
+
+```python
+def __str__() -> str
+```
+
+
+
+## KworkApiError
+
+```python
+class KworkApiError(KworkError)
+```
+
+API request error (4xx, 5xx).
+
+
+
+#### KworkApiError.\_\_init\_\_
+
+```python
+def __init__(message: str,
+ status_code: Optional[int] = None,
+ response: Optional[Any] = None)
+```
+
+
+
+#### KworkApiError.\_\_str\_\_
+
+```python
+def __str__() -> str
+```
+
+
+
+## KworkNotFoundError
+
+```python
+class KworkNotFoundError(KworkApiError)
+```
+
+Resource not found (404).
+
+
+
+#### KworkNotFoundError.\_\_init\_\_
+
+```python
+def __init__(resource: str, response: Optional[Any] = None)
+```
+
+
+
+## KworkRateLimitError
+
+```python
+class KworkRateLimitError(KworkApiError)
+```
+
+Rate limit exceeded (429).
+
+
+
+#### KworkRateLimitError.\_\_init\_\_
+
+```python
+def __init__(message: str = "Rate limit exceeded",
+ response: Optional[Any] = None)
+```
+
+
+
+## KworkValidationError
+
+```python
+class KworkValidationError(KworkApiError)
+```
+
+Validation error (400).
+
+
+
+#### KworkValidationError.\_\_init\_\_
+
+```python
+def __init__(message: str = "Validation failed",
+ fields: Optional[dict[str, list[str]]] = None,
+ response: Optional[Any] = None)
+```
+
+
+
+#### KworkValidationError.\_\_str\_\_
+
+```python
+def __str__() -> str
+```
+
+
+
+## KworkNetworkError
+
+```python
+class KworkNetworkError(KworkError)
+```
+
+Network/connection error.
+
+
+
+#### KworkNetworkError.\_\_init\_\_
+
+```python
+def __init__(message: str = "Network error", response: Optional[Any] = None)
+```
+
+
+
+#### KworkNetworkError.\_\_str\_\_
+
+```python
+def __str__() -> str
+```
+
diff --git a/docs/api_reference.md b/docs/api_reference.md
index f8f2aae..e69de29 100644
--- a/docs/api_reference.md
+++ b/docs/api_reference.md
@@ -1,1949 +0,0 @@
-# Table of Contents
-
-* [kwork\_api](#kwork_api)
- * [KworkClient](#kwork_api.KworkClient)
- * [KworkError](#kwork_api.KworkError)
- * [KworkAuthError](#kwork_api.KworkAuthError)
- * [KworkApiError](#kwork_api.KworkApiError)
- * [\_\_version\_\_](#kwork_api.__version__)
- * [\_\_all\_\_](#kwork_api.__all__)
-* [kwork\_api.client](#kwork_api.client)
- * [logging](#kwork_api.client.logging)
- * [Any](#kwork_api.client.Any)
- * [Optional](#kwork_api.client.Optional)
- * [httpx](#kwork_api.client.httpx)
- * [HttpUrl](#kwork_api.client.HttpUrl)
- * [KworkApiError](#kwork_api.client.KworkApiError)
- * [KworkAuthError](#kwork_api.client.KworkAuthError)
- * [KworkError](#kwork_api.client.KworkError)
- * [KworkNetworkError](#kwork_api.client.KworkNetworkError)
- * [KworkNotFoundError](#kwork_api.client.KworkNotFoundError)
- * [KworkRateLimitError](#kwork_api.client.KworkRateLimitError)
- * [KworkValidationError](#kwork_api.client.KworkValidationError)
- * [APIErrorResponse](#kwork_api.client.APIErrorResponse)
- * [AuthResponse](#kwork_api.client.AuthResponse)
- * [Badge](#kwork_api.client.Badge)
- * [CatalogResponse](#kwork_api.client.CatalogResponse)
- * [City](#kwork_api.client.City)
- * [Country](#kwork_api.client.Country)
- * [DataResponse](#kwork_api.client.DataResponse)
- * [Dialog](#kwork_api.client.Dialog)
- * [Feature](#kwork_api.client.Feature)
- * [Kwork](#kwork_api.client.Kwork)
- * [KworkDetails](#kwork_api.client.KworkDetails)
- * [NotificationsResponse](#kwork_api.client.NotificationsResponse)
- * [Project](#kwork_api.client.Project)
- * [ProjectsResponse](#kwork_api.client.ProjectsResponse)
- * [Review](#kwork_api.client.Review)
- * [ReviewsResponse](#kwork_api.client.ReviewsResponse)
- * [TimeZone](#kwork_api.client.TimeZone)
- * [logger](#kwork_api.client.logger)
- * [KworkClient](#kwork_api.client.KworkClient)
- * [BASE\_URL](#kwork_api.client.KworkClient.BASE_URL)
- * [LOGIN\_URL](#kwork_api.client.KworkClient.LOGIN_URL)
- * [TOKEN\_URL](#kwork_api.client.KworkClient.TOKEN_URL)
- * [\_\_init\_\_](#kwork_api.client.KworkClient.__init__)
- * [login](#kwork_api.client.KworkClient.login)
- * [close](#kwork_api.client.KworkClient.close)
- * [\_\_aenter\_\_](#kwork_api.client.KworkClient.__aenter__)
- * [\_\_aexit\_\_](#kwork_api.client.KworkClient.__aexit__)
- * [CatalogAPI](#kwork_api.client.KworkClient.CatalogAPI)
- * [ProjectsAPI](#kwork_api.client.KworkClient.ProjectsAPI)
- * [UserAPI](#kwork_api.client.KworkClient.UserAPI)
- * [ReferenceAPI](#kwork_api.client.KworkClient.ReferenceAPI)
- * [NotificationsAPI](#kwork_api.client.KworkClient.NotificationsAPI)
- * [OtherAPI](#kwork_api.client.KworkClient.OtherAPI)
- * [catalog](#kwork_api.client.KworkClient.catalog)
- * [projects](#kwork_api.client.KworkClient.projects)
- * [user](#kwork_api.client.KworkClient.user)
- * [reference](#kwork_api.client.KworkClient.reference)
- * [notifications](#kwork_api.client.KworkClient.notifications)
- * [other](#kwork_api.client.KworkClient.other)
-* [kwork\_api.models](#kwork_api.models)
- * [datetime](#kwork_api.models.datetime)
- * [Any](#kwork_api.models.Any)
- * [Optional](#kwork_api.models.Optional)
- * [BaseModel](#kwork_api.models.BaseModel)
- * [Field](#kwork_api.models.Field)
- * [KworkUser](#kwork_api.models.KworkUser)
- * [id](#kwork_api.models.KworkUser.id)
- * [username](#kwork_api.models.KworkUser.username)
- * [avatar\_url](#kwork_api.models.KworkUser.avatar_url)
- * [is\_online](#kwork_api.models.KworkUser.is_online)
- * [rating](#kwork_api.models.KworkUser.rating)
- * [KworkCategory](#kwork_api.models.KworkCategory)
- * [id](#kwork_api.models.KworkCategory.id)
- * [name](#kwork_api.models.KworkCategory.name)
- * [slug](#kwork_api.models.KworkCategory.slug)
- * [parent\_id](#kwork_api.models.KworkCategory.parent_id)
- * [Kwork](#kwork_api.models.Kwork)
- * [id](#kwork_api.models.Kwork.id)
- * [title](#kwork_api.models.Kwork.title)
- * [description](#kwork_api.models.Kwork.description)
- * [price](#kwork_api.models.Kwork.price)
- * [currency](#kwork_api.models.Kwork.currency)
- * [category\_id](#kwork_api.models.Kwork.category_id)
- * [seller](#kwork_api.models.Kwork.seller)
- * [images](#kwork_api.models.Kwork.images)
- * [rating](#kwork_api.models.Kwork.rating)
- * [reviews\_count](#kwork_api.models.Kwork.reviews_count)
- * [created\_at](#kwork_api.models.Kwork.created_at)
- * [updated\_at](#kwork_api.models.Kwork.updated_at)
- * [KworkDetails](#kwork_api.models.KworkDetails)
- * [full\_description](#kwork_api.models.KworkDetails.full_description)
- * [requirements](#kwork_api.models.KworkDetails.requirements)
- * [delivery\_time](#kwork_api.models.KworkDetails.delivery_time)
- * [revisions](#kwork_api.models.KworkDetails.revisions)
- * [features](#kwork_api.models.KworkDetails.features)
- * [faq](#kwork_api.models.KworkDetails.faq)
- * [PaginationInfo](#kwork_api.models.PaginationInfo)
- * [current\_page](#kwork_api.models.PaginationInfo.current_page)
- * [total\_pages](#kwork_api.models.PaginationInfo.total_pages)
- * [total\_items](#kwork_api.models.PaginationInfo.total_items)
- * [items\_per\_page](#kwork_api.models.PaginationInfo.items_per_page)
- * [has\_next](#kwork_api.models.PaginationInfo.has_next)
- * [has\_prev](#kwork_api.models.PaginationInfo.has_prev)
- * [CatalogResponse](#kwork_api.models.CatalogResponse)
- * [kworks](#kwork_api.models.CatalogResponse.kworks)
- * [pagination](#kwork_api.models.CatalogResponse.pagination)
- * [filters](#kwork_api.models.CatalogResponse.filters)
- * [sort\_options](#kwork_api.models.CatalogResponse.sort_options)
- * [Project](#kwork_api.models.Project)
- * [id](#kwork_api.models.Project.id)
- * [title](#kwork_api.models.Project.title)
- * [description](#kwork_api.models.Project.description)
- * [budget](#kwork_api.models.Project.budget)
- * [budget\_type](#kwork_api.models.Project.budget_type)
- * [category\_id](#kwork_api.models.Project.category_id)
- * [customer](#kwork_api.models.Project.customer)
- * [status](#kwork_api.models.Project.status)
- * [created\_at](#kwork_api.models.Project.created_at)
- * [updated\_at](#kwork_api.models.Project.updated_at)
- * [bids\_count](#kwork_api.models.Project.bids_count)
- * [skills](#kwork_api.models.Project.skills)
- * [ProjectsResponse](#kwork_api.models.ProjectsResponse)
- * [projects](#kwork_api.models.ProjectsResponse.projects)
- * [pagination](#kwork_api.models.ProjectsResponse.pagination)
- * [Review](#kwork_api.models.Review)
- * [id](#kwork_api.models.Review.id)
- * [rating](#kwork_api.models.Review.rating)
- * [comment](#kwork_api.models.Review.comment)
- * [author](#kwork_api.models.Review.author)
- * [kwork\_id](#kwork_api.models.Review.kwork_id)
- * [created\_at](#kwork_api.models.Review.created_at)
- * [ReviewsResponse](#kwork_api.models.ReviewsResponse)
- * [reviews](#kwork_api.models.ReviewsResponse.reviews)
- * [pagination](#kwork_api.models.ReviewsResponse.pagination)
- * [average\_rating](#kwork_api.models.ReviewsResponse.average_rating)
- * [Notification](#kwork_api.models.Notification)
- * [id](#kwork_api.models.Notification.id)
- * [type](#kwork_api.models.Notification.type)
- * [title](#kwork_api.models.Notification.title)
- * [message](#kwork_api.models.Notification.message)
- * [is\_read](#kwork_api.models.Notification.is_read)
- * [created\_at](#kwork_api.models.Notification.created_at)
- * [link](#kwork_api.models.Notification.link)
- * [NotificationsResponse](#kwork_api.models.NotificationsResponse)
- * [notifications](#kwork_api.models.NotificationsResponse.notifications)
- * [unread\_count](#kwork_api.models.NotificationsResponse.unread_count)
- * [Dialog](#kwork_api.models.Dialog)
- * [id](#kwork_api.models.Dialog.id)
- * [participant](#kwork_api.models.Dialog.participant)
- * [last\_message](#kwork_api.models.Dialog.last_message)
- * [unread\_count](#kwork_api.models.Dialog.unread_count)
- * [updated\_at](#kwork_api.models.Dialog.updated_at)
- * [AuthResponse](#kwork_api.models.AuthResponse)
- * [success](#kwork_api.models.AuthResponse.success)
- * [user\_id](#kwork_api.models.AuthResponse.user_id)
- * [username](#kwork_api.models.AuthResponse.username)
- * [web\_auth\_token](#kwork_api.models.AuthResponse.web_auth_token)
- * [message](#kwork_api.models.AuthResponse.message)
- * [ErrorDetail](#kwork_api.models.ErrorDetail)
- * [code](#kwork_api.models.ErrorDetail.code)
- * [message](#kwork_api.models.ErrorDetail.message)
- * [field](#kwork_api.models.ErrorDetail.field)
- * [APIErrorResponse](#kwork_api.models.APIErrorResponse)
- * [success](#kwork_api.models.APIErrorResponse.success)
- * [errors](#kwork_api.models.APIErrorResponse.errors)
- * [message](#kwork_api.models.APIErrorResponse.message)
- * [City](#kwork_api.models.City)
- * [id](#kwork_api.models.City.id)
- * [name](#kwork_api.models.City.name)
- * [country\_id](#kwork_api.models.City.country_id)
- * [Country](#kwork_api.models.Country)
- * [id](#kwork_api.models.Country.id)
- * [name](#kwork_api.models.Country.name)
- * [code](#kwork_api.models.Country.code)
- * [cities](#kwork_api.models.Country.cities)
- * [TimeZone](#kwork_api.models.TimeZone)
- * [id](#kwork_api.models.TimeZone.id)
- * [name](#kwork_api.models.TimeZone.name)
- * [offset](#kwork_api.models.TimeZone.offset)
- * [Feature](#kwork_api.models.Feature)
- * [id](#kwork_api.models.Feature.id)
- * [name](#kwork_api.models.Feature.name)
- * [description](#kwork_api.models.Feature.description)
- * [price](#kwork_api.models.Feature.price)
- * [type](#kwork_api.models.Feature.type)
- * [Badge](#kwork_api.models.Badge)
- * [id](#kwork_api.models.Badge.id)
- * [name](#kwork_api.models.Badge.name)
- * [description](#kwork_api.models.Badge.description)
- * [icon\_url](#kwork_api.models.Badge.icon_url)
- * [DataResponse](#kwork_api.models.DataResponse)
- * [success](#kwork_api.models.DataResponse.success)
- * [data](#kwork_api.models.DataResponse.data)
- * [message](#kwork_api.models.DataResponse.message)
-* [kwork\_api.errors](#kwork_api.errors)
- * [Any](#kwork_api.errors.Any)
- * [Optional](#kwork_api.errors.Optional)
- * [KworkError](#kwork_api.errors.KworkError)
- * [\_\_init\_\_](#kwork_api.errors.KworkError.__init__)
- * [\_\_str\_\_](#kwork_api.errors.KworkError.__str__)
- * [KworkAuthError](#kwork_api.errors.KworkAuthError)
- * [\_\_init\_\_](#kwork_api.errors.KworkAuthError.__init__)
- * [\_\_str\_\_](#kwork_api.errors.KworkAuthError.__str__)
- * [KworkApiError](#kwork_api.errors.KworkApiError)
- * [\_\_init\_\_](#kwork_api.errors.KworkApiError.__init__)
- * [\_\_str\_\_](#kwork_api.errors.KworkApiError.__str__)
- * [KworkNotFoundError](#kwork_api.errors.KworkNotFoundError)
- * [\_\_init\_\_](#kwork_api.errors.KworkNotFoundError.__init__)
- * [KworkRateLimitError](#kwork_api.errors.KworkRateLimitError)
- * [\_\_init\_\_](#kwork_api.errors.KworkRateLimitError.__init__)
- * [KworkValidationError](#kwork_api.errors.KworkValidationError)
- * [\_\_init\_\_](#kwork_api.errors.KworkValidationError.__init__)
- * [\_\_str\_\_](#kwork_api.errors.KworkValidationError.__str__)
- * [KworkNetworkError](#kwork_api.errors.KworkNetworkError)
- * [\_\_init\_\_](#kwork_api.errors.KworkNetworkError.__init__)
- * [\_\_str\_\_](#kwork_api.errors.KworkNetworkError.__str__)
-
-
-
-# Module kwork\_api
-
-Kwork.ru API Client
-
-Unofficial Python client for Kwork.ru API.
-
-**Example**:
-
- from kwork_api import KworkClient
-
- # Login with credentials
- client = await KworkClient.login("username", "password")
-
- # Or restore from token
- client = KworkClient(token="your_web_auth_token")
-
- # Get catalog
- catalog = await client.catalog.get_list(page=1)
-
-
-
-## KworkClient
-
-
-
-## KworkError
-
-
-
-## KworkAuthError
-
-
-
-## KworkApiError
-
-
-
-#### \_\_version\_\_
-
-
-
-#### \_\_all\_\_
-
-
-
-# Module kwork\_api.client
-
-Kwork API Client.
-
-Main client class with authentication and all API endpoints.
-
-
-
-## logging
-
-
-
-## Any
-
-
-
-## Optional
-
-
-
-## httpx
-
-
-
-## HttpUrl
-
-
-
-## KworkApiError
-
-
-
-## KworkAuthError
-
-
-
-## KworkError
-
-
-
-## KworkNetworkError
-
-
-
-## KworkNotFoundError
-
-
-
-## KworkRateLimitError
-
-
-
-## KworkValidationError
-
-
-
-## APIErrorResponse
-
-
-
-## AuthResponse
-
-
-
-## Badge
-
-
-
-## CatalogResponse
-
-
-
-## City
-
-
-
-## Country
-
-
-
-## DataResponse
-
-
-
-## Dialog
-
-
-
-## Feature
-
-
-
-## Kwork
-
-
-
-## KworkDetails
-
-
-
-## NotificationsResponse
-
-
-
-## Project
-
-
-
-## ProjectsResponse
-
-
-
-## Review
-
-
-
-## ReviewsResponse
-
-
-
-## TimeZone
-
-
-
-#### logger
-
-
-
-## KworkClient
-
-```python
-class KworkClient()
-```
-
-Kwork.ru API client.
-
-Usage:
- # Login with credentials
- client = await KworkClient.login("username", "password")
-
- # Or restore from token
- client = KworkClient(token="your_web_auth_token")
-
- # Make requests
- catalog = await client.catalog.get_list(page=1)
-
-
-
-#### BASE\_URL
-
-
-
-#### LOGIN\_URL
-
-
-
-#### TOKEN\_URL
-
-
-
-#### KworkClient.\_\_init\_\_
-
-```python
-def __init__(token: Optional[str] = None,
- cookies: Optional[dict[str, str]] = None,
- timeout: float = 30.0,
- base_url: Optional[str] = None)
-```
-
-Initialize client.
-
-**Arguments**:
-
-- `token` - Web auth token (from getWebAuthToken)
-- `cookies` - Session cookies (optional, will be set from token)
-- `timeout` - Request timeout in seconds
-- `base_url` - Custom base URL (for testing)
-
-
-
-#### KworkClient.login
-
-```python
-@classmethod
-async def login(cls,
- username: str,
- password: str,
- timeout: float = 30.0) -> "KworkClient"
-```
-
-Login with username and password.
-
-**Arguments**:
-
-- `username` - Kwork username or email
-- `password` - Kwork password
-- `timeout` - Request timeout
-
-
-**Returns**:
-
- Authenticated KworkClient instance
-
-
-**Raises**:
-
-- `KworkAuthError` - If login fails
-
-
-
-#### KworkClient.close
-
-```python
-async def close() -> None
-```
-
-Close HTTP client.
-
-
-
-#### KworkClient.\_\_aenter\_\_
-
-```python
-async def __aenter__() -> "KworkClient"
-```
-
-
-
-#### KworkClient.\_\_aexit\_\_
-
-```python
-async def __aexit__(*args: Any) -> None
-```
-
-
-
-## CatalogAPI
-
-```python
-class CatalogAPI()
-```
-
-Catalog/Kworks API endpoints.
-
-
-
-#### CatalogAPI.\_\_init\_\_
-
-```python
-def __init__(client: "KworkClient")
-```
-
-
-
-#### CatalogAPI.get\_list
-
-```python
-async def get_list(page: int = 1,
- category_id: Optional[int] = None,
- sort: str = "recommend") -> CatalogResponse
-```
-
-Get kworks catalog.
-
-**Arguments**:
-
-- `page` - Page number
-- `category_id` - Category filter
-- `sort` - Sort option (recommend, price_asc, price_desc, etc.)
-
-
-**Returns**:
-
- CatalogResponse with kworks and pagination
-
-
-
-#### CatalogAPI.get\_details
-
-```python
-async def get_details(kwork_id: int) -> KworkDetails
-```
-
-Get kwork details.
-
-**Arguments**:
-
-- `kwork_id` - Kwork ID
-
-
-**Returns**:
-
- KworkDetails with full information
-
-
-
-#### CatalogAPI.get\_details\_extra
-
-```python
-async def get_details_extra(kwork_id: int) -> dict[str, Any]
-```
-
-Get additional kwork details.
-
-**Arguments**:
-
-- `kwork_id` - Kwork ID
-
-
-**Returns**:
-
- Extra details dict
-
-
-
-## ProjectsAPI
-
-```python
-class ProjectsAPI()
-```
-
-Projects (freelance orders) API endpoints.
-
-
-
-#### ProjectsAPI.\_\_init\_\_
-
-```python
-def __init__(client: "KworkClient")
-```
-
-
-
-#### ProjectsAPI.get\_list
-
-```python
-async def get_list(page: int = 1,
- category_id: Optional[int] = None) -> ProjectsResponse
-```
-
-Get projects list.
-
-**Arguments**:
-
-- `page` - Page number
-- `category_id` - Category filter
-
-
-**Returns**:
-
- ProjectsResponse with projects and pagination
-
-
-
-#### ProjectsAPI.get\_payer\_orders
-
-```python
-async def get_payer_orders() -> list[Project]
-```
-
-Get orders where user is customer.
-
-**Returns**:
-
- List of projects
-
-
-
-#### ProjectsAPI.get\_worker\_orders
-
-```python
-async def get_worker_orders() -> list[Project]
-```
-
-Get orders where user is performer.
-
-**Returns**:
-
- List of projects
-
-
-
-## UserAPI
-
-```python
-class UserAPI()
-```
-
-User API endpoints.
-
-
-
-#### UserAPI.\_\_init\_\_
-
-```python
-def __init__(client: "KworkClient")
-```
-
-
-
-#### UserAPI.get\_info
-
-```python
-async def get_info() -> dict[str, Any]
-```
-
-Get current user info.
-
-**Returns**:
-
- User info dict
-
-
-
-#### UserAPI.get\_reviews
-
-```python
-async def get_reviews(user_id: Optional[int] = None,
- page: int = 1) -> ReviewsResponse
-```
-
-Get user reviews.
-
-**Arguments**:
-
-- `user_id` - User ID (None for current user)
-- `page` - Page number
-
-
-**Returns**:
-
- ReviewsResponse
-
-
-
-#### UserAPI.get\_favorite\_kworks
-
-```python
-async def get_favorite_kworks() -> list[Kwork]
-```
-
-Get favorite kworks.
-
-**Returns**:
-
- List of kworks
-
-
-
-## ReferenceAPI
-
-```python
-class ReferenceAPI()
-```
-
-Reference data (cities, countries, etc.) endpoints.
-
-
-
-#### ReferenceAPI.\_\_init\_\_
-
-```python
-def __init__(client: "KworkClient")
-```
-
-
-
-#### ReferenceAPI.get\_cities
-
-```python
-async def get_cities() -> list[City]
-```
-
-Get all cities.
-
-
-
-#### ReferenceAPI.get\_countries
-
-```python
-async def get_countries() -> list[Country]
-```
-
-Get all countries.
-
-
-
-#### ReferenceAPI.get\_timezones
-
-```python
-async def get_timezones() -> list[TimeZone]
-```
-
-Get all timezones.
-
-
-
-#### ReferenceAPI.get\_features
-
-```python
-async def get_features() -> list[Feature]
-```
-
-Get available features.
-
-
-
-#### ReferenceAPI.get\_public\_features
-
-```python
-async def get_public_features() -> list[Feature]
-```
-
-Get public features.
-
-
-
-#### ReferenceAPI.get\_badges\_info
-
-```python
-async def get_badges_info() -> list[Badge]
-```
-
-Get badges info.
-
-
-
-## NotificationsAPI
-
-```python
-class NotificationsAPI()
-```
-
-Notifications and messages endpoints.
-
-
-
-#### NotificationsAPI.\_\_init\_\_
-
-```python
-def __init__(client: "KworkClient")
-```
-
-
-
-#### NotificationsAPI.get\_list
-
-```python
-async def get_list() -> NotificationsResponse
-```
-
-Get notifications list.
-
-
-
-#### NotificationsAPI.fetch
-
-```python
-async def fetch() -> NotificationsResponse
-```
-
-Fetch new notifications.
-
-
-
-#### NotificationsAPI.get\_dialogs
-
-```python
-async def get_dialogs() -> list[Dialog]
-```
-
-Get dialogs list.
-
-
-
-#### NotificationsAPI.get\_blocked\_dialogs
-
-```python
-async def get_blocked_dialogs() -> list[Dialog]
-```
-
-Get blocked dialogs.
-
-
-
-## OtherAPI
-
-```python
-class OtherAPI()
-```
-
-Other API endpoints.
-
-
-
-#### OtherAPI.\_\_init\_\_
-
-```python
-def __init__(client: "KworkClient")
-```
-
-
-
-#### OtherAPI.get\_wants
-
-```python
-async def get_wants() -> dict[str, Any]
-```
-
-Get user wants.
-
-
-
-#### OtherAPI.get\_wants\_status
-
-```python
-async def get_wants_status() -> dict[str, Any]
-```
-
-Get wants status.
-
-
-
-#### OtherAPI.get\_kworks\_status
-
-```python
-async def get_kworks_status() -> dict[str, Any]
-```
-
-Get kworks status.
-
-
-
-#### OtherAPI.get\_offers
-
-```python
-async def get_offers() -> dict[str, Any]
-```
-
-Get offers.
-
-
-
-#### OtherAPI.get\_exchange\_info
-
-```python
-async def get_exchange_info() -> dict[str, Any]
-```
-
-Get exchange info.
-
-
-
-#### OtherAPI.get\_channel
-
-```python
-async def get_channel() -> dict[str, Any]
-```
-
-Get channel info.
-
-
-
-#### OtherAPI.get\_in\_app\_notification
-
-```python
-async def get_in_app_notification() -> dict[str, Any]
-```
-
-Get in-app notification.
-
-
-
-#### OtherAPI.get\_security\_user\_data
-
-```python
-async def get_security_user_data() -> dict[str, Any]
-```
-
-Get security user data.
-
-
-
-#### OtherAPI.is\_dialog\_allow
-
-```python
-async def is_dialog_allow(user_id: int) -> bool
-```
-
-Check if dialog is allowed.
-
-
-
-#### OtherAPI.get\_viewed\_kworks
-
-```python
-async def get_viewed_kworks() -> list[Kwork]
-```
-
-Get viewed kworks.
-
-
-
-#### OtherAPI.get\_favorite\_categories
-
-```python
-async def get_favorite_categories() -> list[int]
-```
-
-Get favorite categories.
-
-
-
-#### OtherAPI.update\_settings
-
-```python
-async def update_settings(settings: dict[str, Any]) -> dict[str, Any]
-```
-
-Update user settings.
-
-
-
-#### OtherAPI.go\_offline
-
-```python
-async def go_offline() -> dict[str, Any]
-```
-
-Set user status to offline.
-
-
-
-#### OtherAPI.get\_actor
-
-```python
-async def get_actor() -> dict[str, Any]
-```
-
-Get actor info.
-
-
-
-#### KworkClient.catalog
-
-```python
-@property
-def catalog() -> CatalogAPI
-```
-
-Catalog API.
-
-
-
-#### KworkClient.projects
-
-```python
-@property
-def projects() -> ProjectsAPI
-```
-
-Projects API.
-
-
-
-#### KworkClient.user
-
-```python
-@property
-def user() -> UserAPI
-```
-
-User API.
-
-
-
-#### KworkClient.reference
-
-```python
-@property
-def reference() -> ReferenceAPI
-```
-
-Reference data API.
-
-
-
-#### KworkClient.notifications
-
-```python
-@property
-def notifications() -> NotificationsAPI
-```
-
-Notifications API.
-
-
-
-#### KworkClient.other
-
-```python
-@property
-def other() -> OtherAPI
-```
-
-Other endpoints.
-
-
-
-# Module kwork\_api.models
-
-Pydantic models for Kwork API responses.
-
-All models follow the structure found in the HAR dump analysis.
-
-
-
-## datetime
-
-
-
-## Any
-
-
-
-## Optional
-
-
-
-## BaseModel
-
-
-
-## Field
-
-
-
-## KworkUser
-
-```python
-class KworkUser(BaseModel)
-```
-
-User information.
-
-
-
-#### id
-
-
-
-#### username
-
-
-
-#### avatar\_url
-
-
-
-#### is\_online
-
-
-
-#### rating
-
-
-
-## KworkCategory
-
-```python
-class KworkCategory(BaseModel)
-```
-
-Category information.
-
-
-
-#### id
-
-
-
-#### name
-
-
-
-#### slug
-
-
-
-#### parent\_id
-
-
-
-## Kwork
-
-```python
-class Kwork(BaseModel)
-```
-
-Kwork (service) information.
-
-
-
-#### id
-
-
-
-#### title
-
-
-
-#### description
-
-
-
-#### price
-
-
-
-#### currency
-
-
-
-#### category\_id
-
-
-
-#### seller
-
-
-
-#### images
-
-
-
-#### rating
-
-
-
-#### reviews\_count
-
-
-
-#### created\_at
-
-
-
-#### updated\_at
-
-
-
-## KworkDetails
-
-```python
-class KworkDetails(Kwork)
-```
-
-Extended kwork details.
-
-
-
-#### full\_description
-
-
-
-#### requirements
-
-
-
-#### delivery\_time
-
-in days
-
-
-
-#### revisions
-
-
-
-#### features
-
-
-
-#### faq
-
-
-
-## PaginationInfo
-
-```python
-class PaginationInfo(BaseModel)
-```
-
-Pagination metadata.
-
-
-
-#### current\_page
-
-
-
-#### total\_pages
-
-
-
-#### total\_items
-
-
-
-#### items\_per\_page
-
-
-
-#### has\_next
-
-
-
-#### has\_prev
-
-
-
-## CatalogResponse
-
-```python
-class CatalogResponse(BaseModel)
-```
-
-Catalog response with kworks and pagination.
-
-
-
-#### kworks
-
-
-
-#### pagination
-
-
-
-#### filters
-
-
-
-#### sort\_options
-
-
-
-## Project
-
-```python
-class Project(BaseModel)
-```
-
-Project (freelance order) information.
-
-
-
-#### id
-
-
-
-#### title
-
-
-
-#### description
-
-
-
-#### budget
-
-
-
-#### budget\_type
-
-fixed, hourly
-
-
-
-#### category\_id
-
-
-
-#### customer
-
-
-
-#### status
-
-open, in_progress, completed, cancelled
-
-
-
-#### created\_at
-
-
-
-#### updated\_at
-
-
-
-#### bids\_count
-
-
-
-#### skills
-
-
-
-## ProjectsResponse
-
-```python
-class ProjectsResponse(BaseModel)
-```
-
-Projects list response.
-
-
-
-#### projects
-
-
-
-#### pagination
-
-
-
-## Review
-
-```python
-class Review(BaseModel)
-```
-
-Review information.
-
-
-
-#### id
-
-
-
-#### rating
-
-
-
-#### comment
-
-
-
-#### author
-
-
-
-#### kwork\_id
-
-
-
-#### created\_at
-
-
-
-## ReviewsResponse
-
-```python
-class ReviewsResponse(BaseModel)
-```
-
-Reviews list response.
-
-
-
-#### reviews
-
-
-
-#### pagination
-
-
-
-#### average\_rating
-
-
-
-## Notification
-
-```python
-class Notification(BaseModel)
-```
-
-Notification information.
-
-
-
-#### id
-
-
-
-#### type
-
-message, order, system, etc.
-
-
-
-#### title
-
-
-
-#### message
-
-
-
-#### is\_read
-
-
-
-#### created\_at
-
-
-
-#### link
-
-
-
-## NotificationsResponse
-
-```python
-class NotificationsResponse(BaseModel)
-```
-
-Notifications list response.
-
-
-
-#### notifications
-
-
-
-#### unread\_count
-
-
-
-## Dialog
-
-```python
-class Dialog(BaseModel)
-```
-
-Dialog (chat) information.
-
-
-
-#### id
-
-
-
-#### participant
-
-
-
-#### last\_message
-
-
-
-#### unread\_count
-
-
-
-#### updated\_at
-
-
-
-## AuthResponse
-
-```python
-class AuthResponse(BaseModel)
-```
-
-Authentication response.
-
-
-
-#### success
-
-
-
-#### user\_id
-
-
-
-#### username
-
-
-
-#### web\_auth\_token
-
-
-
-#### message
-
-
-
-## ErrorDetail
-
-```python
-class ErrorDetail(BaseModel)
-```
-
-Error detail from API.
-
-
-
-#### code
-
-
-
-#### message
-
-
-
-#### field
-
-
-
-## APIErrorResponse
-
-```python
-class APIErrorResponse(BaseModel)
-```
-
-Standard API error response.
-
-
-
-#### success
-
-
-
-#### errors
-
-
-
-#### message
-
-
-
-## City
-
-```python
-class City(BaseModel)
-```
-
-City information.
-
-
-
-#### id
-
-
-
-#### name
-
-
-
-#### country\_id
-
-
-
-## Country
-
-```python
-class Country(BaseModel)
-```
-
-Country information.
-
-
-
-#### id
-
-
-
-#### name
-
-
-
-#### code
-
-
-
-#### cities
-
-
-
-## TimeZone
-
-```python
-class TimeZone(BaseModel)
-```
-
-Timezone information.
-
-
-
-#### id
-
-
-
-#### name
-
-
-
-#### offset
-
-e.g., "+03:00"
-
-
-
-## Feature
-
-```python
-class Feature(BaseModel)
-```
-
-Feature/addon information.
-
-
-
-#### id
-
-
-
-#### name
-
-
-
-#### description
-
-
-
-#### price
-
-
-
-#### type
-
-extra, premium, etc.
-
-
-
-## Badge
-
-```python
-class Badge(BaseModel)
-```
-
-User badge information.
-
-
-
-#### id
-
-
-
-#### name
-
-
-
-#### description
-
-
-
-#### icon\_url
-
-
-
-## DataResponse
-
-```python
-class DataResponse(BaseModel)
-```
-
-Generic data response wrapper.
-
-
-
-#### success
-
-
-
-#### data
-
-
-
-#### message
-
-
-
-# Module kwork\_api.errors
-
-Kwork API exceptions.
-
-All exceptions provide clear error messages for debugging.
-
-
-
-## Any
-
-
-
-## Optional
-
-
-
-## KworkError
-
-```python
-class KworkError(Exception)
-```
-
-Base exception for all Kwork API errors.
-
-
-
-#### KworkError.\_\_init\_\_
-
-```python
-def __init__(message: str, response: Optional[Any] = None)
-```
-
-
-
-#### KworkError.\_\_str\_\_
-
-```python
-def __str__() -> str
-```
-
-
-
-## KworkAuthError
-
-```python
-class KworkAuthError(KworkError)
-```
-
-Authentication/authorization error.
-
-
-
-#### KworkAuthError.\_\_init\_\_
-
-```python
-def __init__(message: str = "Authentication failed",
- response: Optional[Any] = None)
-```
-
-
-
-#### KworkAuthError.\_\_str\_\_
-
-```python
-def __str__() -> str
-```
-
-
-
-## KworkApiError
-
-```python
-class KworkApiError(KworkError)
-```
-
-API request error (4xx, 5xx).
-
-
-
-#### KworkApiError.\_\_init\_\_
-
-```python
-def __init__(message: str,
- status_code: Optional[int] = None,
- response: Optional[Any] = None)
-```
-
-
-
-#### KworkApiError.\_\_str\_\_
-
-```python
-def __str__() -> str
-```
-
-
-
-## KworkNotFoundError
-
-```python
-class KworkNotFoundError(KworkApiError)
-```
-
-Resource not found (404).
-
-
-
-#### KworkNotFoundError.\_\_init\_\_
-
-```python
-def __init__(resource: str, response: Optional[Any] = None)
-```
-
-
-
-## KworkRateLimitError
-
-```python
-class KworkRateLimitError(KworkApiError)
-```
-
-Rate limit exceeded (429).
-
-
-
-#### KworkRateLimitError.\_\_init\_\_
-
-```python
-def __init__(message: str = "Rate limit exceeded",
- response: Optional[Any] = None)
-```
-
-
-
-## KworkValidationError
-
-```python
-class KworkValidationError(KworkApiError)
-```
-
-Validation error (400).
-
-
-
-#### KworkValidationError.\_\_init\_\_
-
-```python
-def __init__(message: str = "Validation failed",
- fields: Optional[dict[str, list[str]]] = None,
- response: Optional[Any] = None)
-```
-
-
-
-#### KworkValidationError.\_\_str\_\_
-
-```python
-def __str__() -> str
-```
-
-
-
-## KworkNetworkError
-
-```python
-class KworkNetworkError(KworkError)
-```
-
-Network/connection error.
-
-
-
-#### KworkNetworkError.\_\_init\_\_
-
-```python
-def __init__(message: str = "Network error", response: Optional[Any] = None)
-```
-
-
-
-#### KworkNetworkError.\_\_str\_\_
-
-```python
-def __str__() -> str
-```
-
diff --git a/pyproject.toml b/pyproject.toml
index 8ea4e99..5adea36 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -99,5 +99,4 @@ exclude_lines = [
"if TYPE_CHECKING:",
]
-[project.scripts]
-gen-docs = "scripts.gen_docs:main"
+
diff --git a/scripts/gen_docs.py b/scripts/gen_docs.py
deleted file mode 100644
index c339d31..0000000
--- a/scripts/gen_docs.py
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/usr/bin/env python3
-"""Generate API documentation using pydoc-markdown."""
-
-import subprocess
-import sys
-from pathlib import Path
-
-
-def main():
- """Generate API documentation."""
- project_root = Path(__file__).parent.parent
- docs_dir = project_root / "docs"
-
- docs_dir.mkdir(exist_ok=True)
-
- print("š Generating API documentation...")
- result = subprocess.run(
- ["pydoc-markdown"],
- cwd=project_root,
- capture_output=False,
- )
-
- if result.returncode != 0:
- print("ā Failed to generate documentation")
- return 1
-
- # Move generated file to docs/
- generated = project_root / "api_reference.md"
- if generated.exists():
- generated.rename(docs_dir / "api_reference.md")
- print("ā
Documentation generated: docs/api_reference.md")
- else:
- print("ā api_reference.md not found")
- return 1
-
- print("\n⨠Done!")
- return 0
-
-
-if __name__ == "__main__":
- sys.exit(main())