---title: SIP Voicemail - Pythonslug: /guides/voice/sip-voicemail-python---Having voicemail available is an important part of any phone system, and calls to SIP endpoints are no exception. There are a couple different ways to handle voicemails for SIP. You could use a [Domain Application](../../../guides/general/sip-domain-apps/index.mdx) set up with two LaML bin webhooks. The first would dial your SIP endpoint with a timeout parameter. The second would record a voicemail if the call was not answered within the timeout time. To demonstrate how to set this up without a Domain application, this example will accomplish the same task with the [Compatibility SDK with Python](https://docs.signalwire.com/reference/compatibility-sdks/v3/#compatibility-rest-api-client-libraries-and-sdks-python). We will configure a DID (SignalWire phone number) to accept incoming calls and dial our SIP endpoint, then record a voicemail if the call is unanswered. You can clone the [GitHub repo](https://github.com/signalwire/examples/tree/main/Voice/SIP%20Voicemail%20with%20Python) to follow along, test, and change to meet your needs.## Setup Your EnvironmentFirst, you need to provide the application with environmental variables. Copy the contents of env.example and save them in a new file called .env. Fill in your SignalWire credentials.# Project ID copied from the API Credentials in your SignalWire SpacePROJECT_ID=# API token copied from the API Credentials in your SignalWire SpaceAPI_TOKEN=# Your SignalWire Space URL copied from the API Credentials in your SignalWire SpaceSIGNALWIRE_URL=If you need help finding this information, check out our guide to [Navigating Your SignalWire Space](/guides/navigating-your-space#api).The Compatibility SDK will pull these environmental variables from the .env file without any import statement as long as the .env file is in the same parent directory.## Run Your Flask ServerThis example serves our webhooks using a [Flask](https://flask.palletsprojects.com/en/2.2.x/installation/) server. After your environmental variables are set, you can install dependencies with pipenv install then start the Flask server with pipenv run dev. If you prefer to use Docker, build the image with docker build -t sipvoicemail . and run it with docker run --p 3000:3000 --env-file .env sipvoicemail.## Test Endpoints with NgrokNow, we need a way for our SignalWire service to reach those webhooks. SignalWire requires that your webhooks be publicly accessible for them to be used with our services. So, we recommend using [Ngrok](https://ngrok.com/download) to provide an HTTPS URL for testing. In your Ngrok CLI, run ngrok http 3000, where 3000 is the port we set in our Flask server. It will return a secure URL you can copy for the next step.## Configure a Number to Accept Incoming CallsFor this voicemail setup, a phone number is the intermediary that accepts incoming calls and dials your SIP endpoint. In your SignalWire Dashboard, you can purchase a phone number and edit its settings to direct calls to the Ngrok URL. The settings for your phone number of choice will look something like this:With your server and Ngrok running, you should now be able to dial this number and test this example.## Code WalkthroughAll the logic of our program lives within the [index.py](https://github.com/signalwire/examples/blob/main/Voice/SIP%20Voicemail%20with%20Python/index.py) file. It is a simple Flask server serving just three POST routes: an entry route, a voicemail route, and a hangup route.When a call comes in, our setup will hit the default endpoint we have defined. It says a message then dials our SIP endpoint. It is important to note that our dial method has a 15 second timeout before its action redirects it to the voicemail route.The voicemail route will confirm that the call status is completed then ask the caller to record a message. It then starts a recording, and its action directs the call the the hangup route when the recording finishes.The hangup route receives the recording object then hangs up the call.You will notice that these routes all use the same syntax to use the [Compatibility SDK](https://docs.signalwire.com/reference/compatibility-sdks/v3/#compatibility-rest-api-client-libraries-and-sdks-python). We generate XML to run and send it with the following lines.pythonresponse = VoiceResponse()# logic with XML verbs, for example:response.say(Welcome to SignalWire.)return Response(str(response), mimetype=text/xml)Following the same pattern, you can use [Compatibility XML](/compatibility-api/xml/index.mdx) to extend this example to suit your needs.## Wrap UpThis guide shows you one of the ways to set up voicemail if your phone system ends at SIP endpoints.For an example of a full IVR using the Python Compatibility SDK, see [Dynamic IVR using Python](../dynamic-ivr-using-json-menus.mdx). Although that example dials numbers, you can easily substitute SIP endpoints as we did here.