π Build WhatsApp Bots in Python β’ Fast. Effortless. Powerful.
π€ Hey there! I am using PyWa.
π« PyWa is an all-in-one Python framework for the WhatsApp Cloud API.
Send rich media messages, use interactive buttons, listen to real-time events, build and send flows, design and send template messages, and enjoy blazing-fast async support with full integration for FastAPI, Flask, and more. Fully typed, documented, and production-ready β build powerful bots in minutes.
π Quick Documentation Index#
β‘ Why PyWa?#
π Fast & Simple β Focus on building, not boilerplate.
π¬ Rich Messaging β Text, images, files, audio, locations, contacts, buttons & more.
π© Real-Time Updates β Messages, callbacks, delivery/read receipts, account updates, and more.
π Listeners β Wait for user replies, clicks, or reactions with ease.
π Templates β Create and send powerful WhatsApp templates.
β»οΈ Flows β Build interactive WhatsApp flows effortlessly.
π Calls Support β Receive and handle call events.
π Webhook-Ready β Built-in server for development and production, or attach to your own FastAPI/Flask app.
π¬ Filters β Advanced filtering for incoming updates.
β Production-Ready β Typed, documented, and fully tested.
π¨βπ» How to Use#
1. Handle incoming messages#
Start with a WhatsApp client and register handlers for the updates you want to receive.
During development, run the webhook server with pywa dev. For production, use pywa run.
# main.py
from pywa import WhatsApp, filters, types, utils
callback_url = utils.start_ngrok_tunnel(
auth_token="NGROK_AUTH_TOKEN",
domain="your-domain.ngrok-free.app",
)
wa = WhatsApp(
phone_id="1234567890",
token="EAA...",
app_id="1234567890",
app_secret="********",
callback_url=callback_url,
verify_token="my-verify-token",
)
@wa.on_message(filters.text)
def echo(client: WhatsApp, msg: types.Message):
msg.reply(f"You said: {msg.text}")
Run it:
pywa dev
Use this when deploying:
pywa run
See the Handlers guide for decorators, filters, callback URL registration, custom servers, and handler flow.
2. Send messages, media, templates, flows, and manage resources#
Use the same client to send messages, media, templates, flows, and to manage WhatsApp Business resources.
from pywa import WhatsApp, types
wa = WhatsApp(
phone_id="1234567890",
token="EAA...",
)
wa.send_message(
to="9876543210",
text="Hello from PyWa!",
buttons=[
types.Button(title="Menu", callback_data="menu"),
types.Button(title="Help", callback_data="help"),
],
)
wa.send_image(
to="9876543210",
image="https://example.com/image.jpg",
caption="Check out this image!",
)
See the Client guide for the full API.
3. Listen for the next user response#
Handlers are great for entry points. When you need to continue a conversation, use listeners.
from pywa import WhatsApp, filters, types
wa = WhatsApp(...)
@wa.on_message(filters.command("start"))
def start(client: WhatsApp, msg: types.Message):
name = msg.reply("What's your name?").wait_for_reply(filters=filters.text).text
msg.reply(f"Nice to meet you, {name}!")
See the Listeners guide for timeouts, filters, callbacks, and waiting for clicks or replies.
4. Use your own server when needed#
The CLI is the easiest way to run pywa, but you can also attach pywa to an existing FastAPI or Flask app.
from fastapi import FastAPI
from pywa import WhatsApp, filters, types
app = FastAPI()
wa = WhatsApp(
...,
server=app,
webhook_endpoint="/whatsapp",
)
@wa.on_message(filters.text)
def echo(client: WhatsApp, msg: types.Message):
msg.reply(msg.text)
Run your server normally
5. Async usage#
PyWa also supports async usage with the same API. Replace imports from pywa with pywa_async
and use await.
from pywa_async import WhatsApp, filters, types, utils
callback_url = utils.start_ngrok_tunnel(auth_token="NGROK_AUTH_TOKEN")
wa = WhatsApp(..., callback_url=callback_url)
@wa.on_message(filters.text)
async def hello(client: WhatsApp, msg: types.Message):
await msg.react("π")
await msg.reply("Hello from PyWa Async!")
6. Create and send template messages#
See Templates for more details and examples.
from pywa import WhatsApp
from pywa.types.templates import *
wa = WhatsApp(..., waba_id=123456)
# Create a template
wa.create_template(
template=Template(
name="buy_new_iphone_x",
category=TemplateCategory.MARKETING,
language=TemplateLanguage.ENGLISH_US,
parameter_format=ParamFormat.NAMED,
components=[
ht := HeaderText("The New iPhone {{iphone_num}} is here!", iphone_num=15),
bt := BodyText("Buy now and use the code {{code}} to get {{per}}% off!", code="WA_IPHONE_15", per=15),
FooterText(text="Powered by PyWa"),
Buttons(
buttons=[
url := URLButton(text="Buy Now", url="https://example.com/shop/{{1}}", example="iphone15"),
PhoneNumberButton(text="Call Us", phone_number="1234567890"),
qrb1 := QuickReplyButton(text="Unsubscribe from marketing messages"),
qrb2 := QuickReplyButton(text="Unsubscribe from all messages"),
]
),
]
),
)
# Send the template message
wa.send_template(
to="9876543210",
name="buy_new_iphone_x",
language=TemplateLanguage.ENGLISH_US,
params=[
ht.params(iphone_num=30),
bt.params(code="WA_IPHONE_30", per=30),
url.params(url_variable="iphone30", index=0),
qrb1.params(callback_data="unsubscribe_from_marketing_messages", index=1),
qrb2.params(callback_data="unsubscribe_from_all_messages", index=2),
]
)
7. Create and send flows#
See Flows for much more details and examples.
from pywa import WhatsApp, types
from pywa.types.flows import *
# Create a WhatsApp client
wa = WhatsApp(..., waba_id=123456)
# Build a flow
my_flow_json = FlowJSON(
screens=[
Screen(
id="NEWSLETTER",
title="PyWa Newsletter",
layout=Layout(
children=[
TextHeading(text="Subscribe to our newsletter"),
name := TextInput(
name="name",
label="Name",
input_type=InputType.TEXT,
required=False,
),
email := TextInput(
name="email",
label="Email",
input_type=InputType.EMAIL,
required=True,
),
Footer(
label="Subscribe",
on_click_action=CompleteAction(
payload={ # Payload to send to the server
"name": name.ref,
"email": email.ref,
}
)
)
]
)
)
]
)
# Create the flow
wa.create_flow(
name="subscribe_to_newsletter",
categories=[FlowCategory.SIGN_UP, FlowCategory.OTHER],
flow_json=my_flow_json,
publish=True
)
# Send the flow to a user
wa.send_text(
to="9876543210",
text="Hello from PyWa!",
buttons=types.FlowButton(
title="Subscribe to our newsletter!",
flow_name="subscribe_to_newsletter",
)
)
# Handle the flow response
@wa.on_flow_completion
def handle_flow_response(_: WhatsApp, flow: types.FlowCompletion):
flow.reply(
text=f"Thank you for subscribing to our newsletter, {flow.response['name']}! "
f"We will send you updates to {flow.response['email']}.",
buttons=[types.Button(title="Unsubscribe", callback_data="unsubscribe")]
)
π Installation#
Install using pip3:
pip3 install -U pywa
Install the built-in webhook server for
pywa devandpywa run:
pip3 install -U "pywa[server]"
Install ngrok if you want to use
utils.start_ngrok_tunnel()for local development:
pip3 install -U ngrok
Install from source (the bleeding edge):
pip3 install -U git+https://github.com/david-lev/pywa.git
If you use Flows and want pywaβs default encryption helpers:
pip3 install -U "pywa[cryptography]"
πΎ Requirements#
Python 3.10 or higher - https://www.python.org
π Setup and Usage#
See the Documentation for detailed instructions
βοΈ License#
This project is licensed under the MIT License - see the LICENSE file for details
π± Contributing#
Contributions are welcome! Please see the Contributing Guide for more information.
π£ Community#
Join the Telegram Group to discuss, ask questions, and share your projects built with PyWa!
π Changelog#
NOTE: pywa follows the semver versioning standard.
4.0.0b7 (2026-04-30) Latest Beta#
[helpers] fix incoming updates in
fastapiandstarlette[helpers] hide webhook endpoints from OpenAPI schema
[ci] streamline publish workflow for PyPI
4.0.0b6 (2026-04-25)#
[client] add
runmethod to start the webhook server and listen for updates[server] refactor webhook handling to include validation and improve endpoint management
[user] make
profiletemporary optional for testing[utils] add
start_ngrok_tunnelfunction to facilitate local webhook testing[templates] enhance
duplicatemethod to includetarget_waba_idparameter for template creation[templates] add validation for URL variables in
URLButtonto enforce constraints on example and variable usage
4.0.0b5 (2026-04-17)#
[client] add methods for creating and verifying phone numbers on WhatsApp Business Account
[templates] enhance
TemplateandTemplateDetailswith new methods for component retrieval and validation[templates] add
param_namesproperty for introspection of named parameters[templates] enhance error handling for positional and named examples in
HeaderTextandBodyText[templates] enhance
CreativeFeaturesSpecwith new attributes for improved media handling and text optimization[templates] remove
TemplateSubCategoryclass and updatesub_categorytype to string[message] fix reply to message in
EditedMessageandDeletedMessage
See the full changelog here.
π Contents#
- βοΈ Get Started
- π Client
WhatsApp- Sending Messages
- Handling Updates
- Listening
- Media
- Templates
- Flows
- Business
- Managing Users
- QR Codes
- Commerce
- Calls
- Groups
- Server
- Partner tools
- Others
- Client Reference
WhatsApp.send_message()WhatsApp.send_image()WhatsApp.send_video()WhatsApp.send_audio()WhatsApp.send_voice()WhatsApp.send_document()WhatsApp.send_location()WhatsApp.request_location()WhatsApp.send_contact()WhatsApp.send_sticker()WhatsApp.send_catalog()WhatsApp.send_template()WhatsApp.send_product()WhatsApp.send_products()WhatsApp.send_carousel()WhatsApp.send_reaction()WhatsApp.remove_reaction()WhatsApp.mark_message_as_read()WhatsApp.indicate_typing()WhatsApp.listen()WhatsApp.stop_listening()WhatsApp.upload_media()WhatsApp.download_media()WhatsApp.stream_media()WhatsApp.get_media_bytes()WhatsApp.get_media_url()WhatsApp.delete_media()WhatsApp.get_business_account()WhatsApp.update_business_account_settings()WhatsApp.get_business_profile()WhatsApp.get_business_phone_numbers()WhatsApp.get_business_phone_number()WhatsApp.get_business_phone_number_settings()WhatsApp.update_business_phone_number_settings()WhatsApp.update_business_profile()WhatsApp.update_display_name()WhatsApp.update_conversational_automation()WhatsApp.set_business_public_key()WhatsApp.get_commerce_settings()WhatsApp.update_commerce_settings()WhatsApp.create_template()WhatsApp.upsert_authentication_template()WhatsApp.update_template()WhatsApp.get_template()WhatsApp.get_templates()WhatsApp.delete_template()WhatsApp.unpause_template()WhatsApp.compare_templates()WhatsApp.migrate_templates()WhatsApp.create_flow()WhatsApp.update_flow_metadata()WhatsApp.update_flow_json()WhatsApp.publish_flow()WhatsApp.delete_flow()WhatsApp.deprecate_flow()WhatsApp.get_flow()WhatsApp.get_flows()WhatsApp.get_flow_metrics()WhatsApp.get_flow_assets()WhatsApp.migrate_flows()WhatsApp.block_users()WhatsApp.unblock_users()WhatsApp.get_blocked_users()WhatsApp.register_phone_number()WhatsApp.deregister_phone_number()WhatsApp.create_phone_number()WhatsApp.request_verification_code()WhatsApp.verify_phone_number()WhatsApp.create_qr_code()WhatsApp.get_qr_code()WhatsApp.get_qr_codes()WhatsApp.update_qr_code()WhatsApp.delete_qr_code()WhatsApp.set_username()WhatsApp.get_current_username()WhatsApp.get_reserved_usernames()WhatsApp.delete_username()WhatsApp.delete_qr_code()WhatsApp.get_call_permissions()WhatsApp.pre_accept_call()WhatsApp.accept_call()WhatsApp.reject_call()WhatsApp.terminate_call()WhatsApp.create_group()WhatsApp.get_group()WhatsApp.get_groups()WhatsApp.delete_group()WhatsApp.approve_group_join_requests()WhatsApp.reject_group_join_requests()WhatsApp.get_group_invite_link()WhatsApp.reset_group_invite_link()WhatsApp.remove_group_participants()WhatsApp.update_group_settings()WhatsApp.pin_message()WhatsApp.unpin_message()WhatsApp.get_app_access_token()WhatsApp.set_app_callback_url()WhatsApp.override_waba_callback_url()WhatsApp.delete_waba_callback_url()WhatsApp.override_phone_callback_url()WhatsApp.get_shared_business_accounts()WhatsApp.get_owned_business_accounts()WhatsApp.delete_phone_callback_url()WhatsApp.run()WhatsApp.webhook_update_handler()WhatsApp.webhook_update_validator()WhatsApp.webhook_challenge_handler()WhatsApp.get_flow_request_handler()WhatsApp.load_handlers_modules()
- API Reference
- Client Reference
- ποΈ Handlers
- Your First Handler
- Registering Handlers
- Available Handlers
- Handlers or Listeners?
- Making WhatsApp Reach Your App
- Registering the Callback URL
- Subscribing to Webhook Fields
- Running pywa
- Handler Order and Flow
- Validating Updates
- Using Other Web Frameworks
- What pywa runs
- Handler Decorators
WhatsApp.on_message()WhatsApp.on_callback_button()WhatsApp.on_callback_selection()WhatsApp.on_flow_completion()WhatsApp.on_flow_request()WhatsApp.on_message_status()WhatsApp.on_phone_number_change()WhatsApp.on_identity_change()WhatsApp.on_call_connect()WhatsApp.on_call_terminate()WhatsApp.on_call_status()WhatsApp.on_call_permission_update()WhatsApp.on_user_marketing_preferences()WhatsApp.on_template_status_update()WhatsApp.on_template_category_update()WhatsApp.on_template_quality_update()WhatsApp.on_template_components_update()WhatsApp.on_edited_message()WhatsApp.on_deleted_message()WhatsApp.on_outgoing_message()WhatsApp.on_outgoing_edited_message()WhatsApp.on_outgoing_deleted_message()WhatsApp.on_account_update()WhatsApp.on_raw_update()WhatsApp.remove_callbacks()WhatsApp.load_handlers_modules()
- Handler Objects
WhatsApp.add_handlers()WhatsApp.add_flow_request_handler()WhatsApp.remove_handlers()MessageHandlerCallbackButtonHandlerCallbackSelectionHandlerFlowCompletionHandlerFlowRequestHandlerMessageStatusHandlerPhoneNumberChangeHandlerIdentityChangeHandlerCallConnectHandlerCallTerminateHandlerCallStatusHandlerCallPermissionUpdateHandlerUserMarketingPreferencesHandlerTemplateStatusUpdateHandlerTemplateCategoryUpdateHandlerTemplateQualityUpdateHandlerTemplateComponentsUpdateHandlerEditedMessageHandlerDeletedMessageHandlerOutgoingMessageHandlerOutgoingEditedMessageHandlerOutgoingDeletedMessageHandlerAccountUpdateHandlerRawUpdateHandler
- Handler Decorators
- π₯ Listeners
- Listening
- Canceling
- Handling cancel and timeout
- Custom listeners
- Shortcuts
- Listeners reference
SentMessage.wait_for_reply()SentMessage.wait_for_click()SentMessage.wait_for_selection()SentMessage.wait_until_read()SentMessage.wait_until_delivered()SentMessage.wait_for_completion()SentMessage.wait_for_call_permission()SentMessage.wait_for_incoming_voice_call()SentVoiceMessage.wait_until_played()SentLocationRequest.wait_for_location()CreatedTemplate.wait_until_approved()ListenerTimeoutListenerCanceledListenerStopped
- Listeners reference
- π¬ Updates
- Supported Fields
- Update Types
- Common Properties
- Message
- Callback Button
- Callback Selection
- Flow Completion
- Message Status
- Phone Number Change
- Identity Change
- Call Connect
- Call Terminate
- Call Status
- Call Permission Update
- User Marketing Preferences
- Template Status Update
- Template Category Update
- Template Quality Update
- Template Components Update
- Edited Message
- Deleted Message
- Outgoing Message
- Outgoing Edited Message
- Outgoing Deleted Message
- Account Update
- Raw Update
- Common methods
BaseUpdateBaseUserUpdateBaseUserUpdate.senderBaseUserUpdate.recipientBaseUserUpdate.block_sender()BaseUserUpdate.call()BaseUserUpdate.indicate_typing()BaseUserUpdate.mark_as_read()BaseUserUpdate.react()BaseUserUpdate.reply_audio()BaseUserUpdate.reply_carousel()BaseUserUpdate.reply_catalog()BaseUserUpdate.reply_contact()BaseUserUpdate.reply_document()BaseUserUpdate.reply_image()BaseUserUpdate.reply_location()BaseUserUpdate.reply_location_request()BaseUserUpdate.reply_product()BaseUserUpdate.reply_products()BaseUserUpdate.reply_sticker()BaseUserUpdate.reply_template()BaseUserUpdate.reply_text()BaseUserUpdate.reply_video()BaseUserUpdate.reply_voice()BaseUserUpdate.unreact()BaseUserUpdate.unblock_sender()BaseUserUpdate.message_id_to_reply
- β»οΈ Flows
- Creating Flow
- Available components
- Sending Flow
- Getting Flow Completion message
- Handling Flow requests
- Flow JSON
FlowJSONScreenScreenDataScreenDataUpdateLayoutLayoutTypeFormFormComponentTextHeadingTextSubheadingTextBodyTextCaptionRichTextFontWeightTextInputInputTypeTextAreaCheckboxGroupChipsSelectorRadioButtonsGroupMediaSizeFooterOptInDropdownEmbeddedLinkNavigationListNavigationItemNavigationItemStartNavigationItemMainContentNavigationItemEndDatePickerCalendarPickerCalendarPickerModeCalendarDayImageScaleTypePhotoPickerPhotoSourceDocumentPickerIfSwitchDataSourceDataExchangeActionNavigateActionCompleteActionUpdateDataActionOpenURLActionNextNextTypeFlowStrScreenDataRefComponentRefConditionMathExpression
- Flow Types
FlowRequestFlowRequestActionTypeFlowResponseFlowCategoryFlowDetailsFlowStatusFlowPreviewFlowJSONUpdateResultFlowValidationErrorFlowAssetFlowMetricNameFlowMetricGranularityCreatedFlowMigrateFlowsResponseMigratedFlowMigratedFlowErrorFlowResponseErrorFlowTokenNoLongerValidFlowRequestSignatureAuthenticationFailedFlowRequestDecryptedMediaFlowRequestDecryptorFlowResponseEncryptordefault_flow_request_decryptor()default_flow_response_encryptor()flow_request_media_decryptor()FlowRequestCallbackWrapper
- Flow JSON
- π Templates
- Defining Template
- Template Components
- Creating Template
- Sending Template
- Media Templates
- Authentication Templates
- Template Library
- Template Types
TemplateTemplateDetailsTemplateStatusQualityScoreLibraryTemplateTemplateCategoryTemplateLanguageParamFormatHeaderTextHeaderImageHeaderVideoHeaderDocumentHeaderGIFHeaderLocationHeaderProductBodyTextDateTimeCurrencyFooterTextButtonsCopyCodeButtonFlowButtonFlowButtonIconPhoneNumberButtonVoiceCallButtonCallPermissionRequestButtonQuickReplyButtonURLButtonAppDeepLinkCatalogButtonMPMButtonSPMButtonOneTapOTPButtonZeroTapOTPButtonCopyCodeOTPButtonOTPSupportedAppLimitedTimeOfferCarouselCarouselCardTapTargetConfigurationAuthenticationBodyAuthenticationFooterTemplatesResultCreatedTemplateCreatedTemplatesUpdatedTemplateTemplateUnpauseResultTemplatesCompareResultTopBlockReasonTypeMigrateTemplatesResultMigratedTemplateMigratedTemplateErrorDegreesOfFreedomSpecCreativeFeaturesSpec
- Template Types
- π¬ Filters
- Basic Usage
- Combining Filters
- Custom Filters
- Built-in Filters
- Common filters
new()filters.messagefilters.callback_buttonfilters.callback_selectionfilters.message_statusfilters.flow_completionfilters.call_connectfilters.call_terminatefilters.call_statusfilters.call_permission_updatefilters.user_marketing_preferencesfilters.template_statusfilters.template_categoryfilters.template_qualityfilters.template_componentsfilters.phone_number_changefilters.identity_changefilters.account_updatefilters.privatefilters.groupsent_to()filters.sent_to_mefrom_users()from_countries()matches()contains()startswith()endswith()regex()
- Message Filters
filters.forwardedfilters.forwarded_many_timesfilters.replyreplays_to()filters.has_referred_productfilters.textfilters.is_commandcommand()filters.mediamimetypes()extensions()filters.has_captionfilters.imagefilters.videofilters.audiofilters.audio_onlyfilters.voicefilters.documentfilters.stickerfilters.animated_stickerfilters.static_stickerfilters.reactionfilters.reaction_addedfilters.reaction_removedreaction_emojis()filters.unsupportedfilters.locationfilters.current_locationlocation_in_radius()filters.contactsfilters.contacts_has_wafilters.order
- Message Status Filters
- Common filters
- β οΈ Errors
- Basic Example
- Message Status Errors
- Handling Specific Errors
- Incoming Errors (Unsupported Messages)
- Catching All Exceptions
- Base Exception
- Categories of Exceptions
- Sending Messages Errors
SendMessageErrorMessageUndeliverableReEngagementMessageUnsupportedMessageTypeRecipientNotInAllowedListInvalidParameterMissingRequiredParameterMediaDownloadErrorMediaUploadErrorTemplateParamCountMismatchTemplateParamFormatMismatchTemplateNotExistsTemplateTextTooLongGenericErrorUnknownErrorAccessDeniedServiceUnavailableRecipientCannotBeSenderBusinessPaymentIssueIncorrectCertificateAccountInMaintenanceModeUserIsInExperimentGroupRecipientIdentityKeyMismatchUserStoppedMarketingMessagesBSUIDRecipientNotSupportedMarketingTemplatesDisabledForCloudAPI
- Flows Errors
- Authorization Errors
- Rate Limit Errors
- Integrity Errors
- Block Users Errors
- Calling Errors
- Username Errors
- Template Creation Errors
- Group Errors
GroupErrorBadGroupGroupUnknownGroupInvalidCursorGroupRequestPartiallySucceededGroupDuplicateParticipantGroupParticipantOverlimitGroupSuspendedGroupRateLimitHitGroupInvalidProfilePictureAspectRatioGroupImageTooSmallGroupCreationLimitReachedGroupParticipantNotInGroupGroupJoinRequestDoesNotExistGroupCreationTemporarilyDisabledGroupAPINotEligible
- Sending Messages Errors
- βοΈ Types
- Media
- Keyboard
- Others
SentMessageSentTemplateSentMediaMessageSentVoiceMessageSentLocationRequestSentReactionSentTemplateStatusSuccessResultResultPaginationBusinessVerificationStatusMarketingMessagesLiteAPIStatusMarketingMessagesOnboardingStatusBusinessProfileBusinessPhoneNumberBusinessPhoneNumberSettingsStorageConfigurationConversationalAutomationQRCodeQRCodeImageTypeCommandCommerceSettingsIndustryWhatsAppBusinessAccountFacebookApplicationUsersBlockedResultUsersUnblockedResultBlockUserFailureVersionStopHandlingContinueHandlingCallbackURLScopeWebhookFieldsstart_ngrok_tunnel()
- π₯ Groups
- π Calls
- Call Types
CallingSettingsCallingSettingsStatusCallIconVisibilityCallbackPermissionStatusSIPServerSIPStatusSTRPKeyExchangeProtocolCallHoursWeekDayMondayTuesdayWednesdayThursdayFridaySaturdaySundayHolidayScheduleCallPermissionsCallPermissionCallPermissionStatusCallPermissionActionCallPermissionActionLimit
- Call Types
- π‘ Examples
- π Changelog
- 4.0.0b7 (2026-04-30) Latest Beta
- 4.0.0b6 (2026-04-25)
- 4.0.0b5 (2026-04-17)
- 4.0.0b4 (2026-04-11)
- 4.0.0b3 (2026-04-01)
- 4.0.0b1 (2026-03-30)
- 3.9.0 (2026-03-11) Latest
- 3.8.0 (2026-01-23)
- 3.7.0 (2026-01-11)
- 3.6.1 (2025-12-11)
- 3.6.0 (2025-11-27)
- 3.5.2 (2025-11-17)
- 3.5.1 (2025-11-08)
- 3.5.0 (2025-11-08)
- 3.4.0 (2025-10-26)
- 3.3.0 (2025-10-26)
- 3.2.0 (2025-10-24)
- 3.1.1 (2025-09-21)
- 3.1.0 (2025-09-21)
- 3.0.0 (2025-08-22)
- 3.0.0-rc.3 (2025-08-06)
- 3.0.0-rc.2 (2025-08-04)
- 3.0.0-rc.1 (2025-07-31)
- 2.11.0 (2025-06-17)
- 2.10.0 (2025-05-14)
- 2.9.0 (2025-05-04)
- 2.8.0 (2025-04-27)
- 2.7.0 (2025-01-18)
- 2.6.0 (2025-01-11)
- 2.5.2 (2025-01-07)
- 2.5.1 (2025-01-02)
- 2.5.0 (2025-01-02)
- 2.4.0 (2024-12-14)
- 2.3.0 (2024-11-30)
- 2.2.0 (2024-11-29)
- 2.1.0 (2024-11-24)
- 2.0.5 (2024-11-10)
- 2.0.4 (2024-11-08)
- 2.0.3 (2024-11-02)
- 2.0.2 (2024-10-30)
- 2.0.1 (2024-10-30)
- 2.0.0 (2024-10-30)
- 1.26.0 (2024-09-22)
- 1.25.0 (2024-08-15)
- 1.24.0 (2024-07-26)
- 1.23.0 (2024-07-14)
- 1.22.0 (2024-06-16)
- 1.21.0 (2024-06-14)
- 1.20.2 (2024-06-02)
- 1.20.1 (2024-06-02)
- 1.20.0 (2024-06-02)
- 1.19.0-rc.3 (2024-05-23)
- 1.19.0-rc.2 (2024-05-17)
- 1.19.0-rc.1 (2024-05-08)
- 1.18.1 (2024-05-05)
- 1.18.0 (2024-05-02)
- 1.17.0 (2024-04-30)
- 1.16.2 (2024-02-15)
- 1.16.0 (2024-01-22)
- 1.15.0 (2024-01-14)
- 1.14.0 (2024-01-01)
- 1.13.0 (2023-12-22)
- 1.13.0-rc.6 (2023-12-20)
- 1.13.0-rc.5 (2023-12-18)
- 1.13.0-rc.4 (2023-12-16)
- 1.13.0-rc.3 (2023-12-15)
- 1.13.0-rc.2 (2023-12-14)
- 1.13.0-rc.1 (2023-12-14)
- 1.12.1 (2023-11-29)
- 1.12.0 (2023-11-20)
- 1.11.1 (2023-11-07)
- 1.11.0 (2023-11-01)
- 1.10.0 (2023-10-29)
- 1.9.0 (2023-10-25)
- 1.8.0 (2023-10-20)
- 1.7.3 (2023-10-18)
- 1.7.2 (2023-10-12)
- 1.7.1 (2023-10-12)
- 1.7.0 (2023-10-12)
- 1.6.0 (2023-10-11)
- 1.5.4 (2023-10-08)
- 1.5.3 (2023-10-03)
- 1.5.2 (2023-10-03)
- 1.5.1 (2023-10-02)
- 1.5.0 (2023-10-02)
- 1.4.1 (2023-09-12)
- 1.4.0 (2023-09-10)
- 1.3.0 (2023-09-06)
- 1.2.0 (2023-08-21)
- 1.1.0 (2023-08-20)
- 1.0.0 (2023-08-16)
- π€ Contributing
- Prerequisites
- Getting Started
- Code Standards
- Making Changes
- Communication
- License
- Project Structure
- π Migration
- Migration from 3.x to 4.x
- Migration from 2.x to 3.x
- Migration from 1.x to 2.x